version 1.25, 2010/12/26 13:09:22 |
version 1.26, 2012/03/22 13:47:12 |
|
|
#include "error.h" |
#include "error.h" |
#include "lst.h" |
#include "lst.h" |
#include "memory.h" |
#include "memory.h" |
|
#include "location.h" |
|
|
|
|
/* XXX check whether we can free filenames at the end, for a proper |
/* XXX check whether we can free filenames at the end, for a proper |
* definition of `end'. */ |
* definition of `end'. */ |
|
|
|
|
* Strings have F == NULL, str != NULL. |
* Strings have F == NULL, str != NULL. |
*/ |
*/ |
struct input_stream { |
struct input_stream { |
const char *fname; /* Name of file */ |
Location origin; /* Name of file and line number */ |
unsigned long lineno; /* Line number */ |
|
FILE *F; /* Open stream, or NULL if pure string. */ |
FILE *F; /* Open stream, or NULL if pure string. */ |
char *str; /* Input string, if F == NULL. */ |
char *str; /* Input string, if F == NULL. */ |
|
|
|
|
* obj = new_input_file(filename, filehandle); |
* obj = new_input_file(filename, filehandle); |
* Create input stream from filename, filehandle. */ |
* Create input stream from filename, filehandle. */ |
static struct input_stream *new_input_file(const char *, FILE *); |
static struct input_stream *new_input_file(const char *, FILE *); |
/* obj = new_input_string(str, filename, lineno); |
/* obj = new_input_string(str, origin); |
* Create input stream from str, filename, lineno. */ |
* Create input stream from str, origin. */ |
static struct input_stream *new_input_string(char *, const char *, unsigned long); |
static struct input_stream *new_input_string(char *, const Location *); |
/* free_input_stream(obj); |
/* free_input_stream(obj); |
* Discard consumed input stream, closing files, freeing memory. */ |
* Discard consumed input stream, closing files, freeing memory. */ |
static void free_input_stream(struct input_stream *); |
static void free_input_stream(struct input_stream *); |
|
|
#endif |
#endif |
|
|
istream = emalloc(sizeof(*istream)); |
istream = emalloc(sizeof(*istream)); |
istream->fname = name; |
istream->origin.fname = name; |
istream->str = NULL; |
istream->str = NULL; |
/* Naturally enough, we start reading at line 0. */ |
/* Naturally enough, we start reading at line 0. */ |
istream->lineno = 0; |
istream->origin.lineno = 0; |
istream->F = stream; |
istream->F = stream; |
istream->ptr = istream->end = NULL; |
istream->ptr = istream->end = NULL; |
return istream; |
return istream; |
|
|
} |
} |
|
|
static struct input_stream * |
static struct input_stream * |
new_input_string(char *str, const char *name, unsigned long lineno) |
new_input_string(char *str, const Location *origin) |
{ |
{ |
struct input_stream *istream; |
struct input_stream *istream; |
|
|
istream = emalloc(sizeof(*istream)); |
istream = emalloc(sizeof(*istream)); |
/* No malloc, name is always taken from an already existing istream */ |
/* No malloc, name is always taken from an already existing istream |
istream->fname = name; |
* and strings are used in for loops, so we need to reset the line counter |
|
* to an appropriate value. */ |
|
istream->origin = *origin; |
istream->F = NULL; |
istream->F = NULL; |
/* Strings are used in for loops, so we need to reset the line counter |
|
* to an appropriate value. */ |
|
istream->lineno = lineno; |
|
istream->ptr = istream->str = str; |
istream->ptr = istream->str = str; |
istream->end = str + strlen(str); |
istream->end = str + strlen(str); |
return istream; |
return istream; |
|
|
void |
void |
Parse_FromString(char *str, unsigned long lineno) |
Parse_FromString(char *str, unsigned long lineno) |
{ |
{ |
|
Location origin; |
|
|
|
origin.fname = current->origin.fname; |
|
origin.lineno = lineno; |
if (DEBUG(FOR)) |
if (DEBUG(FOR)) |
(void)fprintf(stderr, "%s\n----\n", str); |
(void)fprintf(stderr, "%s\n----\n", str); |
|
|
Lst_Push(&input_stack, current); |
Lst_Push(&input_stack, current); |
assert(current != NULL); |
assert(current != NULL); |
current = new_input_string(str, current->fname, lineno); |
current = new_input_string(str, &origin); |
} |
} |
|
|
|
|
|
|
if (c == '\\') { |
if (c == '\\') { |
c = read_char(); |
c = read_char(); |
if (c == '\n') |
if (c == '\n') |
current->lineno++; |
current->origin.lineno++; |
} |
} |
if (c == EOF) { |
if (c == EOF) { |
Parse_Error(PARSE_FATAL, |
Parse_Error(PARSE_FATAL, |
|
|
return NULL; |
return NULL; |
} |
} |
} |
} |
current->lineno++; |
current->origin.lineno++; |
} |
} |
|
|
/* This is the line we need to copy */ |
/* This is the line we need to copy */ |
|
|
{ |
{ |
for (;;) { |
for (;;) { |
if (c == '\n') { |
if (c == '\n') { |
current->lineno++; |
current->origin.lineno++; |
break; |
break; |
} |
} |
if (c == EOF) |
if (c == EOF) |
|
|
c = read_char(); |
c = read_char(); |
if (c == '\n') { |
if (c == '\n') { |
Buf_AddSpace(linebuf); |
Buf_AddSpace(linebuf); |
current->lineno++; |
current->origin.lineno++; |
do { |
do { |
c = read_char(); |
c = read_char(); |
} while (c == ' ' || c == '\t'); |
} while (c == ' ' || c == '\t'); |
|
|
while (c == '\\') { |
while (c == '\\') { |
c = read_char(); |
c = read_char(); |
if (c == '\n') { |
if (c == '\n') { |
current->lineno++; |
current->origin.lineno++; |
do { |
do { |
c = read_char(); |
c = read_char(); |
} while (c == ' ' || c == '\t'); |
} while (c == ' ' || c == '\t'); |
|
|
while (c == '\\') { |
while (c == '\\') { |
c = read_char(); |
c = read_char(); |
if (c == '\n') { |
if (c == '\n') { |
current->lineno++; |
current->origin.lineno++; |
do { |
do { |
c = read_char(); |
c = read_char(); |
} while (c == ' ' || c == '\t'); |
} while (c == ' ' || c == '\t'); |
|
|
while (c == '\\') { |
while (c == '\\') { |
c = read_char(); |
c = read_char(); |
if (c == '\n') { |
if (c == '\n') { |
current->lineno++; |
current->origin.lineno++; |
do { |
do { |
c = read_char(); |
c = read_char(); |
} while (c == ' ' || c == '\t'); |
} while (c == ' ' || c == '\t'); |
|
|
} |
} |
} |
} |
if (c == '\n') |
if (c == '\n') |
current->lineno++; |
current->origin.lineno++; |
else |
else |
return c; |
return c; |
} |
} |
|
|
unsigned long |
unsigned long |
Parse_Getlineno(void) |
Parse_Getlineno(void) |
{ |
{ |
return current ? current->lineno : 0; |
return current ? current->origin.lineno : 0; |
} |
} |
|
|
const char * |
const char * |
Parse_Getfilename(void) |
Parse_Getfilename(void) |
{ |
{ |
return current ? current->fname : NULL; |
return current ? current->origin.fname : NULL; |
|
} |
|
|
|
void |
|
Parse_FillLocation(Location *origin) |
|
{ |
|
origin->lineno = Parse_Getlineno(); |
|
origin->fname = Parse_Getfilename(); |
} |
} |
|
|
#ifdef CLEANUP |
#ifdef CLEANUP |