|
diff --git a/src/lex.l b/src/lex.l index 9c2c5f8..236474d 100644 --- a/ src/lex.l+++ b/ src/lex.l |
|
@@ -43,24 +43,22 @@ advance_line () |
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; |
@@ -312,24 +310,22 @@ begin_def (void) |
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; |
@@ -450,121 +446,151 @@ lerror (struct locus *loc, const char *fmt, ...) |
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; |
| |
532 | char *ret, *end; |
| |
533 | size_t len; |
| |
534 | |
541 | switch (variable_get (psname (), VART_STRING, (void *) &prompt)) |
535 | switch (variable_get (psname (), VART_STRING, (void *) &prompt)) |
542 | { |
536 | { |
543 | case VAR_OK: |
537 | case VAR_OK: |
544 | break; |
538 | break; |
545 | |
539 | |
546 | case VAR_ERR_NOTSET: |
540 | case VAR_ERR_NOTSET: |
547 | return; |
541 | return NULL; |
548 | |
542 | |
549 | default: |
543 | default: |
550 | abort (); |
544 | abort (); |
551 | } |
545 | } |
552 | |
546 | |
553 | for (s = prompt; *s; s++) |
547 | for (s = prompt; *s; ) |
554 | { |
548 | { |
555 | if (*s == '%') |
549 | if (*s == '%' && s[1]) |
556 | { |
550 | { |
557 | if (!*++s) |
551 | if (s > prompt) |
| |
552 | { |
| |
553 | slist_insert (&tail, slist_new_l (prompt, s - prompt)); |
| |
554 | if (!head) |
| |
555 | head = tail; |
| |
556 | } |
| |
557 | if (expand_char (s[1], &tail) == 0) |
558 | { |
558 | { |
559 | putchar ('%'); |
559 | if (!head) |
560 | break; |
560 | head = tail; |
| |
561 | prompt = s + 2; |
561 | } |
562 | } |
562 | expand_char (*s); |
563 | else |
| |
564 | prompt = s; |
| |
565 | s += 2; |
563 | } |
566 | } |
564 | else |
567 | else |
565 | putchar (*s); |
568 | ++s; |
| |
569 | } |
| |
570 | |
| |
571 | if (s > prompt) |
| |
572 | { |
| |
573 | slist_insert (&tail, slist_new_l (prompt, s - prompt)); |
| |
574 | if (!head) |
| |
575 | head = tail; |
566 | } |
576 | } |
567 | |
577 | |
568 | fflush (stdout); |
578 | len = 0; |
| |
579 | for (p = head; p; p = p->next) |
| |
580 | len += strlen (p->str); |
| |
581 | |
| |
582 | ret = emalloc (len + 1); |
| |
583 | end = ret; |
| |
584 | for (p = head; p; p = p->next) |
| |
585 | { |
| |
586 | s = p->str; |
| |
587 | while (*s) |
| |
588 | *end++ = *s++; |
| |
589 | } |
| |
590 | *end = 0; |
| |
591 | |
| |
592 | slist_free (head); |
| |
593 | |
| |
594 | return ret; |
569 | } |
595 | } |
570 | |
596 | |
|