PostgreSQL Source Code: src/backend/regex/regexec.c File Reference (original) (raw)
Go to the source code of this file.
Data Structures | |
---|---|
struct | arcp |
struct | sset |
struct | dfa |
struct | smalldfa |
struct | vars |
Macros | |
---|---|
#define | HASH(bv, nw) (((nw) == 1) ? *(bv) : hash(bv, nw)) |
#define | HIT(h, bv, ss, nw) |
#define | STARTER 01 /* the initial state set */ |
#define | POSTSTATE 02 /* includes the goal state */ |
#define | LOCKED 04 /* locked in cache */ |
#define | NOPROGRESS 010 /* zero-progress state set */ |
#define | WORK 1 /* number of work bitvectors needed */ |
#define | FEWSTATES 20 /* must be less than UBITS */ |
#define | FEWCOLORS 15 |
#define | DOMALLOC ((struct smalldfa *)NULL) /* force malloc */ |
#define | VISERR(vv) ((vv)->err != 0) /* have we seen an error yet? */ |
#define | ISERR() VISERR(v) |
#define | VERR(vv, e) ((vv)->err = ((vv)->err ? (vv)->err : (e))) |
#define | ERR(e) VERR(v, e) /* record an error */ |
#define | NOERR() {if (ISERR()) return v->err;} /* if error seen, return it */ |
#define | OFF(p) ((p) - v->start) |
#define | LOFF(p) ((long)OFF(p)) |
#define | LOCALMAT 20 |
#define | LOCALDFAS 40 |
Functions | |
---|---|
static struct dfa * | getsubdfa (struct vars *v, struct subre *t) |
static struct dfa * | getladfa (struct vars *v, int n) |
static int | find (struct vars *v, struct cnfa *cnfa, struct colormap *cm) |
static int | cfind (struct vars *v, struct cnfa *cnfa, struct colormap *cm) |
static int | cfindloop (struct vars *v, struct cnfa *cnfa, struct colormap *cm, struct dfa *d, struct dfa *s, chr **coldp) |
static void | zapallsubs (regmatch_t *p, size_t n) |
static void | zaptreesubs (struct vars *v, struct subre *t) |
static void | subset (struct vars *v, struct subre *sub, chr *begin, chr *end) |
static int | cdissect (struct vars *v, struct subre *t, chr *begin, chr *end) |
static int | ccondissect (struct vars *v, struct subre *t, chr *begin, chr *end) |
static int | crevcondissect (struct vars *v, struct subre *t, chr *begin, chr *end) |
static int | cbrdissect (struct vars *v, struct subre *t, chr *begin, chr *end) |
static int | caltdissect (struct vars *v, struct subre *t, chr *begin, chr *end) |
static int | citerdissect (struct vars *v, struct subre *t, chr *begin, chr *end) |
static int | creviterdissect (struct vars *v, struct subre *t, chr *begin, chr *end) |
static chr * | longest (struct vars *v, struct dfa *d, chr *start, chr *stop, int *hitstopp) |
static chr * | shortest (struct vars *v, struct dfa *d, chr *start, chr *min, chr *max, chr **coldp, int *hitstopp) |
static int | matchuntil (struct vars *v, struct dfa *d, chr *probe, struct sset **lastcss, chr **lastcp) |
static chr * | dfa_backref (struct vars *v, struct dfa *d, chr *start, chr *min, chr *max, bool shortest) |
static chr * | lastcold (struct vars *v, struct dfa *d) |
static struct dfa * | newdfa (struct vars *v, struct cnfa *cnfa, struct colormap *cm, struct smalldfa *sml) |
static void | freedfa (struct dfa *d) |
static unsigned | hash (unsigned *uv, int n) |
static struct sset * | initialize (struct vars *v, struct dfa *d, chr *start) |
static struct sset * | miss (struct vars *v, struct dfa *d, struct sset *css, color co, chr *cp, chr *start) |
static int | lacon (struct vars *v, struct cnfa *pcnfa, chr *cp, color co) |
static struct sset * | getvacant (struct vars *v, struct dfa *d, chr *cp, chr *start) |
static struct sset * | pickss (struct vars *v, struct dfa *d, chr *cp, chr *start) |
int | pg_regexec (regex_t *re, const chr *string, size_t len, size_t search_start, rm_detail_t *details, size_t nmatch, regmatch_t pmatch[], int flags) |
◆ DOMALLOC
◆ ERR
◆ FEWCOLORS
◆ FEWSTATES
#define FEWSTATES 20 /* must be less than UBITS */
◆ HASH
| #define HASH | ( | | bv, | | ------------ | -------------------------------------------------------------------------------------------- | | --- | | | nw | | | | | ) | (((nw) == 1) ? *(bv) : hash(bv, nw)) | | |
◆ HIT
| #define HIT | ( | | h, | | ----------- | - | | -- | | | bv, | | | | | | ss, | | | | | | nw | | | | | ) | | | |
Value:
((ss)->hash == (h) && ((nw) == 1 || \
memcmp(VS(bv), VS((ss)->states), (nw)*sizeof(unsigned)) == 0))
static unsigned hash(unsigned *uv, int n)
Definition at line 50 of file regexec.c.
◆ ISERR
◆ LOCALDFAS
◆ LOCALMAT
◆ LOCKED
#define LOCKED 04 /* locked in cache */
◆ LOFF
| #define LOFF | ( | | p | ) | ((long)OFF(p)) | | ------------ | - | | - | - | ------------------------------------------------------------------ |
◆ NOERR
◆ NOPROGRESS
◆ OFF
| #define OFF | ( | | p | ) | ((p) - v->start) | | ----------- | - | | - | - | ------------------------------------------------------------------------------------ |
◆ POSTSTATE
#define POSTSTATE 02 /* includes the goal state */
◆ STARTER
#define STARTER 01 /* the initial state set */
◆ VERR
| #define VERR | ( | | vv, | | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | --- | | | e | | | | | ) | ((vv)->err = ((vv)->err ? (vv)->err : (e))) | | |
◆ VISERR
| #define VISERR | ( | | vv | ) | ((vv)->err != 0) /* have we seen an error yet? */ | | -------------- | - | | -- | - | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
◆ WORK
#define WORK 1 /* number of work bitvectors needed */
◆ caltdissect()
static int caltdissect ( struct vars * v, struct subre * t, chr * begin, chr * end ) | static |
---|
Definition at line 1076 of file regexec.c.
1080{
1081 struct dfa *d;
1082 int er;
1083
1085
1087
1089
1090 while (t != NULL)
1091 {
1093
1094 MDEBUG(("%d: caltdissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end)));
1095
1098 if (longest(v, d, begin, end, (int *) NULL) == end)
1099 {
1100 MDEBUG(("%d: caltdissect matched\n", t->id));
1101 er = cdissect(v, t, begin, end);
1103 return er;
1104 }
1106
1108 }
1109
1111}
static struct dfa * getsubdfa(struct vars *v, struct subre *t)
static chr * longest(struct vars *v, struct dfa *d, chr *start, chr *stop, int *hitstopp)
static int cdissect(struct vars *v, struct subre *t, chr *begin, chr *end)
References assert, cdissect(), subre::child, subre::cnfa, getsubdfa(), subre::id, LOFF, longest(), MDEBUG, NOERR, cnfa::nstates, subre::op, REG_NOMATCH, and subre::sibling.
Referenced by cdissect().
◆ cbrdissect()
static int cbrdissect ( struct vars * v, struct subre * t, chr * begin, chr * end ) | static |
---|
Definition at line 994 of file regexec.c.
998{
1000 size_t numreps;
1001 size_t tlen;
1002 size_t brlen;
1003 chr *brstring;
1005 int min = t->min;
1006 int max = t->max;
1007
1011 assert((size_t) n < v->nmatch);
1012
1013 MDEBUG(("%d: cbrdissect %d{%d-%d} %ld-%ld\n", t->id, n, min, max,
1015
1016
1017 if (v->pmatch[n].rm_so == -1)
1019 brstring = v->start + v->pmatch[n].rm_so;
1020 brlen = v->pmatch[n].rm_eo - v->pmatch[n].rm_so;
1021
1022
1023 if (brlen == 0)
1024 {
1025
1026
1027
1028
1029 if (begin == end && min <= max)
1030 {
1031 MDEBUG(("%d: backref matched trivially\n", t->id));
1033 }
1035 }
1036 if (begin == end)
1037 {
1038
1039 if (min == 0)
1040 {
1041 MDEBUG(("%d: backref matched trivially\n", t->id));
1043 }
1045 }
1046
1047
1048
1049
1050
1051 assert(end > begin);
1052 tlen = end - begin;
1053 if (tlen % brlen != 0)
1055 numreps = tlen / brlen;
1056 if (numreps < min || (numreps > max && max != DUPINF))
1058
1059
1060 p = begin;
1061 while (numreps-- > 0)
1062 {
1063 if ((*v->g->compare) (brstring, p, brlen) != 0)
1065 p += brlen;
1066 }
1067
1068 MDEBUG(("%d: backref matched\n", t->id));
1070}
References assert, subre::backno, DUPINF, vars::g, subre::id, LOFF, subre::max, MDEBUG, subre::min, subre::op, vars::pmatch, REG_NOMATCH, REG_OKAY, and vars::start.
Referenced by cdissect().
◆ ccondissect()
static int ccondissect ( struct vars * v, struct subre * t, chr * begin, chr * end ) | static |
---|
Definition at line 829 of file regexec.c.
833{
836 struct dfa *d;
837 struct dfa *d2;
838 chr *mid;
839 int er;
840
846
851 MDEBUG(("%d: ccondissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end)));
852
853
854 mid = longest(v, d, begin, end, (int *) NULL);
856 if (mid == NULL)
858 MDEBUG(("%d: tentative midpoint %ld\n", t->id, LOFF(mid)));
859
860
861 for (;;)
862 {
863
864 if (longest(v, d2, mid, end, (int *) NULL) == end)
865 {
866 er = cdissect(v, left, begin, mid);
868 {
869 er = cdissect(v, right, mid, end);
871 {
872
873 MDEBUG(("%d: successful\n", t->id));
875 }
876
878 }
880 return er;
881 }
883
884
885 if (mid == begin)
886 {
887
888 MDEBUG(("%d: no midpoint\n", t->id));
890 }
891 mid = longest(v, d, begin, mid - 1, (int *) NULL);
893 if (mid == NULL)
894 {
895
896 MDEBUG(("%d: failed midpoint\n", t->id));
898 }
899 MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid)));
900 }
901
902
904}
static void zaptreesubs(struct vars *v, struct subre *t)
References assert, cdissect(), subre::child, subre::cnfa, subre::flags, getsubdfa(), subre::id, LOFF, longest(), MDEBUG, NOERR, cnfa::nstates, subre::op, REG_ASSERT, REG_NOMATCH, REG_OKAY, SHORTER, subre::sibling, and zaptreesubs().
Referenced by cdissect().
◆ cdissect()
static int cdissect ( struct vars * v, struct subre * t, chr * begin, chr * end ) | static |
---|
Definition at line 756 of file regexec.c.
760{
761 int er;
762
764 MDEBUG(("%d: cdissect %c %ld-%ld\n", t->id, t->op, LOFF(begin), LOFF(end)));
765
766
768
771
772 switch (t->op)
773 {
774 case '=':
776 er = REG_OKAY;
777 break;
778 case 'b':
781 break;
782 case '.':
786 else
788 break;
789 case '|':
792 break;
793 case '*':
797 else
799 break;
800 case '(':
803 break;
804 default:
806 break;
807 }
808
809
810
811
812
813
815
816
817
818
820 subset(v, t, begin, end);
821
822 return er;
823}
static int citerdissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static int ccondissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static int creviterdissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static int cbrdissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static int crevcondissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static int caltdissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static void subset(struct vars *v, struct subre *sub, chr *begin, chr *end)
#define STACK_TOO_DEEP(re)
References assert, BACKR, subre::begin, caltdissect(), subre::capno, cbrdissect(), ccondissect(), cdissect(), subre::child, citerdissect(), crevcondissect(), creviterdissect(), subre::end, subre::flags, subre::id, INTERRUPT, LOFF, MDEBUG, subre::op, vars::re, REG_ASSERT, REG_ETOOBIG, REG_NOMATCH, REG_OKAY, SHORTER, STACK_TOO_DEEP, and subset().
Referenced by caltdissect(), ccondissect(), cdissect(), cfindloop(), citerdissect(), crevcondissect(), creviterdissect(), and find().
◆ cfind()
static int cfind ( struct vars * v, struct cnfa * cnfa, struct colormap * cm ) | static |
---|
Definition at line 509 of file regexec.c.
512{
513 struct dfa *s;
514 struct dfa *d;
515 chr *cold;
516 int ret;
517
519 if (s == NULL)
520 return v->err;
522 if (d == NULL)
523 {
525 return v->err;
526 }
527
529
534 {
536 if (cold != NULL)
538 else
541 }
542 return ret;
543}
static void freedfa(struct dfa *d)
static int cfindloop(struct vars *v, struct cnfa *cnfa, struct colormap *cm, struct dfa *d, struct dfa *s, chr **coldp)
static struct dfa * newdfa(struct vars *v, struct cnfa *cnfa, struct colormap *cm, struct smalldfa *sml)
References assert, cfindloop(), guts::cflags, dfa::cm, vars::details, vars::dfa1, vars::dfa2, vars::err, freedfa(), vars::g, newdfa(), NOERR, OFF, REG_EXPECT, pg_regmatch_t::rm_eo, rm_detail_t::rm_extend, pg_regmatch_t::rm_so, guts::search, and vars::stop.
Referenced by pg_regexec().
◆ cfindloop()
static int cfindloop ( struct vars * v, struct cnfa * cnfa, struct colormap * cm, struct dfa * d, struct dfa * s, chr ** coldp ) | static |
---|
Definition at line 549 of file regexec.c.
555{
556 chr *begin;
557 chr *end;
558 chr *cold;
559 chr *open;
561 chr *estart;
562 chr *estop;
563 int er;
565 int hitend;
566
567 assert(d != NULL && s != NULL);
568 cold = NULL;
570 do
571 {
572
576 {
577 *coldp = cold;
578 return v->err;
579 }
580 if (close == NULL)
581 break;
582 assert(cold != NULL);
583 open = cold;
584 cold = NULL;
585
587 for (begin = open; begin <= close; begin++)
588 {
589 MDEBUG(("\ncfind trying at %ld\n", LOFF(begin)));
590 estart = begin;
591 estop = v->stop;
592 for (;;)
593 {
594
595 if (shorter)
596 end = shortest(v, d, begin, estart,
597 estop, (chr **) NULL, &hitend);
598 else
599 end = longest(v, d, begin, estop,
600 &hitend);
602 {
603 *coldp = cold;
604 return v->err;
605 }
606 if (hitend && cold == NULL)
607 cold = begin;
608 if (end == NULL)
609 break;
610 MDEBUG(("tentative end %ld\n", LOFF(end)));
611
614 {
616 {
619 }
620 *coldp = cold;
622 }
624 {
626 *coldp = cold;
627 return er;
628 }
629
630 if (shorter)
631 {
632 if (end == estop)
633 break;
634 estart = end + 1;
635 }
636 else
637 {
638 if (end == begin)
639 break;
640 estop = end - 1;
641 }
642 }
643 }
644
645
646
647
648
649
651 } while (close < v->stop);
652
653 *coldp = cold;
655}
static chr * shortest(struct vars *v, struct dfa *d, chr *start, chr *min, chr *max, chr **coldp, int *hitstopp)
References assert, cdissect(), close, vars::err, ERR, subre::flags, vars::g, ISERR, LOFF, longest(), MDEBUG, vars::nmatch, OFF, vars::pmatch, REG_NOMATCH, REG_OKAY, vars::search_start, SHORTER, shortest(), vars::stop, and guts::tree.
Referenced by cfind().
◆ citerdissect()
static int citerdissect ( struct vars * v, struct subre * t, chr * begin, chr * end ) | static |
---|
Definition at line 1117 of file regexec.c.
1121{
1122 struct dfa *d;
1123 chr **endpts;
1124 chr *limit;
1125 int min_matches;
1126 size_t max_matches;
1127 int nverified;
1128 int k;
1129 int i;
1130 int er;
1131
1135 assert(begin <= end);
1136
1137 MDEBUG(("%d: citerdissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end)));
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148 min_matches = t->min;
1149 if (min_matches <= 0)
1150 min_matches = 1;
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161 max_matches = end - begin;
1162 if (max_matches > t->max && t->max != DUPINF)
1163 max_matches = t->max;
1164 if (max_matches < min_matches)
1165 max_matches = min_matches;
1166 endpts = (chr **) MALLOC((max_matches + 1) * sizeof(chr *));
1167 if (endpts == NULL)
1169 endpts[0] = begin;
1170
1173 {
1174 FREE(endpts);
1175 return v->err;
1176 }
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189 nverified = 0;
1190 k = 1;
1191 limit = end;
1192
1193
1194 while (k > 0)
1195 {
1196
1197 endpts[k] = longest(v, d, endpts[k - 1], limit, (int *) NULL);
1199 {
1200 FREE(endpts);
1201 return v->err;
1202 }
1203 if (endpts[k] == NULL)
1204 {
1205
1206 k--;
1207 goto backtrack;
1208 }
1209 MDEBUG(("%d: working endpoint %d: %ld\n",
1210 t->id, k, LOFF(endpts[k])));
1211
1212
1213 if (nverified >= k)
1214 nverified = k - 1;
1215
1216 if (endpts[k] != end)
1217 {
1218
1219 if (k >= max_matches)
1220 {
1221
1222 k--;
1223 goto backtrack;
1224 }
1225
1226
1227 if (endpts[k] == endpts[k - 1] &&
1228 (k >= min_matches || min_matches - k < end - endpts[k]))
1229 goto backtrack;
1230
1231 k++;
1232 limit = end;
1233 continue;
1234 }
1235
1236
1237
1238
1239
1240
1241
1242 if (k < min_matches)
1243 goto backtrack;
1244
1245 MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k));
1246
1247 for (i = nverified + 1; i <= k; i++)
1248 {
1249
1253 {
1254 nverified = i;
1255 continue;
1256 }
1258 break;
1259
1260 FREE(endpts);
1261 return er;
1262 }
1263
1264 if (i > k)
1265 {
1266
1267 MDEBUG(("%d: successful\n", t->id));
1268 FREE(endpts);
1270 }
1271
1272
1273 k = i;
1274
1275backtrack:
1276
1277
1278
1279
1280
1281 while (k > 0)
1282 {
1283 chr *prev_end = endpts[k - 1];
1284
1285 if (endpts[k] > prev_end)
1286 {
1287 limit = endpts[k] - 1;
1288 if (limit > prev_end ||
1289 (k < min_matches && min_matches - k >= end - prev_end))
1290 {
1291
1292 break;
1293 }
1294 }
1295
1296 k--;
1297 }
1298 }
1299
1300
1301 FREE(endpts);
1302
1303
1304
1305
1306
1307 if (t->min == 0 && begin == end)
1308 {
1309 MDEBUG(("%d: allowing zero matches\n", t->id));
1311 }
1312
1313 MDEBUG(("%d: failed\n", t->id));
1315}
References assert, cdissect(), subre::child, subre::cnfa, DUPINF, vars::err, subre::flags, FREE, getsubdfa(), i, subre::id, ISERR, LOFF, longest(), MALLOC, subre::max, MDEBUG, subre::min, cnfa::nstates, subre::op, REG_ESPACE, REG_NOMATCH, REG_OKAY, SHORTER, and zaptreesubs().
Referenced by cdissect().
◆ crevcondissect()
static int crevcondissect ( struct vars * v, struct subre * t, chr * begin, chr * end ) | static |
---|
Definition at line 910 of file regexec.c.
914{
917 struct dfa *d;
918 struct dfa *d2;
919 chr *mid;
920 int er;
921
927
932 MDEBUG(("%d: crevcondissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end)));
933
934
935 mid = shortest(v, d, begin, begin, end, (chr **) NULL, (int *) NULL);
937 if (mid == NULL)
939 MDEBUG(("%d: tentative midpoint %ld\n", t->id, LOFF(mid)));
940
941
942 for (;;)
943 {
944
945 if (longest(v, d2, mid, end, (int *) NULL) == end)
946 {
947 er = cdissect(v, left, begin, mid);
949 {
950 er = cdissect(v, right, mid, end);
952 {
953
954 MDEBUG(("%d: successful\n", t->id));
956 }
957
959 }
961 return er;
962 }
964
965
966 if (mid == end)
967 {
968
969 MDEBUG(("%d: no midpoint\n", t->id));
971 }
972 mid = shortest(v, d, begin, mid + 1, end, (chr **) NULL, (int *) NULL);
974 if (mid == NULL)
975 {
976
977 MDEBUG(("%d: failed midpoint\n", t->id));
979 }
980 MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid)));
981 }
982
983
985}
References assert, cdissect(), subre::child, subre::cnfa, subre::flags, getsubdfa(), subre::id, LOFF, longest(), MDEBUG, NOERR, cnfa::nstates, subre::op, REG_ASSERT, REG_NOMATCH, REG_OKAY, SHORTER, shortest(), subre::sibling, and zaptreesubs().
Referenced by cdissect().
◆ creviterdissect()
static int creviterdissect ( struct vars * v, struct subre * t, chr * begin, chr * end ) | static |
---|
Definition at line 1321 of file regexec.c.
1325{
1326 struct dfa *d;
1327 chr **endpts;
1328 chr *limit;
1329 int min_matches;
1330 size_t max_matches;
1331 int nverified;
1332 int k;
1333 int i;
1334 int er;
1335
1339 assert(begin <= end);
1340
1341 MDEBUG(("%d: creviterdissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end)));
1342
1343
1344
1345
1346
1347
1348 min_matches = t->min;
1349 if (min_matches <= 0)
1350 {
1351 if (begin == end)
1352 {
1353 MDEBUG(("%d: allowing zero matches\n", t->id));
1355 }
1356 min_matches = 1;
1357 }
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368 max_matches = end - begin;
1369 if (max_matches > t->max && t->max != DUPINF)
1370 max_matches = t->max;
1371 if (max_matches < min_matches)
1372 max_matches = min_matches;
1373 endpts = (chr **) MALLOC((max_matches + 1) * sizeof(chr *));
1374 if (endpts == NULL)
1376 endpts[0] = begin;
1377
1380 {
1381 FREE(endpts);
1382 return v->err;
1383 }
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396 nverified = 0;
1397 k = 1;
1398 limit = begin;
1399
1400
1401 while (k > 0)
1402 {
1403
1404 if (limit == endpts[k - 1] &&
1405 limit != end &&
1406 (k >= min_matches || min_matches - k < end - limit))
1407 limit++;
1408
1409
1410 if (k >= max_matches)
1411 limit = end;
1412
1413
1414 endpts[k] = shortest(v, d, endpts[k - 1], limit, end,
1415 (chr **) NULL, (int *) NULL);
1417 {
1418 FREE(endpts);
1419 return v->err;
1420 }
1421 if (endpts[k] == NULL)
1422 {
1423
1424 k--;
1425 goto backtrack;
1426 }
1427 MDEBUG(("%d: working endpoint %d: %ld\n",
1428 t->id, k, LOFF(endpts[k])));
1429
1430
1431 if (nverified >= k)
1432 nverified = k - 1;
1433
1434 if (endpts[k] != end)
1435 {
1436
1437 if (k >= max_matches)
1438 {
1439
1440 k--;
1441 goto backtrack;
1442 }
1443
1444 k++;
1445 limit = endpts[k - 1];
1446 continue;
1447 }
1448
1449
1450
1451
1452
1453
1454
1455 if (k < min_matches)
1456 goto backtrack;
1457
1458 MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k));
1459
1460 for (i = nverified + 1; i <= k; i++)
1461 {
1462
1466 {
1467 nverified = i;
1468 continue;
1469 }
1471 break;
1472
1473 FREE(endpts);
1474 return er;
1475 }
1476
1477 if (i > k)
1478 {
1479
1480 MDEBUG(("%d: successful\n", t->id));
1481 FREE(endpts);
1483 }
1484
1485
1486 k = i;
1487
1488backtrack:
1489
1490
1491
1492
1493 while (k > 0)
1494 {
1495 if (endpts[k] < end)
1496 {
1497 limit = endpts[k] + 1;
1498
1499 break;
1500 }
1501
1502 k--;
1503 }
1504 }
1505
1506
1507 MDEBUG(("%d: failed\n", t->id));
1508 FREE(endpts);
1510}
References assert, cdissect(), subre::child, subre::cnfa, DUPINF, vars::err, subre::flags, FREE, getsubdfa(), i, subre::id, ISERR, LOFF, MALLOC, subre::max, MDEBUG, subre::min, cnfa::nstates, subre::op, REG_ESPACE, REG_NOMATCH, REG_OKAY, SHORTER, shortest(), and zaptreesubs().
Referenced by cdissect().
◆ dfa_backref()
static chr * dfa_backref ( struct vars * v, struct dfa * d, chr * start, chr * min, chr * max, bool shortest ) | static |
---|
◆ find()
static int find ( struct vars * v, struct cnfa * cnfa, struct colormap * cm ) | static |
---|
Definition at line 419 of file regexec.c.
422{
423 struct dfa *s;
424 struct dfa *d;
425 chr *begin;
426 chr *end = NULL;
427 chr *cold;
428 chr *open;
430 int hitend;
432
433
435 if (s == NULL)
436 return v->err;
438 cold = NULL;
440 &cold, (int *) NULL);
444 {
446 if (cold != NULL)
448 else
451 }
452 if (close == NULL)
454 if (v->nmatch == 0)
456
457
458 assert(cold != NULL);
459 open = cold;
460 cold = NULL;
463 if (d == NULL)
464 return v->err;
465 for (begin = open; begin <= close; begin++)
466 {
467 MDEBUG(("\nfind trying at %ld\n", LOFF(begin)));
468 if (shorter)
470 (chr **) NULL, &hitend);
471 else
472 end = longest(v, d, begin, v->stop, &hitend);
474 {
476 return v->err;
477 }
478 if (hitend && cold == NULL)
479 cold = begin;
480 if (end != NULL)
481 break;
482 }
483 assert(end != NULL);
485
486
491 {
492 if (cold != NULL)
494 else
497 }
498 if (v->nmatch == 1)
500
501
503}
References assert, cdissect(), guts::cflags, close, dfa::cm, vars::details, vars::dfa1, vars::err, subre::flags, freedfa(), vars::g, ISERR, LOFF, longest(), MDEBUG, newdfa(), vars::nmatch, NOERR, OFF, vars::pmatch, REG_EXPECT, REG_NOMATCH, REG_OKAY, pg_regmatch_t::rm_eo, rm_detail_t::rm_extend, pg_regmatch_t::rm_so, guts::search, vars::search_start, SHORTER, shortest(), vars::start, vars::stop, and guts::tree.
Referenced by NIAddAffix(), NIImportAffixes(), NIImportOOAffixes(), parse_affentry(), parse_ooaffentry(), pg_regexec(), and testdelete().
◆ freedfa()
static void freedfa ( struct dfa * d) | static |
---|
◆ getladfa()
static struct dfa * getladfa ( struct vars * v, int n ) | static |
---|
◆ getsubdfa()
static struct dfa * getsubdfa ( struct vars * v, struct subre * t ) | static |
---|
Definition at line 372 of file regexec.c.
374{
376
377 if (d == NULL)
378 {
380 if (d == NULL)
381 return NULL;
382
383 if (t->op == 'b')
384 {
388 }
390 }
391 return d;
392}
References dfa::backmax, dfa::backmin, dfa::backno, subre::backno, guts::cmap, subre::cnfa, DOMALLOC, vars::g, subre::id, subre::max, subre::min, newdfa(), subre::op, and vars::subdfas.
Referenced by caltdissect(), ccondissect(), citerdissect(), crevcondissect(), and creviterdissect().
◆ getvacant()
static struct sset * getvacant ( struct vars * v, struct dfa * d, chr * cp, chr * start ) | static |
---|
◆ hash()
static unsigned hash ( unsigned * uv, int n ) | static |
---|
◆ initialize()
static struct sset * initialize ( struct vars * v, struct dfa * d, chr * start ) | static |
---|
◆ lacon()
static int lacon ( struct vars * v, struct cnfa * pcnfa, chr * cp, color co ) | static |
---|
◆ lastcold()
static chr * lastcold ( struct vars * v, struct dfa * d ) | static |
---|
◆ longest()
static chr * longest ( struct vars * v, struct dfa * d, chr * start, chr * stop, int * hitstopp ) | static |
---|
◆ matchuntil()
static int matchuntil ( struct vars * v, struct dfa * d, chr * probe, struct sset ** lastcss, chr ** lastcp ) | static |
---|
◆ miss()
◆ newdfa()
◆ pg_regexec()
Definition at line 185 of file regexec.c.
193{
194 struct vars var;
195 struct vars *v = &var;
196 int st;
197 size_t n;
198 size_t i;
199 int backref;
200
201#define LOCALMAT 20
203
204#define LOCALDFAS 40
206
207
208 if (re == NULL || string == NULL || re->re_magic != REMAGIC)
210 if (re->re_csize != sizeof(chr))
212 if (search_start > len)
214
215
217
218
219 v->re = re;
220 v->g = (struct guts *) re->re_guts;
227 if (backref && nmatch <= v->g->nsub)
228 {
229
233 else
235 if (v->pmatch == NULL)
238 }
239 else
240 {
241
243
244 if (nmatch > 0)
246
247 if (nmatch > v->g->nsub + 1)
250 }
255 v->err = 0;
260
261
266 else
267 {
270 {
273 }
274 }
277
280 if (n > 0)
281 {
283 if (v->ladfas == NULL)
284 {
287 }
293 {
296 }
298 {
301 }
302 }
303
304
306 if (backref)
308 else
310
311
312 if (st == REG_OKAY && nmatch > 0)
313 {
314 if (v->pmatch != pmatch)
315 {
316
317 assert(nmatch <= v->nmatch);
319 }
321 {
322
324 }
325 }
326
327
332 {
335 {
338 }
339 if (v->subdfas != subdfas)
341 }
342 if (v->ladfas != NULL)
343 {
346 {
349 }
351 }
356
357#ifdef REG_DEBUG
360#endif
361
362 return st;
363}
static void cleanup(void)
if(TABLE==NULL||TABLE_index==NULL)
void pg_set_regex_collation(Oid collation)
static int find(struct vars *v, struct cnfa *cnfa, struct colormap *cm)
static void zapallsubs(regmatch_t *p, size_t n)
static int cfind(struct vars *v, struct cnfa *cnfa, struct colormap *cm)
References assert, cfind(), guts::cflags, cleanup(), guts::cmap, subre::cnfa, vars::details, vars::eflags, vars::err, find(), for(), FREE, freedfa(), vars::g, i, if(), guts::info, vars::ladfas, vars::lblastcp, vars::lblastcss, len, LOCALDFAS, LOCALMAT, MALLOC, guts::nlacons, vars::nmatch, guts::nsub, guts::ntree, pg_set_regex_collation(), vars::pmatch, vars::re, REG_ESPACE, REG_EXPECT, REG_FTRACE, REG_INVARG, REG_MIXED, REG_MTRACE, REG_NOMATCH, REG_NOSUB, REG_OKAY, REG_UBACKREF, REG_UIMPOSSIBLE, regmatch_t, REMAGIC, vars::search_start, vars::start, generate_unaccent_rules::stdout, vars::stop, vars::subdfas, guts::tree, VS, and zapallsubs().
Referenced by CheckAffix(), RE_wchar_execute(), regexec_auth_token(), replace_text_regexp(), and test_re_execute().
◆ pickss()
static struct sset * pickss ( struct vars * v, struct dfa * d, chr * cp, chr * start ) | static |
---|
◆ shortest()
static chr * shortest ( struct vars * v, struct dfa * d, chr * start, chr * min, chr * max, chr ** coldp, int * hitstopp ) | static |
---|
◆ subset()
static void subset ( struct vars * v, struct subre * sub, chr * begin, chr * end ) | static |
---|
Definition at line 702 of file regexec.c.
706{
707 int n = sub->capno;
708
710 if ((size_t) n >= v->nmatch)
711 return;
712
713 MDEBUG(("%d: setting %d = %ld-%ld\n", sub->id, n, LOFF(begin), LOFF(end)));
716}
References assert, subre::begin, subre::capno, subre::end, subre::id, LOFF, MDEBUG, vars::nmatch, OFF, and vars::pmatch.
Referenced by cdissect().
◆ zapallsubs()
static void zapallsubs ( regmatch_t * p, size_t n ) | static |
---|
Definition at line 663 of file regexec.c.
665{
666 size_t i;
667
668 for (i = n - 1; i > 0; i--)
669 {
670 p[i].rm_so = -1;
671 p[i].rm_eo = -1;
672 }
673}
References i.
Referenced by pg_regexec().
◆ zaptreesubs()
static void zaptreesubs ( struct vars * v, struct subre * t ) | static |
---|