[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Changes to m4/src/Attic/input.c,v [branch-1_4]
From: |
Eric Blake |
Subject: |
Changes to m4/src/Attic/input.c,v [branch-1_4] |
Date: |
Wed, 11 Oct 2006 23:34:23 +0000 |
CVSROOT: /sources/m4
Module name: m4
Branch: branch-1_4
Changes by: Eric Blake <ericb> 06/10/11 23:34:22
Index: src/input.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/input.c,v
retrieving revision 1.1.1.1.2.24
retrieving revision 1.1.1.1.2.25
diff -u -b -r1.1.1.1.2.24 -r1.1.1.1.2.25
--- src/input.c 11 Oct 2006 17:07:03 -0000 1.1.1.1.2.24
+++ src/input.c 11 Oct 2006 23:34:22 -0000 1.1.1.1.2.25
@@ -61,9 +61,11 @@
enum input_type
{
- INPUT_FILE,
- INPUT_STRING,
- INPUT_MACRO
+ INPUT_STRING, /* String resulting from macro expansion. */
+ INPUT_STRING_WRAP, /* String resulting from m4wrap. */
+ INPUT_FILE, /* File which has had at least one character read. */
+ INPUT_FILE_INIT, /* File which has not yet been read. */
+ INPUT_MACRO /* Builtin resulting from defn. */
};
typedef enum input_type input_type;
@@ -71,14 +73,16 @@
struct input_block
{
struct input_block *prev; /* previous input_block on the input stack */
- input_type type; /* INPUT_FILE, INPUT_STRING or INPUT_MACRO */
+ input_type type; /* see enum values */
union
{
struct
{
char *string; /* string value */
+ const char *name; /* file where wrapped text is from */
+ int lineno; /* line where wrapped text is from */
}
- u_s;
+ u_s; /* INPUT_STRING, INPUT_STRING_WRAP */
struct
{
FILE *file; /* input file handle */
@@ -89,7 +93,7 @@
int out_lineno; /* current output line of previous file */
boolean advance_line; /* start_of_input_line from next_char () */
}
- u_f;
+ u_f; /* INPUT_FILE, INPUT_FILE_INIT */
builtin_func *func; /* pointer to macro's function */
}
u;
@@ -184,7 +188,7 @@
i = (input_block *) obstack_alloc (current_input,
sizeof (struct input_block));
- i->type = INPUT_FILE;
+ i->type = INPUT_FILE_INIT;
i->u.u_f.end = FALSE;
i->u.u_f.close = close;
@@ -196,10 +200,11 @@
to expand_macro remembering where the include or sinclude builtin
invocation began, so don't modify them here. However, we are
guaranteed that they are consistent in the context of read or
- peek. So we use u_f.lineno == 0 and a non-empty u_f.name as a
- key that this file is newly pushed, and that current_file/line
- still needs an update (lineno == 0 and an empty name imply that
- when we pop this file, there is no more input to return to).
+ peek. So we use the temporary type INPUT_FILE_INIT as key that
+ this file is newly pushed, u_f.name is the name of this file, and
+ that current_file/line still needs an update; and the
+ longer-lasting type INPUT_FILE as key that the file is in use,
+ with u_f.name as the name of the file that included this file.
Also, we must save title on a separate obstack, again since
expand_macro hangs on to file names even after the file is
closed. */
@@ -255,6 +260,8 @@
next = (input_block *) obstack_alloc (current_input,
sizeof (struct input_block));
next->type = INPUT_STRING;
+ next->u.u_s.name = NULL;
+ next->u.u_s.lineno = 0;
return current_input;
}
@@ -275,7 +282,8 @@
if (next == NULL)
return NULL;
- if (obstack_object_size (current_input) > 0)
+ if (obstack_object_size (current_input) > 0
+ || isp->type == INPUT_STRING_WRAP)
{
obstack_1grow (current_input, '\0');
next->u.u_s.string = obstack_finish (current_input);
@@ -304,8 +312,10 @@
i = (input_block *) obstack_alloc (wrapup_stack,
sizeof (struct input_block));
i->prev = wsp;
- i->type = INPUT_STRING;
+ i->type = INPUT_STRING_WRAP;
i->u.u_s.string = obstack_copy0 (wrapup_stack, s, strlen (s));
+ i->u.u_s.name = current_file;
+ i->u.u_s.lineno = current_line;
wsp = i;
}
@@ -323,6 +333,12 @@
switch (isp->type)
{
+ case INPUT_STRING_WRAP:
+ case INPUT_FILE_INIT:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: input stack botch in pop_input ()"));
+ abort ();
+
case INPUT_STRING:
case INPUT_MACRO:
break;
@@ -446,38 +462,31 @@
peek_input (void)
{
int ch;
+ input_block *block = isp;
while (1)
{
- if (isp == NULL)
+ if (block == NULL)
return CHAR_EOF;
- switch (isp->type)
+ switch (block->type)
{
+ case INPUT_STRING_WRAP:
case INPUT_STRING:
- ch = to_uchar (isp->u.u_s.string[0]);
+ ch = to_uchar (block->u.u_s.string[0]);
if (ch != '\0')
return ch;
break;
+ case INPUT_FILE_INIT:
case INPUT_FILE:
- /* See comments in push_file. */
- if (isp->u.u_f.lineno == 0 && isp->u.u_f.name[0] != '\0')
- {
- const char *tmp = isp->u.u_f.name;
- isp->u.u_f.name = current_file;
- isp->u.u_f.lineno = current_line;
- current_file = tmp;
- current_line = 1;
- }
-
- ch = getc (isp->u.u_f.file);
+ ch = getc (block->u.u_f.file);
if (ch != EOF)
{
- ungetc (ch, isp->u.u_f.file);
+ ungetc (ch, block->u.u_f.file);
return ch;
}
- isp->u.u_f.end = TRUE;
+ block->u.u_f.end = TRUE;
break;
case INPUT_MACRO:
@@ -488,12 +497,7 @@
"INTERNAL ERROR: input stack botch in peek_input ()"));
abort ();
}
- /* End of current input source --- pop one level if another
- level still exists. */
- if (isp->prev != NULL)
- pop_input ();
- else
- return CHAR_EOF;
+ block = block->prev;
}
}
@@ -530,15 +534,19 @@
switch (isp->type)
{
+ case INPUT_STRING_WRAP:
+ current_file = isp->u.u_s.name;
+ current_line = isp->u.u_s.lineno;
+ isp->type = INPUT_STRING;
+ /* fall through */
case INPUT_STRING:
ch = to_uchar (*isp->u.u_s.string++);
if (ch != '\0')
return ch;
break;
- case INPUT_FILE:
+ case INPUT_FILE_INIT:
/* See comments in push_file. */
- if (isp->u.u_f.lineno == 0 && isp->u.u_f.name[0] != '\0')
{
const char *tmp = isp->u.u_f.name;
isp->u.u_f.name = current_file;
@@ -546,7 +554,9 @@
current_file = tmp;
current_line = 1;
}
-
+ isp->type = INPUT_FILE;
+ /* fall through */
+ case INPUT_FILE:
/* If stdin is a terminal, calling getc after peek_input
already called it would make the user have to hit ^D
twice to quit. */
@@ -594,6 +604,25 @@
previous value we stored earlier. */
M4ERROR_AT_LINE ((warning_status, 0, file, line,
"Warning: end of file treated as newline"));
+ /* On the rare occasion that dnl crosses include file boundaries
+ (either the input file did not end in a newline, or changeword
+ was used), calling next_char can update current_file and
+ current_line, and that update will be undone as we return to
+ expand_macro. This hack of sticking an empty INPUT_STRING_WRAP
+ with the correct location as the next thing to parse works around
+ the problem. */
+ if (file != current_file || line != current_line)
+ {
+ input_block *i;
+ i = (input_block *) obstack_alloc (current_input,
+ sizeof (struct input_block));
+ i->prev = isp;
+ i->type = INPUT_STRING_WRAP;
+ i->u.u_s.string = "";
+ i->u.u_s.name = current_file;
+ i->u.u_s.lineno = current_line + 1; /* Account for parsed `\n'. */
+ isp = i;
+ }
}
@@ -828,7 +857,7 @@
token_type type;
#ifdef ENABLE_CHANGEWORD
int startpos;
- char *orig_text = 0;
+ char *orig_text = NULL;
#endif
const char *file;
int line;
@@ -995,74 +1024,53 @@
token_type
peek_token (void)
{
+ token_type result;
int ch = peek_input ();
if (ch == CHAR_EOF)
{
-#ifdef DEBUG_INPUT
- fprintf (stderr, "peek_token -> EOF\n");
-#endif
- return TOKEN_EOF;
+ result = TOKEN_EOF;
}
- if (ch == CHAR_MACRO)
+ else if (ch == CHAR_MACRO)
{
-#ifdef DEBUG_INPUT
- fprintf (stderr, "peek_token -> MACDEF\n");
-#endif
- return TOKEN_MACDEF;
+ result = TOKEN_MACDEF;
}
-
- if (MATCH (ch, bcomm.string, FALSE))
+ else if (MATCH (ch, bcomm.string, FALSE))
{
-#ifdef DEBUG_INPUT
- fprintf (stderr, "peek_token -> COMMENT\n");
-#endif
- return TOKEN_STRING;
+ result = TOKEN_STRING;
}
-
- if ((default_word_regexp && (isalpha (ch) || ch == '_'))
+ else if ((default_word_regexp && (isalpha (ch) || ch == '_'))
#ifdef ENABLE_CHANGEWORD
|| (! default_word_regexp && word_start[ch])
#endif /* ENABLE_CHANGEWORD */
)
{
-#ifdef DEBUG_INPUT
- fprintf (stderr, "peek_token -> WORD\n");
-#endif
- return TOKEN_WORD;
+ result = TOKEN_WORD;
}
-
- if (MATCH (ch, lquote.string, FALSE))
+ else if (MATCH (ch, lquote.string, FALSE))
{
-#ifdef DEBUG_INPUT
- fprintf (stderr, "peek_token -> QUOTE\n");
-#endif
- return TOKEN_STRING;
+ result = TOKEN_STRING;
}
-
+ else
switch (ch)
{
case '(':
-#ifdef DEBUG_INPUT
- fprintf (stderr, "peek_token -> OPEN\n");
-#endif
- return TOKEN_OPEN;
+ result = TOKEN_OPEN;
+ break;
case ',':
-#ifdef DEBUG_INPUT
- fprintf (stderr, "peek_token -> COMMA\n");
-#endif
- return TOKEN_COMMA;
+ result = TOKEN_COMMA;
+ break;
case ')':
-#ifdef DEBUG_INPUT
- fprintf (stderr, "peek_token -> CLOSE\n");
-#endif
- return TOKEN_CLOSE;
+ result = TOKEN_CLOSE;
+ break;
default:
-#ifdef DEBUG_INPUT
- fprintf (stderr, "peek_token -> SIMPLE\n");
-#endif
- return TOKEN_SIMPLE;
+ result = TOKEN_SIMPLE;
}
+
+#ifdef DEBUG_INPUT
+ fprintf (stderr, "peek_token -> %s\n", token_type_string (result));
+#endif /* DEBUG_INPUT */
+ return result;
}
- Changes to m4/src/Attic/input.c,v [branch-1_4], Eric Blake, 2006/10/11
- Changes to m4/src/Attic/input.c,v [branch-1_4],
Eric Blake <=
- Changes to m4/src/Attic/input.c,v [branch-1_4], Eric Blake, 2006/10/12
- Changes to m4/src/Attic/input.c,v [branch-1_4], Eric Blake, 2006/10/14
- Changes to m4/src/Attic/input.c,v [branch-1_4], Eric Blake, 2006/10/25
- Changes to m4/src/Attic/input.c,v [branch-1_4], Eric Blake, 2006/10/26
- Changes to m4/src/Attic/input.c,v [branch-1_4], Eric Blake, 2006/10/26
- Changes to m4/src/Attic/input.c,v [branch-1_4], Eric Blake, 2006/10/29