[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Syncoutput patch for m4-1.4ppre2
From: |
Andrew Bettison |
Subject: |
Syncoutput patch for m4-1.4ppre2 |
Date: |
Thu, 27 Sep 2001 11:35:04 +1000 |
René,
Here is a patch that rolls together a bunch of fixes and enhancements I
submitted to m4-1.4n way back in 1998. These never made it into m4-1.4o,
presumably because I was pretty sloppy -- no ChangeLog entry, no updates to the
texinfo documentation, and a pile of little patches instead of one big one.
This time I hope I've done it a bit better.
This patch fixes some problems with syncoutput on/off -- basically lines were
not being counted correctly. I also added a little extra functionality to the
'syncoutput' builtin so it can be used to query the current state of sync
output. Here's the ChangeLog entry (also included in the patch):
2001-09-27 Andrew Bettison <address@hidden>
* src/builtin.c (builtin_tab): "syncoutput" now expands if no
parentheses ('blind' column now FALSE instead of TRUE).
(m4_syncoutput): only accept arg1 values as documented, expand to 0 or
1 if invoked without args.
* src/m4.h: Added extern output_filename_synced, declared in output.c
and used in input.c.
* src/input.c: Fix bug where filename not emitted in first '#line';
use flag output_filename_synced instead of placing value of -1 in
output_current_line.
* src/output.c (COUNT_LINES): Added.
(count_lines): Added.
(shipout_text): Modified line-counting logic to cope correctly with
sync output being enabled and disabled willy-nilly.
(output_text): Miniscule optimization.
* doc/m4.texinfo (Syncoutput): Document no-parentheses case.
* examples/Makefile.am (pkgdata_DATA): Added syncoutput.m4.
* examples/Makefile.am (TESTS): Added syncoutput.test.
* examples/syncoutput.m4: New file.
* examples/syncoutput.test: New file.
Regards,
Andrew Bettison
diff -u -r -N --exclude config* --exclude aclocal.m4 --exclude Makefile.in
--exclude Makefile --exclude intl --exclude po --exclude *~ --exclude tags
--exclude testSubDir --exclude stamp-vti --exclude version.texi --exclude
*.orig --exclude *.rej --exclude .indent.pro --exclude .deps --exclude *.o
--exclude *.info* --exclude *.a m4-1.4ppre2.orig/ChangeLog m4-1.4ppre2/ChangeLog
--- m4-1.4ppre2.orig/ChangeLog Mon Jan 17 03:18:38 2000
+++ m4-1.4ppre2/ChangeLog Thu Sep 27 11:25:22 2001
@@ -1,3 +1,33 @@
+2001-09-27 Andrew Bettison <address@hidden>
+
+ * src/builtin.c (builtin_tab): "syncoutput" now expands if no
+ parentheses ('blind' column now FALSE instead of TRUE).
+ (m4_syncoutput): only accept arg1 values as documented, expand to 0 or
+ 1 if invoked without args.
+
+ * src/m4.h: Added extern output_filename_synced, declared in output.c
+ and used in input.c.
+
+ * src/input.c: Fix bug where filename not emitted in first '#line';
+ use flag output_filename_synced instead of placing value of -1 in
+ output_current_line.
+
+ * src/output.c (COUNT_LINES): Added.
+ (count_lines): Added.
+ (shipout_text): Modified line-counting logic to cope correctly with
+ sync output being enabled and disabled willy-nilly.
+ (output_text): Miniscule optimization.
+
+ * doc/m4.texinfo (Syncoutput): Document no-parentheses case.
+
+ * examples/Makefile.am (pkgdata_DATA): Added syncoutput.m4.
+
+ * examples/Makefile.am (TESTS): Added syncoutput.test.
+
+ * examples/syncoutput.m4: New file.
+
+ * examples/syncoutput.test: New file.
+
2000-01-16 Rene' Seindal <address@hidden>
* modules/Makefile.am (TESTS): New tests for the module system.
diff -u -r -N --exclude config* --exclude aclocal.m4 --exclude Makefile.in
--exclude Makefile --exclude intl --exclude po --exclude *~ --exclude tags
--exclude testSubDir --exclude stamp-vti --exclude version.texi --exclude
*.orig --exclude *.rej --exclude .indent.pro --exclude .deps --exclude *.o
--exclude *.info* --exclude *.a m4-1.4ppre2.orig/doc/m4.texinfo
m4-1.4ppre2/doc/m4.texinfo
--- m4-1.4ppre2.orig/doc/m4.texinfo Mon Jan 10 15:35:58 2000
+++ m4-1.4ppre2/doc/m4.texinfo Thu Sep 27 10:36:27 2001
@@ -3608,8 +3608,10 @@
@code{syncoutput(0)}, @code{syncoutput(off)}, and @code{syncoutput(no)}
turn them off.
-All other arguments are ignored as is @code{syncoutput} without
-parenthesis.
+All other arguments are ignored.
+
address@hidden with no parentheses expands to @samp{1} if sync output
+is currently enabled, and @samp{0} if not.
@node Frozen files, Compatibility, Miscellaneous, Top
@chapter Fast loading of frozen states
diff -u -r -N --exclude config* --exclude aclocal.m4 --exclude Makefile.in
--exclude Makefile --exclude intl --exclude po --exclude *~ --exclude tags
--exclude testSubDir --exclude stamp-vti --exclude version.texi --exclude
*.orig --exclude *.rej --exclude .indent.pro --exclude .deps --exclude *.o
--exclude *.info* --exclude *.a m4-1.4ppre2.orig/examples/Makefile.am
m4-1.4ppre2/examples/Makefile.am
--- m4-1.4ppre2.orig/examples/Makefile.am Fri Mar 26 22:17:53 1999
+++ m4-1.4ppre2/examples/Makefile.am Wed Sep 12 13:43:19 2001
@@ -24,6 +24,7 @@
pushpop.m4 \
regexp.m4 \
reverse.m4 \
+ syncoutput.m4 \
sysv-args.m4 \
trace.m4 \
translit.m4 \
@@ -49,6 +50,7 @@
pushpop.test \
regexp.test \
reverse.test \
+ syncoutput.test \
sysv-args.test \
trace.test \
translit.test \
diff -u -r -N --exclude config* --exclude aclocal.m4 --exclude Makefile.in
--exclude Makefile --exclude intl --exclude po --exclude *~ --exclude tags
--exclude testSubDir --exclude stamp-vti --exclude version.texi --exclude
*.orig --exclude *.rej --exclude .indent.pro --exclude .deps --exclude *.o
--exclude *.info* --exclude *.a m4-1.4ppre2.orig/examples/syncoutput.m4
m4-1.4ppre2/examples/syncoutput.m4
--- m4-1.4ppre2.orig/examples/syncoutput.m4 Thu Jan 1 10:00:00 1970
+++ m4-1.4ppre2/examples/syncoutput.m4 Tue Sep 4 23:00:20 2001
@@ -0,0 +1,35 @@
+traceon(`syncoutput')dnl
+one
+divert(-1)
+
+define(`NOSYNC', ``'pushdef(`_sync',
syncoutput)syncoutput(0)$1`'syncoutput(_sync)`'popdef(`_sync')')
+
+define(`repeat', `ifelse($1, 0, , `$2`'repeat(decr(`$1'), `$2')')')
+
+define(`A', `>>$1<<')
+define(`B', `line $1
+line $2')
+define(`C', `repeat($1, `$2
+')')
+
+divert`'dnl
+syncoutput(1)dnl
+two
+A(three) A(three and a half) A(three and
+a bit more)
+four
+B(five, five and a half)
+six
+>B(seven, seven and a half)
+eight
+NOSYNC(`B(nine, nine and a half)')
+ten
+>NOSYNC(`B(eleven, eleven and a half)')
+twelve
+thirteen
+NOSYNC(`C(4, fourteen)')
+fifteen
+>NOSYNC(`C(5, sixteen)')
+seventeen
+syncoutput(0)dnl
+eighteen
diff -u -r -N --exclude config* --exclude aclocal.m4 --exclude Makefile.in
--exclude Makefile --exclude intl --exclude po --exclude *~ --exclude tags
--exclude testSubDir --exclude stamp-vti --exclude version.texi --exclude
*.orig --exclude *.rej --exclude .indent.pro --exclude .deps --exclude *.o
--exclude *.info* --exclude *.a m4-1.4ppre2.orig/examples/syncoutput.test
m4-1.4ppre2/examples/syncoutput.test
--- m4-1.4ppre2.orig/examples/syncoutput.test Thu Jan 1 10:00:00 1970
+++ m4-1.4ppre2/examples/syncoutput.test Tue Sep 4 23:00:20 2001
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+# syncoutput.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/syncoutput.m4 >in
+
+cat <<\EOF >ok
+one
+#line 17 "in"
+two
+>>three<< >>three and a half<< >>three and
+a bit more<<
+four
+line five
+#line 21
+line five and a half
+six
+>line seven
+#line 23
+line seven and a half
+eight
+line nine
+line nine and a half
+#line 26
+ten
+>line eleven
+line eleven and a half
+#line 28
+twelve
+thirteen
+fourteen
+fourteen
+fourteen
+fourteen
+#line 31
+
+#line 31
+fifteen
+>sixteen
+sixteen
+sixteen
+sixteen
+sixteen
+#line 33
+
+#line 33
+seventeen
+eighteen
+EOF
+
+cat <<\EOF >okerr
+m4trace: -1- syncoutput(`1')
+m4trace: -2- syncoutput -> `1'
+m4trace: -1- syncoutput(`0')
+m4trace: -1- syncoutput(`1')
+m4trace: -2- syncoutput -> `1'
+m4trace: -1- syncoutput(`0')
+m4trace: -1- syncoutput(`1')
+m4trace: -2- syncoutput -> `1'
+m4trace: -1- syncoutput(`0')
+m4trace: -1- syncoutput(`1')
+m4trace: -2- syncoutput -> `1'
+m4trace: -1- syncoutput(`0')
+m4trace: -1- syncoutput(`1')
+m4trace: -1- syncoutput(`0')
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s,../../src/m4: ,m4: ," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff -u -r -N --exclude config* --exclude aclocal.m4 --exclude Makefile.in
--exclude Makefile --exclude intl --exclude po --exclude *~ --exclude tags
--exclude testSubDir --exclude stamp-vti --exclude version.texi --exclude
*.orig --exclude *.rej --exclude .indent.pro --exclude .deps --exclude *.o
--exclude *.info* --exclude *.a m4-1.4ppre2.orig/src/builtin.c
m4-1.4ppre2/src/builtin.c
--- m4-1.4ppre2.orig/src/builtin.c Sun Jan 16 13:17:41 2000
+++ m4-1.4ppre2/src/builtin.c Tue Sep 4 23:18:22 2001
@@ -143,7 +143,7 @@
{ "sinclude", FALSE, FALSE, TRUE, m4_sinclude },
{ "substr", FALSE, FALSE, TRUE, m4_substr },
{ "symbols", TRUE, FALSE, FALSE, m4_symbols },
- { "syncoutput", TRUE, FALSE, TRUE, m4_syncoutput },
+ { "syncoutput", TRUE, FALSE, FALSE, m4_syncoutput },
{ "syscmd", FALSE, FALSE, TRUE, m4_syscmd },
{ "sysval", FALSE, FALSE, FALSE, m4_sysval },
{ "traceoff", FALSE, FALSE, FALSE, m4_traceoff },
@@ -822,32 +822,55 @@
}
/*------------------------------------------------------------------------.
-| This contains macro which implements syncoutput() which takes one arg |
-| 1, on, yes - turn on sync lines |
-| 0, off, no - turn off sync lines |
-| everything else is silently ignored |
+| This contains macro which implements syncoutput() |
+| if one arg given, |
+| 1, on, yes - turn on sync lines |
+| 0, off, no - turn off sync lines |
+| anything else is silently ignored |
+| if no arg given, expand to |
+| 0 if sync lines currently turned off |
+| 1 if sync lines currently turned on |
| |
`------------------------------------------------------------------------*/
static void
m4_syncoutput (struct obstack *obs, int argc, token_data **argv)
{
- if (m4_bad_argc (argv[0], argc, 2, 2))
+ int value;
+
+ if (m4_bad_argc (argv[0], argc, 1, 2))
return;
+ if (argc == 1)
+ {
+ m4_shipout_int (obs, sync_output);
+ return;
+ }
+
if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
return;
- if (TOKEN_DATA_TEXT(argv[1])[0] == '0'
- || TOKEN_DATA_TEXT(argv[1])[0] == 'n'
- || (TOKEN_DATA_TEXT(argv[1])[0] == 'o'
- && TOKEN_DATA_TEXT(argv[1])[1] == 'f'))
- sync_output = 0;
- else if (TOKEN_DATA_TEXT(argv[1])[0] == '1'
- || TOKEN_DATA_TEXT(argv[1])[0] == 'y'
- || (TOKEN_DATA_TEXT(argv[1])[0] == 'o'
- && TOKEN_DATA_TEXT(argv[1])[1] == 'n'))
- sync_output = 1;
+ if (m4_numeric_arg (argv[0], M4ARG (1), &value))
+ sync_output = value ? 1 : 0;
+ else
+ {
+ if ( (TOKEN_DATA_TEXT(argv[1])[0] == 'n'
+ && TOKEN_DATA_TEXT(argv[1])[1] == 'o'
+ && TOKEN_DATA_TEXT(argv[1])[2] == '\0')
+ || (TOKEN_DATA_TEXT(argv[1])[0] == 'o'
+ && TOKEN_DATA_TEXT(argv[1])[1] == 'f'
+ && TOKEN_DATA_TEXT(argv[1])[2] == 'f'
+ && TOKEN_DATA_TEXT(argv[1])[3] == '\0'))
+ sync_output = 0;
+ else if ( (TOKEN_DATA_TEXT(argv[1])[0] == 'y'
+ && TOKEN_DATA_TEXT(argv[1])[1] == 'e'
+ && TOKEN_DATA_TEXT(argv[1])[2] == 's'
+ && TOKEN_DATA_TEXT(argv[1])[3] == '\0')
+ || (TOKEN_DATA_TEXT(argv[1])[0] == 'o'
+ && TOKEN_DATA_TEXT(argv[1])[1] == 'n'
+ && TOKEN_DATA_TEXT(argv[1])[2] == '\0'))
+ sync_output = 1;
+ }
}
/*------------------------------------------------------------------------.
diff -u -r -N --exclude config* --exclude aclocal.m4 --exclude Makefile.in
--exclude Makefile --exclude intl --exclude po --exclude *~ --exclude tags
--exclude testSubDir --exclude stamp-vti --exclude version.texi --exclude
*.orig --exclude *.rej --exclude .indent.pro --exclude .deps --exclude *.o
--exclude *.info* --exclude *.a m4-1.4ppre2.orig/src/input.c
m4-1.4ppre2/src/input.c
--- m4-1.4ppre2.orig/src/input.c Sun Jan 16 13:17:41 2000
+++ m4-1.4ppre2/src/input.c Tue Sep 4 23:00:20 2001
@@ -318,7 +318,7 @@
output_current_line = isp->u.u_f.out_lineno;
start_of_input_line = isp->u.u_f.advance_line;
if (isp->prev != NULL)
- output_current_line = -1;
+ output_filename_synced = FALSE;
}
static struct input_funcs file_funcs = {
@@ -351,7 +351,7 @@
current_file = obstack_copy0 (current_input, title, strlen (title));
current_line = 1;
- output_current_line = -1;
+ output_filename_synced = FALSE;
i->prev = isp;
isp = i;
diff -u -r -N --exclude config* --exclude aclocal.m4 --exclude Makefile.in
--exclude Makefile --exclude intl --exclude po --exclude *~ --exclude tags
--exclude testSubDir --exclude stamp-vti --exclude version.texi --exclude
*.orig --exclude *.rej --exclude .indent.pro --exclude .deps --exclude *.o
--exclude *.info* --exclude *.a m4-1.4ppre2.orig/src/m4.h m4-1.4ppre2/src/m4.h
--- m4-1.4ppre2.orig/src/m4.h Sun Jan 16 22:18:38 2000
+++ m4-1.4ppre2/src/m4.h Tue Sep 4 23:00:20 2001
@@ -221,6 +221,7 @@
/* File: output.c --- output functions. */
extern int current_diversion;
+extern boolean output_filename_synced;
extern int output_current_line;
void output_init M4_PARAMS((void));
diff -u -r -N --exclude config* --exclude aclocal.m4 --exclude Makefile.in
--exclude Makefile --exclude intl --exclude po --exclude *~ --exclude tags
--exclude testSubDir --exclude stamp-vti --exclude version.texi --exclude
*.orig --exclude *.rej --exclude .indent.pro --exclude .deps --exclude *.o
--exclude *.info* --exclude *.a m4-1.4ppre2.orig/src/output.c
m4-1.4ppre2/src/output.c
--- m4-1.4ppre2.orig/src/output.c Sun Jan 16 13:17:41 2000
+++ m4-1.4ppre2/src/output.c Tue Sep 4 23:00:20 2001
@@ -76,6 +76,10 @@
static char *output_cursor; /* current value of (buffer + used) */
static int output_unused; /* current value of (size - used) */
+/* Whether we have written the current input file name during sync
+ output are generating output for. */
+boolean output_filename_synced;
+
/* Number of input line we are generating output for. */
int output_current_line;
@@ -347,9 +351,6 @@
{
int count;
- if (!output_file && length > output_unused)
- make_room_for (length);
-
if (output_file)
{
count = fwrite (text, length, 1, output_file);
@@ -358,12 +359,33 @@
}
else
{
+ if (length > output_unused)
+ make_room_for (length);
memcpy (output_cursor, text, (size_t) length);
output_cursor += length;
output_unused -= length;
}
}
+/*------------------------------------------------------------------------.
+| Increment the output line counter if the given character is a newline. |
+`------------------------------------------------------------------------*/
+
+#define COUNT_LINES(Char) (output_current_line += (Char) == '\n')
+
+/*------------------------------------------------------------------------.
+| Count the number of newlines in the given TEXT of LENGTH characters. |
+`------------------------------------------------------------------------*/
+
+static int
+count_lines (const char *text, int length)
+{
+ int count = 0;
+ while (length--)
+ count += *text++ == '\n';
+ return count;
+}
+
/*-------------------------------------------------------------------------.
| Add some text into an obstack OBS, taken from TEXT, having LENGTH |
| characters. If OBS is NULL, rather output the text to an external file |
@@ -399,37 +421,44 @@
/* Output TEXT to a file, or in-memory diversion buffer. */
if (!sync_output)
- switch (length)
- {
-
- /* In-line short texts. */
+ {
+ if (start_of_output_line)
+ output_current_line++;
- case 8: OUTPUT_CHARACTER (*text); text++;
- case 7: OUTPUT_CHARACTER (*text); text++;
- case 6: OUTPUT_CHARACTER (*text); text++;
- case 5: OUTPUT_CHARACTER (*text); text++;
- case 4: OUTPUT_CHARACTER (*text); text++;
- case 3: OUTPUT_CHARACTER (*text); text++;
- case 2: OUTPUT_CHARACTER (*text); text++;
- case 1: OUTPUT_CHARACTER (*text);
- case 0:
- return;
+ switch (length)
+ {
- /* Optimize longer texts. */
+ /* In-line short texts. */
- default:
- output_text (text, length);
- }
+ case 8: OUTPUT_CHARACTER (*text); COUNT_LINES(*text); text++;
+ case 7: OUTPUT_CHARACTER (*text); COUNT_LINES(*text); text++;
+ case 6: OUTPUT_CHARACTER (*text); COUNT_LINES(*text); text++;
+ case 5: OUTPUT_CHARACTER (*text); COUNT_LINES(*text); text++;
+ case 4: OUTPUT_CHARACTER (*text); COUNT_LINES(*text); text++;
+ case 3: OUTPUT_CHARACTER (*text); COUNT_LINES(*text); text++;
+ case 2: OUTPUT_CHARACTER (*text); COUNT_LINES(*text); text++;
+ case 1: OUTPUT_CHARACTER (*text);
+ start_of_output_line = *text == '\n';
+ case 0:
+ return;
+
+ /* Optimize longer texts. */
+
+ default:
+ output_current_line += count_lines(text, length - 1);
+ start_of_output_line = text[length - 1] == '\n';
+ output_text (text, length);
+ }
+ }
else
for (; length-- > 0; text++)
{
if (start_of_output_line)
{
- start_of_output_line = FALSE;
output_current_line++;
#ifdef DEBUG_OUTPUT
- printf ("DEBUG: cur %d, cur out %d\n",
+ printf ("DEBUG: cur in %d, cur out %d\n",
current_line, output_current_line);
#endif
@@ -437,26 +466,26 @@
If output_current_line was previously given a negative
value (invalidated), rather output `#line NUM "FILE"'. */
- if (output_current_line != current_line)
+ if (!output_filename_synced || output_current_line != current_line)
{
sprintf (line, "#line %d", current_line);
for (cursor = line; *cursor; cursor++)
OUTPUT_CHARACTER (*cursor);
- if (output_current_line < 1)
+ if (!output_filename_synced)
{
OUTPUT_CHARACTER (' ');
OUTPUT_CHARACTER ('"');
for (cursor = current_file; *cursor; cursor++)
OUTPUT_CHARACTER (*cursor);
OUTPUT_CHARACTER ('"');
+ output_filename_synced = TRUE;
}
OUTPUT_CHARACTER ('\n');
output_current_line = current_line;
}
}
OUTPUT_CHARACTER (*text);
- if (*text == '\n')
- start_of_output_line = TRUE;
+ start_of_output_line = *text == '\n';
}
}
@@ -510,7 +539,7 @@
output_file = output_diversion->file;
output_cursor = output_diversion->buffer + output_diversion->used;
output_unused = output_diversion->size - output_diversion->used;
- output_current_line = -1;
+ output_filename_synced = FALSE;
}
/*-------------------------------------------------------------------.
@@ -574,7 +603,7 @@
else if (diversion->buffer)
output_text (diversion->buffer, diversion->used);
- output_current_line = -1;
+ output_filename_synced = FALSE;
}
/* Return all space used by the diversion. */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Syncoutput patch for m4-1.4ppre2,
Andrew Bettison <=