[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Changes to m4/m4/output.c,v
From: |
Eric Blake |
Subject: |
Changes to m4/m4/output.c,v |
Date: |
Thu, 26 Oct 2006 23:11:42 +0000 |
CVSROOT: /sources/m4
Module name: m4
Changes by: Eric Blake <ericb> 06/10/26 23:11:41
Index: m4/output.c
===================================================================
RCS file: /sources/m4/m4/m4/output.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- m4/output.c 7 Oct 2006 05:02:56 -0000 1.32
+++ m4/output.c 26 Oct 2006 23:11:41 -0000 1.33
@@ -55,35 +55,40 @@
typedef struct temp_dir m4_temp_dir;
-/* In a struct diversion, only one of file or buffer be may non-NULL,
- depending on the fact output is diverted to a file or in memory
- buffer. Further, if buffer is NULL, then pointer is NULL, size and
- unused are zero. */
+/* When part of diversion_table, each struct diversion either
+ represents an open file (zero size, non-NULL u.file), an in-memory
+ buffer (non-zero size, non-NULL u.buffer), or an unused placeholder
+ diversion (zero size, u is NULL). */
-struct diversion
+typedef struct m4_diversion m4_diversion;
+
+struct m4_diversion
+ {
+ union
{
FILE *file; /* diversion file on disk */
char *buffer; /* in-memory diversion buffer */
- int size; /* usable size before reallocation */
- int used; /* used length in characters */
+ } u;
+ size_t size; /* usable size before reallocation */
+ size_t used; /* used length in characters */
};
/* Table of diversions. */
-static struct diversion *diversion_table;
+static m4_diversion *diversion_table;
/* Number of entries in diversion table. */
static int diversions;
/* Total size of all in-memory buffer sizes. */
-static int total_buffer_size;
+static size_t total_buffer_size;
/* Current output diversion, NULL if output is being currently discarded. */
-static struct diversion *output_diversion;
+static m4_diversion *output_diversion;
/* Values of some output_diversion fields, cached out for speed. */
static FILE *output_file; /* current value of (file) */
static char *output_cursor; /* current value of (buffer + used) */
-static int output_unused; /* current value of (size - used) */
+static size_t output_unused; /* current value of (size - used) */
/* Temporary directory holding all spilled diversion files. */
static m4_temp_dir *output_temp_dir;
@@ -97,8 +102,7 @@
{
diversion_table = xmalloc (sizeof *diversion_table);
diversions = 1;
- diversion_table[0].file = stdout;
- diversion_table[0].buffer = NULL;
+ diversion_table[0].u.file = stdout;
diversion_table[0].size = 0;
diversion_table[0].used = 0;
@@ -113,7 +117,12 @@
void
m4_output_exit (void)
{
- assert (diversions = 1);
+#ifndef NDEBUG
+ int divnum;
+ for (divnum = 1; divnum < diversions; divnum++)
+ assert (!diversion_table[divnum].size
+ && !diversion_table[divnum].u.file);
+#endif
DELETE (diversion_table);
}
@@ -166,9 +175,14 @@
to be flushed to a newly created temporary file. This flushed buffer
might well be the current one. */
static void
-make_room_for (m4 *context, int length)
+make_room_for (m4 *context, size_t length)
{
- int wanted_size;
+ size_t wanted_size;
+ m4_diversion *selected_diversion = NULL;
+
+ assert (!output_file);
+ assert (output_diversion);
+ assert (output_diversion->size || !output_diversion->u.file);
/* Compute needed size for in-memory buffer. Diversions in-memory
buffers start at 0 bytes, then 512, then keep doubling until it is
@@ -177,7 +191,8 @@
output_diversion->used = output_diversion->size - output_unused;
for (wanted_size = output_diversion->size;
- wanted_size < output_diversion->used + length;
+ wanted_size <= MAXIMUM_TOTAL_SIZE
+ && wanted_size - output_diversion->used < length;
wanted_size = wanted_size == 0 ? INITIAL_BUFFER_SIZE : wanted_size * 2)
;
@@ -186,10 +201,10 @@
if (total_buffer_size - output_diversion->size + wanted_size
> MAXIMUM_TOTAL_SIZE)
{
- struct diversion *selected_diversion;
- int selected_used;
- struct diversion *diversion;
- int count;
+ size_t selected_used;
+ char *selected_buffer;
+ m4_diversion *diversion;
+ size_t count;
/* Find out the buffer having most data, in view of flushing it to
disk. Fake the current buffer as having already received the
@@ -211,17 +226,16 @@
/* Create a temporary file, write the in-memory buffer of the
diversion to this file, then release the buffer. */
- selected_diversion->file = m4_tmpfile (context);
- if (set_cloexec_flag (fileno (selected_diversion->file), true) != 0)
+ selected_buffer = selected_diversion->u.buffer;
+ selected_diversion->u.file = m4_tmpfile (context);
+ if (set_cloexec_flag (fileno (selected_diversion->u.file), true) != 0)
m4_error (context, 0, errno,
_("cannot protect diversion across forks"));
if (selected_diversion->used > 0)
{
- count = fwrite (selected_diversion->buffer,
- (size_t) selected_diversion->used,
- 1,
- selected_diversion->file);
+ count = fwrite (selected_buffer, selected_diversion->used, 1,
+ selected_diversion->u.file);
if (count != 1)
m4_error (context, EXIT_FAILURE, errno,
_("cannot flush diversion to temporary file"));
@@ -229,37 +243,36 @@
/* Reclaim the buffer space for other diversions. */
- free (selected_diversion->buffer);
+ free (selected_buffer);
total_buffer_size -= selected_diversion->size;
- selected_diversion->buffer = NULL;
selected_diversion->size = 0;
selected_diversion->used = 0;
}
/* Reload output_file, just in case the flushed diversion was current. */
- output_file = output_diversion->file;
- if (output_file)
+ if (output_diversion == selected_diversion)
{
/* The flushed diversion was current indeed. */
+ output_file = output_diversion->u.file;
output_cursor = NULL;
output_unused = 0;
}
else
{
-
/* The buffer may be safely reallocated. */
- output_diversion->buffer
- = xrealloc (output_diversion->buffer, (size_t) wanted_size);
+ output_diversion->u.buffer
+ = xrealloc (output_diversion->u.buffer,
+ wanted_size > length ? wanted_size : length);
total_buffer_size += wanted_size - output_diversion->size;
output_diversion->size = wanted_size;
- output_cursor = output_diversion->buffer + output_diversion->used;
+ output_cursor = output_diversion->u.buffer + output_diversion->used;
output_unused = wanted_size - output_diversion->used;
}
}
@@ -292,9 +305,9 @@
/* Output one TEXT having LENGTH characters, when it is known that it goes
to a diversion file or an in-memory diversion buffer. */
static void
-output_text (m4 *context, const char *text, int length)
+output_text (m4 *context, const char *text, size_t length)
{
- int count;
+ size_t count;
if (!output_file && length > output_unused)
make_room_for (context, length);
@@ -307,7 +320,7 @@
}
else
{
- memcpy (output_cursor, text, (size_t) length);
+ memcpy (output_cursor, text, length);
output_cursor += length;
output_unused -= length;
}
@@ -324,7 +337,7 @@
output lines, or when several input lines does not generate any output. */
void
m4_shipout_text (m4 *context, m4_obstack *obs,
- const char *text, int length)
+ const char *text, size_t length)
{
static bool start_of_output_line = true;
char line[20];
@@ -376,9 +389,9 @@
m4_set_output_line (context, m4_get_output_line (context) + 1);
#ifdef DEBUG_OUTPUT
- fprintf (stderr, "DEBUG: cur %d, cur out %d\n",
- m4_get_current_line (context),
- m4_get_output_line (context));
+ fprintf (stderr, "DEBUG: cur %lu, cur out %lu\n",
+ (unsigned long int) m4_get_current_line (context),
+ (unsigned long int) m4_get_output_line (context));
#endif
/* Output a `#line NUM' synchronization directive if needed.
@@ -387,7 +400,8 @@
if (m4_get_output_line (context) != m4_get_current_line (context))
{
- sprintf (line, "#line %d", m4_get_current_line (context));
+ sprintf (line, "#line %lu",
+ (unsigned long int) m4_get_current_line (context));
for (cursor = line; *cursor; cursor++)
OUTPUT_CHARACTER (*cursor);
if (m4_get_output_line (context) < 1
@@ -412,8 +426,9 @@
}
}
-/* Format an int VAL, and stuff it into an obstack OBS. Used for macros
- expanding to numbers. */
+/* Format an int VAL, and stuff it into an obstack OBS. Used for
+ macros expanding to numbers. FIXME - support wider types, and
+ unsigned types. */
void
m4_shipout_int (m4_obstack *obs, int val)
{
@@ -424,7 +439,7 @@
}
void
-m4_shipout_string (m4 *context, m4_obstack *obs, const char *s, int len,
+m4_shipout_string (m4 *context, m4_obstack *obs, const char *s, size_t len,
bool quoted)
{
if (s == NULL)
@@ -455,11 +470,11 @@
void
m4_make_diversion (m4 *context, int divnum)
{
- struct diversion *diversion;
+ m4_diversion *diversion;
if (output_diversion)
{
- output_diversion->file = output_file;
+ assert (!output_file || output_diversion->u.file == output_file);
output_diversion->used = output_diversion->size - output_unused;
output_diversion = NULL;
output_file = NULL;
@@ -474,14 +489,14 @@
if (divnum >= diversions)
{
- diversion_table = (struct diversion *)
- xrealloc (diversion_table, (divnum + 1) * sizeof (struct diversion));
+ diversion_table = (m4_diversion *) xnrealloc (diversion_table,
+ divnum + 1,
+ sizeof (*diversion_table));
for (diversion = diversion_table + diversions;
diversion <= diversion_table + divnum;
diversion++)
{
- diversion->file = NULL;
- diversion->buffer = NULL;
+ diversion->u.file = NULL;
diversion->size = 0;
diversion->used = 0;
}
@@ -489,9 +504,14 @@
}
output_diversion = diversion_table + divnum;
- output_file = output_diversion->file;
- output_cursor = output_diversion->buffer + output_diversion->used;
+ if (output_diversion->size)
+ {
+ output_cursor = output_diversion->u.buffer + output_diversion->used;
output_unused = output_diversion->size - output_diversion->used;
+ }
+ else
+ output_file = output_diversion->u.file;
+
m4_set_output_line (context, -1);
}
@@ -527,7 +547,7 @@
void
m4_insert_diversion (m4 *context, int divnum)
{
- struct diversion *diversion;
+ m4_diversion *diversion;
/* Do not care about unexisting diversions. */
@@ -544,31 +564,28 @@
if (output_diversion)
{
- if (diversion->file)
+ if (diversion->size)
+ output_text (context, diversion->u.buffer, diversion->used);
+ else if (diversion->u.file)
{
- rewind (diversion->file);
- m4_insert_file (context, diversion->file);
+ rewind (diversion->u.file);
+ m4_insert_file (context, diversion->u.file);
}
- else if (diversion->buffer)
- output_text (context, diversion->buffer, diversion->used);
m4_set_output_line (context, -1);
}
/* Return all space used by the diversion. */
- if (diversion->file)
- {
- close_stream_temp (diversion->file);
- diversion->file = NULL;
- }
- else if (diversion->buffer)
+ if (diversion->size)
{
- free (diversion->buffer);
- diversion->buffer = NULL;
+ free (diversion->u.buffer);
diversion->size = 0;
diversion->used = 0;
}
+ else if (diversion->u.file)
+ close_stream_temp (diversion->u.file);
+ diversion->u.file = NULL;
}
/* Get back all diversions. This is done just before exiting from main (),
@@ -589,7 +606,7 @@
int saved_number;
int last_inserted;
int divnum;
- struct diversion *diversion;
+ m4_diversion *diversion;
struct stat file_stat;
saved_number = m4_get_current_diversion (context);
@@ -600,14 +617,22 @@
for (divnum = 1; divnum < diversions; divnum++)
{
diversion = diversion_table + divnum;
- if (diversion->file || diversion->buffer)
+ if (diversion->size || diversion->u.file)
{
- if (diversion->file)
+ if (diversion->size)
{
- fflush (diversion->file);
- if (fstat (fileno (diversion->file), &file_stat) < 0)
+ assert (diversion->used == (int) diversion->used);
+ fprintf (file, "D%d,%d\n", divnum, (int) diversion->used);
+ }
+ else
+ {
+ fflush (diversion->u.file);
+ if (fstat (fileno (diversion->u.file), &file_stat) < 0)
m4_error (context, EXIT_FAILURE, errno,
_("cannot stat diversion"));
+ /* FIXME - support 64-bit off_t with 32-bit long, and
+ fix frozen file format to support 64-bit
+ integers. */
if (file_stat.st_size < 0
|| file_stat.st_size != (unsigned long) file_stat.st_size)
m4_error (context, EXIT_FAILURE, errno,
@@ -615,8 +640,6 @@
fprintf (file, "D%d,%lu", divnum,
(unsigned long) file_stat.st_size);
}
- else
- fprintf (file, "D%d,%d\n", divnum, diversion->used);
m4_insert_diversion (context, divnum);
putc ('\n', file);
- Changes to m4/m4/output.c,v, Eric Blake, 2006/10/03
- Changes to m4/m4/output.c,v, Eric Blake, 2006/10/06
- Changes to m4/m4/output.c,v, Eric Blake, 2006/10/07
- Changes to m4/m4/output.c,v,
Eric Blake <=
- Changes to m4/m4/output.c,v, Eric Blake, 2006/10/26
- Changes to m4/m4/output.c,v, Eric Blake, 2006/10/27