Lines 64-84
Link Here
|
64 |
int lh_ref; |
64 |
int lh_ref; |
65 |
} *labels[LHSZ]; |
65 |
} *labels[LHSZ]; |
66 |
|
66 |
|
67 |
static char *compile_addr(char *, struct s_addr *); |
67 |
static const char *compile_addr(const char *, struct s_addr *); |
68 |
static char *compile_ccl(char **, char *); |
68 |
static char *compile_ccl(const char **, char *); |
69 |
static char *compile_delimited(char *, char *, int); |
69 |
static const char *compile_delimited(const char *, char *, int); |
70 |
static char *compile_flags(char *, struct s_subst *); |
70 |
static const char *compile_flags(const char *, struct s_subst *); |
71 |
static regex_t *compile_re(char *, int); |
71 |
static regex_t *compile_re(const char *, int); |
72 |
static char *compile_subst(char *, struct s_subst *); |
72 |
static const char *compile_subst(const char *, struct s_subst *); |
73 |
static char *compile_text(void); |
73 |
static char *compile_text(size_t *); |
74 |
static char *compile_tr(char *, struct s_tr **); |
74 |
static const char *compile_tr(const char *, struct s_tr **); |
75 |
static struct s_command |
75 |
static struct s_command |
76 |
**compile_stream(struct s_command **); |
76 |
**compile_stream(struct s_command **); |
77 |
static char *duptoeol(char *, const char *); |
77 |
static char *duptoeol(const char *, const char *, size_t *); |
78 |
static void enterlabel(struct s_command *); |
78 |
static void enterlabel(struct s_command *); |
79 |
static struct s_command |
79 |
static struct s_command |
80 |
*findlabel(char *); |
80 |
*findlabel(const char *); |
81 |
static void fixuplabel(struct s_command *, struct s_command *); |
81 |
static void fixuplabel(struct s_command *, const struct s_command *); |
82 |
static void uselabel(void); |
82 |
static void uselabel(void); |
83 |
|
83 |
|
84 |
/* |
84 |
/* |
Lines 144-183
Link Here
|
144 |
err(1, "malloc"); |
144 |
err(1, "malloc"); |
145 |
} |
145 |
} |
146 |
|
146 |
|
147 |
#define EATSPACE() do { \ |
147 |
#define EATSPACE() do { \ |
148 |
if (p) \ |
148 |
while (*p && isspace((unsigned char)*p)) \ |
149 |
while (*p && isspace((unsigned char)*p)) \ |
149 |
p++; \ |
150 |
p++; \ |
|
|
151 |
} while (0) |
150 |
} while (0) |
152 |
|
151 |
|
|
|
152 |
#define EATSPACEN() do { \ |
153 |
while (*p && *p != '\n' && isspace((unsigned char)*p)) \ |
154 |
p++; \ |
155 |
} while (0) |
156 |
|
153 |
static struct s_command ** |
157 |
static struct s_command ** |
154 |
compile_stream(struct s_command **link) |
158 |
compile_stream(struct s_command **link) |
155 |
{ |
159 |
{ |
156 |
char *p; |
160 |
const char *p; |
157 |
static char lbuf[_POSIX2_LINE_MAX + 1]; /* To save stack */ |
|
|
158 |
struct s_command *cmd, *cmd2, *stack; |
161 |
struct s_command *cmd, *cmd2, *stack; |
159 |
struct s_format *fp; |
162 |
struct s_format *fp; |
160 |
char re[_POSIX2_LINE_MAX + 1]; |
163 |
char re[_POSIX2_LINE_MAX + 1]; |
161 |
int naddr; /* Number of addresses */ |
164 |
int naddr; /* Number of addresses */ |
|
|
165 |
int stackdepth = 0; |
162 |
|
166 |
|
163 |
stack = 0; |
167 |
stack = NULL; |
164 |
for (;;) { |
168 |
for (;;) { |
165 |
if ((p = cu_fgets(lbuf, sizeof(lbuf), NULL)) == NULL) { |
169 |
if ((p = cu_fgets(NULL)) == NULL) { |
166 |
if (stack != 0) |
170 |
if (stack != NULL) |
167 |
errx(1, "%lu: %s: unexpected EOF (pending }'s)", |
171 |
errx(1, "%lu: %s: unexpected EOF (pending }'s)", |
168 |
linenum, fname); |
172 |
linenum, fname); |
169 |
return (link); |
173 |
return (link); |
170 |
} |
174 |
} |
171 |
|
175 |
|
172 |
semicolon: EATSPACE(); |
176 |
semicolon: EATSPACEN(); |
173 |
if (p) { |
177 |
switch (*p) { |
174 |
if (*p == '#' || *p == '\0') |
178 |
case '#': case '\0': case '\n': |
175 |
continue; |
179 |
continue; /* to next command-unit */ |
176 |
else if (*p == ';') { |
180 |
case ';': |
177 |
p++; |
181 |
p++; |
178 |
goto semicolon; |
182 |
goto semicolon; |
179 |
} |
|
|
180 |
} |
183 |
} |
|
|
184 |
|
181 |
if ((*link = cmd = malloc(sizeof(struct s_command))) == NULL) |
185 |
if ((*link = cmd = malloc(sizeof(struct s_command))) == NULL) |
182 |
err(1, "malloc"); |
186 |
err(1, "malloc"); |
183 |
link = &cmd->next; |
187 |
link = &cmd->next; |
Lines 208-214
Link Here
|
208 |
cmd->a1 = cmd->a2 = 0; |
212 |
cmd->a1 = cmd->a2 = 0; |
209 |
|
213 |
|
210 |
nonsel: /* Now parse the command */ |
214 |
nonsel: /* Now parse the command */ |
211 |
if (!*p) |
215 |
if (*p == '\0' || *p == '\n') |
212 |
errx(1, "%lu: %s: command expected", linenum, fname); |
216 |
errx(1, "%lu: %s: command expected", linenum, fname); |
213 |
cmd->code = *p; |
217 |
cmd->code = *p; |
214 |
for (fp = cmd_fmts; fp->code; fp++) |
218 |
for (fp = cmd_fmts; fp->code; fp++) |
Lines 215-221
Link Here
|
215 |
if (fp->code == *p) |
219 |
if (fp->code == *p) |
216 |
break; |
220 |
break; |
217 |
if (!fp->code) |
221 |
if (!fp->code) |
218 |
errx(1, "%lu: %s: invalid command code %c", linenum, fname, *p); |
222 |
errx(1, "%lu: %s: invalid command code %c (%s)", linenum, fname, *p, p); |
219 |
if (naddr > fp->naddr) |
223 |
if (naddr > fp->naddr) |
220 |
errx(1, |
224 |
errx(1, |
221 |
"%lu: %s: command %c expects up to %d address(es), found %d", |
225 |
"%lu: %s: command %c expects up to %d address(es), found %d", |
Lines 228-238
Link Here
|
228 |
goto nonsel; |
232 |
goto nonsel; |
229 |
case GROUP: /* { */ |
233 |
case GROUP: /* { */ |
230 |
p++; |
234 |
p++; |
231 |
EATSPACE(); |
235 |
EATSPACEN(); |
232 |
cmd->next = stack; |
236 |
cmd->next = stack; |
233 |
stack = cmd; |
237 |
stack = cmd; |
234 |
link = &cmd->u.c; |
238 |
link = &cmd->u.c; |
235 |
if (*p) |
239 |
if (*p != '\0' && *p != '\n') |
236 |
goto semicolon; |
240 |
goto semicolon; |
237 |
break; |
241 |
break; |
238 |
case ENDGROUP: |
242 |
case ENDGROUP: |
Lines 241-247
Link Here
|
241 |
* group is really just a noop. |
245 |
* group is really just a noop. |
242 |
*/ |
246 |
*/ |
243 |
cmd->nonsel = 1; |
247 |
cmd->nonsel = 1; |
244 |
if (stack == 0) |
248 |
if (stack == NULL) |
245 |
errx(1, "%lu: %s: unexpected }", linenum, fname); |
249 |
errx(1, "%lu: %s: unexpected }", linenum, fname); |
246 |
cmd2 = stack; |
250 |
cmd2 = stack; |
247 |
stack = cmd2->next; |
251 |
stack = cmd2->next; |
Lines 249-261
Link Here
|
249 |
/*FALLTHROUGH*/ |
253 |
/*FALLTHROUGH*/ |
250 |
case EMPTY: /* d D g G h H l n N p P q x = \0 */ |
254 |
case EMPTY: /* d D g G h H l n N p P q x = \0 */ |
251 |
p++; |
255 |
p++; |
252 |
EATSPACE(); |
256 |
EATSPACEN(); |
253 |
if (*p == ';') { |
257 |
if (*p == ';') { |
254 |
p++; |
258 |
p++; |
255 |
link = &cmd->next; |
259 |
link = &cmd->next; |
256 |
goto semicolon; |
260 |
goto semicolon; |
257 |
} |
261 |
} |
258 |
if (*p) |
262 |
if (*p != '\0' && *p != '\n') |
259 |
errx(1, "%lu: %s: extra characters at the end of %c command", |
263 |
errx(1, "%lu: %s: extra characters at the end of %c command", |
260 |
linenum, fname, cmd->code); |
264 |
linenum, fname, cmd->code); |
261 |
break; |
265 |
break; |
Lines 266-277
Link Here
|
266 |
errx(1, |
270 |
errx(1, |
267 |
"%lu: %s: command %c expects \\ followed by text", linenum, fname, cmd->code); |
271 |
"%lu: %s: command %c expects \\ followed by text", linenum, fname, cmd->code); |
268 |
p++; |
272 |
p++; |
269 |
EATSPACE(); |
273 |
EATSPACEN(); |
270 |
if (*p) |
274 |
if (*p != '\n') |
271 |
errx(1, |
275 |
errx(1, |
272 |
"%lu: %s: extra characters after \\ at the end of %c command", |
276 |
"%lu: %s: extra characters (%c) after \\ at the end of %c command", |
273 |
linenum, fname, cmd->code); |
277 |
linenum, fname, *p, cmd->code); |
274 |
cmd->t = compile_text(); |
278 |
cmd->t = compile_text(&cmd->tlen); |
275 |
break; |
279 |
break; |
276 |
case COMMENT: /* \0 # */ |
280 |
case COMMENT: /* \0 # */ |
277 |
break; |
281 |
break; |
Lines 280-289
Link Here
|
280 |
EATSPACE(); |
284 |
EATSPACE(); |
281 |
if (*p == '\0') |
285 |
if (*p == '\0') |
282 |
errx(1, "%lu: %s: filename expected", linenum, fname); |
286 |
errx(1, "%lu: %s: filename expected", linenum, fname); |
283 |
cmd->t = duptoeol(p, "w command"); |
287 |
cmd->t = duptoeol(p, "w command", &cmd->tlen); |
284 |
if (aflag) |
288 |
if (aflag) |
285 |
cmd->u.fd = -1; |
289 |
cmd->u.fd = -1; |
286 |
else if ((cmd->u.fd = open(p, |
290 |
else if ((cmd->u.fd = open(cmd->t, |
287 |
O_WRONLY|O_APPEND|O_CREAT|O_TRUNC, |
291 |
O_WRONLY|O_APPEND|O_CREAT|O_TRUNC, |
288 |
DEFFILEMODE)) == -1) |
292 |
DEFFILEMODE)) == -1) |
289 |
err(1, "%s", p); |
293 |
err(1, "%s", p); |
Lines 294-320
Link Here
|
294 |
if (*p == '\0') |
298 |
if (*p == '\0') |
295 |
errx(1, "%lu: %s: filename expected", linenum, fname); |
299 |
errx(1, "%lu: %s: filename expected", linenum, fname); |
296 |
else |
300 |
else |
297 |
cmd->t = duptoeol(p, "read command"); |
301 |
cmd->t = duptoeol(p, "read command", &cmd->tlen); |
298 |
break; |
302 |
break; |
299 |
case BRANCH: /* b t */ |
303 |
case BRANCH: /* b t */ |
300 |
p++; |
304 |
p++; |
301 |
EATSPACE(); |
305 |
EATSPACEN(); |
302 |
if (*p == '\0') |
306 |
if (*p == '\0' || *p == '\n') |
303 |
cmd->t = NULL; |
307 |
cmd->t = NULL; |
304 |
else |
308 |
else |
305 |
cmd->t = duptoeol(p, "branch"); |
309 |
cmd->t = duptoeol(p, "branch", &cmd->tlen); |
306 |
break; |
310 |
break; |
307 |
case LABEL: /* : */ |
311 |
case LABEL: /* : */ |
308 |
p++; |
312 |
p++; |
309 |
EATSPACE(); |
313 |
EATSPACE(); |
310 |
cmd->t = duptoeol(p, "label"); |
314 |
cmd->t = duptoeol(p, "label", &cmd->tlen); |
311 |
if (strlen(p) == 0) |
315 |
if (cmd->t[0] == '\0') |
312 |
errx(1, "%lu: %s: empty label", linenum, fname); |
316 |
errx(1, "%lu: %s: empty label", linenum, fname); |
313 |
enterlabel(cmd); |
317 |
enterlabel(cmd); |
314 |
break; |
318 |
break; |
315 |
case SUBST: /* s */ |
319 |
case SUBST: /* s */ |
316 |
p++; |
320 |
p++; |
317 |
if (*p == '\0' || *p == '\\') |
321 |
if (*p == '\0' || *p == '\\' || *p == '\n') |
318 |
errx(1, |
322 |
errx(1, |
319 |
"%lu: %s: substitute pattern can not be delimited by newline or backslash", |
323 |
"%lu: %s: substitute pattern can not be delimited by newline or backslash", |
320 |
linenum, fname); |
324 |
linenum, fname); |
Lines 339-345
Link Here
|
339 |
cmd->u.s->re = NULL; |
343 |
cmd->u.s->re = NULL; |
340 |
else |
344 |
else |
341 |
cmd->u.s->re = compile_re(re, cmd->u.s->icase); |
345 |
cmd->u.s->re = compile_re(re, cmd->u.s->icase); |
342 |
EATSPACE(); |
|
|
343 |
if (*p == ';') { |
346 |
if (*p == ';') { |
344 |
p++; |
347 |
p++; |
345 |
link = &cmd->next; |
348 |
link = &cmd->next; |
Lines 372-379
Link Here
|
372 |
* in the case of a non-terminated string. The character array d is filled |
375 |
* in the case of a non-terminated string. The character array d is filled |
373 |
* with the processed string. |
376 |
* with the processed string. |
374 |
*/ |
377 |
*/ |
375 |
static char * |
378 |
static const char * |
376 |
compile_delimited(char *p, char *d, int is_tr) |
379 |
compile_delimited(const char *p, char *d, int is_tr) |
377 |
{ |
380 |
{ |
378 |
char c; |
381 |
char c; |
379 |
|
382 |
|
Lines 416-425
Link Here
|
416 |
|
419 |
|
417 |
/* compile_ccl: expand a POSIX character class */ |
420 |
/* compile_ccl: expand a POSIX character class */ |
418 |
static char * |
421 |
static char * |
419 |
compile_ccl(char **sp, char *t) |
422 |
compile_ccl(const char **sp, char *t) |
420 |
{ |
423 |
{ |
421 |
int c, d; |
424 |
int c, d; |
422 |
char *s = *sp; |
425 |
const char *s = *sp; |
423 |
|
426 |
|
424 |
*t++ = *s++; |
427 |
*t++ = *s++; |
425 |
if (*s == '^') |
428 |
if (*s == '^') |
Lines 442-448
Link Here
|
442 |
* Cflags are passed to regcomp. |
445 |
* Cflags are passed to regcomp. |
443 |
*/ |
446 |
*/ |
444 |
static regex_t * |
447 |
static regex_t * |
445 |
compile_re(char *re, int case_insensitive) |
448 |
compile_re(const char *re, int case_insensitive) |
446 |
{ |
449 |
{ |
447 |
regex_t *rep; |
450 |
regex_t *rep; |
448 |
int eval, flags; |
451 |
int eval, flags; |
Lines 466-479
Link Here
|
466 |
* point to a saved copy of it. Nsub is the number of parenthesized regular |
469 |
* point to a saved copy of it. Nsub is the number of parenthesized regular |
467 |
* expressions. |
470 |
* expressions. |
468 |
*/ |
471 |
*/ |
469 |
static char * |
472 |
static const char * |
470 |
compile_subst(char *p, struct s_subst *s) |
473 |
compile_subst(const char *p, struct s_subst *s) |
471 |
{ |
474 |
{ |
472 |
static char lbuf[_POSIX2_LINE_MAX + 1]; |
|
|
473 |
int asize, size; |
475 |
int asize, size; |
474 |
u_char ref; |
476 |
u_char ref; |
475 |
char c, *text, *op, *sp; |
477 |
char c, *text, *op, *sp; |
476 |
int more = 1, sawesc = 0; |
478 |
int more = 0, sawesc = 0; |
477 |
|
479 |
|
478 |
c = *p++; /* Terminator character */ |
480 |
c = *p++; /* Terminator character */ |
479 |
if (c == '\0') |
481 |
if (c == '\0') |
Lines 487-493
Link Here
|
487 |
size = 0; |
489 |
size = 0; |
488 |
do { |
490 |
do { |
489 |
op = sp = text + size; |
491 |
op = sp = text + size; |
490 |
for (; *p; p++) { |
492 |
for (; *p != '\0' && *p != '\n'; p++) { |
491 |
if (*p == '\\' || sawesc) { |
493 |
if (*p == '\\' || sawesc) { |
492 |
/* |
494 |
/* |
493 |
* If this is a continuation from the last |
495 |
* If this is a continuation from the last |
Lines 509-515
Link Here
|
509 |
*/ |
511 |
*/ |
510 |
sawesc = 1; |
512 |
sawesc = 1; |
511 |
p--; |
513 |
p--; |
512 |
continue; |
514 |
break; |
|
|
515 |
} else if (*p == '\n') { |
516 |
*sp++ = '\n'; |
517 |
break; |
513 |
} else if (strchr("123456789", *p) != NULL) { |
518 |
} else if (strchr("123456789", *p) != NULL) { |
514 |
*sp++ = '\\'; |
519 |
*sp++ = '\\'; |
515 |
ref = *p - '0'; |
520 |
ref = *p - '0'; |
Lines 522-530
Link Here
|
522 |
} else if (*p == '&' || *p == '\\') |
527 |
} else if (*p == '&' || *p == '\\') |
523 |
*sp++ = '\\'; |
528 |
*sp++ = '\\'; |
524 |
} else if (*p == c) { |
529 |
} else if (*p == c) { |
525 |
if (*++p == '\0' && more) { |
530 |
if ((*++p == '\0' || *p == '\n') && more) { |
526 |
if (cu_fgets(lbuf, sizeof(lbuf), &more)) |
531 |
const char *nextp; |
527 |
p = lbuf; |
532 |
|
|
|
533 |
nextp = cu_fgets(&more); |
534 |
if (nextp != NULL) |
535 |
p = nextp; |
528 |
} |
536 |
} |
529 |
*sp++ = '\0'; |
537 |
*sp++ = '\0'; |
530 |
size += sp - op; |
538 |
size += sp - op; |
Lines 532-537
Link Here
|
532 |
err(1, "realloc"); |
540 |
err(1, "realloc"); |
533 |
return (p); |
541 |
return (p); |
534 |
} else if (*p == '\n') { |
542 |
} else if (*p == '\n') { |
|
|
543 |
break; |
535 |
errx(1, |
544 |
errx(1, |
536 |
"%lu: %s: unescaped newline inside substitute pattern", linenum, fname); |
545 |
"%lu: %s: unescaped newline inside substitute pattern", linenum, fname); |
537 |
/* NOTREACHED */ |
546 |
/* NOTREACHED */ |
Lines 544-550
Link Here
|
544 |
if ((text = realloc(text, asize)) == NULL) |
553 |
if ((text = realloc(text, asize)) == NULL) |
545 |
err(1, "realloc"); |
554 |
err(1, "realloc"); |
546 |
} |
555 |
} |
547 |
} while (cu_fgets(p = lbuf, sizeof(lbuf), &more)); |
556 |
} while ((p = cu_fgets(&more))); |
548 |
errx(1, "%lu: %s: unterminated substitute in regular expression", |
557 |
errx(1, "%lu: %s: unterminated substitute in regular expression", |
549 |
linenum, fname); |
558 |
linenum, fname); |
550 |
/* NOTREACHED */ |
559 |
/* NOTREACHED */ |
Lines 553-560
Link Here
|
553 |
/* |
562 |
/* |
554 |
* Compile the flags of the s command |
563 |
* Compile the flags of the s command |
555 |
*/ |
564 |
*/ |
556 |
static char * |
565 |
static const char * |
557 |
compile_flags(char *p, struct s_subst *s) |
566 |
compile_flags(const char *p, struct s_subst *s) |
558 |
{ |
567 |
{ |
559 |
int gn; /* True if we have seen g or n */ |
568 |
int gn; /* True if we have seen g or n */ |
560 |
unsigned long nval; |
569 |
unsigned long nval; |
Lines 566-572
Link Here
|
566 |
s->wfd = -1; |
575 |
s->wfd = -1; |
567 |
s->icase = 0; |
576 |
s->icase = 0; |
568 |
for (gn = 0;;) { |
577 |
for (gn = 0;;) { |
569 |
EATSPACE(); /* EXTENSION */ |
578 |
EATSPACEN(); /* EXTENSION */ |
570 |
switch (*p) { |
579 |
switch (*p) { |
571 |
case 'g': |
580 |
case 'g': |
572 |
if (gn) |
581 |
if (gn) |
Lines 594-605
Link Here
|
594 |
"%lu: %s: more than one number or 'g' in substitute flags", linenum, fname); |
603 |
"%lu: %s: more than one number or 'g' in substitute flags", linenum, fname); |
595 |
gn = 1; |
604 |
gn = 1; |
596 |
errno = 0; |
605 |
errno = 0; |
597 |
nval = strtol(p, &p, 10); |
606 |
nval = strtol(p, &q, 10); |
598 |
if (errno == ERANGE || nval > INT_MAX) |
607 |
if (errno == ERANGE || nval > INT_MAX) |
599 |
errx(1, |
608 |
errx(1, |
600 |
"%lu: %s: overflow in the 'N' substitute flag", linenum, fname); |
609 |
"%lu: %s: overflow in the 'N' substitute flag", linenum, fname); |
601 |
s->n = nval; |
610 |
s->n = nval; |
602 |
p--; |
611 |
p = q - 1; |
603 |
break; |
612 |
break; |
604 |
case 'w': |
613 |
case 'w': |
605 |
p++; |
614 |
p++; |
Lines 637-644
Link Here
|
637 |
/* |
646 |
/* |
638 |
* Compile a translation set of strings into a lookup table. |
647 |
* Compile a translation set of strings into a lookup table. |
639 |
*/ |
648 |
*/ |
640 |
static char * |
649 |
static const char * |
641 |
compile_tr(char *p, struct s_tr **py) |
650 |
compile_tr(const char *p, struct s_tr **py) |
642 |
{ |
651 |
{ |
643 |
struct s_tr *y; |
652 |
struct s_tr *y; |
644 |
int i; |
653 |
int i; |
Lines 730-753
Link Here
|
730 |
* Compile the text following an a or i command. |
739 |
* Compile the text following an a or i command. |
731 |
*/ |
740 |
*/ |
732 |
static char * |
741 |
static char * |
733 |
compile_text(void) |
742 |
compile_text(size_t *ptlen) |
734 |
{ |
743 |
{ |
735 |
int asize, esc_nl, size; |
744 |
int asize, esc_nl, size; |
736 |
char *text, *p, *op, *s; |
745 |
char *text, *s; |
737 |
char lbuf[_POSIX2_LINE_MAX + 1]; |
746 |
const char *p, *op; |
738 |
|
747 |
|
739 |
asize = 2 * _POSIX2_LINE_MAX + 1; |
748 |
asize = 2 * _POSIX2_LINE_MAX + 1; |
740 |
if ((text = malloc(asize)) == NULL) |
749 |
if ((text = malloc(asize)) == NULL) |
741 |
err(1, "malloc"); |
750 |
err(1, "malloc"); |
742 |
size = 0; |
751 |
size = 0; |
743 |
while (cu_fgets(lbuf, sizeof(lbuf), NULL)) { |
752 |
while ((p = cu_fgets(NULL))) { |
744 |
op = s = text + size; |
753 |
op = s = text + size; |
745 |
p = lbuf; |
|
|
746 |
EATSPACE(); |
754 |
EATSPACE(); |
747 |
for (esc_nl = 0; *p != '\0'; p++) { |
755 |
for (esc_nl = 0; *p != '\0'; p++) { |
748 |
if (*p == '\\' && p[1] != '\0' && *++p == '\n') |
756 |
if (*p == '\\' && p[1] != '\0' && *++p == '\n') |
749 |
esc_nl = 1; |
757 |
esc_nl = 1; |
750 |
*s++ = *p; |
758 |
*s++ = *p; |
|
|
759 |
if (*p == '\n') |
760 |
break; |
751 |
} |
761 |
} |
752 |
size += s - op; |
762 |
size += s - op; |
753 |
if (!esc_nl) { |
763 |
if (!esc_nl) { |
Lines 761-769
Link Here
|
761 |
} |
771 |
} |
762 |
} |
772 |
} |
763 |
text[size] = '\0'; |
773 |
text[size] = '\0'; |
764 |
if ((p = realloc(text, size + 1)) == NULL) |
774 |
if ((text = realloc(text, size + 1)) == NULL) |
765 |
err(1, "realloc"); |
775 |
err(1, "realloc"); |
766 |
return (p); |
776 |
*ptlen = size; |
|
|
777 |
return (text); |
767 |
} |
778 |
} |
768 |
|
779 |
|
769 |
/* |
780 |
/* |
Lines 770-777
Link Here
|
770 |
* Get an address and return a pointer to the first character after |
781 |
* Get an address and return a pointer to the first character after |
771 |
* it. Fill the structure pointed to according to the address. |
782 |
* it. Fill the structure pointed to according to the address. |
772 |
*/ |
783 |
*/ |
773 |
static char * |
784 |
static const char * |
774 |
compile_addr(char *p, struct s_addr *a) |
785 |
compile_addr(const char *p, struct s_addr *a) |
775 |
{ |
786 |
{ |
776 |
char *end, re[_POSIX2_LINE_MAX + 1]; |
787 |
char *end, re[_POSIX2_LINE_MAX + 1]; |
777 |
int icase; |
788 |
int icase; |
Lines 825-846
Link Here
|
825 |
* Return a copy of all the characters up to \n or \0. |
836 |
* Return a copy of all the characters up to \n or \0. |
826 |
*/ |
837 |
*/ |
827 |
static char * |
838 |
static char * |
828 |
duptoeol(char *s, const char *ctype) |
839 |
duptoeol(const char *s, const char *ctype, size_t *ptlen) |
829 |
{ |
840 |
{ |
830 |
size_t len; |
841 |
size_t len; |
831 |
int ws; |
842 |
int ws; |
832 |
char *p, *start; |
843 |
char *p; |
|
|
844 |
const char *start; |
833 |
|
845 |
|
834 |
ws = 0; |
846 |
ws = 0; |
835 |
for (start = s; *s != '\0' && *s != '\n'; ++s) |
847 |
for (start = s; *s != '\0' && *s != '\n'; ++s) |
836 |
ws = isspace((unsigned char)*s); |
848 |
ws = isspace((unsigned char)*s); |
837 |
*s = '\0'; |
|
|
838 |
if (ws) |
849 |
if (ws) |
839 |
warnx("%lu: %s: whitespace after %s", linenum, fname, ctype); |
850 |
warnx("%lu: %s: whitespace after %s", linenum, fname, ctype); |
840 |
len = s - start + 1; |
851 |
len = s - start; |
841 |
if ((p = malloc(len)) == NULL) |
852 |
if ((p = malloc(len + 1)) == NULL) |
842 |
err(1, "malloc"); |
853 |
err(1, "malloc"); |
843 |
return (memmove(p, start, len)); |
854 |
memmove(p, start, len); |
|
|
855 |
p[len] = '\0'; |
856 |
*ptlen = len; |
857 |
return p; |
844 |
} |
858 |
} |
845 |
|
859 |
|
846 |
/* |
860 |
/* |
Lines 851-857
Link Here
|
851 |
* TODO: Remove } nodes |
865 |
* TODO: Remove } nodes |
852 |
*/ |
866 |
*/ |
853 |
static void |
867 |
static void |
854 |
fixuplabel(struct s_command *cp, struct s_command *end) |
868 |
fixuplabel(struct s_command *cp, const struct s_command *end) |
855 |
{ |
869 |
{ |
856 |
|
870 |
|
857 |
for (; cp != end; cp = cp->next) |
871 |
for (; cp != end; cp = cp->next) |
Lines 868-874
Link Here
|
868 |
break; |
882 |
break; |
869 |
} |
883 |
} |
870 |
if ((cp->u.c = findlabel(cp->t)) == NULL) |
884 |
if ((cp->u.c = findlabel(cp->t)) == NULL) |
871 |
errx(1, "%lu: %s: undefined label '%s'", linenum, fname, cp->t); |
885 |
errx(1, "%lu: %s: %c: undefined label '%s'", linenum, fname, cp->code, cp->t); |
872 |
free(cp->t); |
886 |
free(cp->t); |
873 |
break; |
887 |
break; |
874 |
case '{': |
888 |
case '{': |
Lines 908-914
Link Here
|
908 |
* list cp. L is excluded from the search. Return NULL if not found. |
922 |
* list cp. L is excluded from the search. Return NULL if not found. |
909 |
*/ |
923 |
*/ |
910 |
static struct s_command * |
924 |
static struct s_command * |
911 |
findlabel(char *name) |
925 |
findlabel(const char *name) |
912 |
{ |
926 |
{ |
913 |
struct labhash *lh; |
927 |
struct labhash *lh; |
914 |
u_char *p; |
928 |
u_char *p; |