diff --git a/configure b/configure index 5d69d4a8..3b3f4bcc 100755 --- a/configure +++ b/configure @@ -4721,7 +4721,9 @@ _ACEOF -for ac_header in sys/file.h glob.h + + +for ac_header in sys/file.h glob.h wctype.h locale.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then @@ -5221,7 +5223,9 @@ fi -for ac_func in setenv unsetenv glob + + +for ac_func in setenv unsetenv glob mbstowcs setlocale do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 diff --git a/configure.in b/configure.in index 806005bb..7ed5654a 100644 --- a/configure.in +++ b/configure.in @@ -61,7 +61,7 @@ AC_CHECK_SIZEOF(unsigned int) AC_CHECK_SIZEOF(unsigned long) dnl Checks for header files. -AC_CHECK_HEADERS(sys/file.h glob.h) +AC_CHECK_HEADERS(sys/file.h glob.h wctype.h locale.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_STRUCT_TM @@ -74,7 +74,7 @@ if test "$GCC" = yes; then CFLAGS="$CFLAGS -Wall -Wstrict-prototypes" fi -AC_CHECK_FUNCS(setenv unsetenv glob) +AC_CHECK_FUNCS(setenv unsetenv glob mbstowcs setlocale) VERSION=03.01.10 AC_SUBST(VERSION) AC_OUTPUT(src/Makefile www/Makefile src/version.h) diff --git a/src/calendar.c b/src/calendar.c index e678a090..ac7c1cb5 100644 --- a/src/calendar.c +++ b/src/calendar.c @@ -18,6 +18,10 @@ #include +#ifdef REM_USE_WCHAR +#include +#endif + #include "types.h" #include "protos.h" #include "expr.h" @@ -30,6 +34,10 @@ typedef struct cal_entry { struct cal_entry *next; char const *text; char const *pos; +#ifdef REM_USE_WCHAR + wchar_t const *wc_text; + wchar_t const *wc_pos; +#endif int is_color; int r, g, b; int time; @@ -137,6 +145,40 @@ static void WriteBottomCalLine (void); static void WriteIntermediateCalLine (void); static void WriteCalDays (void); +#ifdef REM_USE_WCHAR +static void PutWideChar(wchar_t const wc) +{ + char buf[MB_CUR_MAX+1]; + int len; + + len = wctomb(buf, wc); + if (len > 0) { + buf[len] = 0; + fputs(buf, stdout); + } +} +#endif + +static int make_wchar_versions(CalEntry *e) +{ +#ifdef REM_USE_WCHAR + size_t len; + wchar_t *buf; + len = mbstowcs(NULL, e->text, 0); + if (len == (size_t) -1) return 0; + + buf = calloc(len+1, sizeof(wchar_t)); + if (!buf) return 0; + + (void) mbstowcs(buf, e->text, len+1); + e->wc_text = buf; + e->wc_pos = buf; + return 1; +#else + return 1; +#endif +} + static void gon(void) { printf("%s", linestruct->graphics_on); @@ -519,74 +561,158 @@ static int WriteOneColLine(int col) CalEntry *e = CalColumn[col]; char const *s; char const *space; + +#ifdef REM_USE_WCHAR + wchar_t const *ws; + wchar_t const *wspace; +#endif + int numwritten = 0; -/* Print as many characters as possible within the column */ - space = NULL; - s = e->pos; + /* Print as many characters as possible within the column */ +#ifdef REM_USE_WCHAR + if (e->wc_text) { + wspace = NULL; + ws = e->wc_pos; -/* If we're at the end, and there's another entry, do a blank line and move - to next entry. */ - if (!*s && e->next) { - PrintLeft("", ColSpaces, ' '); - CalColumn[col] = e->next; - free((char *) e->text); - free((char *) e->filename); - free(e); - return 1; - } - -/* Find the last space char within the column. */ - while (s - e->pos <= ColSpaces) { - if (!*s) {space = s; break;} - if (*s == ' ') space = s; - s++; - } - -/* Colorize reminder if necessary */ - if (UseVTColors && e->is_color) { - Colorize(e); - } - -/* If we couldn't find a space char, print what we have. */ - if (!space) { - for (s = e->pos; s - e->pos < ColSpaces; s++) { - if (!*s) break; - numwritten++; - PutChar(*s); + /* If we're at the end, and there's another entry, do a blank + line and move to next entry. */ + if (!*ws && e->next) { + PrintLeft("", ColSpaces, ' '); + CalColumn[col] = e->next; + free((void *)e->text); + free((void *)e->filename); + if (e->wc_text) free((void *)e->wc_text); + free(e); + return 1; } - e->pos = s; - } else { -/* We found a space - print everything before it. */ - for (s = e->pos; swc_pos <= ColSpaces) { + if (!*ws) {wspace = ws; break;} + if (iswspace(*ws)) wspace = ws; + ws++; } - } -/* Decolorize reminder if necessary */ - if (UseVTColors && e->is_color) { - Decolorize(); - } + /* Colorize reminder if necessary */ + if (UseVTColors && e->is_color) { + Colorize(e); + } -/* Flesh out the rest of the column */ - while(numwritten++ < ColSpaces) PutChar(' '); + /* If we couldn't find a space char, print what we have. */ + if (!wspace) { + for (ws = e->wc_pos; ws - e->wc_pos < ColSpaces; ws++) { + if (!*ws) break; + numwritten++; + PutWideChar(*ws); + } + e->wc_pos = ws; + } else { + /* We found a space - print everything before it. */ + for (ws = e->wc_pos; wsis_color) { + Decolorize(); + } -/* If done, free memory if no next entry. */ - if (!*s && !e->next) { - CalColumn[col] = e->next; - free((char *) e->text); - free((char *) e->filename); - free(e); + /* Flesh out the rest of the column */ + while(numwritten++ < ColSpaces) PutChar(' '); + + /* Skip any spaces before next word */ + while (iswspace(*ws)) ws++; + + /* If done, free memory if no next entry. */ + if (!*ws && !e->next) { + CalColumn[col] = e->next; + free((void *)e->text); + free((void *)e->filename); + if (e->wc_text) free((void *)e->wc_text); + free(e); + } else { + e->wc_pos = ws; + } + if (CalColumn[col]) return 1; else return 0; } else { - e->pos = s; +#endif + space = NULL; + s = e->pos; + + /* If we're at the end, and there's another entry, do a blank + line and move to next entry. */ + if (!*s && e->next) { + PrintLeft("", ColSpaces, ' '); + CalColumn[col] = e->next; + free((void *)e->text); + free((void *)e->filename); +#ifdef REM_USE_WCHAR + if (e->wc_text) free((void *)e->wc_text); +#endif + free(e); + return 1; + } + + /* Find the last space char within the column. */ + while (s - e->pos <= ColSpaces) { + if (!*s) {space = s; break;} + if (*s == ' ') space = s; + s++; + } + + /* Colorize reminder if necessary */ + if (UseVTColors && e->is_color) { + Colorize(e); + } + + /* If we couldn't find a space char, print what we have. */ + if (!space) { + for (s = e->pos; s - e->pos < ColSpaces; s++) { + if (!*s) break; + numwritten++; + PutChar(*s); + } + e->pos = s; + } else { + /* We found a space - print everything before it. */ + for (s = e->pos; sis_color) { + Decolorize(); + } + + /* Flesh out the rest of the column */ + while(numwritten++ < ColSpaces) PutChar(' '); + + /* Skip any spaces before next word */ + while (*s == ' ') s++; + + /* If done, free memory if no next entry. */ + if (!*s && !e->next) { + CalColumn[col] = e->next; + free((void *)e->text); + free((void *)e->filename); +#ifdef REM_USE_WCHAR + if (e->wc_text) free((void *)e->wc_text); +#endif + free(e); + } else { + e->pos = s; + } + if (CalColumn[col]) return 1; else return 0; +#ifdef REM_USE_WCHAR } - if (CalColumn[col]) return 1; else return 0; +#endif } /***************************************************************/ @@ -929,15 +1055,19 @@ static int DoCalRem(ParsePtr p, int col) DBufPuts(&pre_buf, s); s = DBufValue(&pre_buf); e = NEW(CalEntry); - e->is_color = is_color; - e->r = col_r; - e->g = col_g; - e->b = col_b; if (!e) { DBufFree(&obuf); DBufFree(&pre_buf); return E_NO_MEM; } +#ifdef REM_USE_WCHAR + e->wc_pos = NULL; + e->wc_text = NULL; +#endif + e->is_color = is_color; + e->r = col_r; + e->g = col_g; + e->b = col_b; e->text = StrDup(s); DBufFree(&obuf); DBufFree(&pre_buf); @@ -945,6 +1075,7 @@ static int DoCalRem(ParsePtr p, int col) free(e); return E_NO_MEM; } + make_wchar_versions(e); StrnCpy(e->tag, trig.tag, TAG_LEN); if (!e->tag[0]) { if (SynthesizeTags) { @@ -1014,8 +1145,11 @@ static void WriteSimpleEntries(int col, int jul) printf("* "); } printf("%s\n", e->text); - free((char *) e->text); - free((char *) e->filename); + free((void *)e->text); + free((void *)e->filename); +#ifdef REM_USE_WCHAR + if (e->wc_text) free((void *)e->wc_text); +#endif n = e->next; free(e); e = n; diff --git a/src/config.h.in b/src/config.h.in index ac4f6319..5518ca8d 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -13,12 +13,20 @@ /* Define if you have the header file */ #undef HAVE_GLOB_H +#undef HAVE_WCTYPE_H + +#undef HAVE_LOCALE_H + #undef HAVE_GLOB #undef HAVE_SETENV #undef HAVE_UNSETENV +#undef HAVE_MBSTOWCS + +#undef HAVE_SETLOCALE + /* The number of bytes in a unsigned int. */ #undef SIZEOF_UNSIGNED_INT diff --git a/src/custom.h b/src/custom.h index 840aaf11..2090830c 100644 --- a/src/custom.h +++ b/src/custom.h @@ -221,3 +221,9 @@ #define Putc putc #define PutChar putchar #endif + +#if defined(HAVE_MBSTOWCS) && defined(HAVE_WCTYPE_H) +#define REM_USE_WCHAR 1 +#else +#undef REM_USE_WCHAR +#endif diff --git a/src/custom.h.in b/src/custom.h.in index 840aaf11..2090830c 100644 --- a/src/custom.h.in +++ b/src/custom.h.in @@ -221,3 +221,9 @@ #define Putc putc #define PutChar putchar #endif + +#if defined(HAVE_MBSTOWCS) && defined(HAVE_WCTYPE_H) +#define REM_USE_WCHAR 1 +#else +#undef REM_USE_WCHAR +#endif diff --git a/src/main.c b/src/main.c index f01f6679..356b2aa7 100644 --- a/src/main.c +++ b/src/main.c @@ -19,6 +19,9 @@ #include #include #include +#ifdef HAVE_LOCALE_H +#include +#endif #include #ifdef TIME_WITH_SYS_TIME @@ -57,6 +60,10 @@ int main(int argc, char *argv[]) { int pid; +#ifdef HAVE_SETLOCALE + setlocale(LC_ALL, ""); +#endif + /* The very first thing to do is to set up ErrFp to be stderr */ ErrFp = stderr;