[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::decc

Title:DECC
Notice:General DEC C discussions
Moderator:TLE::D_SMITHNTE
Created:Fri Nov 13 1992
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:2212
Total number of notes:11045

2174.0. "0xDF becomes 0X00000000000000DF. A bug?" by JOBIM::VUJNOVIC (I�t�r��t���l�z�t��L���l�z�t��) Fri May 02 1997 12:50

I'm trying to compile the following module (after the <FF>) with the command 
(which has worked for years):

        $ cc/stand=vaxc search.c

I'm running DEC C V5.6-003 on OpenVMS Alpha V6.2-1H2 and keep getting these
errors:


                ch = upcase(ch);
................^
%CC-W-UNDEFVARMOD, In this statement, the expression 
"ch=((!MOST_C_OPT&&(ch<='z')&&(ch>='a'))?ch&=0X00000000000000DF:ch)" modifies .
at line number 60 in file A:[L.C.CSWING.SOURCE]SEARCH.C;2

          while (ch = *beg, ch = upcase(ch), ch != char1)
.................^
%CC-W-UNDEFVARMOD, In this statement, the expression 
"ch=*beg,ch=((!MOST_C_OPT&&(ch<='z')&&(ch>='a'))?ch&=0X00000000000000DF:ch)" m.
at line number 77 in file A:[L.C.CSWING.SOURCE]SEARCH.C;2

                while(ch = *beg++, ch = upcase(ch), ch2 = work[j++],
......................^
%CC-W-UNDEFVARMOD, In this statement, the expression 
"ch=*beg++,ch=((!MOST_C_OPT&&(ch<='z')&&(ch>='a'))?ch&=0X00000000000000DF:ch)".
at line number 169 in file A:[L.C.CSWING.SOURCE]SEARCH.C;2
...

Something seems to be wrong with this macro:

#define upcase(ch) ((!MOST_C_OPT && (ch<='z') && (ch>='a')) ? ch &= 0xDF : ch)

Any ideas?

Regards,
Slobodan



/******************************************************************************
**      MOST for C Swing and Gopher - A file viewer                          **
*******************************************************************************
**      Original C coding by: John E. Davis                                  **
**      Modifications primarily by Foteos Macrides                           **
**      Copyright 1991, John E. Davis                                        **
**      Terms of Copyright: See MAIN.C                                       **
**      Disclaimer: No warranties as to the use or reliability of this       **
**          software are given by the authors or distributors.  Use at       **
**          your own risk.                                                   **
******************************************************************************/
/*
 *  MOST:  SEARCH.C
 *  Modified for C SWING and GOPHER compatibility by Foteos Macrides
*/

#include "most.h"
#include "externs.h"
#include "buffer.h"
#include "line.h"

#define upcase(ch) ((!MOST_C_OPT && (ch<='z') && (ch>='a')) ? ch &= 0xDF : ch)

int S_DIFF = 0;

/*
**  This routine returns the 1 + position of first match of key in str.
**  Key is modified to match the case of str.
**  We should try to optimize this routine.
**  Searches from beg up to but not including end.
**  If tabs (^I) or formatting characters or strings (^H, ^M, <ESC>[#m) are
**    in the original text, they are handled such that hits will occur for
**    matches as the search string appears on the screen, i.e, the search
**    string should be entered with spaces instead of tabs and without the
**    formatting characters when not in Binary or Verbose mode (plus -t or
**    :Ot set for tabs).
*/
unsigned char *forw_search_region(unsigned char *beg,unsigned char *end,
                                  unsigned char *key)
{
    char ch,ch2,char1,work[136];
    unsigned char *pos,*save_pos,*b,*e,*i;
    int key_len,j,s,str_len,tab_flag;
    static unsigned char *s_pos1;
    static unsigned char *s_pos2;
    extern int M_FLAG;
    extern char *M_POS;

    if (MOST_C_OPT)
      {
          strcpy(work,key);
          key_len = strlen(key);
      }
    else
      {
          /* upcase key */
          key_len = 0;
          while (ch = key[key_len],ch != '\0')
            {
                ch = upcase(ch);
                work[key_len++] = ch;        /* null char is ok */
            }
      }
    
    str_len = (int) (end - beg);
    if (str_len < key_len) return (EOB);
    str_len = str_len - key_len; /* effective length */
    end -= key_len;
          
    char1 = work[0];
    
    while(1)
      {
again:
          tab_flag = 0;
          S_DIFF = 0;
          while (ch = *beg, ch = upcase(ch), ch != char1)
            {
                if (beg > end) return(EOB);
                if (!MOST_B_OPT)
                  {
                      if((!MOST_V_OPT || !MOST_T_OPT) &&
                         char1 == ' ' && ch == '\t')
                        {
                            tab_flag = 1;
                            break;
                        }
                  }
                beg++;
            }
          beg++;

          /*
          **  We have a position of possible match.
          **  If not Binary mode,
          **    skip if not Verbose mode and it's in an <ESC>[#m
          **    sequence, or a ^M overstrike string.
          */
          if (!MOST_B_OPT)
            {
                if (!MOST_V_OPT)
                  {
                      if ((char1 == '[' &&
                           (*(beg - 2) == '\033' && *(beg + 1) == 'm' &&
                            (*beg == '0' || *beg == '1' ||
                             *beg == '4' || *beg == '7'))) ||
                          (char1 == 'm' &&
                           (*(beg - 4) == '\033' && *(beg - 3) == '[' &&
                            (*(beg - 2) == '0' || *(beg - 2) == '1' ||
                             *(beg - 2) == '4' || *(beg - 2) == '7'))) ||
                          ((char1 == '0' || char1 == '1' ||
                            char1 == '4' || char1 == '7') &&
                           (*(beg - 3) == '\033' && *(beg - 2) == '[' &&
                            *beg == 'm')))
                        goto again;
                      else if ((char1 == '[' &&
                                *(beg - 2) == '\033' && *(beg) == 'm') ||
                               (char1 == 'm' &&
                                *(beg - 3) == '\033' && *(beg - 2) == '['))
                        goto again;
                      else
                        {
                            save_pos = C_POS;
                            C_POS = beg - 1;
                            b = beg_of_line1();
                            if (!MOST_W_OPT)
                              {
                                  e = end_of_line1();
                                  for (i = b; i <= e; i++)
                                    if (*i == '\015')
                                      {
                                          M_FLAG = 1;
                                          M_POS = i;
                                      }
                              }
                            else
                              e = end_of_line();
                            if (M_FLAG && C_POS > M_POS)
                              {
                                  C_POS = save_pos;
                                  M_FLAG = 0;
                                  goto again;
                              }
                            C_POS = save_pos;
                            M_FLAG = 0;
                        }
                  }
            }
            
          /*
          **  Now see if the rest of the string matches.
          **  If not Binary mode,
          **    deal with any embedded backspaces (^H)
          **    or <ESC>[#m sequences if not Verbose mode,
          **    and with tabs if not Verbose or explicit Tab modes.
          */
          pos = beg;  /* save this position so we start from here again */

          if (!MOST_B_OPT && tab_flag)
            {
                beg--;
                j = 0;
            }
          else
            j = 1;

          if (MOST_B_OPT)
            {
                while(ch = *beg++, ch = upcase(ch), ch2 = work[j++],
                      (ch == ch2 && j <= key_len)) ;
            }
          else
            {
                while(ch = *beg++, ch = upcase(ch), ch2 = work[j++],
                      ((ch == ch2) ||
                       (!MOST_V_OPT && (ch == '_' || ch == '\033')) ||
                       ((!MOST_V_OPT || !MOST_T_OPT) &&
                        ch == '\t' && ch2 == ' ') &&
                       (j <= key_len)))
                  {
                      /*
                      **  deal with underlining via ^H if not Verbose mode
                      */
                      if (ch2 != '_' && ch == '_')
                        {
			    if (*beg == '\b')
			      {
                                  ch = *(beg + 1);
                                  ch = upcase(ch);
                                  if (ch == ch2)
                                    beg += 2;
                                  else break;
			      }
			    else break;
                        }
                      
                      /*
                      **  deal with bolding via ^H if not Verbose mode
                      */
                      else if (!MOST_B_OPT && !MOST_V_OPT && *beg == '\b')
                        beg += 2;
                      
                      /*
                      **  deal with <ESC>[#m if not Verbose mode
                      */
                      else if (!MOST_B_OPT && !MOST_V_OPT && ch == '\033' &&
                               *beg == '[' && *(beg + 2) == 'm' &&
                               (*(beg + 1) == '0' || *(beg + 1) == '1' ||
                                *(beg + 1) == '4' || *(beg + 1) == '7'))
                        {
                            ch = *(beg + 3);
                            ch = upcase(ch);
                            if (ch != ch2) break;
                            else beg += 4;
                        }
                      else if (!MOST_B_OPT && !MOST_V_OPT && ch == '\033' &&
                               *beg == '[' && *(beg + 1) == 'm')
                        {
                            ch = *(beg + 2);
                            ch = upcase(ch);
                            if (ch != ch2) break;
                            else beg += 3;
                        }
                        
                      /*
                      **  deal with tabs if not Verbose or explicit Tab modes
                      */
                      else if (ch == '\t' && ch2 == ' ')
                        {
                            j--;
                            save_pos = beg - 1;
                            if (tab_flag && beg == pos &&
                                (*(beg - 2) == '\t' || *(beg - 2) == ' '))
                              break;
                            while (*beg == '\t' || *beg == ' ')
                              beg++;
                            if (save_pos == beg_of_line1())
                              s = apparant_distance(beg) - 1;
                            else if (MOST_W_OPT)
                              {
                                  MOST_W_OPT = 0;
                                  s = apparant_distance(beg) -
                                      apparant_distance(save_pos);
                                  MOST_W_OPT = 1;
                              }
                            else
                              s = apparant_distance(beg) -
                                  apparant_distance(save_pos);
                            while (s && work[j] == ' ' && j < key_len)
                              {
                                  j++;
                                  s--;
                              }
                            if (tab_flag &&
                                save_pos == pos - 1 && *beg == work[j])
                                  S_DIFF = s;
                            else if (!tab_flag && s != 0 && j < key_len)
                              {
                                  j = key_len;
                                  break;
                              }
                        }
                  }
            }
            
          /*
          **  if it's a full match
          */
          if (j > key_len)
            {
                /*
                **  make key match 'key' in beg
                */
                beg = pos - 1;  /* skip back to beginning of match */
                for (j = 0; j < key_len; j++)
                  {
                      if (MOST_B_OPT)
                        {
                            key[j] = *beg++;
                        }
                      else
                        {
                            /*
                            **  deal with overstriking via ^H if not Verbose
                            */
                            if (!MOST_V_OPT && *(beg + 1) == '\b')
                              beg += 2;
                            
                            /*
                            **  now deal with tabs if not Verbose or
                            **    explicit Tab modes,
                            **  else just get the character
                            */
                            if ((!MOST_V_OPT || !MOST_T_OPT) &&
                                *beg == '\t' && work[j] == ' ')
                              {
                                  while (*beg == '\t' || *beg == ' ') beg++;
                                  while (key[j] == ' ') j++;
                                  j--;
                              }
                            else
                              key[j] = *beg++;
			      
                              
                            /*
                            **  now deal with <ESC>[#m if not Verbose
                            */
                            if (!MOST_V_OPT && *(beg) == '\033' &&
                                *(beg + 1) == '[' && *(beg + 3) == 'm' &&
                                (*(beg + 2) == '0' || *(beg + 2) == '1' ||
                                 *(beg + 2) == '4' || *(beg + 2) == '7'))
                              beg += 4;
                            if (!MOST_V_OPT && *(beg) == '\033' &&
                                *(beg + 1) == '[' && *(beg + 2) == 'm')
                              beg += 3;
                        }
                  }
                return(pos - 1);
            }
          else beg = pos;
      }
}


/*
**  This routine returns the 1 + position of first match of key in str.
**  Key is modified to match the case of str.
**  We should try to optimize this routine.
**  Searches from end up to but not including beg.
**  If tabs (^I) or formatting characters or strings (^H, ^M, <ESC>[#m) are
**    in the original text, they are handled such that hits will occur for
**    matches as the search string appears on the screen, i.e, the search
**    string should be entered with spaces instead of tabs and without the
**    formatting characters when not in Binary or Verbose mode (plus -t or
**    :Ot set for tabs).
*/
unsigned char *back_search_region(unsigned char *beg,unsigned char *end,
                                  unsigned char *key)
{
    char ch,ch2,char1,work[136];
    unsigned char *pos,*save_pos,*b,*e,*i;
    int key_len,j,s,str_len,tab_flag;
    extern int M_FLAG;
    extern char *M_POS;

    if (MOST_C_OPT)
      {
          strcpy(work,key);
          key_len = strlen(key);
      }
    else
      {
          /* upcase key */
          key_len = 0;
          while (ch = key[key_len],ch != '\0')
            {
                ch = upcase(ch);
                work[key_len++] = ch;        /* null char is ok */
            }
      }
    
    str_len = (int) (end - beg);
    if (str_len < key_len) return (EOB);
    str_len = str_len - key_len; /* effective length */
    beg += key_len;
          
    char1 = work[key_len - 1];
    
    while(1)
      {
again:
          tab_flag = 0;
          S_DIFF = 0;
          while (ch = *end, ch = upcase(ch), ch != char1)
            {
                if (beg > end) return(EOB);
                if (!MOST_B_OPT)
                  {
                      if((!MOST_V_OPT || !MOST_T_OPT) &&
                         char1 == ' ' && ch == '\t')
                        {
                            tab_flag = 1;
                            break;
                        }
                  }
                end--;
            }
          end--;
            
          /*
          **  We have a position of possible match.
          **  If not Binary mode,
          **    skip if not Verbose mode and it's in an <ESC>[#m
          **    sequence, or a ^M overstrike string.
          */
          if (!MOST_B_OPT)
            {
                if (!MOST_V_OPT)
                  {
                      if ((char1 == '[' &&
                           (*end == '\033' && *(end + 3) == 'm' &&
                            (*(end + 2) == '0' || *(end + 2) == '1' || 
                             *(end + 2) == '4' || *(end + 2) == '7'))) ||
                          (char1 == 'm' &&
                           (*(end - 2) == '\033' && *(end - 1) == '[' &&
                            (*end == '0' || *end == '1' ||
                             *end == '4' || *end == '7'))) ||
                          ((char1 == '0' || char1 == '1' ||
                            char1 == '4' || char1 == '7') &&
                           (*(end - 1) == '\033' && *end == '[' &&
                            *(end + 2) == 'm')))
                        goto again;
                      else if ((char1 == '[' &&
                                *end == '\033' && *(end + 2) == 'm') ||
                               (char1 == 'm' &&
                                *(end - 1) == '\033' && *end == '['))
                        goto again;
                      else
                        {
                            save_pos = C_POS;
                            C_POS = end + 1;
                            b = beg_of_line1();
                            if (!MOST_W_OPT)
                              {
                                  e = end_of_line1();
                                  for (i = b; i <= e; i++)
                                    if (*i == '\015')
                                      {
                                          M_FLAG = 1;
                                          M_POS = i;
                                      }
                              }
                            else
                              e = end_of_line();
                            if (M_FLAG && C_POS > M_POS)
                              {
                                  C_POS = save_pos;
                                  M_FLAG = 0;
                                  goto again;
                              }
                            C_POS = save_pos;
                            M_FLAG = 0;
                        }
                  }
            }
            
          /*
          **  Now see if the rest of the string matches.
          **  If not Binary mode,
          **    deal with any embedded backspaces (^H)
          **    or <ESC>[#m sequences if not Verbose mode,
          **    and with tabs if not Verbose or explicit Tab modes.
          */
          pos = end;  /* save this position so we start from here again */

          if (!MOST_B_OPT && tab_flag)
            {
                end++;
                j = key_len - 1;
            }
          else
            j = key_len - 2;

          if (MOST_B_OPT)
            {
                while(ch = *end--, ch = upcase(ch), ch2 = work[j],
                      (ch == ch2 && j >= 0)) j--;
            }
          else
            {
                while(ch = *end--, ch = upcase(ch), ch2 = work[j],
                      ((ch == ch2) ||
                       (!MOST_V_OPT && ch == '\b') ||
                       (!MOST_V_OPT &&
		        ((!MOST_C_OPT && ch == 'M') ||
                         ( MOST_C_OPT && ch == 'm'))) ||
                       ((!MOST_V_OPT || !MOST_T_OPT) &&
                         ch == '\t' && ch2 == ' ') &&
                       (j >= 0)))
                  {
                      j--;
                   
                      /*
                      **  deal with ^H if not Verbose mode
                      */
                      if (ch2 != '\b' && ch == '\b')
                        {
                            ch = *(end - 1);
                            ch = upcase(ch);
                            if (ch == ch2)
                              end -= 2;
                            else
                              break;
                        }
                         
                      /*
                      **  deal with <ESC>[#m if not Verbose mode
                      */
                      else if (!MOST_V_OPT &&
                               ((!MOST_C_OPT && ch == 'M') ||
                                ( MOST_C_OPT && ch == 'm')) &&
                               *(end - 2) == '\033' && *(end - 1) == '[' &&
                               (*end == '0' || *end == '1' ||
                                *end == '4' || *end == '7'))
                        {
                            ch = *(end - 3);
                            ch = upcase(ch);
                            if (ch != ch2) break;
                            else end -= 4;
                        }
                      else if (!MOST_V_OPT &&
                               ((!MOST_C_OPT && ch == 'M') ||
                                ( MOST_C_OPT && ch == 'm')) &&
                               *(end - 1) == '\033' && *end == '[')
                        {
                            ch = *(end - 2);
                            ch = upcase(ch);
                            if (ch != ch2) break;
                            else end -= 3;
                        }
                        
                      /*
                      **  deal with tabs if not Verbose or explicit Tab modes
                      */
                      else if (ch == '\t' && ch2 == ' ')
                        {
                            j++;
                            save_pos = end + 2;
                            while (*end == '\t' || *end == ' ')
                              end--;
                            if (save_pos >= EOB)
                              s = EOB - apparant_distance(end);
                            else if (MOST_W_OPT)
                              {
                                  MOST_W_OPT = 0;
                                  s = apparant_distance(save_pos) -
                                      apparant_distance(end) - 1;
                                  MOST_W_OPT = 1;
                              }
                            else
                              s = apparant_distance(save_pos) -
                                  apparant_distance(end) - 1;
                            if (end < b) s++;
                            while (s && work[j] == ' ' && j >= 0)
                              {
                                  j--;
                                  s--;
                              }
                            if (j < 0)
                              {
                                  S_DIFF = s;
                              }
                            else if (!tab_flag && s != 0 && j >= 0)
                              {
                                  j = 0;
                                  break;
                              }
                        }
                  }
            }
             
          /*
          **  if it's a full match
          */
          if (j < 0)
            {
                /* 
                **  make key match 'key' in beg
                */
                end = pos +  1;  /* skip back to beginning of match */
                for (j = key_len; j > 0; j--)
                  {
                      if (MOST_B_OPT)
                        {
                            key[j - 1] = *end--;
                        }
                      else
                        {
                            /*
                            **  deal with overstriking via ^H if not Verbose
                            */
                            if (!MOST_V_OPT && *end == '\b')
                              end -= 2;
                            
                            /*
                            **  now deal with tabs if not Verbose or
                            **    explicit Tab modes,
                            **  else just get the character
                            */
                            if ((!MOST_V_OPT || !MOST_T_OPT) &&
                                *end == '\t' && work[j - 1] == ' ')
                              {
                                  while (*end == '\t' || *end == ' ') end--;
                                  while (key[j - 1] == ' ') j--;
                                  j++;
                              }
                            else
                              key[j - 1] = *end--;
                            
                            /*
                            **  now deal with <ESC>[#m if not Verbose
                            */
                            if (!MOST_V_OPT && *end == 'm' &&
                                *(end - 3) == '\033' && *(end - 2) == '[' &&
                                (*(end - 1) == '0' || *(end - 1) == '1' ||
                                 *(end - 1) == '4' || *(end - 1) == '7'))
                              end -= 4;
                            if (!MOST_V_OPT && *end == 'm' &&
                                *(end - 2) == '\033' && *(end - 1) == '[')
                              end -= 3;
                        }
                  }
                return(end + 1);
            }
          else end = pos;
      }
}


/*
**  Return the line match was found as well as line number.
**  Search from 'from' on.
**  Assume that line_array match the 'from' so we need no initial lookup.
*/
int search(unsigned char *from, int repeat, int *col)
{
    int str_len,i,test,j,save_line,the_col,row;
    char ch,string[136];
    unsigned char *pos,*save_pos,*found_at;
    extern int SCREEN_WIDTH;

    /*
    **  if out out bounds, do nothing
    */
    if ((from < BEG) || (from > EOB))
      return(-1);

    /*
    **  If not Binary mode,
    **    if not Verbose mode and search string has an overstrike
    **      (^H or ^M) character or a legal <ESC>[#m sequence,
    **    else if not Verbose or not explicit Tab mode and search
    **      string has a tab,
    **    tell the user to implement the appropriate mode(s).
    */
    if (!MOST_B_OPT)
      {
          if (!MOST_V_OPT || !MOST_T_OPT)
            {
                str_len = strlen(SEARCH_STR);
                for (i = 0; i < str_len; i++)
                  {
                      if ((!MOST_V_OPT) &&
                          (SEARCH_STR[i] == '\b' || SEARCH_STR[i] == '\015' ||
                           (SEARCH_STR[i] == '\033' && i + 3 < str_len &&
                            SEARCH_STR[i+1] == '[' && SEARCH_STR[i+3] == 'm' &&
                            (SEARCH_STR[i+2] == '0' ||
                             SEARCH_STR[i+2] == '1' ||
                             SEARCH_STR[i+2] == '4' ||
                             SEARCH_STR[i+2] == '7')) ||
                           (SEARCH_STR[i] == '\033' && i + 2 < str_len &&
                            SEARCH_STR[i+1] == '[' &&
                            SEARCH_STR[i+2] == 'm')))
                        {
                            most_message
                              ("Use Verbose mode to search for this string.",1);
                            return(-1);
                        }
                      else if ((!MOST_V_OPT || !MOST_T_OPT) &&
                               (SEARCH_STR[i] == '\t'))
                        {
                            most_message
             ("Use Verbose and explicit Tab mode to search for this string.",1);
                            return(-1);
                        }
                  }
            }
      }

    save_pos = C_POS;
    save_line = C_LINE;
    found_at = EOB;
    *col = 0;

    pos = from;
    if (SEARCH_STR[0] != '\0')
      {
          test = repeat && (pos < EOB) && (pos >= BEG);
          while(test)
            {
                if (SEARCH_DIR == 1)
                  pos = forw_search_region(pos,EOB,(unsigned char*) SEARCH_STR);
                else
                  pos = back_search_region(BEG,pos,(unsigned char*) SEARCH_STR);
                
                
                if (pos < EOB)
                  {
                      repeat--;
                      found_at = pos;
                      if (SEARCH_DIR == 1)
                        pos += strlen(SEARCH_STR);
                      else pos--;
                  }
                test = repeat && (pos < EOB) && (pos >= BEG);
            }
      }
    
    if (repeat) /* not found */
      {
          *col = 0;
          if (SEARCH_STR[0] == '\0')
            most_message("Search string not specified.",1);
          else
            {
                (void) sprintf(string,"%s NOT FOUND.",SEARCH_STR);
                most_message(string,1);
            }
          
          row = -1;
      }

    else
      {
           find_row_column(found_at,&row,&the_col);
           *col = the_col;
      }

    S_DIFF = 0;
    C_POS = save_pos;
    C_LINE = save_line;
    if (row > 0) CURS_POS = found_at;
    return( row );
}
T.RTitleUserPersonal
Name
DateLines
2174.1Your macro modifies the variable you call it withWIBBIN::NOYCEPulling weeds, pickin&#039; stonesFri May 02 1997 13:5315
> #define upcase(ch) ((!MOST_C_OPT && (ch<='z') && (ch>='a')) ? ch &= 0xDF : ch)

This macro converts ch tu upper case if it was lower case (modifying ch), and
returns the result.

>                ch = upcase(ch);

This statement modifies ch as above, and then stores the result into ch.
The C language says that doing this produces undefined results.  Previously,
the compiler didn't notice; now it's giving you a warning.

If you didn't want the macro to modify ch, then change this part:
>	ch &= 0xDF
to
	ch & 0xDF
2174.2And if you *want* the macro to modify its argument...CXXC::REPETERich Peterson 381-1802 ZKO2-3/N30Fri May 02 1997 18:169
don't assign the result (to the same variable).

Instead of:

   ch = upcase(ch);

just write:

   upcase(ch);
2174.3As inCXXC::REPETERich Peterson 381-1802 ZKO2-3/N30Fri May 02 1997 18:2823
Looking through your uses of upcase, it seems that you invariably
assign the result to the same variable as the argument.  Bill's
change to the definition works fine without source code changes,
and is probably better style.

Leaving the definition as-is, you'd have to change all the call
sites to get rid of the assignment.  In a couple of places, this
would allow you to remove a source line:

>                ch = upcase(ch);
>                work[key_len++] = ch;        /* null char is ok */

Equivalent to:

                 work[key_len++] = upcase(ch);


>                ch = upcase(ch);
>                if (ch == ch2)

Equivalent to:

>                if (upcase(ch) == ch2)
2174.4Fixed!JOBIM::VUJNOVICI�t�r��t���l�z�t��L���l�z�t��Mon May 05 1997 05:495
Thanks everybody. I opted for changing ch &= 0xDF to ch & 0xDF in
the macro.

Regards,
Slobodan