From f3ece85092f08d347ff72157b8067330b85c441c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Sun, 28 Feb 1999 21:32:44 -0800 Subject: [PATCH] bugfixes for wide-char compiler/cpp Rev: src/lexer.h:1.4 Rev: src/modules/Makefile.in:1.25 Rev: src/preprocessor.h:1.4 Rev: src/stralloc.c:1.55 Rev: src/stralloc.h:1.32 Rev: src/stuff.c:1.9 Rev: src/stuff.h:1.7 Rev: src/testsuite.in:1.149 --- src/lexer.h | 48 +++---------- src/modules/Makefile.in | 12 +++- src/preprocessor.h | 57 +++++++-------- src/stralloc.c | 156 +++++++++++++++++++++++++++++++++++++++- src/stralloc.h | 3 +- src/stuff.c | 31 +------- src/stuff.h | 3 +- src/testsuite.in | 14 ++-- 8 files changed, 216 insertions(+), 108 deletions(-) diff --git a/src/lexer.h b/src/lexer.h index 6d2d8382a9..900440264b 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -1,5 +1,5 @@ /* - * $Id: lexer.h,v 1.3 1999/02/20 20:06:22 grubba Exp $ + * $Id: lexer.h,v 1.4 1999/03/01 05:32:32 hubbe Exp $ * * Lexical analyzer template. * Based on lex.c 1.62 @@ -117,46 +117,20 @@ static int lex_atoi(char *buf) static long lex_strtol(char *buf, char **end, int base) { - /* NOTE: Cuts at 63 digits */ - char buff[64]; - int i; - long res; - char *end_; - - for(i=0; i < 63; i++) { - int c = INDEX_CHARP(buf, i, SHIFT); - if ((c<=0) || (c >= 256)) { - break; - } - buff[i] = c; - } - buff[i] = 0; - - res = STRTOL(buff, &end_, base); - *end = buf + ((end_ - buff)<<SHIFT); - return(res); + PCHARP foo; + long ret; + ret=STRTOL_PCHARP(MKPCHARP(buf,SHIFT),&foo,base); + if(end) end[0]=foo.ptr; + return ret; } static double lex_strtod(char *buf, char **end) { - /* NOTE: Cuts at 63 digits */ - char buff[64]; - int i; - long res; - char *end_; - - for(i=0; i < 63; i++) { - int c = INDEX_CHARP(buf, i, SHIFT); - if ((c<=0) || (c >= 256)) { - break; - } - buff[i] = c; - } - buff[i] = 0; - - res = my_strtod(buff, &end_); - *end = buf + ((end_ - buff)<<SHIFT); - return(res); + PCHARP foo; + double ret; + ret=STRTOD_PCHARP(MKPCHARP(buf,SHIFT),&foo); + if(end) end[0]=foo.ptr; + return ret; } #endif /* SHIFT == 0 */ diff --git a/src/modules/Makefile.in b/src/modules/Makefile.in index faa558eab1..c4a3948383 100644 --- a/src/modules/Makefile.in +++ b/src/modules/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.24 1998/08/08 20:09:19 grubba Exp $ +# $Id: Makefile.in,v 1.25 1999/03/01 05:32:44 hubbe Exp $ @SET_MAKE@ @@ -19,7 +19,15 @@ $(MODULE_SEGMENTS) $(MODULE_LINKOPTS): modules force: -modules: force +$MODULES: force + echo Making $@; \ + ( cd $@; \ + rm remake >/dev/null 2>&1 || : ; \ + $(MAKE) $(MAKE_FLAGS) MODNAME=$@ || \ + ( test -f remake && $(MAKE) $(MAKE_FLAGS) MODNAME=$@ ) \ + ) || exit $$?; + +modules: $(MODULES) @for a in $(MODULES) ; do \ echo Making $$a; \ ( cd $$a; \ diff --git a/src/preprocessor.h b/src/preprocessor.h index 6d53c62da2..014dd69184 100644 --- a/src/preprocessor.h +++ b/src/preprocessor.h @@ -1,5 +1,5 @@ /* - * $Id: preprocessor.h,v 1.3 1999/02/28 03:22:30 grubba Exp $ + * $Id: preprocessor.h,v 1.4 1999/03/01 05:32:34 hubbe Exp $ * * Preprocessor template. * Based on cpp.c 1.45 @@ -169,9 +169,9 @@ static struct pike_string *WC_BINARY_FINDSTRING(WCHAR *str, INT32 len) #define CHECKWORD2(X,LEN) \ (!MEMCMP(X,data+pos,LEN<<SHIFT) && !WC_ISIDCHAR(data[pos+LEN])) -#define WGOBBLE2(X,LEN) (CHECKWORD2(X,LEN) ? (pos+=LEN),1 : 0) -#define GOBBLEOP2(X,LEN) \ - ((!MEMCMP(X,data+pos,LEN)) ? (pos += LEN),1 : 0) +#define WGOBBLE2(X) (CHECKWORD2(X,NELEM(X)) ? (pos+=NELEM(X)),1 : 0) +#define GOBBLEOP2(X) \ + ((!MEMCMP(X,data+pos,NELEM(X))) ? (pos += NELEM(X)),1 : 0) /* * Some prototypes @@ -335,9 +335,9 @@ static INT32 calcC(struct cpp *this,WCHAR *data,INT32 len,INT32 pos) long l; p = MKPCHARP(data+pos, SHIFT); - f = strtod_pcharp(p, &p1); + f = STRTOD_PCHARP(p, &p1); l = STRTOL_PCHARP(p, &p2, 0); - if(p1.ptr > p2.ptr) + if(COMPARE_PCHARP(p1,>,p2)) { push_float(f); pos = ((WCHAR *)p1.ptr) - data; @@ -479,14 +479,14 @@ static INT32 calc8(struct cpp *this,WCHAR *data,INT32 len,INT32 pos) static WCHAR rsh_[] = { '>', '>' }; FINDTOK(); - if(GOBBLEOP2(lsh_, 2)) + if(GOBBLEOP2(lsh_)) { pos=calc9(this,data,len,pos); o_lsh(); break; } - if(GOBBLEOP2(rsh_, 2)) + if(GOBBLEOP2(rsh_)) { pos=calc9(this,data,len,pos); o_rsh(); @@ -549,14 +549,14 @@ static INT32 calc7(struct cpp *this,WCHAR *data,INT32 len,INT32 pos) static WCHAR ne_[] = { '!', '=' }; FINDTOK(); - if(GOBBLEOP2(eq_, 2)) + if(GOBBLEOP2(eq_)) { pos=calc7b(this,data,len,pos); f_eq(2); continue; } - if(GOBBLEOP2(ne_, 2)) + if(GOBBLEOP2(ne_)) { pos=calc7b(this,data,len,pos); f_ne(2); @@ -616,7 +616,7 @@ static INT32 calc3(struct cpp *this,WCHAR *data,INT32 len,INT32 pos) pos=calc4(this,data,len,pos); FINDTOK(); - while(GOBBLEOP2(land_, 2)) + while(GOBBLEOP2(land_)) { check_destructed(sp-1); if(IS_ZERO(sp-1)) @@ -638,7 +638,7 @@ static INT32 calc2(struct cpp *this,WCHAR *data,INT32 len,INT32 pos) pos=calc3(this,data,len,pos); FINDTOK(); - while(GOBBLEOP2(lor_, 2)) + while(GOBBLEOP2(lor_)) { check_destructed(sp-1); if(!IS_ZERO(sp-1)) @@ -874,7 +874,7 @@ static INT32 lower_cpp(struct cpp *this, if(d->args >= 0 && arg != d->args) cpp_error(this, "Wrong number of arguments to macro."); - init_string_builder(&tmp, 0); + init_string_builder(&tmp, SHIFT); if(d->magic) { d->magic(this, d, arguments, &tmp); @@ -1030,7 +1030,7 @@ static INT32 lower_cpp(struct cpp *this, { static WCHAR line_[] = { 'l', 'i', 'n', 'e' }; - if(WGOBBLE2(line_, 4)) + if(WGOBBLE2(line_)) { /* FIXME: Why not use SKIPSPACE()? */ while(data[pos]==' ' || data[pos]=='\t') pos++; @@ -1093,7 +1093,7 @@ static INT32 lower_cpp(struct cpp *this, READSTRING2(nf); if(OUTP()) { - PUSH_STRING((WCHAR *)nf.s->str, nf.s->len, &this->buf); + PUSH_STRING_SHIFT(nf.s->str, nf.s->len,nf.s->size_shift, &this->buf); } free_string_builder(&nf); break; @@ -1103,7 +1103,7 @@ static INT32 lower_cpp(struct cpp *this, { WCHAR string_[] = { 's', 't', 'r', 'i', 'n', 'g' }; - if(WGOBBLE2(string_, 6)) + if(WGOBBLE2(string_)) { tmp2=1; goto do_include; @@ -1118,7 +1118,7 @@ static INT32 lower_cpp(struct cpp *this, static WCHAR ifdef_[] = { 'i', 'f', 'd', 'e', 'f' }; static WCHAR ifndef_[] = { 'i', 'f', 'n', 'd', 'e', 'f' }; - if(WGOBBLE2(include_, 7)) + if(WGOBBLE2(include_)) { tmp2=0; do_include: @@ -1251,7 +1251,7 @@ static INT32 lower_cpp(struct cpp *this, } } - if(WGOBBLE2(if_, 2)) + if(WGOBBLE2(if_)) { struct string_builder save,tmp; INT32 nflags=CPP_EXPECT_ELSE | CPP_EXPECT_ENDIF; @@ -1276,7 +1276,7 @@ static INT32 lower_cpp(struct cpp *this, break; } - if(WGOBBLE2(ifdef_, 5)) + if(WGOBBLE2(ifdef_)) { INT32 namestart,nflags; struct pike_string *s; @@ -1300,7 +1300,7 @@ static INT32 lower_cpp(struct cpp *this, break; } - if(WGOBBLE2(ifndef_, 6)) + if(WGOBBLE2(ifndef_)) { INT32 namestart,nflags; struct pike_string *s; @@ -1334,7 +1334,7 @@ static INT32 lower_cpp(struct cpp *this, static WCHAR elif_[] = { 'e', 'l', 'i', 'f' }; static WCHAR error_[] = { 'e', 'r', 'r', 'o', 'r' }; - if(WGOBBLE2(endif_, 5)) + if(WGOBBLE2(endif_)) { if(!(flags & CPP_EXPECT_ENDIF)) cpp_error(this, "Unmatched #endif"); @@ -1342,7 +1342,7 @@ static INT32 lower_cpp(struct cpp *this, return pos; } - if(WGOBBLE2(else_, 4)) + if(WGOBBLE2(else_)) { if(!(flags & CPP_EXPECT_ELSE)) cpp_error(this, "Unmatched #else"); @@ -1358,7 +1358,7 @@ static INT32 lower_cpp(struct cpp *this, break; } - if(WGOBBLE2(elif_, 4) || WGOBBLE2(elseif_, 6)) + if(WGOBBLE2(elif_) || WGOBBLE2(elseif_)) { if(!(flags & CPP_EXPECT_ELSE)) cpp_error(this, "Unmatched #elif"); @@ -1389,7 +1389,7 @@ static INT32 lower_cpp(struct cpp *this, break; } - if(WGOBBLE2(error_, 5)) + if(WGOBBLE2(error_)) { INT32 foo; SKIPSPACE(); @@ -1418,7 +1418,7 @@ static INT32 lower_cpp(struct cpp *this, { static WCHAR define_[] = { 'd', 'e', 'f', 'i', 'n', 'e' }; - if(WGOBBLE2(define_, 6)) + if(WGOBBLE2(define_)) { struct string_builder str; INT32 namestart, tmp3, nameend, argno=-1; @@ -1668,10 +1668,11 @@ static INT32 lower_cpp(struct cpp *this, } case 'u': /* undefine */ { + static WCHAR undef_[] = { 'u', 'n', 'd', 'e', 'f' }; static WCHAR undefine_[] = { 'u', 'n', 'd', 'e', 'f', 'i', 'n', 'e' }; /* NOTE: Reuses undefine_ for undef_ */ - if(WGOBBLE2(undefine_, 8) || WGOBBLE2(undefine_, 5)) + if(WGOBBLE2(undefine_) || WGOBBLE2(undef_)) { INT32 tmp; struct pike_string *s; @@ -1704,7 +1705,7 @@ static INT32 lower_cpp(struct cpp *this, { static WCHAR charset_[] = { 'c', 'h', 'a', 'r', 's', 'e', 't' }; - if (WGOBBLE2(charset_, 7)) { + if (WGOBBLE2(charset_)) { INT32 p; struct pike_string *s; @@ -1764,7 +1765,7 @@ static INT32 lower_cpp(struct cpp *this, { static WCHAR pragma_[] = { 'p', 'r', 'a', 'g', 'm', 'a' }; - if(WGOBBLE2(pragma_, 6)) + if(WGOBBLE2(pragma_)) { if(OUTP()) STRCAT("#pragma", 7); diff --git a/src/stralloc.c b/src/stralloc.c index 67ad6e8a18..03cc88d369 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -14,9 +14,11 @@ #include "gc.h" #include "stuff.h" +#include <errno.h> #include <ctype.h> +#include <math.h> -RCSID("$Id: stralloc.c,v 1.54 1999/02/27 22:27:02 grubba Exp $"); +RCSID("$Id: stralloc.c,v 1.55 1999/03/01 05:32:35 hubbe Exp $"); #define BEGIN_HASH_SIZE 997 #define MAX_AVG_LINK_LENGTH 3 @@ -1703,6 +1705,158 @@ long STRTOL_PCHARP(PCHARP str, PCHARP *ptr, int base) return (neg ? val : -val); } +/* Convert PCHARP to a double. If ENDPTR is not NULL, a pointer to the + character after the last one used in the number is put in *ENDPTR. */ +double STRTOD_PCHARP(PCHARP nptr, PCHARP *endptr) +{ + register PCHARP s; + short int sign; + + /* The number so far. */ + double num; + + int got_dot; /* Found a decimal point. */ + int got_digit; /* Seen any digits. */ + + /* The exponent of the number. */ + long int exponent; + + if (nptr.ptr == NULL) + { + errno = EINVAL; + goto noconv; + } + + s = nptr; + + /* Eat whitespace. */ + while (EXTRACT_PCHARP(s) <256 && ISSPACE(EXTRACT_PCHARP(s))) INC_PCHARP(s,1); + + /* Get the sign. */ + sign = EXTRACT_PCHARP(s) == '-' ? -1 : 1; + if (EXTRACT_PCHARP(s) == '-' || EXTRACT_PCHARP(s) == '+') + INC_PCHARP(s,1); + + /* Get the sign. */ + sign = EXTRACT_PCHARP(s) == '-' ? -1 : 1; + if (EXTRACT_PCHARP(s) == '-' || EXTRACT_PCHARP(s) == '+') + INC_PCHARP(s,1); + + num = 0.0; + got_dot = 0; + got_digit = 0; + exponent = 0; + for (;; INC_PCHARP(s,1)) + { + if (EXTRACT_PCHARP(s)<256 && isdigit (EXTRACT_PCHARP(s))) + { + got_digit = 1; + + /* Make sure that multiplication by 10 will not overflow. */ + if (num > DBL_MAX * 0.1) + /* The value of the digit doesn't matter, since we have already + gotten as many digits as can be represented in a `double'. + This doesn't necessarily mean the result will overflow. + The exponent may reduce it to within range. + + We just need to record that there was another + digit so that we can multiply by 10 later. */ + ++exponent; + else + num = (num * 10.0) + (EXTRACT_PCHARP(s) - '0'); + + /* Keep track of the number of digits after the decimal point. + If we just divided by 10 here, we would lose precision. */ + if (got_dot) + --exponent; + } + else if (!got_dot && (char) EXTRACT_PCHARP(s) == '.') + /* Record that we have found the decimal point. */ + got_dot = 1; + else + /* Any other character terminates the number. */ + break; + } + + if (!got_digit) + goto noconv; + + if (EXTRACT_PCHARP(s) <256 && tolower(EXTRACT_PCHARP(s)) == 'e') + { + /* Get the exponent specified after the `e' or `E'. */ + int save = errno; + PCHARP end; + long int exp; + + errno = 0; + INC_PCHARP(s,1); + exp = STRTOL_PCHARP(s, &end, 10); + if (errno == ERANGE) + { + /* The exponent overflowed a `long int'. It is probably a safe + assumption that an exponent that cannot be represented by + a `long int' exceeds the limits of a `double'. */ + if (endptr != NULL) + *endptr = end; + if (exp < 0) + goto underflow; + else + goto overflow; + } + else if (COMPARE_PCHARP(end,==,s)) + /* There was no exponent. Reset END to point to + the 'e' or 'E', so *ENDPTR will be set there. */ + end = ADD_PCHARP(s,-1); + errno = save; + s = end; + exponent += exp; + } + + if(got_dot && INDEX_PCHARP(s,-1)=='.') INC_PCHARP(s,-1); + if (endptr != NULL) + *endptr = s; + + if (num == 0.0) + return 0.0; + + /* Multiply NUM by 10 to the EXPONENT power, + checking for overflow and underflow. */ + + if (exponent < 0) + { + if (num < DBL_MIN * pow(10.0, (double) -exponent)) + goto underflow; + } + else if (exponent > 0) + { + if (num > DBL_MAX * pow(10.0, (double) -exponent)) + goto overflow; + } + + num *= pow(10.0, (double) exponent); + + return num * sign; + + overflow: + /* Return an overflow error. */ + errno = ERANGE; + return HUGE * sign; + + underflow: + /* Return an underflow error. */ + if (endptr != NULL) + *endptr = nptr; + errno = ERANGE; + return 0.0; + + noconv: + /* There was no number. */ + if (endptr != NULL) + *endptr = nptr; + return 0.0; +} + + p_wchar0 *require_wstring0(struct pike_string *s, char **to_free) { diff --git a/src/stralloc.h b/src/stralloc.h index 7ff9ad08a6..483550f9e6 100644 --- a/src/stralloc.h +++ b/src/stralloc.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: stralloc.h,v 1.31 1999/02/27 17:20:07 grubba Exp $ + * $Id: stralloc.h,v 1.32 1999/03/01 05:32:37 hubbe Exp $ */ #ifndef STRALLOC_H #define STRALLOC_H @@ -230,6 +230,7 @@ void free_string_builder(struct string_builder *s); struct pike_string *finish_string_builder(struct string_builder *s); PCHARP MEMCHR_PCHARP(PCHARP ptr, int chr, int len); long STRTOL_PCHARP(PCHARP str, PCHARP *ptr, int base); +double STRTOD_PCHARP(PCHARP nptr, PCHARP *endptr); p_wchar0 *require_wstring0(struct pike_string *s, char **to_free); p_wchar1 *require_wstring1(struct pike_string *s, diff --git a/src/stuff.c b/src/stuff.c index ccad2cdbf6..e6fb8d7161 100644 --- a/src/stuff.c +++ b/src/stuff.c @@ -5,7 +5,7 @@ \*/ /* - * $Id: stuff.c,v 1.8 1999/02/27 21:54:39 grubba Exp $ + * $Id: stuff.c,v 1.9 1999/03/01 05:32:38 hubbe Exp $ */ #include "global.h" #include "stuff.h" @@ -126,32 +126,3 @@ double my_strtod(char *nptr, char **endptr) return tmp; } -double strtod_pcharp(PCHARP ptr, PCHARP *endptr) -{ - /* NOTE: Cuts at 63 digits */ - - char buff[64]; - int i; - double res; - char *end_; - - endptr->shift = ptr.shift; - - if (!ptr.shift) { - return my_strtod(ptr.ptr, (char **)&endptr->ptr); - } - - for (i=0; i < 63; i++) { - unsigned int c = INDEX_PCHARP(ptr, i); - if (!c || (c >= 256)) { - break; - } - buff[i] = c; - } - buff[i] = 0; - - res = my_strtod(buff, &end_); - - endptr->ptr = ptr.ptr + ((end_ - buff)<<ptr.shift); - return res; -} diff --git a/src/stuff.h b/src/stuff.h index cfde9b6a1e..e9ffedf957 100644 --- a/src/stuff.h +++ b/src/stuff.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: stuff.h,v 1.6 1999/02/27 20:36:14 grubba Exp $ + * $Id: stuff.h,v 1.7 1999/03/01 05:32:40 hubbe Exp $ */ #ifndef STUFF_H #define STUFF_H @@ -17,7 +17,6 @@ int my_log2(unsigned INT32 x); int count_bits(unsigned INT32 x); int is_more_than_one_bit(unsigned INT32 x); double my_strtod(char *nptr, char **endptr); -double strtod_pcharp(PCHARP ptr, PCHARP *endptr); /* Prototypes end here */ extern INT32 hashprimes[32]; diff --git a/src/testsuite.in b/src/testsuite.in index c7e62b1751..a5b9c605ae 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,4 @@ -stest_true([["$Id: testsuite.in,v 1.148 1999/02/24 01:52:55 grubba Exp $"]]) +stest_true([["$Id: testsuite.in,v 1.149 1999/03/01 05:32:41 hubbe Exp $"]]) cond([[all_constants()->_verify_internals]], [[ test_do(_verify_internals()) @@ -139,7 +139,7 @@ test_eval_error([[ return 0.0[0]; ]]) test_eval_error([[ return 0[0]; ]]) test_compile_error([[constant x=class {}(); ]]) -test_compile([[int x=gauge { return; },1;]]) +test_compile([[int x=(gauge { return; },1);]]) cond( [[ master()->resolv("Gmp")->mpz ]], [[ test_compile_error([[object x = Gmp.mpz(17); constant y = x;]]) @@ -153,10 +153,6 @@ test_any([[class G { mapping t=([]); class tO { void init(string name) { t[name]=this_object(); }} class W { inherit tO; void create() { init("foo"); }} }; object x=G(); x->W(); return objectp(x->t->foo)]],1) -test_eq([[cpp("#define FOO(X,Y) (X) (Y)\nFOO( (A),(B) )")]],"# 1 \"-\"\n\n( (A) ) ( (B) )") -test_eq([[cpp("#define F 'F'\nF")]],"# 1 \"-\"\n\n'F'") -test_eq([[cpp("#define MAX(X,Y) ((X)>(Y)?(X):(Y))\n#define MAX3(X,Y,Z) MAX(MAX(X,Y),Z)\nMAX3(1,2,3)")]],"# 1 \"-\"\n\n\n(( (( 1 )>( 2 )?( 1 ):( 2 )) )>( 3 )?( (( 1 )>( 2 )?( 1 ):( 2 )) ):( 3 ))") -test_eq([[cpp("foo\xfeff""bar \xfeff gazonk")]],[[cpp("foobar gazonk")]]) test_program([[class foo { program x() { return class {}; }}; class bar { inherit foo; program x() { return class {}; }} int a() { return foo()->x != bar()->x(); }]]) @@ -1663,6 +1659,11 @@ cond([[all_constants()->_verify_internals]], ]]) // testing preprocessor +test_eq([[cpp("#define FOO(X,Y) (X) (Y)\nFOO( (A),(B) )")]],"# 1 \"-\"\n\n( (A) ) ( (B) )") +test_eq([[cpp("#define F 'F'\nF")]],"# 1 \"-\"\n\n'F'") +test_eq([[cpp("#define MAX(X,Y) ((X)>(Y)?(X):(Y))\n#define MAX3(X,Y,Z) MAX(MAX(X,Y),Z)\nMAX3(1,2,3)")]],"# 1 \"-\"\n\n\n(( (( 1 )>( 2 )?( 1 ):( 2 )) )>( 3 )?( (( 1 )>( 2 )?( 1 ):( 2 )) ):( 3 ))") +test_eq([[cpp("foo\xfeff""bar \xfeff gazonk")]],[[cpp("foobar gazonk")]]) + test_any(int e; object o=clone(Stdio.File); if(!o->open("conftest.h","wct")) return -1; e=o->write("return 17;\n"); if(!o->close()) return -1; return e,11) test_any([[ #include "conftest.h" @@ -2115,7 +2116,6 @@ test_compile_error([[ #error Gurgel ]]) - // foop define(do_test_foop,[[ test_eq($1 (17), !($2)) -- GitLab