| sub.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
| git clone git://git.suckless.org/9base | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| sub.c (4041B) | |
| --- | |
| 1 #include "grep.h" | |
| 2 | |
| 3 void* | |
| 4 mal(int n) | |
| 5 { | |
| 6 static char *s = NULL; | |
| 7 static int m = 0; | |
| 8 void *v = NULL; | |
| 9 | |
| 10 n = (n+3) & ~3; | |
| 11 if(m < n) { | |
| 12 if(n > Nhunk) { | |
| 13 v = malloc(n); | |
| 14 if(v != NULL) | |
| 15 memset(v, 0, n); | |
| 16 return v; | |
| 17 } | |
| 18 s = malloc(Nhunk); | |
| 19 m = Nhunk; | |
| 20 } | |
| 21 v = s; | |
| 22 if(s != NULL) | |
| 23 s += n; | |
| 24 m -= n; | |
| 25 if(v != NULL) | |
| 26 memset(v, 0, n); | |
| 27 return v; | |
| 28 } | |
| 29 | |
| 30 State* | |
| 31 sal(int n) | |
| 32 { | |
| 33 State *s; | |
| 34 | |
| 35 s = mal(sizeof(*s)); | |
| 36 /* s->next = mal(256*sizeof(*s->next)); */ | |
| 37 s->count = n; | |
| 38 s->re = mal(n*sizeof(*state0->re)); | |
| 39 return s; | |
| 40 } | |
| 41 | |
| 42 Re* | |
| 43 ral(int type) | |
| 44 { | |
| 45 Re *r; | |
| 46 | |
| 47 r = mal(sizeof(*r)); | |
| 48 r->type = type; | |
| 49 maxfollow++; | |
| 50 return r; | |
| 51 } | |
| 52 | |
| 53 void | |
| 54 error(char *s) | |
| 55 { | |
| 56 fprint(2, "grep: internal error: %s\n", s); | |
| 57 exits(s); | |
| 58 } | |
| 59 | |
| 60 int | |
| 61 countor(Re *r) | |
| 62 { | |
| 63 int n; | |
| 64 | |
| 65 n = 0; | |
| 66 loop: | |
| 67 switch(r->type) { | |
| 68 case Tor: | |
| 69 n += countor(r->u.alt); | |
| 70 r = r->next; | |
| 71 goto loop; | |
| 72 case Tclass: | |
| 73 return n + r->u.x.hi - r->u.x.lo + 1; | |
| 74 } | |
| 75 return n; | |
| 76 } | |
| 77 | |
| 78 Re* | |
| 79 oralloc(int t, Re *r, Re *b) | |
| 80 { | |
| 81 Re *a; | |
| 82 | |
| 83 if(b == 0) | |
| 84 return r; | |
| 85 a = ral(t); | |
| 86 a->u.alt = r; | |
| 87 a->next = b; | |
| 88 return a; | |
| 89 } | |
| 90 | |
| 91 void | |
| 92 case1(Re *c, Re *r) | |
| 93 { | |
| 94 int n; | |
| 95 | |
| 96 loop: | |
| 97 switch(r->type) { | |
| 98 case Tor: | |
| 99 case1(c, r->u.alt); | |
| 100 r = r->next; | |
| 101 goto loop; | |
| 102 | |
| 103 case Tclass: /* add to character */ | |
| 104 for(n=r->u.x.lo; n<=r->u.x.hi; n++) | |
| 105 c->u.cases[n] = oralloc(Tor, r->next, c->u.cases… | |
| 106 break; | |
| 107 | |
| 108 default: /* add everything unknown to next */ | |
| 109 c->next = oralloc(Talt, r, c->next); | |
| 110 break; | |
| 111 } | |
| 112 } | |
| 113 | |
| 114 Re* | |
| 115 addcase(Re *r) | |
| 116 { | |
| 117 int i, n; | |
| 118 Re *a; | |
| 119 | |
| 120 if(r->gen == gen) | |
| 121 return r; | |
| 122 r->gen = gen; | |
| 123 switch(r->type) { | |
| 124 default: | |
| 125 error("addcase"); | |
| 126 | |
| 127 case Tor: | |
| 128 n = countor(r); | |
| 129 if(n >= Caselim) { | |
| 130 a = ral(Tcase); | |
| 131 a->u.cases = mal(256*sizeof(*a->u.cases)); | |
| 132 case1(a, r); | |
| 133 for(i=0; i<256; i++) | |
| 134 if(a->u.cases[i]) { | |
| 135 r = a->u.cases[i]; | |
| 136 if(countor(r) < n) | |
| 137 a->u.cases[i] = addcase(… | |
| 138 } | |
| 139 return a; | |
| 140 } | |
| 141 return r; | |
| 142 | |
| 143 case Talt: | |
| 144 r->next = addcase(r->next); | |
| 145 r->u.alt = addcase(r->u.alt); | |
| 146 return r; | |
| 147 | |
| 148 case Tbegin: | |
| 149 case Tend: | |
| 150 case Tclass: | |
| 151 return r; | |
| 152 } | |
| 153 } | |
| 154 | |
| 155 void | |
| 156 str2top(char *p) | |
| 157 { | |
| 158 Re2 oldtop; | |
| 159 | |
| 160 oldtop = topre; | |
| 161 input = p; | |
| 162 topre.beg = 0; | |
| 163 topre.end = 0; | |
| 164 yyparse(); | |
| 165 gen++; | |
| 166 if(topre.beg == 0) | |
| 167 yyerror("syntax"); | |
| 168 if(oldtop.beg) | |
| 169 topre = re2or(oldtop, topre); | |
| 170 } | |
| 171 | |
| 172 void | |
| 173 appendnext(Re *a, Re *b) | |
| 174 { | |
| 175 Re *n; | |
| 176 | |
| 177 while(n = a->next) | |
| 178 a = n; | |
| 179 a->next = b; | |
| 180 } | |
| 181 | |
| 182 void | |
| 183 patchnext(Re *a, Re *b) | |
| 184 { | |
| 185 Re *n; | |
| 186 | |
| 187 while(a) { | |
| 188 n = a->next; | |
| 189 a->next = b; | |
| 190 a = n; | |
| 191 } | |
| 192 } | |
| 193 | |
| 194 int | |
| 195 getrec(void) | |
| 196 { | |
| 197 int c; | |
| 198 | |
| 199 if(flags['f']) { | |
| 200 c = Bgetc(rein); | |
| 201 if(c <= 0) | |
| 202 return 0; | |
| 203 } else | |
| 204 c = *input++ & 0xff; | |
| 205 if(flags['i'] && c >= 'A' && c <= 'Z') | |
| 206 c += 'a'-'A'; | |
| 207 if(c == '\n') | |
| 208 lineno++; | |
| 209 return c; | |
| 210 } | |
| 211 | |
| 212 Re2 | |
| 213 re2cat(Re2 a, Re2 b) | |
| 214 { | |
| 215 Re2 c; | |
| 216 | |
| 217 c.beg = a.beg; | |
| 218 c.end = b.end; | |
| 219 patchnext(a.end, b.beg); | |
| 220 return c; | |
| 221 } | |
| 222 | |
| 223 Re2 | |
| 224 re2star(Re2 a) | |
| 225 { | |
| 226 Re2 c; | |
| 227 | |
| 228 c.beg = ral(Talt); | |
| 229 c.beg->u.alt = a.beg; | |
| 230 patchnext(a.end, c.beg); | |
| 231 c.end = c.beg; | |
| 232 return c; | |
| 233 } | |
| 234 | |
| 235 Re2 | |
| 236 re2or(Re2 a, Re2 b) | |
| 237 { | |
| 238 Re2 c; | |
| 239 | |
| 240 c.beg = ral(Tor); | |
| 241 c.beg->u.alt = b.beg; | |
| 242 c.beg->next = a.beg; | |
| 243 c.end = b.end; | |
| 244 appendnext(c.end, a.end); | |
| 245 return c; | |
| 246 } | |
| 247 | |
| 248 Re2 | |
| 249 re2char(int c0, int c1) | |
| 250 { | |
| 251 Re2 c; | |
| 252 | |
| 253 c.beg = ral(Tclass); | |
| 254 c.beg->u.x.lo = c0 & 0xff; | |
| 255 c.beg->u.x.hi = c1 & 0xff; | |
| 256 c.end = c.beg; | |
| 257 return c; | |
| 258 } | |
| 259 | |
| 260 void | |
| 261 reprint1(Re *a) | |
| 262 { | |
| 263 int i, j; | |
| 264 | |
| 265 loop: | |
| 266 if(a == 0) | |
| 267 return; | |
| 268 if(a->gen == gen) | |
| 269 return; | |
| 270 a->gen = gen; | |
| 271 print("%p: ", a); | |
| 272 switch(a->type) { | |
| 273 default: | |
| 274 print("type %d\n", a->type); | |
| 275 error("print1 type"); | |
| 276 | |
| 277 case Tcase: | |
| 278 print("case ->%p\n", a->next); | |
| 279 for(i=0; i<256; i++) | |
| 280 if(a->u.cases[i]) { | |
| 281 for(j=i+1; j<256; j++) | |
| 282 if(a->u.cases[i] != a->u.cases[j… | |
| 283 break; | |
| 284 print(" [%.2x-%.2x] ->%p\n", i, j… | |
| 285 i = j-1; | |
| 286 } | |
| 287 for(i=0; i<256; i++) | |
| 288 reprint1(a->u.cases[i]); | |
| 289 break; | |
| 290 | |
| 291 case Tbegin: | |
| 292 print("^ ->%p\n", a->next); | |
| 293 break; | |
| 294 | |
| 295 case Tend: | |
| 296 print("$ ->%p\n", a->next); | |
| 297 break; | |
| 298 | |
| 299 case Tclass: | |
| 300 print("[%.2x-%.2x] ->%p\n", a->u.x.lo, a->u.x.hi, a->nex… | |
| 301 break; | |
| 302 | |
| 303 case Tor: | |
| 304 case Talt: | |
| 305 print("| %p ->%p\n", a->u.alt, a->next); | |
| 306 reprint1(a->u.alt); | |
| 307 break; | |
| 308 } | |
| 309 a = a->next; | |
| 310 goto loop; | |
| 311 } | |
| 312 | |
| 313 void | |
| 314 reprint(char *s, Re *r) | |
| 315 { | |
| 316 print("%s:\n", s); | |
| 317 gen++; | |
| 318 reprint1(r); | |
| 319 print("\n\n"); | |
| 320 } |