2 /* This file is part of GDBM, the GNU data base manager.
3 Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
6 GDBM is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GDBM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GDBM. If not, see <http://www.gnu.org/licenses/>. */
24 /* Advance locus to the next line */
32 #define YY_USER_ACTION \
40 point.col += yyleng; \
46 #define YY_INPUT(buf,result,max_size) \
49 result = read_input (buf, max_size); \
53 void string_begin (void);
54 void string_add (const char *s, int l);
55 void string_addc (int c);
56 char *string_end (void);
59 static ssize_t read_input (char *buf, size_t size);
61 struct context /* Input context */
63 struct context *parent; /* Pointer to the parent context */
64 struct locus locus; /* Locus */
67 ino_t ino; /* Inode number */
68 dev_t dev; /* Device number */
69 FILE *file; /* Input file */
70 YY_BUFFER_STATE buf; /* Buffer */
73 static struct context *context_tos;
76 int interactive; /* Are we running in interactive mode? */
77 static int initialized;
82 struct context *cp = ecalloc (1, sizeof (*cp));
86 cp->interactive = interactive;
90 cp->buf = YY_CURRENT_BUFFER;
91 cp->parent = context_tos;
98 struct context *cp = context_tos;
104 memset (&yylloc, 0, sizeof (yylloc));
109 context_tos = cp->parent;
113 interactive = cp->interactive;
117 yy_delete_buffer (YY_CURRENT_BUFFER);
118 yy_switch_to_buffer (cp->buf);
123 static struct context *
124 findctx (struct stat *st)
128 for (cp = context_tos; cp; cp = cp->parent)
129 if (cp->dev == st->st_dev && cp->ino == st->st_ino)
135 setsource (const char *name, int intr)
141 if (strcmp (name, "-") == 0)
148 if (stat (name, &st))
150 terror (_("cannot open `%s': %s"), name, strerror (errno));
153 else if (!S_ISREG (st.st_mode))
155 terror (_("%s is not a regular file"), name);
162 terror (_("recursive sourcing"));
164 lerror (&cp->locus, _("%s already sourced here"), name);
168 fp = fopen (name, "r");
171 terror (_("cannot open %s for reading: %s"), name,
181 yy_switch_to_buffer (yy_create_buffer (yyin, YY_BUF_SIZE));
187 point.file = estrdup (name);
202 IDENT [a-zA-Z_][a-zA-Z_0-9-]*
209 ^[ \t]*#[ \t]*line[ \t].*\n {
214 for (p = strchr (yytext, '#') + 1; *p == ' ' || *p == '\t'; p++);
216 for (; *p == ' ' || *p == '\t'; p++);
218 line = strtol (p, &p, 10);
219 for (; *p == ' ' || *p == '\t'; p++);
224 len = strcspn (p, "\"");
227 yyerror (_("invalid #line statement"));
230 file = emalloc (len + 1);
231 memcpy (file, p, len);
233 for (p += len + 1; *p == ' ' || *p == '\t'; p++);
237 yyerror (_("invalid #line statement"));
246 #.*\n advance_line ();
247 #.* /* end-of-file comment */;
249 <DEF>off { return T_OFF; }
250 <DEF>pad { return T_PAD; }
251 <DEF>0[xX]{X}{X}* { yylval.num = strtoul (yytext, NULL, 16);
253 <DEF>0{O}{O}* { yylval.num = strtoul (yytext, NULL, 8);
255 <DEF>0|{P} { yylval.num = strtoul (yytext, NULL, 10);
257 ^[ \t]*\? { return command_lookup ("help", &yylloc, &yylval.cmd); }
258 ^[ \t]*{IDENT} { char *p = yytext + strspn (yytext, " \t");
259 return command_lookup (p, &yylloc, &yylval.cmd);
261 <DEF>{IDENT} { if ((yylval.type = datadef_lookup (yytext)))
265 yylval.string = estrdup (yytext);
269 {IDENT} { yylval.string = estrdup (yytext);
272 <INITIAL,DEF>[^ \"\t\n\[\]{},=]+ { yylval.string = estrdup (yytext);
274 \"[^\\\"\n]*\" { yylval.string = emalloc (yyleng - 1);
275 memcpy (yylval.string, yytext+1, yyleng-2);
276 yylval.string[yyleng-2] = 0;
278 \"[^\\\"\n]*\\$ { string_begin ();
279 string_add (yytext + 1, yyleng - 2);
281 \"[^\\\"\n]*\\. { string_begin ();
282 string_add (yytext + 1, yyleng - 3);
283 string_addc (unescape (yytext[yyleng-1]));
285 <STR,MLSTR>[^\\\"\n]*\" { if (yyleng > 1)
286 string_add (yytext, yyleng - 1);
287 yylval.string = string_end ();
290 <STR,MLSTR>[^\\\"\n]*\\$ { string_add (yytext, yyleng - 1); }
291 <STR,MLSTR>[^\\\"\n]*\\. { string_add (yytext, yyleng - 2);
292 string_addc (unescape (yytext[yyleng-1])); }
294 <DEF>\n { advance_line (); }
295 \n { advance_line (); return '\n'; }
296 <INITIAL,DEF>. return yytext[0];
302 return context_pop ();
318 read_input (char *buf, size_t size)
324 if (fgets (buf, size, yyin) == NULL)
328 return fread (buf, 1, size, yyin);
339 static struct strseg *strseg_head, *strseg_tail;
344 strseg_head = strseg_tail = NULL;
348 strseg_attach (struct strseg *seg)
352 strseg_tail->next = seg;
359 string_add (const char *s, int l)
361 struct strseg *seg = emalloc (sizeof (*seg) + l);
362 memcpy (seg->ptr, s, l);
370 struct strseg *seg = emalloc (sizeof (*seg));
383 for (seg = strseg_head; seg; seg = seg->next)
388 for (seg = strseg_head; seg; )
390 struct strseg *next = seg->next;
391 memcpy (p, seg->ptr, seg->len);
398 strseg_head = strseg_tail = NULL;
403 static char transtab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
410 for (p = transtab; *p; p += 2)
422 for (p = transtab + sizeof (transtab) - 2; p > transtab; p -= 2)
431 vlerror (struct locus *loc, const char *fmt, va_list ap)
434 fprintf (stderr, "%s: ", progname);
435 if (initialized && loc && loc->beg.file)
437 YY_LOCATION_PRINT (stderr, *loc);
438 fprintf (stderr, ": ");
440 vfprintf (stderr, fmt, ap);
441 fputc ('\n', stderr);
445 lerror (struct locus *loc, const char *fmt, ...)
450 vlerror (loc, fmt, ap);
458 pe_file_name (struct prompt_exp *p)
461 fwrite (file_name, strlen (file_name), 1, stdout);
465 pe_program_name (struct prompt_exp *p)
467 fwrite (progname, strlen (progname), 1, stdout);
471 pe_package_name (struct prompt_exp *p)
473 fwrite (PACKAGE_NAME, sizeof (PACKAGE_NAME) - 1, 1, stdout);
477 pe_program_version (struct prompt_exp *p)
479 fwrite (PACKAGE_VERSION, sizeof (PACKAGE_VERSION) - 1, 1, stdout);
483 pe_space (struct prompt_exp *p)
485 fwrite (" ", 1, 1, stdout);
491 void (*fun) (struct prompt_exp *);
495 struct prompt_exp prompt_exp[] = {
496 { 'f', pe_file_name },
497 { 'p', pe_program_name },
498 { 'P', pe_package_name },
499 { 'v', pe_program_version },
507 struct prompt_exp *p;
511 for (p = prompt_exp; p->ch; p++)
528 if (YYSTATE == DEF || YYSTATE == MLSTR)
539 switch (variable_get (psname (), VART_STRING, (void *) &prompt))
551 for (s = prompt; *s; s++)