dp = strchr (digits, tolower (*runp));
dp = strchr (digits, _tolower (*runp));
collate_simple_weight (struct linereader *lr, struct localedef_t *locale,		       struct token *code, struct charset_t *charset){  struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate;  unsigned int value = 0;  /* There current tokens can be `IGNORE', `...', or a string.  */  switch (code->tok)    {    case tok_ignore:      /* This token is allowed in all situations.  */      value = IGNORE_CHAR;      break;    case tok_ellipsis:      /* The ellipsis is only allowed for the `...' or `UNDEFINED'	 entry.  */      if (collate->kind != ellipsis && collate->kind != undefined)	{	  lr_error (lr, _("\`...' must only be used in `...' and `UNDEFINED' entries"));	  lr_ignore_rest (lr, 0);	  return -1;	}      value = ELLIPSIS_CHAR;      break;    case tok_string:      /* This can become difficult.  We have to get the weights which	 correspond to the single wide chars in the string.  But some	 of the `chars' might not be real characters, but collation	 elements or symbols.  And so the string decoder might have	 signaled errors.  The string at this point is not translated.	 I.e., all <...> sequences are still there.  */      {	char *runp = code->val.str.start;	void *tmp;	while (*runp != '\0')	  {	    char *startp = (char *) runp;	    char *putp = (char *) runp;	    wchar_t wch;	    /* Lookup weight for char and store it.  */	    if (*runp == '<')	      {		while (*++runp != '\0' && *runp != '>')		  {		    if (*runp == lr->escape_char)		      if (*++runp == '\0')			{			  lr_error (lr, _("unterminated weight name"));			  lr_ignore_rest (lr, 0);			  return -1;			}		    *putp++ = *runp;		  }		if (*runp == '>')		  ++runp;		if (putp == startp)		  {		    lr_error (lr, _("empty weight name: line ignored"));		    lr_ignore_rest (lr, 0);		    return -1;		  }		wch = charset_find_value (&charset->char_table, startp,					  putp - startp);		if (wch != ILLEGAL_CHAR_VALUE)		  {		    element_t *pelem;		    if (find_entry (&collate->result, &wch, sizeof (wchar_t),				    (void *)&pelem) < 0)		      pelem = NULL;		    while (pelem != NULL			   && (pelem->name[0] != wch			       || pelem->name[1] != L'\0'))		      pelem = pelem->next;		    value = pelem == NULL ? 0 : pelem->this_weight;		  }		else if (find_entry (&collate->elements, startp, putp - startp,				     &tmp) >= 0)		  {		    element_t *pelem = (element_t *) tmp;		    value = pelem->this_weight;		  }		else if (find_entry (&collate->symbols, startp, putp - startp,				     &tmp) >= 0)		  {		    value = (unsigned int) tmp;		  }		else		  {		    if (verbose)		      lr_error (lr, _("unknown symbol `%.*s': line ignored"),				(int) (putp - startp), startp);		    lr_ignore_rest (lr, 0);		    return -1;		  }	      }	    else	      {		element_t *wp;		wchar_t wch;		if (*runp == lr->escape_char)		  {		    static const char digits[] = "0123456789abcdef";		    const char *dp;		    int base;		    ++runp;		    if (tolower (*runp) == 'x')		      {			++runp;			base = 16;		      }		    else if (tolower (*runp) == 'd')		      {			++runp;			base = 10;		      }		    else		      base = 8;		    dp = strchr (digits, tolower (*runp));		    if (dp == NULL || (dp - digits) >= base)		      {		      illegal_char:			lr_error (lr, _("\illegal character constant in string"));			lr_ignore_rest (lr, 0);			return -1;		      }		    wch = dp - digits;		    ++runp;		    dp = strchr (digits, tolower (*runp));		    if (dp == NULL || (dp - digits) >= base)		      goto illegal_char;		    wch *= base;		    wch += dp - digits;		    ++runp;		    if (base != 16)		      {			dp = strchr (digits, tolower (*runp));			if (dp != NULL && (dp - digits < base))			  {			    wch *= base;			    wch += dp - digits;			    ++runp;			  }		      }		  }		else		  wch = (wchar_t) *runp++;		/* Lookup the weight for WCH.  */		if (find_entry (&collate->result, &wch, sizeof (wch),				(void *)&wp) < 0)		  wp = NULL;		while (wp != NULL		       && (wp->name[0] != wch || wp->name[1] != L'\0'))		  wp = wp->next;		value = wp == NULL ? 0 : wp->this_weight;		/* To get the correct name for the error message.  */		putp = runp;		/**************************************************\		|* I know here is something wrong.  Characters in *|		|* the string which are not in the <...> form	  *|		|* cannot be declared forward for now!!!	  *|		\**************************************************/	      }	    /* Store in weight array.  */	    if (collate->nweight >= collate->nweight_max)	      {		collate->nweight_max *= 2;		collate->weight		  = (unsigned int *) xrealloc (collate->weight,					       collate->nweight_max);	      }	    if (value == 0)	      {		patch_t *newp;		newp = (patch_t *) obstack_alloc (&collate->element_mem,						  sizeof (patch_t));		newp->fname = lr->fname;		newp->lineno = lr->lineno;		newp->token		  = (const char *) obstack_copy0 (&collate->element_mem,						  startp, putp - startp);		newp->where.idx = collate->nweight++;		newp->next = collate->current_patch;		collate->current_patch = newp;	      }	    else	      collate->weight[collate->nweight++] = value;	    ++collate->weight_cnt[collate->weight_idx];	  }      }      return 0;    default:      assert (! "should not happen");    }  if (collate->nweight >= collate->nweight_max)    {      collate->nweight_max *= 2;      collate->weight = (unsigned int *) xrealloc (collate->weight,						   collate->nweight_max);    }  collate->weight[collate->nweight++] = value;  ++collate->weight_cnt[collate->weight_idx];  return 0;}