+2001-09-28 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cpphash.h (struct cpp_buff): Make unsigned.
+ (_cpp_get_buff): Take length of size_t.
+ (_cpp_unaligned_alloc): New.
+ (BUFF_ROOM, BUFF_FRONT, BUFF_LIMIT): New.
+ (struct cpp_reader): Remove ident_pool. Add u_buff.
+ * cppinit.c (cpp_create_reader): Initialize u_buff, not ident_pool.
+ (cpp_destroy): Destroy u_buff, not ident_pool.
+ * cpplex.c (parse_number, parse_string, save_comment,
+ cpp_token_as_text): Update to use the unaligned buffer.
+ (new_buff): Make unsigned.
+ (_cpp_unaligned_alloc): New.
+ * cpplib.c (glue_header_name): Update to use the unaligned buffer.
+ * cppmacro.c (new_number_token, builtin_macro, stringify_arg):
+ Similarly.
+ (collect_args): Make unsigned.
+
2001-09-27 Zack Weinberg <zack@codesourcery.com>
* cpplex.c (cpp_output_token): Use a putc loop for
struct _cpp_buff
{
struct _cpp_buff *next;
- char *base, *cur, *limit;
+ unsigned char *base, *cur, *limit;
};
-extern _cpp_buff *_cpp_get_buff PARAMS ((cpp_reader *, unsigned int));
+extern _cpp_buff *_cpp_get_buff PARAMS ((cpp_reader *, size_t));
extern void _cpp_release_buff PARAMS ((cpp_reader *, _cpp_buff *));
extern _cpp_buff *_cpp_extend_buff PARAMS ((cpp_reader *, _cpp_buff *,
- unsigned int));
+ size_t));
extern void _cpp_free_buff PARAMS ((_cpp_buff *));
+extern unsigned char *_cpp_unaligned_alloc PARAMS ((cpp_reader *, size_t));
+#define BUFF_ROOM(BUFF) ((BUFF)->limit - (BUFF)->cur)
+#define BUFF_FRONT(BUFF) ((BUFF)->cur)
+#define BUFF_LIMIT(BUFF) ((BUFF)->limit)
/* List of directories to look for include files in. */
struct search_path
unsigned int directive_line;
/* Memory pools. */
- cpp_pool ident_pool; /* For all identifiers, and permanent
- numbers and strings. */
cpp_pool macro_pool; /* For macro definitions. Permanent. */
/* Memory buffers. */
- _cpp_buff *free_buffs;
+ _cpp_buff *u_buff; /* Unaligned permanent storage. */
+ _cpp_buff *free_buffs; /* Free buffer chain. */
/* Context stack. */
struct cpp_context base_context;
pfile->base_context.macro = 0;
pfile->base_context.prev = pfile->base_context.next = 0;
- /* Identifier pool initially 8K. Unaligned, permanent pool. */
- _cpp_init_pool (&pfile->ident_pool, 8 * 1024, 1, 0);
+ /* Unaligned storage. */
+ pfile->u_buff = _cpp_get_buff (pfile, 0);
/* Macro pool initially 8K. Aligned, permanent pool. */
_cpp_init_pool (&pfile->macro_pool, 8 * 1024, 0, 0);
_cpp_destroy_hashtable (pfile);
_cpp_cleanup_includes (pfile);
- _cpp_free_pool (&pfile->ident_pool);
_cpp_free_pool (&pfile->macro_pool);
+ _cpp_free_buff (pfile->u_buff);
_cpp_free_buff (pfile->free_buffs);
for (run = &pfile->base_run; run; run = runn)
int leading_period;
{
cpp_buffer *buffer = pfile->buffer;
- cpp_pool *pool = &pfile->ident_pool;
unsigned char *dest, *limit;
- dest = POOL_FRONT (pool);
- limit = POOL_LIMIT (pool);
+ dest = BUFF_FRONT (pfile->u_buff);
+ limit = BUFF_LIMIT (pfile->u_buff);
/* Place a leading period. */
if (leading_period)
{
- if (dest >= limit)
- limit = _cpp_next_chunk (pool, 0, &dest);
+ if (dest == limit)
+ {
+ pfile->u_buff = _cpp_extend_buff (pfile, pfile->u_buff, 1);
+ dest = BUFF_FRONT (pfile->u_buff);
+ limit = BUFF_LIMIT (pfile->u_buff);
+ }
*dest++ = '.';
}
do
{
/* Need room for terminating null. */
- if (dest + 1 >= limit)
- limit = _cpp_next_chunk (pool, 0, &dest);
+ if ((size_t) (limit - dest) < 2)
+ {
+ size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
+ pfile->u_buff = _cpp_extend_buff (pfile, pfile->u_buff, 2);
+ dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
+ limit = BUFF_LIMIT (pfile->u_buff);
+ }
*dest++ = c;
c = EOF;
/* Null-terminate the number. */
*dest = '\0';
- number->text = POOL_FRONT (pool);
+ number->text = BUFF_FRONT (pfile->u_buff);
number->len = dest - number->text;
- POOL_COMMIT (pool, number->len + 1);
+ BUFF_FRONT (pfile->u_buff) = dest + 1;
}
/* Subroutine of parse_string. Emits error for unterminated strings. */
if (pfile->state.angled_headers)
return 1;
- start = POOL_FRONT (&pfile->ident_pool);
+ start = BUFF_FRONT (pfile->u_buff);
/* An odd number of consecutive backslashes represents an escaped
terminator. */
cppchar_t terminator;
{
cpp_buffer *buffer = pfile->buffer;
- cpp_pool *pool = &pfile->ident_pool;
unsigned char *dest, *limit;
cppchar_t c;
bool warned_nulls = false, warned_multi = false;
- dest = POOL_FRONT (pool);
- limit = POOL_LIMIT (pool);
+ dest = BUFF_FRONT (pfile->u_buff);
+ limit = BUFF_LIMIT (pfile->u_buff);
for (;;)
{
have_char:
/* We need space for the terminating NUL. */
- if (dest >= limit)
- limit = _cpp_next_chunk (pool, 0, &dest);
+ if ((size_t) (limit - dest) < 1)
+ {
+ size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
+ pfile->u_buff = _cpp_extend_buff (pfile, pfile->u_buff, 2);
+ dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
+ limit = BUFF_LIMIT (pfile->u_buff);
+ }
if (c == EOF)
{
buffer->read_ahead = c;
*dest = '\0';
- token->val.str.text = POOL_FRONT (pool);
- token->val.str.len = dest - token->val.str.text;
- POOL_COMMIT (pool, token->val.str.len + 1);
+ token->val.str.text = BUFF_FRONT (pfile->u_buff);
+ token->val.str.len = dest - BUFF_FRONT (pfile->u_buff);
+ BUFF_FRONT (pfile->u_buff) = dest + 1;
}
/* The stored comment includes the comment start and any terminator. */
line, which we don't want to save in the comment. */
if (pfile->buffer->read_ahead != EOF)
len--;
- buffer = _cpp_pool_alloc (&pfile->ident_pool, len);
+ buffer = _cpp_unaligned_alloc (pfile, len);
token->type = CPP_COMMENT;
token->val.str.len = len;
const cpp_token *token;
{
unsigned int len = cpp_token_len (token);
- unsigned char *start = _cpp_pool_alloc (&pfile->ident_pool, len), *end;
+ unsigned char *start = _cpp_unaligned_alloc (pfile, len), *end;
end = cpp_spell_token (pfile, token, start);
end[0] = '\0';
unsigned int len;
{
_cpp_buff *result;
- char *base;
+ unsigned char *base;
if (len < MIN_BUFF_SIZE)
len = MIN_BUFF_SIZE;
}
}
+/* Allocate permanent, unaligned storage of length LEN. */
+unsigned char *
+_cpp_unaligned_alloc (pfile, len)
+ cpp_reader *pfile;
+ size_t len;
+{
+ _cpp_buff *buff = pfile->u_buff;
+ unsigned char *result = buff->cur;
+
+ if (len > (size_t) (buff->limit - result))
+ {
+ buff = _cpp_get_buff (pfile, len);
+ buff->next = pfile->u_buff;
+ pfile->u_buff = buff;
+ result = buff->cur;
+ }
+
+ buff->cur = result + len;
+ return result;
+}
+
static int
chunk_suitable (chunk, size)
cpp_chunk *chunk;
{
cpp_token *header = NULL;
const cpp_token *token;
- unsigned char *buffer, *token_mem;
- size_t len, total_len = 0, capacity = 1024;
+ unsigned char *dest;
+ size_t len;
/* To avoid lexed tokens overwriting our glued name, we can only
allocate from the string pool once we've lexed everything. */
- buffer = (unsigned char *) xmalloc (capacity);
+ dest = BUFF_FRONT (pfile->u_buff);
for (;;)
{
token = cpp_get_token (pfile);
if (token->type == CPP_GREATER || token->type == CPP_EOF)
break;
- len = cpp_token_len (token);
- if (total_len + len > capacity)
+ /* + 1 for terminating NUL. */
+ len = cpp_token_len (token) + 1;
+ if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len)
{
- capacity = (capacity + len) * 2;
- buffer = (unsigned char *) xrealloc (buffer, capacity);
+ size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
+ pfile->u_buff = _cpp_extend_buff (pfile, pfile->u_buff, len);
+ dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
}
if (token->flags & PREV_WHITE)
- buffer[total_len++] = ' ';
+ *dest++ = ' ';
- total_len = cpp_spell_token (pfile, token, &buffer[total_len]) - buffer;
+ dest = cpp_spell_token (pfile, token, dest);
}
if (token->type == CPP_EOF)
cpp_error (pfile, "missing terminating > character");
else
{
- token_mem = _cpp_pool_alloc (&pfile->ident_pool, total_len + 1);
- memcpy (token_mem, buffer, total_len);
- token_mem[total_len] = '\0';
-
header = _cpp_temp_token (pfile);
header->type = CPP_HEADER_NAME;
- header->flags &= ~PREV_WHITE;
- header->val.str.len = total_len;
- header->val.str.text = token_mem;
+ header->flags = 0;
+ header->val.str.len = dest - BUFF_FRONT (pfile->u_buff);
+ header->val.str.text = BUFF_FRONT (pfile->u_buff);
+ *dest++ = '\0';
+ BUFF_FRONT (pfile->u_buff) = dest;
}
- free ((PTR) buffer);
return header;
}
int number;
{
cpp_token *token = _cpp_temp_token (pfile);
- unsigned char *buf = _cpp_pool_alloc (&pfile->ident_pool, 20);
+ unsigned char *buf = _cpp_unaligned_alloc (pfile, 20);
sprintf ((char *) buf, "%d", number);
token->type = CPP_NUMBER;
name = map->to_file;
len = strlen (name);
- buf = _cpp_pool_alloc (&pfile->ident_pool, len * 4 + 1);
+ buf = _cpp_unaligned_alloc (pfile, len * 4 + 1);
len = quote_string (buf, (const unsigned char *) name, len) - buf;
return new_string_token (pfile, buf, len);
struct tm *tb = localtime (&tt);
pfile->date.val.str.text =
- _cpp_pool_alloc (&pfile->ident_pool, sizeof ("Oct 11 1347"));
+ _cpp_unaligned_alloc (pfile, sizeof ("Oct 11 1347"));
pfile->date.val.str.len = sizeof ("Oct 11 1347") - 1;
pfile->date.type = CPP_STRING;
pfile->date.flags = 0;
monthnames[tb->tm_mon], tb->tm_mday, tb->tm_year + 1900);
pfile->time.val.str.text =
- _cpp_pool_alloc (&pfile->ident_pool, sizeof ("12:34:56"));
+ _cpp_unaligned_alloc (pfile, sizeof ("12:34:56"));
pfile->time.val.str.len = sizeof ("12:34:56") - 1;
pfile->time.type = CPP_STRING;
pfile->time.flags = 0;
cpp_reader *pfile;
macro_arg *arg;
{
- cpp_pool *pool = &pfile->ident_pool;
- unsigned char *start = POOL_FRONT (pool);
- unsigned int i, escape_it, total_len = 0, backslash_count = 0;
+ unsigned char *dest = BUFF_FRONT (pfile->u_buff);
+ unsigned int i, escape_it, backslash_count = 0;
const cpp_token *source = NULL;
+ size_t len;
/* Loop, reading in the argument's tokens. */
for (i = 0; i < arg->count; i++)
{
- unsigned char *dest;
const cpp_token *token = arg->first[i];
- unsigned int len;
if (token->type == CPP_PADDING)
{
escape_it = (token->type == CPP_STRING || token->type == CPP_WSTRING
|| token->type == CPP_CHAR || token->type == CPP_WCHAR);
+ /* Room for each char being written in octal, initial space and
+ final NUL. */
len = cpp_token_len (token);
if (escape_it)
- /* Worst case is each char is octal. */
len *= 4;
- len += 2; /* Room for initial space and final NUL. */
+ len += 2;
- dest = &start[total_len];
- if (dest + len > POOL_LIMIT (pool))
+ if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len)
{
- _cpp_next_chunk (pool, len, (unsigned char **) &start);
- dest = &start[total_len];
+ size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
+ pfile->u_buff = _cpp_extend_buff (pfile, pfile->u_buff, len);
+ dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
}
/* Leading white space? */
- if (total_len)
+ if (dest != BUFF_FRONT (pfile->u_buff))
{
if (source == NULL)
source = token;
if (escape_it)
{
- unsigned char *buf = (unsigned char *) xmalloc (len);
-
+ _cpp_buff *buff = _cpp_get_buff (pfile, len);
+ unsigned char *buf = BUFF_FRONT (buff);
len = cpp_spell_token (pfile, token, buf) - buf;
dest = quote_string (dest, buf, len);
- free (buf);
+ _cpp_release_buff (pfile, buff);
}
else
dest = cpp_spell_token (pfile, token, dest);
- total_len = dest - start;
if (token->type == CPP_OTHER && token->val.c == '\\')
backslash_count++;
if (backslash_count & 1)
{
cpp_warning (pfile, "invalid string literal, ignoring final '\\'");
- total_len--;
+ dest--;
}
/* Commit the memory, including NUL, and return the token. */
- POOL_COMMIT (pool, total_len + 1);
- return new_string_token (pfile, start, total_len);
+ len = dest - BUFF_FRONT (pfile->u_buff);
+ BUFF_FRONT (pfile->u_buff) = dest + 1;
+ return new_string_token (pfile, dest - len, len);
}
/* Try to paste two tokens. On success, return non-zero. In any
base_buff = buff;
args = (macro_arg *) buff->base;
memset (args, 0, argc * sizeof (macro_arg));
- buff->cur = (char *) &args[argc];
+ buff->cur = (unsigned char *) &args[argc];
arg = args, argc = 0;
/* Collect the tokens making up each argument. We don't yet know
for (;;)
{
/* Require space for 2 new tokens (including a CPP_EOF). */
- if ((char *) &arg->first[ntokens + 2] > buff->limit)
+ if ((unsigned char *) &arg->first[ntokens + 2] > buff->limit)
{
buff = _cpp_extend_buff (pfile, buff,
1000 * sizeof (cpp_token *));
overwrite the final legitimate argument, before failing. */
if (argc <= macro->paramc)
{
- buff->cur = (char *) &arg->first[ntokens + 1];
+ buff->cur = (unsigned char *) &arg->first[ntokens + 1];
if (argc != macro->paramc)
arg++;
}
step_back = true;
}
else
- /* We still need the CPP_EOF to end directives, and to end
- pre-expansion of a macro argument. */
step_back = (pfile->context->prev || pfile->state.in_directive);
+ /* We still need the CPP_EOF to end directives, and to end
+ pre-expansion of a macro argument. Step back is not
+ unconditional, since we don't want to return a CPP_EOF to our
+ callers at the end of an -include-d file. */
if (step_back)
_cpp_backup_tokens (pfile, 1);
cpp_error (pfile, "unterminated argument list invoking macro \"%s\"",