[tex-k] [tlbuild] 2010 builds

Jukka Salmi j+tex-live at 2010.salmi.ch
Thu Jun 10 13:55:45 CEST 2010


Karl Berry --> tlbuild (2010-06-10 00:34:13 +0000):
> Working on netbsd 5.0.2, I observe that the problem is definitely
> isspace().  I put in printf's that showed that the \264 char was getting
> "normalized" to a space by the conditional around line 848 in
> FindErrs.c.
> 
> A tiny test program shows that isspace('\264') indeed returns true
> (specifically, it returns 8), independent of LC_ALL=C or any other
> setting I could think of.
> 
> NetBSD is probably standards-compliant in doing this (not that it really
> matters -- it does what it does), since POSIX
> (http://www.opengroup.org/onlinepubs/9699919799/functions/isspace.html)
> has made it explicitly locale-dependent, hence must be considered
> backward-incompatible for any traditional use.
> 
> Therefore, the only solution is to define our own isspace that
> actually does something consistent across platforms.
> 
> I added this code to ChkTeX.h before the #define LOOP (it could go anywhere):
> 
> #undef c_isspace
> #define c_isspace(c) \
>   ({ int __c = (c); \
>      (__c == ' ' || __c == '\t' \
>       || __c == '\n' || __c == '\v' || __c == '\f' || __c == '\r'); \
>    })
> #undef isspace
> #define isspace c_isspace
> 
> And with that, make check passed for me on netbsd.
> 
> Jukka, can you confirm?

Yes, your change makes the check-TESTS target succeed, but I don't think
it's the correct fix.

IIUC calling isspace('\264') leads to undefined behaviour (returns 8
here as well) because '\264' is interpreted as a signed int (i.e. -76).
POSIX states:

    The c argument is an int, the value of which the application shall
    ensure is a character representable as an unsigned char or equal to
    the value of the macro EOF. If the argument has any other value, the
    behavior is undefined.

Thus the arguments of those ctype functions need to be casted to
unsigned char, e.g. isspace((unsigned char)'\264').  I've done this for
utils/chktex/chktex-1.6.4/*.c (patch attached) and now the problem seems
to be fixed.


Regards, Jukka

-- 
This email fills a much-needed gap in the archives.
-------------- next part --------------
Index: utils/chktex/chktex-1.6.4/Utility.c
===================================================================
--- utils/chktex/chktex-1.6.4/Utility.c	(revision 18843)
+++ utils/chktex/chktex-1.6.4/Utility.c	(working copy)
@@ -231,7 +231,7 @@
     char TmpC;
 
     for (Bufptr = String; (TmpC = *Bufptr); Bufptr++)
-        *Bufptr = tolower(TmpC);
+        *Bufptr = tolower((unsigned char)TmpC);
 
     return (String);
 }
@@ -291,10 +291,10 @@
         aa = *a++;
         bb = *b++;
     }
-    while (aa && (tolower(aa) == tolower(bb)));
+    while (aa && (tolower((unsigned char)aa) == tolower((unsigned char)bb)));
     /* bb != 0 is implicit */
 
-    return (tolower(aa) - tolower(bb));
+    return (tolower((unsigned char)aa) - tolower((unsigned char)bb));
 }
 #endif
 
Index: utils/chktex/chktex-1.6.4/FindErrs.c
===================================================================
--- utils/chktex/chktex-1.6.4/FindErrs.c	(revision 18843)
+++ utils/chktex/chktex-1.6.4/FindErrs.c	(working copy)
@@ -42,7 +42,7 @@
     ERRMSGS {emMaxFault, etErr, iuOK, 0, INTERNFAULT}
 };
 
-#define istex(c)        (isalpha(c) || (AtLetter && (c == '@')))
+#define istex(c)        (isalpha((unsigned char)c) || (AtLetter && (c == '@')))
 #define CTYPE(func) \
 static int my_##func(int c) \
 { \
@@ -517,7 +517,7 @@
             PSERR(CmdPtr - Buf, CmdLen, emNoArgFound);
     }
 
-    if (HasWord(CmdBuffer, &NotPreSpaced) && isspace(CmdPtr[-1]))
+    if (HasWord(CmdBuffer, &NotPreSpaced) && isspace((unsigned char)CmdPtr[-1]))
         PSERRA(CmdPtr - Buf - 1, 1, emRemPSSpace, CmdBuffer);
 
     if ((TmpPtr = HasWord(CmdBuffer, &NoCharNext)))
@@ -622,7 +622,7 @@
         for (i = Abbrev.MaxLen; i >= 0; i--)
         {
             *--TmpPtr = *AbbPtr--;
-            if (!isalpha(*AbbPtr) && HasWord(TmpPtr, &Abbrev))
+            if (!isalpha((unsigned char)*AbbPtr) && HasWord(TmpPtr, &Abbrev))
                 PSERR(Buffer - Buf + 1, 1, emInterWord);
             if (!*AbbPtr)
                 break;
@@ -702,9 +702,9 @@
     {
         if (LATEX_SPACE(*PrePtr) && LATEX_SPACE(*TmpPtr))
             wl = &WordDash;
-        if (isdigit(*PrePtr) && isdigit(*TmpPtr))
+        if (isdigit((unsigned char)*PrePtr) && isdigit((unsigned char)*TmpPtr))
             wl = &NumDash;
-        if (isalpha(*PrePtr) && isalpha(*TmpPtr))
+        if (isalpha((unsigned char)*PrePtr) && isalpha((unsigned char)*TmpPtr))
             wl = &HyphDash;
 
         if (wl)
@@ -845,16 +845,16 @@
         {
             PrePtr = BufPtr - 1;
             Char = *BufPtr++;
-            if (isspace(Char))
+            if (isspace((unsigned char)Char))
                 Char = ' ';
 
             switch (Char)
             {
             case '~':
                 TmpPtr = NULL;
-                if (isspace(*PrePtr))
+                if (isspace((unsigned char)*PrePtr))
                     TmpPtr = PrePtr;
-                else if (isspace(*BufPtr))
+                else if (isspace((unsigned char)*BufPtr))
                     TmpPtr = BufPtr;
 
                 if (TmpPtr)
@@ -868,14 +868,14 @@
                 SKIP_BACK(TmpPtr, TmpC,
                           (LATEX_SPACE(TmpC) || strchr("{}$", TmpC)));
 
-                if (isdigit(*TmpPtr))
+                if (isdigit((unsigned char)*TmpPtr))
                 {
                     TmpPtr = BufPtr;
 
                     SKIP_AHEAD(TmpPtr, TmpC,
                                (LATEX_SPACE(TmpC) || strchr("{}$", TmpC)));
 
-                    if (isdigit(*TmpPtr))
+                    if (isdigit((unsigned char)*TmpPtr))
                         HERE(1, emUseTimes);
                 }
                 /* FALLTHRU */
@@ -931,7 +931,7 @@
             case 'W':          /* case 'X': */
             case 'Y':
             case 'Z':
-                if (!isalpha(*PrePtr) && (*PrePtr != '\\') && MathMode)
+                if (!isalpha((unsigned char)*PrePtr) && (*PrePtr != '\\') && MathMode)
                 {
                     TmpPtr = BufPtr;
                     CmdPtr = CmdBuffer;
@@ -940,7 +940,7 @@
                         *CmdPtr++ = Char;
                         Char = *TmpPtr++;
                     }
-                    while (isalpha(Char));
+                    while (isalpha((unsigned char)Char));
 
                     *CmdPtr = 0;
 
@@ -978,11 +978,11 @@
                 SKIP_AHEAD(TmpPtr, TmpC, strchr(LTX_GenPunc, TmpC));
                 if (LATEX_SPACE(*TmpPtr))
                 {
-                    if (!isupper(*PrePtr) && (*PrePtr != '@') &&
+                    if (!isupper((unsigned char)*PrePtr) && (*PrePtr != '@') &&
                         (*PrePtr != '.'))
                     {
                         SKIP_AHEAD(TmpPtr, TmpC, LATEX_SPACE(TmpC));
-                        if (islower(*TmpPtr))
+                        if (islower((unsigned char)*TmpPtr))
                             PSERR(BufPtr - Buf, 1, emInterWord);
                         else
                             CheckAbbrevs(&BufPtr[-1]);
@@ -996,14 +996,14 @@
             case ';':
                 /* Regexp: "[A-Z][A-Z][.!?:;]\s+" */
 
-                if (isspace(*BufPtr) && isupper(*PrePtr) &&
-                    (isupper(PrePtr[-1]) || (Char != '.')))
+                if (isspace((unsigned char)*BufPtr) && isupper((unsigned char)*PrePtr) &&
+                    (isupper((unsigned char)PrePtr[-1]) || (Char != '.')))
                     HERE(1, emInterSent);
 
                 /* FALLTHRU */
             case ',':
-                if (isspace(*PrePtr) &&
-                    !(isdigit(*BufPtr) &&
+                if (isspace((unsigned char)*PrePtr) &&
+                    !(isdigit((unsigned char)*BufPtr) &&
                       ((BufPtr[-1] == '.') || (BufPtr[-1] == ','))))
                     PSERR(PrePtr - Buf, 1, emSpacePunct);
 
@@ -1050,8 +1050,8 @@
                 switch (Char)
                 {
                 case '\'':
-                    if (isalpha(*TmpPtr) &&
-                        (strchr(LTX_GenPunc, *PrePtr) || isspace(*PrePtr)))
+                    if (isalpha((unsigned char)*TmpPtr) &&
+                        (strchr(LTX_GenPunc, *PrePtr) || isspace((unsigned char)*PrePtr)))
                         HERE(TmpPtr - BufPtr + 1, emBeginQ);
 
                     /* Now check quote style */
@@ -1061,7 +1061,7 @@
 
                     {
                         char *WordPtr = PrePtr;
-                        SKIP_BACK(WordPtr, TmpC, (isalnum(TmpC) ||
+                        SKIP_BACK(WordPtr, TmpC, (isalnum((unsigned char)TmpC) ||
                                                   strchr(LTX_GenPunc, TmpC)));
 
                         if (*WordPtr != '`')
@@ -1080,8 +1080,8 @@
 
                     break;
                 case '`':
-                    if (isalpha(*PrePtr) &&
-                        (strchr(LTX_GenPunc, *TmpPtr) || isspace(*TmpPtr)))
+                    if (isalpha((unsigned char)*PrePtr) &&
+                        (strchr(LTX_GenPunc, *TmpPtr) || isspace((unsigned char)*TmpPtr)))
                         HERE(TmpPtr - BufPtr + 1, emEndQ);
                     break;
                 }
@@ -1129,9 +1129,9 @@
 
                     ErrPtr = TmpPtr;
 
-                    if (isalpha(*TmpPtr))
+                    if (isalpha((unsigned char)*TmpPtr))
                         pstcb = &my_isalpha;
-                    else if (isdigit(*TmpPtr))
+                    else if (isdigit((unsigned char)*TmpPtr))
                         pstcb = &my_isdigit;
                     else
                         break;
@@ -1164,7 +1164,7 @@
                 {
                     PSERR(BufPtr - Buf, 1, emSpaceTerm);
                 }
-                else if ((*BufPtr == '\\') && (!isalpha(BufPtr[1])) &&
+                else if ((*BufPtr == '\\') && (!isalpha((unsigned char)BufPtr[1])) &&
                          (!LATEX_SPACE(BufPtr[1])))
                     PSERR(BufPtr - Buf, 2, emNotIntended);
 
@@ -1174,7 +1174,7 @@
                 break;
 
             case '(':
-                if (!(!*PrePtr || LATEX_SPACE(*PrePtr) || isdigit(*PrePtr)) ||
+                if (!(!*PrePtr || LATEX_SPACE(*PrePtr) || isdigit((unsigned char)*PrePtr)) ||
                     strchr("([{`~", *PrePtr))
                 {
                     if (PrePtr[-1] != '\\')     /* Short cmds */
@@ -1186,16 +1186,16 @@
                                    "in front of");
                     }
                 }
-                if (isspace(*BufPtr))
+                if (isspace((unsigned char)*BufPtr))
                     PSERRA(BufPtr - Buf, 1, emNoSpaceParen, "after");
                 HandleBracket(Char);
                 break;
 
             case ')':
-                if (isspace(*PrePtr))
+                if (isspace((unsigned char)*PrePtr))
                     PSERRA(BufPtr - Buf - 1, 1, emNoSpaceParen,
                            "in front of");
-                if (isalpha(*BufPtr))
+                if (isalpha((unsigned char)*BufPtr))
                     PSERRA(BufPtr - Buf, 1, emSpaceParen, "after");
                 HandleBracket(Char);
                 break;
Index: utils/chktex/chktex-1.6.4/ChkTeX.c
===================================================================
--- utils/chktex/chktex-1.6.4/ChkTeX.c	(revision 18843)
+++ utils/chktex/chktex-1.6.4/ChkTeX.c	(working copy)
@@ -243,11 +243,11 @@
 
     FORWL(i, AbbrevCase)
     {
-        if (isalpha(ThisItem[0]))
+        if (isalpha((unsigned char)ThisItem[0]))
         {
-            ThisItem[0] = toupper(ThisItem[0]);
+            ThisItem[0] = toupper((unsigned char)ThisItem[0]);
             InsertWord(ThisItem, &Abbrev);
-            ThisItem[0] = tolower(ThisItem[0]);
+            ThisItem[0] = tolower((unsigned char)ThisItem[0]);
         }
         InsertWord(ThisItem, &Abbrev);
     }
@@ -401,7 +401,7 @@
             NOCOMMON(Italic, ItalCmd);
             NOCOMMON(LowDots, CenterDots);
 
-            if (TabSize && isdigit(*TabSize))
+            if (TabSize && isdigit((unsigned char)*TabSize))
                 Tab = strtol(TabSize, NULL, 10);
 
             if (OpenOut())
@@ -691,7 +691,7 @@
                        long Default,    /* Value to put in if no in argue */
                        char **Argument) /* optarg or similar */
 {
-    if (Argument && *Argument && isdigit(**Argument))
+    if (Argument && *Argument && isdigit((unsigned char)**Argument))
         *Dest = strtol(*Argument, Argument, 10);
     else
         *Dest = Default;
@@ -838,7 +838,7 @@
             ErrType = etWarn; InUse = iuOK; LAST(warntype); case 'e':
             ErrType = etErr; InUse = iuOK; LAST(warntype); case 'm':
             ErrType = etMsg; InUse = iuOK; LAST(warntype); case 'n':
-            ErrType = etMsg; InUse = iuNotUser; LAST(warntype);) if (isdigit(*optarg))
+            ErrType = etMsg; InUse = iuNotUser; LAST(warntype);) if (isdigit((unsigned char)*optarg))
                 {
                     nextc = ParseNumArg(&Err, -1, &optarg);
                     if (betw(emMinFault, Err, emMaxFault))
Index: utils/chktex/chktex-1.6.4/Resource.c
===================================================================
--- utils/chktex/chktex-1.6.4/Resource.c	(revision 18843)
+++ utils/chktex/chktex-1.6.4/Resource.c	(working copy)
@@ -348,7 +348,7 @@
                         while (Cont)
                         {
                             Chr = *String++;
-                            if (isalpha(Chr))
+                            if (isalpha((unsigned char)Chr))
                                 *Ptr++ = Chr;
                             else
                                 Cont = FALSE;
@@ -374,7 +374,7 @@
                                 *Ptr++ = Chr;
                                 break;
                             default:
-                                if (!isspace(Chr))
+                                if (!isspace((unsigned char)Chr))
                                     *Ptr++ = Chr;
                                 else
                                     Cont = FALSE;
@@ -417,7 +417,7 @@
 
     Chr = *((char *) (*String)++);
 
-    switch (tolower(Chr))
+    switch (tolower((unsigned char)Chr))
     {
         MAP(QUOTE, QUOTE);
         MAP(ESCAPE, ESCAPE);
@@ -439,12 +439,12 @@
         for (Cnt = 0; Cnt < 2; Cnt++)
         {
             Chr = *((*String)++);
-            if (isxdigit(Chr))
+            if (isxdigit((unsigned char)Chr))
             {
-                Chr = toupper(Chr);
+                Chr = toupper((unsigned char)Chr);
                 Tmp = (Tmp << 4) + Chr;
 
-                if (isdigit(Chr))
+                if (isdigit((unsigned char)Chr))
                     Tmp -= '0';
                 else
                     Tmp -= 'A' - 10;
@@ -490,7 +490,7 @@
     case 'd':
         for (Cnt = 0; Cnt < 3; Cnt++)
         {
-            if (isdigit(Chr = *((*String)++)))
+            if (isdigit((unsigned char)(Chr = *((*String)++))))
                 Tmp = (Tmp * 10) + Chr - '0';
             else
             {


More information about the tex-k mailing list