diff options
Diffstat (limited to 'src/lex.l')
-rw-r--r-- | src/lex.l | 134 |
1 files changed, 80 insertions, 54 deletions
@@ -37,36 +37,34 @@ advance_line () | |||
37 | yylloc.beg = point; \ | 37 | yylloc.beg = point; \ |
38 | yylloc.beg.col++; \ | 38 | yylloc.beg.col++; \ |
39 | } \ | 39 | } \ |
40 | point.col += yyleng; \ | 40 | point.col += yyleng; \ |
41 | yylloc.end = point; \ | 41 | yylloc.end = point; \ |
42 | } \ | 42 | } \ |
43 | while (0); | 43 | while (0); |
44 | 44 | ||
45 | #undef YY_INPUT | 45 | #undef YY_INPUT |
46 | #define YY_INPUT(buf,result,max_size) \ | 46 | #define YY_INPUT(buf,result,max_size) \ |
47 | do \ | 47 | do \ |
48 | { \ | 48 | { \ |
49 | result = read_input (buf, max_size); \ | 49 | result = input_read (yyin, buf, max_size); \ |
50 | } \ | 50 | } \ |
51 | while (0); | 51 | while (0); |
52 | 52 | ||
53 | void string_begin (void); | 53 | void string_begin (void); |
54 | void string_add (const char *s, int l); | 54 | void string_add (const char *s, int l); |
55 | void string_addc (int c); | 55 | void string_addc (int c); |
56 | char *string_end (void); | 56 | char *string_end (void); |
57 | int unescape (int c); | 57 | int unescape (int c); |
58 | 58 | ||
59 | static ssize_t read_input (char *buf, size_t size); | ||
60 | |||
61 | struct context /* Input context */ | 59 | struct context /* Input context */ |
62 | { | 60 | { |
63 | struct context *parent; /* Pointer to the parent context */ | 61 | struct context *parent; /* Pointer to the parent context */ |
64 | struct locus locus; /* Locus */ | 62 | struct locus locus; /* Locus */ |
65 | struct point point; | 63 | struct point point; |
66 | int interactive; | 64 | int interactive; |
67 | ino_t ino; /* Inode number */ | 65 | ino_t ino; /* Inode number */ |
68 | dev_t dev; /* Device number */ | 66 | dev_t dev; /* Device number */ |
69 | FILE *file; /* Input file */ | 67 | FILE *file; /* Input file */ |
70 | YY_BUFFER_STATE buf; /* Buffer */ | 68 | YY_BUFFER_STATE buf; /* Buffer */ |
71 | }; | 69 | }; |
72 | 70 | ||
@@ -306,36 +304,34 @@ yywrap () | |||
306 | void | 304 | void |
307 | begin_def (void) | 305 | begin_def (void) |
308 | { | 306 | { |
309 | BEGIN (DEF); | 307 | BEGIN (DEF); |
310 | } | 308 | } |
311 | 309 | ||
312 | void | 310 | void |
313 | end_def (void) | 311 | end_def (void) |
314 | { | 312 | { |
315 | BEGIN (INITIAL); | 313 | BEGIN (INITIAL); |
316 | } | 314 | } |
317 | 315 | ||
318 | static ssize_t | 316 | void |
319 | read_input (char *buf, size_t size) | 317 | print_prompt_at_bol (void) |
320 | { | 318 | { |
321 | if (interactive) | 319 | if (YY_AT_BOL ()) |
322 | { | 320 | { |
323 | if (YY_AT_BOL ()) | 321 | char *s = make_prompt (); |
324 | print_prompt (); | 322 | fputs (s, stdout); |
325 | if (fgets (buf, size, yyin) == NULL) | 323 | fflush (stdout); |
326 | return 0; | 324 | free (s); |
327 | return strlen (buf); | ||
328 | } | 325 | } |
329 | return fread (buf, 1, size, yyin); | ||
330 | } | 326 | } |
331 | 327 | ||
332 | 328 | ||
333 | struct strseg | 329 | struct strseg |
334 | { | 330 | { |
335 | struct strseg *next; | 331 | struct strseg *next; |
336 | int len; | 332 | int len; |
337 | char ptr[1]; | 333 | char ptr[1]; |
338 | }; | 334 | }; |
339 | 335 | ||
340 | static struct strseg *strseg_head, *strseg_tail; | 336 | static struct strseg *strseg_head, *strseg_tail; |
341 | 337 | ||
@@ -444,127 +440,157 @@ vlerror (struct locus *loc, const char *fmt, va_list ap) | |||
444 | 440 | ||
445 | void | 441 | void |
446 | lerror (struct locus *loc, const char *fmt, ...) | 442 | lerror (struct locus *loc, const char *fmt, ...) |
447 | { | 443 | { |
448 | va_list ap; | 444 | va_list ap; |
449 | 445 | ||
450 | va_start (ap, fmt); | 446 | va_start (ap, fmt); |
451 | vlerror (loc, fmt, ap); | 447 | vlerror (loc, fmt, ap); |
452 | va_end (ap); | 448 | va_end (ap); |
453 | } | 449 | } |
454 | 450 | ||
455 | 451 | ||
456 | struct prompt_exp; | 452 | static struct slist * |
457 | 453 | pe_file_name (void) | |
458 | void | ||
459 | pe_file_name (struct prompt_exp *p) | ||
460 | { | 454 | { |
461 | if (file_name) | 455 | return file_name ? slist_new (file_name) : NULL; |
462 | fwrite (file_name, strlen (file_name), 1, stdout); | ||
463 | } | 456 | } |
464 | 457 | ||
465 | void | 458 | static struct slist * |
466 | pe_program_name (struct prompt_exp *p) | 459 | pe_program_name (void) |
467 | { | 460 | { |
468 | fwrite (progname, strlen (progname), 1, stdout); | 461 | return slist_new (progname); |
469 | } | 462 | } |
470 | 463 | ||
471 | void | 464 | static struct slist * |
472 | pe_package_name (struct prompt_exp *p) | 465 | pe_package_name (void) |
473 | { | 466 | { |
474 | fwrite (PACKAGE_NAME, sizeof (PACKAGE_NAME) - 1, 1, stdout); | 467 | return slist_new (PACKAGE_NAME); |
475 | } | 468 | } |
476 | 469 | ||
477 | void | 470 | static struct slist * |
478 | pe_program_version (struct prompt_exp *p) | 471 | pe_program_version (void) |
479 | { | 472 | { |
480 | fwrite (PACKAGE_VERSION, sizeof (PACKAGE_VERSION) - 1, 1, stdout); | 473 | return slist_new (PACKAGE_VERSION); |
481 | } | 474 | } |
482 | 475 | ||
483 | void | 476 | static struct slist * |
484 | pe_space (struct prompt_exp *p) | 477 | pe_space (void) |
485 | { | 478 | { |
486 | fwrite (" ", 1, 1, stdout); | 479 | return slist_new (" "); |
487 | } | 480 | } |
488 | 481 | ||
489 | struct prompt_exp | 482 | struct prompt_exp |
490 | { | 483 | { |
491 | int ch; | 484 | int ch; |
492 | void (*fun) (struct prompt_exp *); | 485 | struct slist *(*fun) (void); |
493 | char *cache; | ||
494 | }; | 486 | }; |
495 | 487 | ||
496 | struct prompt_exp prompt_exp[] = { | 488 | struct prompt_exp prompt_exp[] = { |
497 | { 'f', pe_file_name }, | 489 | { 'f', pe_file_name }, |
498 | { 'p', pe_program_name }, | 490 | { 'p', pe_program_name }, |
499 | { 'P', pe_package_name }, | 491 | { 'P', pe_package_name }, |
500 | { 'v', pe_program_version }, | 492 | { 'v', pe_program_version }, |
501 | { '_', pe_space }, | 493 | { '_', pe_space }, |
502 | { 0 } | 494 | { 0 } |
503 | }; | 495 | }; |
504 | 496 | ||
505 | static void | 497 | static int |
506 | expand_char (int c) | 498 | expand_char (int c, struct slist **tailp) |
507 | { | 499 | { |
508 | struct prompt_exp *p; | 500 | struct prompt_exp *p; |
509 | 501 | ||
510 | if (c && c != '%') | 502 | if (c && c != '%') |
511 | { | 503 | { |
512 | for (p = prompt_exp; p->ch; p++) | 504 | for (p = prompt_exp; p->ch; p++) |
513 | { | 505 | { |
514 | if (c == p->ch) | 506 | if (c == p->ch) |
515 | { | 507 | { |
516 | if (p->cache) | 508 | struct slist *s = p->fun (); |
517 | free (p->cache); | 509 | if (s) |
518 | p->fun (p); | 510 | slist_insert (tailp, s); |
519 | return; | 511 | return 0; |
520 | } | 512 | } |
521 | } | 513 | } |
522 | } | 514 | } |
523 | putchar ('%'); | 515 | return 1; |
524 | putchar (c); | ||
525 | } | 516 | } |
526 | 517 | ||
527 | char const * | 518 | char const * |
528 | psname () | 519 | psname (void) |
529 | { | 520 | { |
530 | if (YYSTATE == DEF || YYSTATE == MLSTR) | 521 | if (YYSTATE == DEF || YYSTATE == MLSTR) |
531 | return "ps2"; | 522 | return "ps2"; |
532 | return "ps1"; | 523 | return "ps1"; |
533 | } | 524 | } |
534 | 525 | ||
535 | void | 526 | char * |
536 | print_prompt () | 527 | make_prompt (void) |
537 | { | 528 | { |
538 | const char *s; | 529 | const char *s; |
539 | const char *prompt; | 530 | const char *prompt; |
540 | 531 | struct slist *head = NULL, *tail = NULL, *p; | |
53 |