about summary refs log tree commit diff
path: root/stdio-common/printf-parse.h
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-04-03 16:31:49 +0000
committerRoland McGrath <roland@gnu.org>1996-04-03 16:31:49 +0000
commit299a95b9f048679f1288512b0a6ab6ca16dd9d7c (patch)
tree4788a62ee8f131887e5817e8daa3339084dbe764 /stdio-common/printf-parse.h
parent30de3b18a526acc837957865129b7fa6d8ac91d1 (diff)
downloadglibc-299a95b9f048679f1288512b0a6ab6ca16dd9d7c.tar.gz
glibc-299a95b9f048679f1288512b0a6ab6ca16dd9d7c.tar.xz
glibc-299a95b9f048679f1288512b0a6ab6ca16dd9d7c.zip
Tue Apr 2 21:27:01 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
	* posix/glob.c (glob_pattern_p): Avoid scanning past eos if
	the pattern ends with a backslash and quoting is enabled.
	* posix/fnmatch.c (fnmatch): Likewise; return FNM_NOMATCH for such
 	patterns.
Diffstat (limited to 'stdio-common/printf-parse.h')
-rw-r--r--stdio-common/printf-parse.h135
1 files changed, 68 insertions, 67 deletions
diff --git a/stdio-common/printf-parse.h b/stdio-common/printf-parse.h
index 9abbdba187..a7960e6003 100644
--- a/stdio-common/printf-parse.h
+++ b/stdio-common/printf-parse.h
@@ -1,5 +1,5 @@
 /* Internal header for parsing printf format strings.
-Copyright (C) 1995 Free Software Foundation, Inc.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of th GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -73,14 +73,14 @@ union printf_arg
 /* Read a simple integer from a string and update the string pointer.
    It is assumed that the first character is a digit.  */
 static inline unsigned int
-read_int (const char * *pstr)
+read_int (const UCHAR_T * *pstr)
 {
-  unsigned int retval = **pstr - '0';
+  unsigned int retval = **pstr - L_('0');
 
-  while (isdigit (*++(*pstr)))
+  while (ISDIGIT (*++(*pstr)))
     {
       retval *= 10;
-      retval += **pstr - '0';
+      retval += **pstr - L_('0');
     }
 
   return retval;
@@ -91,13 +91,13 @@ read_int (const char * *pstr)
 /* Find the next spec in FORMAT, or the end of the string.  Returns
    a pointer into FORMAT, to a '%' or a '\0'.  */
 static inline const char *
-find_spec (const char *format)
+find_spec (const char *format, mbstate_t *ps)
 {
   while (*format != '\0' && *format != '%')
     {
       int len;
 
-      if (isascii (*format) || (len = mblen (format, MB_CUR_MAX)) <= 0)
+      if (isascii (*format) || (len = mbrlen (format, MB_CUR_MAX, ps)) <= 0)
 	++format;
       else
 	format += len;
@@ -116,8 +116,8 @@ extern printf_arginfo_function **__printf_arginfo_table;
    the number of args consumed by this spec; *MAX_REF_ARG is updated so it
    remains the highest argument index used.  */
 static inline size_t
-parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
-		size_t *max_ref_arg)
+parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
+		size_t *max_ref_arg, mbstate_t *ps)
 {
   unsigned int n;
   size_t nargs = 0;
@@ -135,13 +135,13 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
   spec->info.pad = ' ';
 
   /* Test for positional argument.  */
-  if (isdigit (*format))
+  if (ISDIGIT (*format))
     {
-      const char *begin = format;
+      const UCHAR_T *begin = format;
 
       n = read_int (&format);
 
-      if (n > 0 && *format == '$')
+      if (n > 0 && *format == L_('$'))
 	/* Is positional parameter.  */
 	{
 	  ++format;		/* Skip the '$'.  */
@@ -155,32 +155,32 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
     }
 
   /* Check for spec modifiers.  */
-  while (*format == ' ' || *format == '+' || *format == '-' ||
-	 *format == '#' || *format == '0' || *format == '\'')
+  while (*format == L_(' ') || *format == L_('+') || *format == L_('-') ||
+	 *format == L_('#') || *format == L_('0') || *format == L_('\''))
     switch (*format++)
       {
-      case ' ':
+      case L_(' '):
 	/* Output a space in place of a sign, when there is no sign.  */
 	spec->info.space = 1;
 	break;
-      case '+':
+      case L_('+'):
 	/* Always output + or - for numbers.  */
 	spec->info.showsign = 1;
 	break;
-      case '-':
+      case L_('-'):
 	/* Left-justify things.  */
 	spec->info.left = 1;
 	break;
-      case '#':
+      case L_('#'):
 	/* Use the "alternate form":
 	   Hex has 0x or 0X, FP always has a decimal point.  */
 	spec->info.alt = 1;
 	break;
-      case '0':
+      case L_('0'):
 	/* Pad with 0s.  */
 	spec->info.pad = '0';
 	break;
-      case '\'':
+      case L_('\''):
 	/* Show grouping in numbers if the locale information
 	   indicates any.  */
 	spec->info.group = 1;
@@ -192,18 +192,18 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
   /* Get the field width.  */
   spec->width_arg = -1;
   spec->info.width = 0;
-  if (*format == '*')
+  if (*format == L_('*'))
     {
       /* The field width is given in an argument.
 	 A negative field width indicates left justification.  */
-      const char *begin = ++format;
+      const UCHAR_T *begin = ++format;
 
-      if (isdigit (*format))
+      if (ISDIGIT (*format))
 	{
 	  /* The width argument might be found in a positional parameter.  */
 	  n = read_int (&format);
 
-	  if (n > 0 && *format == '$')
+	  if (n > 0 && *format == L_('$'))
 	    {
 	      spec->width_arg = n - 1;
 	      *max_ref_arg = MAX (*max_ref_arg, n);
@@ -219,7 +219,7 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
 	  format = begin;	/* Step back and reread.  */
 	}
     }
-  else if (isdigit (*format))
+  else if (ISDIGIT (*format))
     /* Constant width specification.  */
     spec->info.width = read_int (&format);
 
@@ -227,19 +227,19 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
   spec->prec_arg = -1;
   /* -1 means none given; 0 means explicit 0.  */
   spec->info.prec = -1;
-  if (*format == '.')
+  if (*format == L_('.'))
     {
       ++format;
-      if (*format == '*')
+      if (*format == L_('*'))
 	{
 	  /* The precision is given in an argument.  */
-	  const char *begin = ++format;
+	  const UCHAR_T *begin = ++format;
 
-	  if (isdigit (*format))
+	  if (ISDIGIT (*format))
 	    {
 	      n = read_int (&format);
 
-	      if (n > 0 && *format == '$')
+	      if (n > 0 && *format == L_('$'))
 		{
 		  spec->prec_arg = n - 1;
 		  *max_ref_arg = MAX (*max_ref_arg, n);
@@ -255,7 +255,7 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
 	      format = begin;
 	    }
 	}
-      else if (isdigit (*format))
+      else if (ISDIGIT (*format))
 	spec->info.prec = read_int (&format);
       else
 	/* "%.?" is treated like "%.0?".  */
@@ -268,40 +268,41 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
   spec->info.is_short = 0;
   spec->info.is_long = 0;
 
-  while (*format == 'h' || *format == 'l' || *format == 'L' ||
-	 *format == 'Z' || *format == 'q')
+  if (*format == L_('h') || *format == L_('l') || *format == L_('L') ||
+      *format == L_('Z') || *format == L_('q'))
     switch (*format++)
       {
-      case 'h':
+      case L_('h'):
 	/* int's are short int's.  */
 	spec->info.is_short = 1;
 	break;
-      case 'l':
-	if (spec->info.is_long)
-	  /* A double `l' is equivalent to an `L'.  */
-	  spec->info.is_longlong = 1;
-	else
-	  /* int's are long int's.  */
-	  spec->info.is_long = 1;
-	break;
-      case 'L':
+      case L_('l'):
+	/* int's are long int's.  */
+	spec->info.is_long = 1;
+	if (*format != L_('l'))
+	  break;
+	++format;
+	/* FALLTHROUGH */
+      case L_('L'):
 	/* double's are long double's, and int's are long long int's.  */
+      case L_('q'):
+	/* 4.4 uses this for long long.  */
 	spec->info.is_long_double = 1;
 	break;
-      case 'Z':
+      case L_('Z'):
 	/* int's are size_t's.  */
 	assert (sizeof(size_t) <= sizeof(unsigned long long int));
 	spec->info.is_longlong = sizeof(size_t) > sizeof(unsigned long int);
 	spec->info.is_long = sizeof(size_t) > sizeof(unsigned int);
 	break;
-      case 'q':
-	/* 4.4 uses this for long long.  */
-	spec->info.is_longlong = 1;
-	break;
       }
 
   /* Get the format specification.  */
-  spec->info.spec = *format++;
+#ifdef THIS_IS_INCOMPATIBLE_WITH_LINUX_LIBC
+  spec->info.spec = (wchar_t) *format++;
+#else
+  spec->info.spec = (char) *format++;
+#endif
   if (__printf_arginfo_table != NULL &&
       __printf_arginfo_table[spec->info.spec] != NULL)
     /* We don't try to get the types for all arguments if the format
@@ -315,12 +316,12 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
 
       switch (spec->info.spec)
 	{
-	case 'i':
-	case 'd':
-	case 'u':
-	case 'o':
-	case 'X':
-	case 'x':
+	case L'i':
+	case L'd':
+	case L'u':
+	case L'o':
+	case L'X':
+	case L'x':
 	  if (spec->info.is_longlong)
 	    spec->data_arg_type = PA_INT|PA_FLAG_LONG_LONG;
 	  else if (spec->info.is_long)
@@ -330,30 +331,30 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
 	  else
 	    spec->data_arg_type = PA_INT;
 	  break;
-	case 'e':
-	case 'E':
-	case 'f':
-	case 'g':
-	case 'G':
+	case L'e':
+	case L'E':
+	case L'f':
+	case L'g':
+	case L'G':
 	  if (spec->info.is_long_double)
 	    spec->data_arg_type = PA_DOUBLE|PA_FLAG_LONG_DOUBLE;
 	  else
 	    spec->data_arg_type = PA_DOUBLE;
 	  break;
-	case 'c':
+	case L'c':
 	  spec->data_arg_type = PA_CHAR;
 	  break;
-	case 's':
+	case L's':
 	  spec->data_arg_type = PA_STRING;
 	  break;
-	case 'p':
+	case L'p':
 	  spec->data_arg_type = PA_POINTER;
 	  break;
-	case 'n':
+	case L'n':
 	  spec->data_arg_type = PA_INT|PA_FLAG_PTR;
 	  break;
 
-	case 'm':
+	case L'm':
 	default:
 	  /* An unknown spec will consume no args.  */
 	  spec->ndata_args = 0;
@@ -370,14 +371,14 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
 	}
     }
 
-  if (spec->info.spec == '\0')
+  if (spec->info.spec == L'\0')
     /* Format ended before this spec was complete.  */
     spec->end_of_fmt = spec->next_fmt = format - 1;
   else
     {
       /* Find the next format spec.  */
       spec->end_of_fmt = format;
-      spec->next_fmt = find_spec (format);
+      spec->next_fmt = find_spec (format, ps);
     }
 
   return nargs;