From: William D. <wdo...@us...> - 2006-08-24 20:22:24
|
Update of /cvsroot/flexml/flexml In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv22541 Modified Files: flexml.pl skel Log Message: Fix bug #1529930 (parsing mixed content fails on sparc/solaris); replace static bufferstack by dynamic (bufferstack,indexstack) pair, so former char* pointers are now integer indices; replace stack-size option by stack-increment; quiet perl warnings when $debug is on; compute and output FLEXML_NEED_BUFFERLIT symbol to quiet compiler warning if bufferliteral() is unused; replace several A_* variables and pcdata by AX_* and pcdata_ix since we are now using indices. Index: skel =================================================================== RCS file: /cvsroot/flexml/flexml/skel,v retrieving revision 1.33 retrieving revision 1.34 diff -u -d -r1.33 -r1.34 --- skel 15 Aug 2006 16:01:13 -0000 1.33 +++ skel 24 Aug 2006 20:22:21 -0000 1.34 @@ -1,8 +1,8 @@ /* Flex(1) XML processor skeleton scanner (in -*-C-*-). - * Copyright (c) 1999 Kristoffer Rose. All rights reserved. + * Copyright © 1999 Kristoffer Rose. All rights reserved. * * This file is part of the FleXML XML processor generator system. - * Copyright (c) 1999 Kristoffer Rose. All rights reserved. + * Copyright © 1999 Kristoffer Rose. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -36,6 +36,10 @@ #include <stdarg.h> #include <ctype.h> +#ifndef FLEXML_INDEXSTACKSIZE +#define FLEXML_INDEXSTACKSIZE 1000 +#endif + /* Generated definitions. */ FLEXML_DEFINITIONS @@ -59,54 +63,90 @@ #define FAIL return fail static int fail(const char*, ...); -const char * parse_err_msg(void); + +enum {flexml_max_err_msg_size = 512}; +static char flexml_err_msg[flexml_max_err_msg_size]; +const char * parse_err_msg() +{ + return flexml_err_msg; +} +static void reset_parse_err_msg() +{ + flexml_err_msg[0] = '\0'; +} /* Cleanup */ static void cleanup(void); #define CLEANUP cleanup() /* Text buffer stack handling. */ -static char bufferstack[FLEXML_BUFFERSTACKSIZE]; -static char* limit = bufferstack + FLEXML_BUFFERSTACKSIZE; -typedef struct BufferLast_s { - struct BufferLast_s *old; const char* saved; char new1[1]; -} BufferLast; -static BufferLast* last = (BufferLast*)0; -static char* next = bufferstack; +char *bufferstack = NULL; +static int blimit = FLEXML_BUFFERSTACKSIZE; +static int bnext = 1; -#define BUFFERSET(P) (P = next) -#define BUFFERPUTC(C) (assert(next<limit), *(next++) = (C)) +static int *indexstack = NULL; +static int ilimit = FLEXML_INDEXSTACKSIZE; +static int inext = 1; + +#define BUFFERSET(P) (P = bnext) +#define BUFFERPUTC(C) (ck_blimit(), bufferstack[bnext++] = (C)) #define BUFFERDONE (BUFFERPUTC('\0')) -#define BUFFERLITERAL(C,P) bufferliteral(C,&(P),yytext) -static void bufferliteral(char c, const char** pp, char* text) +#define BUFFERLITERAL(C, P) bufferliteral(C, &(P), yytext) + +/* after this is called, there are at least 2 slots left in the stack */ +static int ck_blimit() { - char *s = strchr(text,c), *e = strrchr(text,c); + if (bnext >= blimit) { + blimit += FLEXML_BUFFERSTACKSIZE + 2; + { + char *temp = (char *) realloc(bufferstack, blimit); + assert(temp); + bufferstack = temp; + } + } + return 0; +} + +/* after this is called, there are at least 2 slots left in the stack */ +static int ck_ilimit() +{ + if (inext >= ilimit) { + ilimit += FLEXML_INDEXSTACKSIZE + 2; + { + int *temp = (int *) realloc(indexstack, ilimit); + assert(temp); + indexstack = temp; + } + } + return 0; +} + +#ifdef FLEXML_NEED_BUFFERLIT +static void bufferliteral(char c, int* pp, char* text) +{ + char *s = (c ? strchr(text,c) : text-1), *e = strrchr(text,c); assert(s <= e); BUFFERSET(*pp); while (++s<e) { - if (isspace(*s)) { BUFFERPUTC(' '); while (isspace(*s)) ++s; } + if (isspace(*s) && c) { BUFFERPUTC(' '); while (isspace(*s)) ++s; } else BUFFERPUTC(*s); } BUFFERDONE; } +#endif -static void pushbuffer(const char* p) +static void pushbuffer(int p) { - BufferLast* l = (BufferLast*)next; - assert(next < limit); - l->old = last; - l->saved = p; - next = l->new1; - last = l; + ck_ilimit(); + indexstack[inext++] = p; + indexstack[inext++] = bnext; } -static const char* popbuffer(void) +static int popbuffer(void) { - BufferLast* l = last; - assert(last != (BufferLast*)0); - last = l->old; - next = (char*)l; - return l->saved; + assert(inext >= 2); + bnext = indexstack[--inext]; + return indexstack[--inext]; } /* General internal entities are `unput' back onto the input stream... */ @@ -169,14 +209,22 @@ /* Bypass Flex's default INITIAL state and begin by parsing the XML prolog. */ SET(PROLOG); + reset_parse_err_msg(); + bufferstack = (char *) malloc(FLEXML_BUFFERSTACKSIZE); + assert(bufferstack); #ifdef FLEX_DEBUG { int i; - for (i = 0; i < FLEXML_BUFFERSTACKSIZE; i++) { + for (i = 0; i < blimit; i++) { bufferstack[i] = '\377'; } } #endif + bufferstack[0] = '\0'; + indexstack = (int *) malloc(FLEXML_INDEXSTACKSIZE * sizeof(int)); + assert(indexstack); + indexstack[0] = 0; + FLEXML_EXTRA_DEFINITIONS_INIT /* COMMENTS and PIs: handled uniformly for efficiency. */ @@ -306,7 +354,7 @@ { int i; fputs("Buffer: ", stderr); - for (i = 0; i < FLEXML_BUFFERSTACKSIZE; i++) { + for (i = 0; i < blimit; i++) { if ( bufferstack[i] == '\377' ) break; putc(bufferstack[i], stderr); } @@ -322,7 +370,10 @@ } static void debug_leave(void) { - if (yy_flex_debug) print_yy_stack("--LEAVE : "); + if (yy_flex_debug) { + print_yy_stack("--LEAVE : "); + print_bufferstack(); + } yy_pop_state(); } @@ -332,19 +383,6 @@ } #endif -enum {flexml_max_err_msg_size = 512}; - -static char flexml_err_msg[flexml_max_err_msg_size]; -const char * parse_err_msg() -{ - return flexml_err_msg; -} - -static void reset_parse_err_msg() -{ - flexml_err_msg[0] = '\0'; -} - static void cleanup(void) { @@ -352,6 +390,11 @@ free(statenames); statenames = NULL; } + free(bufferstack); + bufferstack = NULL; + + free(indexstack); + indexstack = NULL; } Index: flexml.pl =================================================================== RCS file: /cvsroot/flexml/flexml/flexml.pl,v retrieving revision 1.55 retrieving revision 1.56 diff -u -d -r1.55 -r1.56 --- flexml.pl 15 Aug 2006 16:01:13 -0000 1.55 +++ flexml.pl 24 Aug 2006 20:22:20 -0000 1.56 @@ -246,12 +246,22 @@ sub api_data { # Print XML application interface parameters. - my ($pre) = @_; + my ($pre) = @_; # pre should be a storage class spec like 'static' or 'extern' print "/* FleXML-provided data. */\n"; - print $pre . "const char* ${tagprefix}pcdata;\n"; + print $pre . "int ${tagprefix}pcdata_ix;\n"; + print "extern char *bufferstack;\n"; + print "#define ${tagprefix}pcdata (bufferstack + ${tagprefix}pcdata_ix)\n"; + for (keys %atttype) { if (m.($Nmtoken)[/]($Nmtoken).xo) { - print $pre . "AT_${tagprefix}$ctag{$1}_$catt{$2} A_${tagprefix}$ctag{$1}_$catt{$2};\n"; + print $pre . "AT_${tagprefix}$ctag{$1}_$catt{$2} AX_${tagprefix}$ctag{$1}_$catt{$2};\n"; + print "#define A_${tagprefix}$ctag{$1}_$catt{$2} "; + if ($enumtype{$_}) { + print "AX_${tagprefix}$ctag{$1}_$catt{$2}\n"; + } + else { + print "(bufferstack + AX_${tagprefix}$ctag{$1}_$catt{$2})\n"; + } } } } @@ -312,6 +322,16 @@ # } } +# add attribute to list of all default attributes +my @default_attributes; +my $next_att_loc = 1; +sub add_def_att { + my ($att) = @_; + my $retval = $next_att_loc; + push @default_attributes, ($att); + $next_att_loc += length($att) + 1; + return $retval; +} sub nextline { # return one input line @@ -500,7 +520,7 @@ # Parse options. $Use = "Usage: flexml [-ASHDvdqnLXV] [-s skel] [-T actbin] [--sysid sysid] [-p pubid] [-u uri]\n" - . " [-b stack_size] [-r roottags] [-a actions] [-P prefix] name[.dtd]"; + . " [-b stack_increment] [-r roottags] [-a actions] [-P prefix] name[.dtd]"; sub show_version { @@ -532,7 +552,7 @@ }, # Specific stack size? - "stack-size|b=s" => \$stacksize, + "stack-increment|b=s" => \$stacksize, # Specific tagprefix? "tag-prefix|P=s" => sub { $tagprefix = $_[1]."_" }, @@ -846,12 +866,12 @@ } # ...and string/token types. else { - $typeof{"$tag/$attribute"} = 'const char*'; + $typeof{"$tag/$attribute"} = 'int'; if ($default) { - $initof{"$tag/$attribute"} = "\"$default\""; + $initof{"$tag/$attribute"} = add_def_att($default); } else { - $initof{"$tag/$attribute"} = 'NULL'; + $initof{"$tag/$attribute"} = '0'; } # Special treatment of token types. @@ -1053,32 +1073,32 @@ } # display the options we got - print "debug=$debug\n"; - print "verbose=$verbose\n"; - print "quiet=$quiet_parser\n"; - - print "dry-run=$dryrun\n"; - print "lineno=$lineno\n"; - - print "nofail=$nofail\n"; - - print "stack-size=$stacksize\n"; - print "tag-prefix=$tagprefix\n"; - - print "act-bin=$actbin\n"; - - print "skel=$SKELETON\n"; - - print "uri=$uri\n"; - print "pubid=$pubid\n\n"; - print "sysid=$sysid\n\n"; + print "debug=".($debug||'undef')."\n"; + print "verbose=".($verbose||'undef')."\n"; + print "quiet=".($quiet_parser||'undef')."\n"; + + print "dry-run=".($dryrun||'undef')."\n"; + print "lineno=".($lineno||'undef')."\n"; + + print "nofail=".($nofail||'undef')."\n"; + + print "stack-increment=".($stacksize||'undef')."\n"; + print "tag-prefix=".($tagprefix||'undef')."\n"; + + print "act-bin=".($actbin||'undef')."\n"; + + print "skel=".($SKELETON||'undef')."\n"; + + print "uri=".($uri||'undef')."\n"; + print "pubid=".($pubid||'undef')."\n\n"; + print "sysid=".($sysid||'undef')."\n\n"; print "header=".($header||'undef')."\n"; print "dummy=".($dummy||'undef')."\n"; print "stand-alone=".($standalone||'undef')."\n"; print "scanner=".($scanner||'undef')."\n"; print "actions=".($actions||'undef')."\n\n"; - + print '%source = (' . printhash(\%source) . ")\n"; print "\n"; @@ -1215,7 +1235,11 @@ print "#define FLEXML_yylineno\n" if $lineno; print "#define FLEXML_NOFAIL\n" if $nofail; print "#define FLEXML_quiet_parser\n" if $quiet_parser; + print "#ifndef FLEXML_BUFFERSTACKSIZE\n"; print "#define FLEXML_BUFFERSTACKSIZE $stacksize\n"; + print "#endif\n"; + print "#define FLEXML_NEED_BUFFERLIT\n" + if (scalar(%literaltype) or ($#default_attributes >= 0)); print "\n"; if ($standalone) { @@ -1263,7 +1287,9 @@ my ($state, $tag); print " /* FleXML_init */\n"; - print " next = bufferstack;\n"; + for my $att (@default_attributes) { + print " bufferliteral('\\0', &bnext, \"$att\");\n"; + } print " if(!${tagprefix}statenames) {${tagprefix}statenames= (const char **)calloc(IMPOSSIBLE,sizeof(char*));\n"; for ('PROLOG','DOCTYPE','EPILOG','INCOMMENT','INPI','VALUE1','VALUE2','CDATA') { print " ${tagprefix}statenames[$_] = NULL;\n"; @@ -1349,9 +1375,9 @@ print ">\"<$tag\"{s} {\n"; for my $attribute (@myattributes) { - print " A_${tagprefix}${myctag}_$catt{$attribute} = " . $initof{"$tag/$attribute"} . ";\n"; + print " AX_${tagprefix}${myctag}_$catt{$attribute} = " . $initof{"$tag/$attribute"} . ";\n"; } - print " ENTER(AL_${tagprefix}$myctag); pushbuffer(NULL);\n"; + print " ENTER(AL_${tagprefix}$myctag); pushbuffer(0);\n"; print " }\n"; # print " . FAIL(\"Unexpected character `%c': `<$tag' expected.\",yytext[0]);\n"; @@ -1394,23 +1420,23 @@ print " \"$attribute\"{Eq}\"'" . $attdef{"$tag/$attribute"} . "'\"" . " |\n" . " \"$attribute\"{Eq}\"\\\"" . $attdef{"$tag/$attribute"} . "\\\"\"" - . " A_${tagprefix}${myctag}_$catt{$attribute}" + . " AX_${tagprefix}${myctag}_$catt{$attribute}" . " = " . $initof{"$tag/$attribute"} . ";\n"; } elsif ($type = $literaltype{"$tag/$attribute"}) { # - (non-fixed) literal-type attribute: scan literal string directly, or - print " \"$attribute\"{Eq}\'$type\' BUFFERLITERAL('\\\'',A_${tagprefix}${myctag}_$catt{$attribute});\n"; + print " \"$attribute\"{Eq}\'$type\' BUFFERLITERAL('\\\'',AX_${tagprefix}${myctag}_$catt{$attribute});\n"; - print " \"$attribute\"{Eq}\\\"$type\\\" BUFFERLITERAL('\"',A_${tagprefix}${myctag}_$catt{$attribute});\n"; + print " \"$attribute\"{Eq}\\\"$type\\\" BUFFERLITERAL('\"',AX_${tagprefix}${myctag}_$catt{$attribute});\n"; } else { # - (non-fixed non-literal) attribute: scan string with entity expansion. - print " \"$attribute\"{Eq}\\' ENTER(VALUE1); BUFFERSET(A_${tagprefix}${myctag}_$catt{$attribute});\n"; - print " \"$attribute\"{Eq}\\\" ENTER(VALUE2); BUFFERSET(A_${tagprefix}${myctag}_$catt{$attribute});\n"; + print " \"$attribute\"{Eq}\\' ENTER(VALUE1); BUFFERSET(AX_${tagprefix}${myctag}_$catt{$attribute});\n"; + print " \"$attribute\"{Eq}\\\" ENTER(VALUE2); BUFFERSET(AX_${tagprefix}${myctag}_$catt{$attribute});\n"; } print "\n"; @@ -1426,8 +1452,8 @@ } } print " LEAVE; STag_${tagprefix}$myctag(); popbuffer(); " - . (%inmixed ? ' pushbuffer('."${tagprefix}".'pcdata);' : '') - . ($mixed{$tag} ? 'pushbuffer('."${tagprefix}".'pcdata); BUFFERSET('."${tagprefix}".'pcdata);' : "${tagprefix}".'pcdata = NULL'). ";" + . (%inmixed ? ' pushbuffer('."${tagprefix}".'pcdata_ix);' : '') + . ($mixed{$tag} ? 'pushbuffer('."${tagprefix}".'pcdata_ix); BUFFERSET('."${tagprefix}".'pcdata_ix);' : "${tagprefix}".'pcdata_ix = 0'). ";" . " ENTER($startstate{$tag});\n"; print " }\n"; # @@ -1441,10 +1467,10 @@ } } print " LEAVE; STag_${tagprefix}$myctag(); popbuffer();" - . (%inmixed ? ' pushbuffer('."${tagprefix}".'pcdata);' : '') - . " ${tagprefix}".'pcdata = ' . ($mixed{$tag} ? '""' : 'NULL') . ';' + . (%inmixed ? ' pushbuffer('."${tagprefix}".'pcdata_ix);' : '') + . " ${tagprefix}".'pcdata_ix = 0;' . " ETag_${tagprefix}$myctag();" - . (%inmixed ? " ${tagprefix}".'pcdata = popbuffer();' : '') + . (%inmixed ? " ${tagprefix}".'pcdata_ix = popbuffer();' : '') . "\n"; # print $exitswitch; @@ -1469,8 +1495,8 @@ print " LEAVE;\n"; print " BUFFERDONE;\n" if $mixed{$tag}; print " ETag_${tagprefix}$myctag();\n"; - print " ${tagprefix}pcdata = popbuffer();\n" if $mixed{$tag}; - print " ${tagprefix}pcdata = popbuffer();\n" if %inmixed; + print " ${tagprefix}pcdata_ix = popbuffer();\n" if $mixed{$tag}; + print " ${tagprefix}pcdata_ix = popbuffer();\n" if %inmixed; print $exitswitch; print " }\n"; @@ -1845,11 +1871,10 @@ This is an internal option mainly used to test versions of flexml not installed yet. -=item B<--stack-size> I<stack_size>, B<-b> I<stack_size> +=item B<--stack-increment> I<stack_increment>, B<-b> I<stack_increment> -Sets the FLEXML_BUFFERSTACKSIZE to stack_size (100000 by default). Use -this option when you get an error like "Assertion `next<limit' -failed". +Sets the FLEXML_BUFFERSTACKSIZE to stack_increment (100000 by default). This +controls how much the data stack grows in each realloc(). =item B<--tag-prefix> I<STRING>, B<-O> I<STRING> @@ -2016,11 +2041,6 @@ =item * -The XML processor currently uses a fixed-size buffer to read -C<pcdata>. It should not. - -=item * - The DTD parser is presently a perl hack so it may parse some DTDs badly; in particular the expansion of parameter entities may not conform fully to the XML specification. |