improve locale support in scanner and write: basically, just hide current locale
This commit is contained in:
parent
5013880fc5
commit
d447d80fdb
86
C/scanner.c
86
C/scanner.c
@ -54,6 +54,9 @@
|
|||||||
#if HAVE_WCTYPE_H
|
#if HAVE_WCTYPE_H
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if O_LOCALE
|
||||||
|
#include "locale.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* You just can't trust some machines */
|
/* You just can't trust some machines */
|
||||||
#define my_isxdigit(C,SU,SL) (chtype(C) == NU || (C >= 'A' && \
|
#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 */
|
/* 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,
|
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, 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,
|
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,
|
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,
|
UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC,
|
||||||
|
|
||||||
/* Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß */
|
/* Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß */
|
||||||
#ifdef vms
|
#ifdef vms
|
||||||
UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, LC,
|
UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, LC,
|
||||||
#else
|
#else
|
||||||
UC, UC, UC, UC, UC, UC, UC, SY, UC, UC, UC, UC, UC, UC, UC, LC,
|
UC, UC, UC, UC, UC, UC, UC, SY, UC, UC, UC, UC, UC, UC, UC, LC,
|
||||||
#endif
|
#endif
|
||||||
/* à á â ã ä å æ ç è é ê ë ì í î ï */
|
/* à á â ã ä å æ ç è é ê ë ì í î ï */
|
||||||
LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC,
|
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
|
#ifdef vms
|
||||||
LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC
|
LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC
|
||||||
#else
|
#else
|
||||||
@ -234,7 +237,6 @@ float_send(char *s, int sign)
|
|||||||
{
|
{
|
||||||
GET_LD
|
GET_LD
|
||||||
Float f = (Float)(sign*atof(s));
|
Float f = (Float)(sign*atof(s));
|
||||||
printf("buf=%s && f= %f\n", s, f);
|
|
||||||
#if HAVE_ISFINITE
|
#if HAVE_ISFINITE
|
||||||
if (truePrologFlag(PLFLAG_ISO)) { /* iso */
|
if (truePrologFlag(PLFLAG_ISO)) { /* iso */
|
||||||
if (!isfinite(f)) {
|
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 ch = *chp;
|
||||||
Int val = 0L, base = ch - '0';
|
Int val = 0L, base = ch - '0';
|
||||||
int might_be_float = TRUE, has_overflow = FALSE;
|
int might_be_float = TRUE, has_overflow = FALSE;
|
||||||
|
const unsigned char *decimalpoint;
|
||||||
|
|
||||||
*sp++ = ch;
|
*sp++ = ch;
|
||||||
ch = getchr(inp_stream);
|
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);
|
ch = getchr(inp_stream);
|
||||||
}
|
}
|
||||||
if (might_be_float && ( ch == '.' || ch == 'e' || ch == 'E')) {
|
if (might_be_float && ( ch == '.' || ch == 'e' || ch == 'E')) {
|
||||||
if (truePrologFlag(PLFLAG_ISO) && (ch == 'e' || ch == 'E')) {
|
int has_dot = ( ch == '.' );
|
||||||
return num_send_error_message("Float format not allowed in ISO mode");
|
if (has_dot) {
|
||||||
}
|
unsigned char * dp;
|
||||||
if (ch == '.') {
|
int dc;
|
||||||
if (--max_size == 0) {
|
|
||||||
return num_send_error_message("Number Too Long");
|
|
||||||
}
|
|
||||||
*sp++ = '.';
|
|
||||||
if (chtype(ch = getchr(inp_stream)) != NU) {
|
if (chtype(ch = getchr(inp_stream)) != NU) {
|
||||||
*chbuffp = '.';
|
if ( ch == 'e' || ch == 'E') {
|
||||||
*chp = ch;
|
if (truePrologFlag(PLFLAG_ISO))
|
||||||
*--sp = '\0';
|
return num_send_error_message("Float format not allowed in ISO mode");
|
||||||
if (has_overflow)
|
} else {/* followed by a letter, end of term? */
|
||||||
return read_int_overflow(s,base,val,sign);
|
sp[0] = '\0';
|
||||||
if (sign == -1)
|
*chbuffp = '.';
|
||||||
return MkIntegerTerm(-val);
|
*chp = ch;
|
||||||
return MkIntegerTerm(val);
|
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) {
|
if (--max_size == 0) {
|
||||||
return num_send_error_message("Number Too Long");
|
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') {
|
if (ch == 'e' || ch == 'E') {
|
||||||
char *sp0 = sp;
|
|
||||||
char cbuff = ch;
|
char cbuff = ch;
|
||||||
|
|
||||||
if (--max_size == 0) {
|
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);
|
ch = getchr(inp_stream);
|
||||||
}
|
}
|
||||||
if (chtype(ch) != NU) {
|
if (chtype(ch) != NU) {
|
||||||
/* error */
|
if (has_dot)
|
||||||
char *sp;
|
return float_send(s,sign);
|
||||||
*chp = ch;
|
|
||||||
*chbuffp = cbuff;
|
|
||||||
*sp0 = '\0';
|
|
||||||
for (sp = s; sp < sp0; sp++) {
|
|
||||||
if (*sp == '.')
|
|
||||||
return float_send(s,sign);
|
|
||||||
}
|
|
||||||
return MkIntegerTerm(sign*val);
|
return MkIntegerTerm(sign*val);
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
34
C/write.c
34
C/write.c
@ -36,6 +36,9 @@ static char SccsId[] = "%W% %G%";
|
|||||||
#if HAVE_CTYPE_H
|
#if HAVE_CTYPE_H
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if HAVE_LOCALE_H
|
||||||
|
#include <locale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* describe the type of the previous term to have been written */
|
/* describe the type of the previous term to have been written */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -331,6 +334,15 @@ wrputf(Float f, struct write_globs *wglb) /* writes a float */
|
|||||||
int found_dot = FALSE;
|
int found_dot = FALSE;
|
||||||
char *pt = s;
|
char *pt = s;
|
||||||
int ch;
|
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) {
|
if (lastw == symbol || lastw == alphanum) {
|
||||||
wrputc(' ', stream);
|
wrputc(' ', stream);
|
||||||
@ -345,24 +357,26 @@ wrputf(Float f, struct write_globs *wglb) /* writes a float */
|
|||||||
pt++;
|
pt++;
|
||||||
}
|
}
|
||||||
while ((ch = *pt) != '\0') {
|
while ((ch = *pt) != '\0') {
|
||||||
switch (ch) {
|
// skip locale
|
||||||
case '.':
|
if (ch == decimalpoint[0] && !strncmp(pt+1, (char *)decimalpoint+1, l1)) {
|
||||||
found_dot = TRUE;
|
found_dot = TRUE;
|
||||||
wrputc('.', stream);
|
pt += l1;
|
||||||
break;
|
ch = '.';
|
||||||
case 'e':
|
}
|
||||||
case 'E':
|
if (ch == 'e' || ch == 'E') {
|
||||||
if (!found_dot) {
|
if (!found_dot) {
|
||||||
found_dot = TRUE;
|
found_dot = TRUE;
|
||||||
wrputs(".0", stream);
|
wrputs((char *)decimalpoint, stream);
|
||||||
|
wrputc('0', stream);
|
||||||
}
|
}
|
||||||
default:
|
found_dot = TRUE;
|
||||||
wrputc(ch, stream);
|
|
||||||
}
|
}
|
||||||
|
wrputc(ch, stream);
|
||||||
pt++;
|
pt++;
|
||||||
}
|
}
|
||||||
if (!found_dot) {
|
if (!found_dot) {
|
||||||
wrputs(".0", stream);
|
wrputs((char *)decimalpoint, stream);
|
||||||
|
wrputc('0', stream);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
char *format_float(double f, char *buf);
|
char *format_float(double f, char *buf);
|
||||||
|
Reference in New Issue
Block a user