[pure-lang-svn] SF.net SVN: pure-lang: [121] pure/trunk
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-05-24 11:11:02
|
Revision: 121 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=121&view=rev Author: agraef Date: 2008-05-24 04:11:10 -0700 (Sat, 24 May 2008) Log Message: ----------- Bugfixes in the scanf functions. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lib/system.pure pure/trunk/runtime.cc pure/trunk/test/test011.log Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-24 10:30:04 UTC (rev 120) +++ pure/trunk/ChangeLog 2008-05-24 11:11:10 UTC (rev 121) @@ -1,5 +1,8 @@ 2008-05-24 Albert Graef <Dr....@t-...> + * runtime.cc, lib/system.pure: Bugfixes in the scanf + functions. Reported by Jiri Spitz. + * pure.cc, runtime.cc, util.cc: Windows/MinGW compatibility fixes. Suggested by Jiri Spitz. Modified: pure/trunk/lib/system.pure =================================================================== --- pure/trunk/lib/system.pure 2008-05-24 10:30:04 UTC (rev 120) +++ pure/trunk/lib/system.pure 2008-05-24 11:11:10 UTC (rev 121) @@ -265,7 +265,9 @@ "p" = pure_fscanf_pointer fp s buf; _ = throw (this_cant_happen ret); end; - res = if res>=1 then res + // Note: In difference to C scanf, the return value is the number of read + // characters here, with -1 denoting an error condition. + res = if res>=0 then res else (throw (scanf_error ret) when _ = free buf end); val = case t of "d" = get_int buf; @@ -350,8 +352,8 @@ "p" = pure_sscanf_pointer u s buf; _ = throw (this_cant_happen ret); end; - // Note: In difference to pure_fscanf, the return value is the number of - // read characters here, with -1 denoting an error condition. + // Note: In difference to C scanf, the return value is the number of read + // characters here, with -1 denoting an error condition. res = if res>=0 then res else (throw (scanf_error ret) when _ = free buf end); val = case t of Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-05-24 10:30:04 UTC (rev 120) +++ pure/trunk/runtime.cc 2008-05-24 11:11:10 UTC (rev 121) @@ -1742,79 +1742,95 @@ return snprintf(buf, size, format, x); } +#define myformat(format) scanf_format((char*)alloca(strlen(format)+3), format) + +static inline char *scanf_format(char *buf, const char *format) +{ + strcpy(buf, format); strcat(buf, "%n"); + return buf; +} + extern "C" int pure_fscanf(FILE *fp, const char *format) { - return fscanf(fp, format); + int count = -1; + fscanf(fp, myformat(format), &count); + return count; } extern "C" int pure_fscanf_int(FILE *fp, const char *format, int32_t *x) { - return fscanf(fp, format, x); + // wrap this up in case int on the target platform is not 32 bit + int count = -1, y; + fscanf(fp, myformat(format), &y, &count); + if (count >= 0) *x = y; + return count; } extern "C" int pure_fscanf_double(FILE *fp, const char *format, double *x) { - return fscanf(fp, format, x); + int count = -1; + fscanf(fp, myformat(format), x, &count); + return count; } extern "C" int pure_fscanf_string(FILE *fp, const char *format, const char *x) { - return fscanf(fp, format, x); + int count = -1; + fscanf(fp, myformat(format), x, &count); + return count; } extern "C" int pure_fscanf_pointer(FILE *fp, const char *format, const void **x) { - return fscanf(fp, format, x); + int count = -1; + fscanf(fp, myformat(format), x, &count); + return count; } -#define myformat(format) sscanf_format((char*)alloca(strlen(format)+3), format) - -static inline char *sscanf_format(char *buf, const char *format) -{ - strcpy(buf, format); strcat(buf, "%n"); - return buf; -} - extern "C" int pure_sscanf(const char *buf, const char *format) { - int count = -1, res = sscanf(buf, myformat(format), &count); - return (res >= 0)?count:-1; + int count = -1; + sscanf(buf, myformat(format), &count); + return count; } extern "C" int pure_sscanf_int(const char *buf, const char *format, int32_t *x) { // wrap this up in case int on the target platform is not 32 bit - int count = -1, y, res = sscanf(buf, myformat(format), &y, &count); - *x = y; - return (res >= 0)?count:-1; + int count = -1, y; sscanf(buf, myformat(format), &y, &count); + if (count >= 0) *x = y; + return count; } extern "C" int pure_sscanf_double(const char *buf, const char *format, double *x) { - int count = -1, res = sscanf(buf, myformat(format), x, &count); - return (res >= 0)?count:-1; + int count = -1; + sscanf(buf, myformat(format), x, &count); + return count; } extern "C" int pure_sscanf_string(const char *buf, const char *format, char *x) { - int count = -1, res = sscanf(buf, myformat(format), x, &count); - return (res >= 0)?count:-1; + int count = -1; + sscanf(buf, myformat(format), x, &count); + return count; } extern "C" int pure_sscanf_pointer(const char *buf, const char *format, void **x) { - int count = -1, res = sscanf(buf, myformat(format), x, &count); - return (res >= 0)?count:-1; + int count = -1; + sscanf(buf, myformat(format), x, &count); + return count; } #include <fnmatch.h> Modified: pure/trunk/test/test011.log =================================================================== --- pure/trunk/test/test011.log 2008-05-24 10:30:04 UTC (rev 120) +++ pure/trunk/test/test011.log 2008-05-24 11:11:10 UTC (rev 121) @@ -689,7 +689,7 @@ state 3: #1 #4 state 4: #2 #4 state 5: #3 #4 -} end; res/*0:*/ = if res/*0:*/>=1 then res/*0:*/ else throw (scanf_error ret/*4:01*/) when _/*0:*/ = free buf/*1:*/ { +} end; res/*0:*/ = if res/*0:*/>=0 then res/*0:*/ else throw (scanf_error ret/*4:01*/) when _/*0:*/ = free buf/*1:*/ { rule #0: _ = free buf state 0: #0 <var> state 1 @@ -727,7 +727,7 @@ <var> state 1 state 1: #0 } { - rule #0: res = if res>=1 then res else throw (scanf_error ret) when _ = free buf end + rule #0: res = if res>=0 then res else throw (scanf_error ret) when _ = free buf end state 0: #0 <var> state 1 state 1: #0 @@ -765,7 +765,7 @@ <var> state 1 state 1: #0 } end; do_fscanf _/*0:001*/ ret/*0:01*/ _/*0:1*/ = throw (this_cant_happen ret/*0:01*/) { - rule #0: do_fscanf fp ret (scanf_format_spec t s) = ret when size,s = if t=="s" then guestimate s else 16,s; buf = check_buf (calloc size 1); res = case t of "d" = pure_fscanf_int fp s buf; "g" = pure_fscanf_double fp s buf; "s" = pure_fscanf_string fp s buf; "p" = pure_fscanf_pointer fp s buf; _ = throw (this_cant_happen ret) end; res = if res>=1 then res else throw (scanf_error ret) when _ = free buf end; val = case t of "d" = get_int buf; "g" = get_double buf; "s" = cstring buf; "p" = get_pointer buf; _ = throw (this_cant_happen ret) end; _ = if t=="s" then () else free buf; ret = val:ret end + rule #0: do_fscanf fp ret (scanf_format_spec t s) = ret when size,s = if t=="s" then guestimate s else 16,s; buf = check_buf (calloc size 1); res = case t of "d" = pure_fscanf_int fp s buf; "g" = pure_fscanf_double fp s buf; "s" = pure_fscanf_string fp s buf; "p" = pure_fscanf_pointer fp s buf; _ = throw (this_cant_happen ret) end; res = if res>=0 then res else throw (scanf_error ret) when _ = free buf end; val = case t of "d" = get_int buf; "g" = get_double buf; "s" = cstring buf; "p" = get_pointer buf; _ = throw (this_cant_happen ret) end; _ = if t=="s" then () else free buf; ret = val:ret end rule #1: do_fscanf fp ret (scanf_format_str s) = ret when res = pure_fscanf fp s; ret = if res>=0 then ret else throw (scanf_error ret) end rule #2: do_fscanf _ ret _ = throw (this_cant_happen ret) state 0: #0 #1 #2 @@ -1900,7 +1900,7 @@ state 1: #0 } { - rule #0: fscanf fp format::string = tuple$reverse ret when ret = catch error_handler (foldl (do_fscanf fp) []$scanf_split_format format) end with error_handler (scanf_error ret) = throw (scanf_error (tuple$reverse ret)); error_handler x = throw x; check_buf buf = throw printf_malloc_error if null buf; check_buf buf = buf; do_fscanf fp ret (scanf_format_spec t s) = ret when size,s = if t=="s" then guestimate s else 16,s; buf = check_buf (calloc size 1); res = case t of "d" = pure_fscanf_int fp s buf; "g" = pure_fscanf_double fp s buf; "s" = pure_fscanf_string fp s buf; "p" = pure_fscanf_pointer fp s buf; _ = throw (this_cant_happen ret) end; res = if res>=1 then res else throw (scanf_error ret) when _ = free buf end; val = case t of "d" = get_int buf; "g" = get_double buf; "s" = cstring buf; "p" = get_pointer buf; _ = throw (this_cant_happen ret) end; _ = if t=="s" then () else free buf; ret = val:ret end; do_fscanf fp ret (scanf_format_str s) = ret when res = pure_fscanf fp s; ret = if res>=0 then ret else throw (scanf_error ret) end; do_fscanf _ ret _ = throw (this_cant_happen ret); guestimate format = n,format when 1,0,_,1,s = regex "^%([0-9]*)" REG_EXTENDED format 0; n,format = if null s then 1025,"%1024"+tail format else eval s+1,format end end + rule #0: fscanf fp format::string = tuple$reverse ret when ret = catch error_handler (foldl (do_fscanf fp) []$scanf_split_format format) end with error_handler (scanf_error ret) = throw (scanf_error (tuple$reverse ret)); error_handler x = throw x; check_buf buf = throw printf_malloc_error if null buf; check_buf buf = buf; do_fscanf fp ret (scanf_format_spec t s) = ret when size,s = if t=="s" then guestimate s else 16,s; buf = check_buf (calloc size 1); res = case t of "d" = pure_fscanf_int fp s buf; "g" = pure_fscanf_double fp s buf; "s" = pure_fscanf_string fp s buf; "p" = pure_fscanf_pointer fp s buf; _ = throw (this_cant_happen ret) end; res = if res>=0 then res else throw (scanf_error ret) when _ = free buf end; val = case t of "d" = get_int buf; "g" = get_double buf; "s" = cstring buf; "p" = get_pointer buf; _ = throw (this_cant_happen ret) end; _ = if t=="s" then () else free buf; ret = val:ret end; do_fscanf fp ret (scanf_format_str s) = ret when res = pure_fscanf fp s; ret = if res>=0 then ret else throw (scanf_error ret) end; do_fscanf _ ret _ = throw (this_cant_happen ret); guestimate format = n,format when 1,0,_,1,s = regex "^%([0-9]*)" REG_EXTENDED format 0; n,format = if null s then 1025,"%1024"+tail format else eval s+1,format end end state 0: #0 <var> state 1 state 1: #0 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |