4 * (c) 2007 Martin Mares <mj@ucw.cz>
16 #define DEFAULT_MAX_TOKEN (32 << 20)
18 void tok_init(struct tokenizer *t, struct stream *s)
20 memset(t, 0, sizeof(*t));
23 t->token = xmalloc(t->bufsize);
24 t->maxsize = DEFAULT_MAX_TOKEN;
28 void tok_cleanup(struct tokenizer *t)
33 void tok_err(struct tokenizer *t, char *msg, ...)
37 fprintf(stderr, "Error at %s line %d:\n", t->stream->name, t->line);
38 vfprintf(stderr, msg, args);
44 static inline int is_white(int c)
46 return (c == ' ' || c == '\t' || c == '\r' || c == '\n');
49 char *get_token(struct tokenizer *t)
63 if (t->flags & TF_REPORT_LINES)
73 // This is the token itself
77 if (len >= t->bufsize)
80 tok_err(t, "Token too long");
82 if (t->bufsize > t->maxsize)
83 t->bufsize = t->maxsize+1;
84 t->token = xrealloc(t->token, t->bufsize);
88 while (c >= 0 && !is_white(c));
98 * Parsing functions. They return 1 if successfully parsed, 0 otherwise.
101 #define PARSE(f, ...) \
106 *x = f(t->token, &end, ##__VA_ARGS__); \
107 return !(errno || (unsigned char *) end != t->token + t->toksize)
109 int to_long(struct tokenizer *t, long int *x)
114 int to_ulong(struct tokenizer *t, unsigned long int *x)
116 if (t->token[0] == '-') // strtoul accepts negative numbers, but we don't
121 int to_double(struct tokenizer *t, double *x)
126 int to_long_double(struct tokenizer *t, long double *x)
131 int to_int(struct tokenizer *t, int *x)
134 if (!to_long(t, &y) || y > LONG_MAX || y < LONG_MIN)
140 int to_uint(struct tokenizer *t, unsigned int *x)
143 if (!to_ulong(t, &y) || y > ULONG_MAX)
149 #define GET(fn, type) \
150 type get_##fn(struct tokenizer *t) \
154 tok_err(t, "Unexpected end of file"); \
155 if (!to_##fn(t, &x)) \
156 tok_err(t, "Expected " #fn); \
161 GET(uint, unsigned int)
163 GET(ulong, unsigned long int)
165 GET(long_double, long double)
167 void get_nl(struct tokenizer *t)
169 char *tok = get_token(t);
171 tok_err(t, "Expected end of line");