Picol  Check-in [8c778169ee]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:vendor/regexp.{c,h}: Update the library to Git commit 32773617b3.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | trunk
Files: files | file ages | folders
SHA1:8c778169ee1c4f5f2dd5247ea56aa4e9f28fc9ef
User & Date: dbohdan 2019-02-19 07:55:44
Original Comment: Update the vendored regexp library to commit 32773617b3.
Context
2019-02-19
07:55
vendor/regexp.{c,h}: Update the library to Git commit 32773617b3. Leaf check-in: 8c778169ee user: dbohdan tags: trunk
2018-12-05
12:52
.travis.yml: Switch to VM infrastructure. check-in: a1c5daa3bc user: dbohdan tags: trunk
Changes

Changes to vendor/regexp.c.

1
2
3
4


5
6
7
8
9
10
11
..
27
28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
...
111
112
113
114
115
116
117





118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
...
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
...
560
561
562
563
564
565
566
567
568

569

570
571
572
573
574


575
576
577
578
579
580
581
582
583
...
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625


626
627
628
629
630
631
632
...
644
645
646
647
648
649
650

651
652
653
654
655
656
657
658
659
660
661
662
...
821
822
823
824
825
826
827
828
829

830
831
832
833
834
835
836
837
838










839
840
841
842
843
844
845
...
848
849
850
851
852
853
854









855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
...
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959

960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981

982
983
984



985
986
987
988
989

990
991
992
993

994
995

996
997

998
999

1000
1001

1002
1003
1004
1005
1006


1007
1008
1009
1010
1011

1012
1013


1014
1015
1016
1017
1018

1019
1020
1021
1022


1023
1024
1025
1026
1027

1028
1029
1030

1031
1032
1033

1034

1035
1036
1037
1038
1039

1040
1041
1042

1043
1044
1045

1046

1047
1048
1049
1050
1051
1052

1053
1054
1055

1056
1057
1058

1059
1060
1061
1062

1063

1064
1065

1066
1067



1068
1069

1070

1071
1072

1073
1074



1075
1076
1077
1078


1079
1080
1081
1082
1083
1084


1085
1086
1087
1088
1089

1090
1091
1092

1093
1094
1095

1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <stdio.h>



#include "regexp.h"

#define nelem(a) (sizeof (a) / sizeof (a)[0])

typedef unsigned int Rune;

................................................................................
{
	/* TODO: Add UTF-8 decoding */
	*r = *s;
	return 1;
}

#define REPINF 255
#define MAXTHREAD 1000
#define MAXSUB REG_MAXSUB


typedef struct Reclass Reclass;
typedef struct Renode Renode;
typedef struct Reinst Reinst;
typedef struct Rethread Rethread;

struct Reclass {
................................................................................
{
	if (c >= '0' && c <= '9') return c - '0';
	die("invalid quantifier");
	return 0;
}

#define ESCAPES "BbDdSsWw^$\\.*+?()[]{}|0123456789"






static int nextrune(void)
{
	g.source += chartorune(&g.yychar, g.source);
	if (g.yychar == '\\') {
		g.source += chartorune(&g.yychar, g.source);
		switch (g.yychar) {
		case 0: die("unterminated escape sequence");
		case 'f': g.yychar = '\f'; return 0;
		case 'n': g.yychar = '\n'; return 0;
		case 'r': g.yychar = '\r'; return 0;
		case 't': g.yychar = '\t'; return 0;
		case 'v': g.yychar = '\v'; return 0;
		case 'c':
			g.yychar = (*g.source++) & 31;
................................................................................
				g.yychar = '0';
				return 1;
			}
			return 0;
		}
		if (strchr(ESCAPES, g.yychar))
			return 1;
		if (isalpharune(g.yychar) || g.yychar == '_') /* check identity escape */
			die("invalid escape character");
		return 0;
	}
	return 0;
}

static int lexcount(void)
................................................................................
	addrange('z'+1, 0xFFFF);
}

static int lexclass(void)
{
	int type = L_CCLASS;
	int quoted, havesave, havedash;
	Rune save;

	newcclass();

	quoted = nextrune();
	if (!quoted && g.yychar == '^') {
		type = L_NCCLASS;
		quoted = nextrune();
................................................................................
	if (accept('+')) return newrep(atom, accept('?'), 1, REPINF);
	if (accept('?')) return newrep(atom, accept('?'), 0, 1);
	return atom;
}

static Renode *parsecat(void)
{
	Renode *cat, *x;
	if (g.lookahead && g.lookahead != '|' && g.lookahead != ')') {

		cat = parserep();

		while (g.lookahead && g.lookahead != '|' && g.lookahead != ')') {
			x = cat;
			cat = newnode(P_CAT);
			cat->x = x;
			cat->y = parserep();


		}
		return cat;
	}
	return NULL;
}

static Renode *parsealt(void)
{
	Renode *alt, *x;
................................................................................
	Reclass *cc;
	Reinst *x;
	Reinst *y;
};

static unsigned int count(Renode *node)
{
	unsigned int min, max;
	if (!node) return 0;
	switch (node->type) {
	default: return 1;
	case P_CAT: return count(node->x) + count(node->y);
	case P_ALT: return count(node->x) + count(node->y) + 2;
	case P_REP:
		min = node->m;
		max = node->n;
		if (min == max) return count(node->x) * min;
		if (max < REPINF) return count(node->x) * max + (max - min);
		return count(node->x) * (min + 1) + 2;


	case P_PAR: return count(node->x) + 2;
	case P_PLA: return count(node->x) + 2;
	case P_NLA: return count(node->x) + 2;
	}
}

static Reinst *emit(Reprog *prog, int opcode)
................................................................................
{
	Reinst *inst, *split, *jump;
	unsigned int i;

	if (!node)
		return;


	switch (node->type) {
	case P_CAT:
		compile(prog, node->x);
		compile(prog, node->y);
		break;

	case P_ALT:
		split = emit(prog, I_SPLIT);
		compile(prog, node->x);
		jump = emit(prog, I_JUMP);
		compile(prog, node->y);
		split->x = split + 1;
................................................................................
}
#endif

Reprog *regcomp(const char *pattern, int cflags, const char **errorp)
{
	Renode *node;
	Reinst *split, *jump;
	int i;


	g.prog = malloc(sizeof (Reprog));
	g.pstart = g.pend = malloc(sizeof (Renode) * strlen(pattern) * 2);

	if (setjmp(g.kaboom)) {
		if (errorp) *errorp = g.error;
		free(g.pstart);
		free(g.prog);
		return NULL;
	}











	g.source = pattern;
	g.ncclass = 0;
	g.nsub = 1;
	for (i = 0; i < MAXSUB; ++i)
		g.sub[i] = 0;

................................................................................
	next();
	node = parsealt();
	if (g.lookahead == ')')
		die("unmatched ')'");
	if (g.lookahead != 0)
		die("syntax error");










	g.prog->nsub = g.nsub;
	g.prog->start = g.prog->end = malloc((count(node) + 6) * sizeof (Reinst));

	split = emit(g.prog, I_SPLIT);
	split->x = split + 3;
	split->y = split + 1;
	emit(g.prog, I_ANYNL);
	jump = emit(g.prog, I_JUMP);
	jump->x = split;
	emit(g.prog, I_LPAR);
	compile(g.prog, node);
	emit(g.prog, I_RPAR);
	emit(g.prog, I_END);

#ifdef TEST
	dumpnode(node);
	putchar('\n');
	dumpprog(g.prog);
#endif

	free(g.pstart);

	if (errorp) *errorp = NULL;
	return g.prog;
................................................................................
		c = canon(ra) - canon(rb);
		if (c)
			return c;
	}
	return 0;
}

struct Rethread {
	Reinst *pc;
	const char *sp;
	Resub sub;
};

static void spawn(Rethread *t, Reinst *pc, const char *sp, Resub *sub)
{
	t->pc = pc;
	t->sp = sp;
	memcpy(&t->sub, sub, sizeof t->sub);
}

static int match(Reinst *pc, const char *sp, const char *bol, int flags, Resub *out)
{
	Rethread ready[MAXTHREAD];
	Resub scratch;
	Resub sub;
	Rune c;
	unsigned int nready;
	int i;


	/* queue initial thread */
	spawn(ready + 0, pc, sp, out);
	nready = 1;

	/* run threads in stack order */
	while (nready > 0) {
		--nready;
		pc = ready[nready].pc;
		sp = ready[nready].sp;
		memcpy(&sub, &ready[nready].sub, sizeof sub);
		for (;;) {
			switch (pc->opcode) {
			case I_END:
				for (i = 0; i < MAXSUB; ++i) {
					out->sub[i].sp = sub.sub[i].sp;
					out->sub[i].ep = sub.sub[i].ep;
				}
				return 1;
			case I_JUMP:
				pc = pc->x;
				continue;

			case I_SPLIT:
				if (nready >= MAXTHREAD) {
					fprintf(stderr, "regexec: backtrack overflow!\n");



					return 0;
				}
				spawn(&ready[nready++], pc->y, sp, &sub);
				pc = pc->x;
				continue;


			case I_PLA:
				if (!match(pc->x, sp, bol, flags, &sub))
					goto dead;

				pc = pc->y;
				continue;

			case I_NLA:
				memcpy(&scratch, &sub, sizeof scratch);

				if (match(pc->x, sp, bol, flags, &scratch))
					goto dead;

				pc = pc->y;
				continue;


			case I_ANYNL:
				sp += chartorune(&c, sp);
				if (c == 0)
					goto dead;


				break;
			case I_ANY:
				sp += chartorune(&c, sp);
				if (c == 0)
					goto dead;

				if (isnewline(c))
					goto dead;


				break;
			case I_CHAR:
				sp += chartorune(&c, sp);
				if (c == 0)
					goto dead;

				if (flags & REG_ICASE)
					c = canon(c);
				if (c != pc->c)
					goto dead;


				break;
			case I_CCLASS:
				sp += chartorune(&c, sp);
				if (c == 0)
					goto dead;

				if (flags & REG_ICASE) {
					if (!incclasscanon(pc->cc, canon(c)))
						goto dead;

				} else {
					if (!incclass(pc->cc, c))
						goto dead;

				}

				break;
			case I_NCCLASS:
				sp += chartorune(&c, sp);
				if (c == 0)
					goto dead;

				if (flags & REG_ICASE) {
					if (incclasscanon(pc->cc, canon(c)))
						goto dead;

				} else {
					if (incclass(pc->cc, c))
						goto dead;

				}

				break;
			case I_REF:
				i = sub.sub[pc->n].ep - sub.sub[pc->n].sp;
				if (flags & REG_ICASE) {
					if (strncmpcanon(sp, sub.sub[pc->n].sp, i))
						goto dead;

				} else {
					if (strncmp(sp, sub.sub[pc->n].sp, i))
						goto dead;

				}
				if (i > 0)
					sp += i;

				break;

			case I_BOL:
				if (sp == bol && !(flags & REG_NOTBOL))

					break;

				if (flags & REG_NEWLINE)
					if (sp > bol && isnewline(sp[-1]))

						break;
				goto dead;



			case I_EOL:
				if (*sp == 0)

					break;

				if (flags & REG_NEWLINE)
					if (isnewline(*sp))

						break;
				goto dead;



			case I_WORD:
				i = sp > bol && iswordchar(sp[-1]);
				i ^= iswordchar(sp[0]);
				if (i)


					break;
				goto dead;
			case I_NWORD:
				i = sp > bol && iswordchar(sp[-1]);
				i ^= iswordchar(sp[0]);
				if (!i)


					break;
				goto dead;

			case I_LPAR:
				sub.sub[pc->n].sp = sp;

				break;
			case I_RPAR:
				sub.sub[pc->n].ep = sp;

				break;
			default:
				goto dead;

			}
			pc = pc + 1;
		}
dead: ;
	}
	return 0;
}

int regexec(Reprog *prog, const char *sp, Resub *sub, int eflags)
{
	Resub scratch;
	int i;

|
<


>
>







 







<

>







 







>
>
>
>
>







|







 







|







 







|







 







|

>
|
>

<

|

>
>

|







 







|








|
|
|
>
>







 







>



|
|







 







|

>
|
<







>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>

|













<
<







 







<
<
<
<
<
<
<
<
<
<
<
<
<


<

<
<
<

>

<
<
<
<
<
<
<
<
<
<
|
|
|
<
<
<
<
|
|
|
<
>
|
<
<
>
>
>
|
|
<
|
<
>

|
|
<
>
|
<
>
|
<
>
|
<
>
|
<
>

|
|
|
<
>
>
|
|
|
|
<
>
|
<
>
>
|
|
|
|
<
>
|
|
|
<
>
>
|
|
|
|
<
>
|
|
<
>
|
|
<
>
|
>
|
|
|
|
<
>
|
|
<
>
|
|
<
>
|
>
|
|
|
|
|
<
>
|
|
<
>
|
|
|
>
|

|
|
>
|
>
|
|
>
|
<
>
>
>
|
|
>
|
>
|
|
>
|
<
>
>
>
|
|
|
|
>
>
|
<
|
|
|
|
>
>
|
<

|
|
>
|
|
|
>
|
|
<
>
|
<
|
<
<
<







1

2
3
4
5
6
7
8
9
10
11
12
..
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
...
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
...
566
567
568
569
570
571
572
573
574
575
576
577
578

579
580
581
582
583
584
585
586
587
588
589
590
591
592
...
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
...
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
...
833
834
835
836
837
838
839
840
841
842
843

844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
...
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900


901
902
903
904
905
906
907
...
961
962
963
964
965
966
967













968
969

970



971
972
973










974
975
976




977
978
979

980
981


982
983
984
985
986

987

988
989
990
991

992
993

994
995

996
997

998
999

1000
1001
1002
1003
1004

1005
1006
1007
1008
1009
1010

1011
1012

1013
1014
1015
1016
1017
1018

1019
1020
1021
1022

1023
1024
1025
1026
1027
1028

1029
1030
1031

1032
1033
1034

1035
1036
1037
1038
1039
1040
1041

1042
1043
1044

1045
1046
1047

1048
1049
1050
1051
1052
1053
1054
1055

1056
1057
1058

1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074

1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093
1094
1095
1096

1097
1098
1099
1100
1101
1102
1103

1104
1105
1106
1107
1108
1109
1110
1111
1112
1113

1114
1115

1116



1117
1118
1119
1120
1121
1122
1123
#include <limits.h>

#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "regexp.h"

#define nelem(a) (sizeof (a) / sizeof (a)[0])

typedef unsigned int Rune;

................................................................................
{
	/* TODO: Add UTF-8 decoding */
	*r = *s;
	return 1;
}

#define REPINF 255

#define MAXSUB REG_MAXSUB
#define MAXPROG (32 << 10)

typedef struct Reclass Reclass;
typedef struct Renode Renode;
typedef struct Reinst Reinst;
typedef struct Rethread Rethread;

struct Reclass {
................................................................................
{
	if (c >= '0' && c <= '9') return c - '0';
	die("invalid quantifier");
	return 0;
}

#define ESCAPES "BbDdSsWw^$\\.*+?()[]{}|0123456789"

static int isunicodeletter(int c)
{
	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || isalpharune(c);
}

static int nextrune(void)
{
	g.source += chartorune(&g.yychar, g.source);
	if (g.yychar == '\\') {
		g.source += chartorune(&g.yychar, g.source);
		switch (g.yychar) {
		case 0: die("unterminated escape sequence"); break;
		case 'f': g.yychar = '\f'; return 0;
		case 'n': g.yychar = '\n'; return 0;
		case 'r': g.yychar = '\r'; return 0;
		case 't': g.yychar = '\t'; return 0;
		case 'v': g.yychar = '\v'; return 0;
		case 'c':
			g.yychar = (*g.source++) & 31;
................................................................................
				g.yychar = '0';
				return 1;
			}
			return 0;
		}
		if (strchr(ESCAPES, g.yychar))
			return 1;
		if (isunicodeletter(g.yychar) || g.yychar == '_') /* check identity escape */
			die("invalid escape character");
		return 0;
	}
	return 0;
}

static int lexcount(void)
................................................................................
	addrange('z'+1, 0xFFFF);
}

static int lexclass(void)
{
	int type = L_CCLASS;
	int quoted, havesave, havedash;
	Rune save = 0;

	newcclass();

	quoted = nextrune();
	if (!quoted && g.yychar == '^') {
		type = L_NCCLASS;
		quoted = nextrune();
................................................................................
	if (accept('+')) return newrep(atom, accept('?'), 1, REPINF);
	if (accept('?')) return newrep(atom, accept('?'), 0, 1);
	return atom;
}

static Renode *parsecat(void)
{
	Renode *cat, *head, **tail;
	if (g.lookahead && g.lookahead != '|' && g.lookahead != ')') {
		/* Build a right-leaning tree by splicing in new 'cat' at the tail. */
		head = parserep();
		tail = &head;
		while (g.lookahead && g.lookahead != '|' && g.lookahead != ')') {

			cat = newnode(P_CAT);
			cat->x = *tail;
			cat->y = parserep();
			*tail = cat;
			tail = &cat->y;
		}
		return head;
	}
	return NULL;
}

static Renode *parsealt(void)
{
	Renode *alt, *x;
................................................................................
	Reclass *cc;
	Reinst *x;
	Reinst *y;
};

static unsigned int count(Renode *node)
{
	unsigned int min, max, n;
	if (!node) return 0;
	switch (node->type) {
	default: return 1;
	case P_CAT: return count(node->x) + count(node->y);
	case P_ALT: return count(node->x) + count(node->y) + 2;
	case P_REP:
		min = node->m;
		max = node->n;
		if (min == max) n = count(node->x) * min;
		else if (max < REPINF) n = count(node->x) * max + (max - min);
		else n = count(node->x) * (min + 1) + 2;
		if (n > MAXPROG) die("program too large");
		return n;
	case P_PAR: return count(node->x) + 2;
	case P_PLA: return count(node->x) + 2;
	case P_NLA: return count(node->x) + 2;
	}
}

static Reinst *emit(Reprog *prog, int opcode)
................................................................................
{
	Reinst *inst, *split, *jump;
	unsigned int i;

	if (!node)
		return;

loop:
	switch (node->type) {
	case P_CAT:
		compile(prog, node->x);
		node = node->y;
		goto loop;

	case P_ALT:
		split = emit(prog, I_SPLIT);
		compile(prog, node->x);
		jump = emit(prog, I_JUMP);
		compile(prog, node->y);
		split->x = split + 1;
................................................................................
}
#endif

Reprog *regcomp(const char *pattern, int cflags, const char **errorp)
{
	Renode *node;
	Reinst *split, *jump;
	int i, n;

	g.pstart = NULL;
	g.prog = NULL;


	if (setjmp(g.kaboom)) {
		if (errorp) *errorp = g.error;
		free(g.pstart);
		free(g.prog);
		return NULL;
	}

	g.prog = malloc(sizeof (Reprog));
	if (!g.prog)
		die("cannot allocate regular expression");
	n = strlen(pattern) * 2;
	if (n > 0) {
		g.pstart = g.pend = malloc(sizeof (Renode) * n);
		if (!g.pstart)
			die("cannot allocate regular expression parse list");
	}

	g.source = pattern;
	g.ncclass = 0;
	g.nsub = 1;
	for (i = 0; i < MAXSUB; ++i)
		g.sub[i] = 0;

................................................................................
	next();
	node = parsealt();
	if (g.lookahead == ')')
		die("unmatched ')'");
	if (g.lookahead != 0)
		die("syntax error");

#ifdef TEST
	dumpnode(node);
	putchar('\n');
#endif

	n = 6 + count(node);
	if (n < 0 || n > MAXPROG)
		die("program too large");

	g.prog->nsub = g.nsub;
	g.prog->start = g.prog->end = malloc(n * sizeof (Reinst));

	split = emit(g.prog, I_SPLIT);
	split->x = split + 3;
	split->y = split + 1;
	emit(g.prog, I_ANYNL);
	jump = emit(g.prog, I_JUMP);
	jump->x = split;
	emit(g.prog, I_LPAR);
	compile(g.prog, node);
	emit(g.prog, I_RPAR);
	emit(g.prog, I_END);

#ifdef TEST


	dumpprog(g.prog);
#endif

	free(g.pstart);

	if (errorp) *errorp = NULL;
	return g.prog;
................................................................................
		c = canon(ra) - canon(rb);
		if (c)
			return c;
	}
	return 0;
}














static int match(Reinst *pc, const char *sp, const char *bol, int flags, Resub *out)
{

	Resub scratch;



	int i;
	Rune c;











	for (;;) {
		switch (pc->opcode) {
		case I_END:




			return 1;
		case I_JUMP:
			pc = pc->x;

			break;
		case I_SPLIT:


			scratch = *out;
			if (match(pc->x, sp, bol, flags, &scratch)) {
				*out = scratch;
				return 1;
			}

			pc = pc->y;

			break;

		case I_PLA:
			if (!match(pc->x, sp, bol, flags, out))

				return 0;
			pc = pc->y;

			break;
		case I_NLA:

			scratch = *out;
			if (match(pc->x, sp, bol, flags, &scratch))

				return 0;
			pc = pc->y;

			break;

		case I_ANYNL:
			sp += chartorune(&c, sp);
			if (c == 0)

				return 0;
			pc = pc + 1;
			break;
		case I_ANY:
			sp += chartorune(&c, sp);
			if (c == 0)

				return 0;
			if (isnewline(c))

				return 0;
			pc = pc + 1;
			break;
		case I_CHAR:
			sp += chartorune(&c, sp);
			if (c == 0)

				return 0;
			if (flags & REG_ICASE)
				c = canon(c);
			if (c != pc->c)

				return 0;
			pc = pc + 1;
			break;
		case I_CCLASS:
			sp += chartorune(&c, sp);
			if (c == 0)

				return 0;
			if (flags & REG_ICASE) {
				if (!incclasscanon(pc->cc, canon(c)))

					return 0;
			} else {
				if (!incclass(pc->cc, c))

					return 0;
			}
			pc = pc + 1;
			break;
		case I_NCCLASS:
			sp += chartorune(&c, sp);
			if (c == 0)

				return 0;
			if (flags & REG_ICASE) {
				if (incclasscanon(pc->cc, canon(c)))

					return 0;
			} else {
				if (incclass(pc->cc, c))

					return 0;
			}
			pc = pc + 1;
			break;
		case I_REF:
			i = out->sub[pc->n].ep - out->sub[pc->n].sp;
			if (flags & REG_ICASE) {
				if (strncmpcanon(sp, out->sub[pc->n].sp, i))

					return 0;
			} else {
				if (strncmp(sp, out->sub[pc->n].sp, i))

					return 0;
			}
			if (i > 0)
				sp += i;
			pc = pc + 1;
			break;

		case I_BOL:
			if (sp == bol && !(flags & REG_NOTBOL)) {
				pc = pc + 1;
				break;
			}
			if (flags & REG_NEWLINE) {
				if (sp > bol && isnewline(sp[-1])) {
					pc = pc + 1;
					break;

				}
			}
			return 0;
		case I_EOL:
			if (*sp == 0) {
				pc = pc + 1;
				break;
			}
			if (flags & REG_NEWLINE) {
				if (isnewline(*sp)) {
					pc = pc + 1;
					break;

				}
			}
			return 0;
		case I_WORD:
			i = sp > bol && iswordchar(sp[-1]);
			i ^= iswordchar(sp[0]);
			if (!i)
				return 0;
			pc = pc + 1;
			break;

		case I_NWORD:
			i = sp > bol && iswordchar(sp[-1]);
			i ^= iswordchar(sp[0]);
			if (i)
				return 0;
			pc = pc + 1;
			break;


		case I_LPAR:
			out->sub[pc->n].sp = sp;
			pc = pc + 1;
			break;
		case I_RPAR:
			out->sub[pc->n].ep = sp;
			pc = pc + 1;
			break;
		default:

			return 0;
		}

	}



}

int regexec(Reprog *prog, const char *sp, Resub *sub, int eflags)
{
	Resub scratch;
	int i;

Changes to vendor/regexp.h.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
	REG_ICASE = 1,
	REG_NEWLINE = 2,

	/* regexec flags */
	REG_NOTBOL = 4,

	/* limits */
	REG_MAXSUB = 16
};

struct Resub {
	unsigned int nsub;
	struct {
		const char *sp;
		const char *ep;
	} sub[REG_MAXSUB];
};

#endif







|











13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
	REG_ICASE = 1,
	REG_NEWLINE = 2,

	/* regexec flags */
	REG_NOTBOL = 4,

	/* limits */
	REG_MAXSUB = 10
};

struct Resub {
	unsigned int nsub;
	struct {
		const char *sp;
		const char *ep;
	} sub[REG_MAXSUB];
};

#endif