diff --git a/C/scanner.c b/C/scanner.c index 23f5cfc79..988b81d08 100644 --- a/C/scanner.c +++ b/C/scanner.c @@ -54,6 +54,9 @@ #if HAVE_WCTYPE_H #include #endif +#if O_LOCALE +#include "locale.h" +#endif /* You just can't trust some machines */ #define my_isxdigit(C,SU,SL) (chtype(C) == NU || (C >= 'A' && \ @@ -95,28 +98,28 @@ EF, /* 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 */ BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, -/* 144 145 147 148 149 150 151 152 153 154 155 156 157 158 159 */ +/* 144 145 ’ 147 148 149 150 151 152 153 154 155 156 157 158 159 */ BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, -/* */ +/*   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ */ BS, SY, SY, SY, SY, SY, SY, SY, SY, SY, LC, SY, SY, SY, SY, SY, -/* */ +/* ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ */ SY, SY, LC, LC, SY, SY, SY, SY, SY, LC, LC, SY, SY, SY, SY, SY, -/* */ +/* À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï */ UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, -/* */ +/* Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß */ #ifdef vms UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, LC, #else UC, UC, UC, UC, UC, UC, UC, SY, UC, UC, UC, UC, UC, UC, UC, LC, #endif -/* */ +/* à á â ã ä å æ ç è é ê ë ì í î ï */ LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, -/* cannot write the last three because of lcc */ +/* ð ñ ò ó ô õ ö ÷ ø ù ú û ü cannot write the last three because of lcc */ #ifdef vms LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC #else @@ -234,7 +237,6 @@ float_send(char *s, int sign) { GET_LD Float f = (Float)(sign*atof(s)); - printf("buf=%s && f= %f\n", s, f); #if HAVE_ISFINITE if (truePrologFlag(PLFLAG_ISO)) { /* iso */ if (!isfinite(f)) { @@ -471,6 +473,7 @@ get_num(int *chp, int *chbuffp, IOSTREAM *inp_stream, char *s, UInt max_size, in int ch = *chp; Int val = 0L, base = ch - '0'; int might_be_float = TRUE, has_overflow = FALSE; + const unsigned char *decimalpoint; *sp++ = ch; ch = getchr(inp_stream); @@ -582,34 +585,50 @@ get_num(int *chp, int *chbuffp, IOSTREAM *inp_stream, char *s, UInt max_size, in ch = getchr(inp_stream); } if (might_be_float && ( ch == '.' || ch == 'e' || ch == 'E')) { - if (truePrologFlag(PLFLAG_ISO) && (ch == 'e' || ch == 'E')) { - return num_send_error_message("Float format not allowed in ISO mode"); - } - if (ch == '.') { - if (--max_size == 0) { - return num_send_error_message("Number Too Long"); - } - *sp++ = '.'; + int has_dot = ( ch == '.' ); + if (has_dot) { + unsigned char * dp; + int dc; + if (chtype(ch = getchr(inp_stream)) != NU) { - *chbuffp = '.'; - *chp = ch; - *--sp = '\0'; - if (has_overflow) - return read_int_overflow(s,base,val,sign); - if (sign == -1) - return MkIntegerTerm(-val); - return MkIntegerTerm(val); + if ( ch == 'e' || ch == 'E') { + if (truePrologFlag(PLFLAG_ISO)) + return num_send_error_message("Float format not allowed in ISO mode"); + } else {/* followed by a letter, end of term? */ + sp[0] = '\0'; + *chbuffp = '.'; + *chp = ch; + if (has_overflow) + return read_int_overflow(s,base,val,sign); + if (sign == -1) + return MkIntegerTerm(-val); + return MkIntegerTerm(val); + } } - do { +#if O_LOCALE + if ((decimalpoint = (unsigned char*) ( localeconv()->decimal_point )) == NULL) +#endif + decimalpoint = (const unsigned char*)"."; + dp =(unsigned char *)decimalpoint; + /* translate . to current locale */ + while ((dc = *dp++) != '\0') { + *sp++ = dc; if (--max_size == 0) { return num_send_error_message("Number Too Long"); } - *sp++ = ch; } - while (chtype(ch = getchr(inp_stream)) == NU); + /* numbers after . */ + if (chtype(ch) == NU) { + do { + if (--max_size == 0) { + return num_send_error_message("Number Too Long"); + } + *sp++ = ch; + } + while (chtype(ch = getchr(inp_stream)) == NU); + } } if (ch == 'e' || ch == 'E') { - char *sp0 = sp; char cbuff = ch; if (--max_size == 0) { @@ -629,15 +648,8 @@ get_num(int *chp, int *chbuffp, IOSTREAM *inp_stream, char *s, UInt max_size, in ch = getchr(inp_stream); } if (chtype(ch) != NU) { - /* error */ - char *sp; - *chp = ch; - *chbuffp = cbuff; - *sp0 = '\0'; - for (sp = s; sp < sp0; sp++) { - if (*sp == '.') - return float_send(s,sign); - } + if (has_dot) + return float_send(s,sign); return MkIntegerTerm(sign*val); } do { diff --git a/C/write.c b/C/write.c index 987609ed2..6575aa1a6 100644 --- a/C/write.c +++ b/C/write.c @@ -36,6 +36,9 @@ static char SccsId[] = "%W% %G%"; #if HAVE_CTYPE_H #include #endif +#if HAVE_LOCALE_H +#include +#endif /* describe the type of the previous term to have been written */ typedef enum { @@ -331,6 +334,15 @@ wrputf(Float f, struct write_globs *wglb) /* writes a float */ int found_dot = FALSE; char *pt = s; int ch; + /* always use C locale for writing numbers */ +#if O_LOCALE + const unsigned char *decimalpoint = (unsigned char*) + localeconv()->decimal_point; + size_t l1 = strlen(decimalpoint+1); +#else + const unsigned char *decimalpoint = "."; + l1 = 0; +#endif if (lastw == symbol || lastw == alphanum) { wrputc(' ', stream); @@ -345,24 +357,26 @@ wrputf(Float f, struct write_globs *wglb) /* writes a float */ pt++; } while ((ch = *pt) != '\0') { - switch (ch) { - case '.': + // skip locale + if (ch == decimalpoint[0] && !strncmp(pt+1, (char *)decimalpoint+1, l1)) { found_dot = TRUE; - wrputc('.', stream); - break; - case 'e': - case 'E': + pt += l1; + ch = '.'; + } + if (ch == 'e' || ch == 'E') { if (!found_dot) { found_dot = TRUE; - wrputs(".0", stream); + wrputs((char *)decimalpoint, stream); + wrputc('0', stream); } - default: - wrputc(ch, stream); + found_dot = TRUE; } + wrputc(ch, stream); pt++; } if (!found_dot) { - wrputs(".0", stream); + wrputs((char *)decimalpoint, stream); + wrputc('0', stream); } #else char *format_float(double f, char *buf);