1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-08 17:42:12 +03:00

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.
This commit is contained in:
Roland McGrath
1996-04-03 16:31:49 +00:00
parent 30de3b18a5
commit 299a95b9f0
49 changed files with 1525 additions and 1913 deletions

View File

@@ -1,5 +1,5 @@
/* Internal function for converting integers to ASCII.
Copyright (C) 1994, 1995 Free Software Foundation, Inc.
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Torbjorn Granlund <tege@matematik.su.se>
and Ulrich Drepper <drepper@gnu.ai.mit.edu>.
@@ -159,10 +159,10 @@ static const struct base_table_t base_table[] =
};
/* Lower-case digits. */
static const char _itoa_lower_digits[]
const char _itoa_lower_digits[]
= "0123456789abcdefghijklmnopqrstuvwxyz";
/* Upper-case digits. */
static const char _itoa_upper_digits[]
const char _itoa_upper_digits[]
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

View File

@@ -1,5 +1,5 @@
/* Internal function for converting integers to ASCII.
Copyright (C) 1994, 1995 Free Software Foundation, Inc.
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -29,4 +29,31 @@ Cambridge, MA 02139, USA. */
extern char *_itoa __P ((unsigned long long int value, char *buflim,
unsigned int base, int upper_case));
static inline char *_itoa_word (unsigned long value, char *buflim,
unsigned int base, int upper_case)
{
extern const char _itoa_upper_digits[], _itoa_lower_digits[];
const char *digits = upper_case ? _itoa_upper_digits : _itoa_lower_digits;
char *bp = buflim;
switch (base)
{
#define SPECIAL(Base) \
case Base: \
do \
*--bp = digits[value % Base]; \
while ((value /= Base) != 0); \
break
SPECIAL (10);
SPECIAL (16);
SPECIAL (8);
default:
do
*--bp = digits[value % base];
while ((value /= base) != 0);
}
return bp;
}
#endif /* itoa.h */

View File

@@ -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;

View File

@@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
/* Copyright (C) 1991, 1992, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -20,6 +20,50 @@ Cambridge, MA 02139, USA. */
#include <printf.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#ifndef COMPILE_WPRINTF
# define CHAR_T char
# define UCHAR_T unsigned char
# define INT_T int
# define L_(Str) Str
# define ISDIGIT(Ch) isdigit (Ch)
# ifdef USE_IN_LIBIO
# define PUT(F, S, N) _IO_sputn (F, S, N)
# define PAD(Padchar) \
if (width > 0) \
done += _IO_padn (s, Padchar, width)
# else
# define PUTC(C, F) putc (C, F)
ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
# define PAD(Padchar) \
if (width > 0) \
{ if (__printf_pad (s, Padchar, width) == -1) \
return -1; else done += width; }
# endif
#else
# define vfprintf vfwprintf
# define CHAR_T wchar_t
# define UCHAR_T uwchar_t
# define INT_T wint_t
# define L_(Str) L##Str
# define ISDIGIT(Ch) iswdigit (Ch)
# ifdef USE_IN_LIBIO
# define PUT(F, S, N) _IO_sputn (F, S, N)
# define PAD(Padchar) \
if (width > 0) \
done += _IO_wpadn (s, Padchar, width)
# else
# define PUTC(C, F) wputc (C, F)
ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n));
# define PAD(Padchar) \
if (width > 0) \
{ if (__wprintf_pad (s, Padchar, width) == -1) \
return -1; else done += width; }
# endif
#endif
#include "printf-parse.h"
@@ -33,15 +77,17 @@ parse_printf_format (fmt, n, argtypes)
size_t nargs; /* Number of arguments. */
size_t max_ref_arg; /* Highest index used in a positional arg. */
struct printf_spec spec;
mbstate_t mbstate;
nargs = 0;
max_ref_arg = 0;
mbstate = 0;
/* Search for format specifications. */
for (fmt = find_spec (fmt); *fmt != '\0'; fmt = spec.next_fmt)
for (fmt = find_spec (fmt, &mbstate); *fmt != '\0'; fmt = spec.next_fmt)
{
/* Parse this spec. */
nargs += parse_one_spec (fmt, nargs, &spec, &max_ref_arg);
nargs += parse_one_spec (fmt, nargs, &spec, &max_ref_arg, &mbstate);
/* If the width is determined by an argument this is an int. */
if (spec.width_arg != -1 && spec.width_arg < n)

View File

@@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
/* Copyright (C) 1991, 92, 93, 95, 96 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -26,6 +26,7 @@ __BEGIN_DECLS
#define __need_FILE
#include <stdio.h>
#define __need_size_t
#define __need_wchar_t
#include <stddef.h>
@@ -33,7 +34,11 @@ struct printf_info
{
int prec; /* Precision. */
int width; /* Width. */
unsigned char spec; /* Format letter. */
#ifdef THIS_IS_INCOMPATIBLE_WITH_LINUX_LIBC
wchar_t spec; /* Format letter. */
#else
char spec; /* Format letter. */
#endif
unsigned int is_long_double:1;/* L flag. */
unsigned int is_short:1; /* h flag. */
unsigned int is_long:1; /* l flag. */

View File

@@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
/* Copyright (C) 1991, 1992, 1993, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -188,7 +188,7 @@ I am ready for my first lesson today.";
{
double d = FLT_MIN;
int niter = 17;
while (niter-- != 0)
printf ("%.17e\n", d / 2);
fflush (stdout);
@@ -233,7 +233,18 @@ I am ready for my first lesson today.";
rfg1 ();
rfg2 ();
exit(EXIT_SUCCESS);
{
char buf[200];
int result;
sprintf(buf,"%*s%*s%*s",-1,"one",-20,"two",-30,"three");
result = strcmp (buf,
"onetwo three ");
puts (result != 0 ? "Test failed!" : "Test ok.");
return result != 0;
}
}
rfg1 ()

File diff suppressed because it is too large Load Diff