From 8df75db2fd57c0b066931264f30294c86f508c04 Mon Sep 17 00:00:00 2001 From: solar <> Date: Mon, 20 Dec 2010 05:17:35 +0000 Subject: [PATCH 01/16] Some testcases for scanf(). Fixed bug with %*... . Fixed artifact in Makefile. --- Makefile | 2 +- functions/_PDCLIB/scan.c | 105 ++++++++++++++++++++------------------ testing/scanf_testcases.h | 54 ++++++++++++++++++++ 3 files changed, 109 insertions(+), 52 deletions(-) diff --git a/Makefile b/Makefile index 2993c25..2d1fa6d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # $Id$ # This is where you chose which platform to compile for (see 'make links' / './platform') -PLATFORM := example_cygwin +PLATFORM := example # This is a list of all non-source files that are part of the distribution. AUXFILES := Makefile Readme.txt diff --git a/functions/_PDCLIB/scan.c b/functions/_PDCLIB/scan.c index 6bef32e..15b1d50 100644 --- a/functions/_PDCLIB/scan.c +++ b/functions/_PDCLIB/scan.c @@ -519,67 +519,70 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) return NULL; } /* convert value to target type and assign to parameter */ - switch ( status->flags & ( E_char | E_short | E_long | E_llong | - E_intmax | E_size | E_ptrdiff | - E_unsigned ) ) + if ( ! ( status->flags & E_suppressed ) ) { - case E_char: - *( va_arg( status->arg, char * ) ) = (char)( value * sign ); - break; - case E_char | E_unsigned: - *( va_arg( status->arg, unsigned char * ) ) = (unsigned char)( value * sign ); - break; + switch ( status->flags & ( E_char | E_short | E_long | E_llong | + E_intmax | E_size | E_ptrdiff | + E_unsigned ) ) + { + case E_char: + *( va_arg( status->arg, char * ) ) = (char)( value * sign ); + break; + case E_char | E_unsigned: + *( va_arg( status->arg, unsigned char * ) ) = (unsigned char)( value * sign ); + break; - case E_short: - *( va_arg( status->arg, short * ) ) = (short)( value * sign ); - break; - case E_short | E_unsigned: - *( va_arg( status->arg, unsigned short * ) ) = (unsigned short)( value * sign ); - break; + case E_short: + *( va_arg( status->arg, short * ) ) = (short)( value * sign ); + break; + case E_short | E_unsigned: + *( va_arg( status->arg, unsigned short * ) ) = (unsigned short)( value * sign ); + break; - case 0: - *( va_arg( status->arg, int * ) ) = (int)( value * sign ); - break; - case E_unsigned: - *( va_arg( status->arg, unsigned int * ) ) = (unsigned int)( value * sign ); - break; + case 0: + *( va_arg( status->arg, int * ) ) = (int)( value * sign ); + break; + case E_unsigned: + *( va_arg( status->arg, unsigned int * ) ) = (unsigned int)( value * sign ); + break; - case E_long: - *( va_arg( status->arg, long * ) ) = (long)( value * sign ); - break; - case E_long | E_unsigned: - *( va_arg( status->arg, unsigned long * ) ) = (unsigned long)( value * sign ); - break; + case E_long: + *( va_arg( status->arg, long * ) ) = (long)( value * sign ); + break; + case E_long | E_unsigned: + *( va_arg( status->arg, unsigned long * ) ) = (unsigned long)( value * sign ); + break; - case E_llong: - *( va_arg( status->arg, long long * ) ) = (long long)( value * sign ); - break; - case E_llong | E_unsigned: - *( va_arg( status->arg, unsigned long long * ) ) = (unsigned long long)( value * sign ); - break; + case E_llong: + *( va_arg( status->arg, long long * ) ) = (long long)( value * sign ); + break; + case E_llong | E_unsigned: + *( va_arg( status->arg, unsigned long long * ) ) = (unsigned long long)( value * sign ); + break; - case E_intmax: - *( va_arg( status->arg, intmax_t * ) ) = (intmax_t)( value * sign ); - break; - case E_intmax | E_unsigned: - *( va_arg( status->arg, uintmax_t * ) ) = (uintmax_t)( value * sign ); - break; + case E_intmax: + *( va_arg( status->arg, intmax_t * ) ) = (intmax_t)( value * sign ); + break; + case E_intmax | E_unsigned: + *( va_arg( status->arg, uintmax_t * ) ) = (uintmax_t)( value * sign ); + break; - case E_size: - /* E_size always implies unsigned */ - *( va_arg( status->arg, size_t * ) ) = (size_t)( value * sign ); - break; + case E_size: + /* E_size always implies unsigned */ + *( va_arg( status->arg, size_t * ) ) = (size_t)( value * sign ); + break; - case E_ptrdiff: - /* E_ptrdiff always implies signed */ - *( va_arg( status->arg, ptrdiff_t * ) ) = (ptrdiff_t)( value * sign ); - break; + case E_ptrdiff: + /* E_ptrdiff always implies signed */ + *( va_arg( status->arg, ptrdiff_t * ) ) = (ptrdiff_t)( value * sign ); + break; - default: - puts( "UNSUPPORTED SCANF FLAG COMBINATION" ); - return NULL; /* behaviour unspecified */ + default: + puts( "UNSUPPORTED SCANF FLAG COMBINATION" ); + return NULL; /* behaviour unspecified */ + } + ++(status->n); } - ++(status->n); return ++spec; } /* TODO: Floats. */ diff --git a/testing/scanf_testcases.h b/testing/scanf_testcases.h index f8d3b0f..a1521fe 100644 --- a/testing/scanf_testcases.h +++ b/testing/scanf_testcases.h @@ -1,5 +1,59 @@ { char buffer[100]; + int i; + unsigned int u; + /* basic: reading of three-char string */ SCANF_TEST( 1, "foo", "%3c", buffer ); TESTCASE( memcmp( buffer, "foo", 3 ) == 0 ); +#ifndef TEST_CONVERSION_ONLY + /* %% for single % */ + SCANF_TEST( 1, "%x", "%%%c", buffer ); + TESTCASE( buffer[0] == 'x' ); + /* * to skip assignment */ + SCANF_TEST( 1, "3xfoo", "%*dx%3c", buffer ); + TESTCASE( memcmp( buffer, "foo", 3 ) == 0 ); +#endif + /* domain testing on 'int' type */ + SCANF_TEST( 1, "-" INT_MIN_DEZ_STR, "%d", &i ); + TESTCASE( i == INT_MIN ); + SCANF_TEST( 1, INT_MAX_DEZ_STR, "%d", &i ); + TESTCASE( i == INT_MAX ); + SCANF_TEST( 1, "-1", "%d", &i ); + TESTCASE( i == -1 ); + SCANF_TEST( 1, "0", "%d", &i ); + TESTCASE( i == 0 ); + SCANF_TEST( 1, "1", "%d", &i ); + TESTCASE( i == 1 ); + SCANF_TEST( 1, "-" INT_MIN_DEZ_STR, "%i", &i ); + TESTCASE( i == INT_MIN ); + SCANF_TEST( 1, INT_MAX_DEZ_STR, "%i", &i ); + TESTCASE( i == INT_MAX ); + SCANF_TEST( 1, "-1", "%i", &i ); + TESTCASE( i == -1 ); + SCANF_TEST( 1, "0", "%i", &i ); + TESTCASE( i == 0 ); + SCANF_TEST( 1, "1", "%i", &i ); + TESTCASE( i == 1 ); + SCANF_TEST( 1, "0x7" INT_HEXDIG, "%i", &i ); + TESTCASE( i == INT_MAX ); + SCANF_TEST( 1, "0x0", "%i", &i ); + TESTCASE( i == 0 ); +#ifndef TEST_CONVERSION_ONLY + SCANF_TEST( 1, "00", "%i%n", &i, &u ); + TESTCASE( i == 0 ); + TESTCASE( u == 2 ); +#endif + /* domain testing on 'unsigned int' type */ + SCANF_TEST( 1, UINT_MAX_DEZ_STR, "%u", &u ); + TESTCASE( u == UINT_MAX ); + SCANF_TEST( 1, "0", "%u", &u ); + TESTCASE( u == 0 ); + SCANF_TEST( 1, "f" INT_HEXDIG, "%x", &u ); + TESTCASE( u == UINT_MAX ); + SCANF_TEST( 1, "7" INT_HEXDIG, "%x", &u ); + TESTCASE( u == INT_MAX ); + SCANF_TEST( 1, "0", "%o", &u ); + TESTCASE( u == 0 ); + SCANF_TEST( 1, INT_OCTDIG, "%o", &u ); + TESTCASE( u == UINT_MAX ); } -- 2.40.0 From c185bcf47f7399b4d3e0029c64fb5b85352bfb0a Mon Sep 17 00:00:00 2001 From: solar <> Date: Mon, 20 Dec 2010 07:15:23 +0000 Subject: [PATCH 02/16] Basic tests for %c, %s, %[ and %p. --- testing/scanf_testcases.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/testing/scanf_testcases.h b/testing/scanf_testcases.h index a1521fe..f9007d6 100644 --- a/testing/scanf_testcases.h +++ b/testing/scanf_testcases.h @@ -2,6 +2,7 @@ char buffer[100]; int i; unsigned int u; + int * p; /* basic: reading of three-char string */ SCANF_TEST( 1, "foo", "%3c", buffer ); TESTCASE( memcmp( buffer, "foo", 3 ) == 0 ); @@ -56,4 +57,31 @@ TESTCASE( u == 0 ); SCANF_TEST( 1, INT_OCTDIG, "%o", &u ); TESTCASE( u == UINT_MAX ); + /* testing %c */ + memset( buffer, '\0', 100 ); + SCANF_TEST( 1, "x", "%c", buffer ); + TESTCASE( memcmp( buffer, "x\0", 2 ) == 0 ); + /* testing %s */ + memset( buffer, '\0', 100 ); + SCANF_TEST( 1, "foo bar", "%s", buffer ); + TESTCASE( memcmp( buffer, "foo\0", 4 ) == 0 ); +#ifndef TEST_CONVERSION_ONLY + SCANF_TEST( 2, "foo bar baz", "%s %s %n", buffer, buffer + 4, &u ); + TESTCASE( u == 9 ); + TESTCASE( memcmp( buffer, "foo\0bar\0", 8 ) == 0 ); +#endif + /* testing %[ */ + SCANF_TEST( 1, "abcdefg", "%[cba]", buffer ); + TESTCASE( memcmp( buffer, "abc\0", 4 ) == 0 ); + /* testing %p */ + p = NULL; + sprintf( buffer, "%p", p ); + p = &i; + SCANF_TEST( 1, buffer, "%p", &p ); + TESTCASE( p == NULL ); + p = &i; + sprintf( buffer, "%p", p ); + p = NULL; + SCANF_TEST( 1, buffer, "%p", &p ); + TESTCASE( p == &i ); } -- 2.40.0 From 0d39579ef886e25aa6c87053de44ddd4c8a71803 Mon Sep 17 00:00:00 2001 From: solar <> Date: Wed, 22 Dec 2010 21:44:28 +0000 Subject: [PATCH 03/16] Comment on v0.5 release --- Readme.txt | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Readme.txt b/Readme.txt index 315e0bb..0628fc6 100644 --- a/Readme.txt +++ b/Readme.txt @@ -183,7 +183,7 @@ a backport of bugfixes in the current development code. - #9 stdint.h dysfunctional (fixed) - #10 NULL redefinition warnings (fixed) -v0.5 - unreleased +v0.5 - 2010-12-22 Implementations for , , most parts of , and strerror() from . Still no locale / wide-char support. Enabled all GCC compiler warnings I @@ -191,3 +191,27 @@ could find, and fixed everything that threw a warning. (You see this, maintainers of Open Source software? No warnings whatsoever. Stop telling me it cannot be done.) Fixed all known bugs in the v0.4 release. + +A WORD ON THE v0.5 RELEASE +========================== + +The v0.5 release is not well-tested. There are several things in it done +in a way that I would never label "release quality". Some things are not +even in the *structure* I would like them to be. An example for this is +the current handling of errno values: It needlessly introduces dependency +on PDCLib (because I use non-standard values), and the values are placed +in the wrong header (_PDCLIB_int.h instead of _PDCLIB_glue.h where they +would be more appropriate). + +But at some point during the development toward the v0.5 release, I found +that my current PDCLib work schedule simply does not allow me to wait +until every piece of is as I would like it to be. It would +probably take another year or two, and my patience is UP. + +I want this released, and I want to think about something else but + for some time. + +So, expect significant change to how stdio is done in upcoming releases. +Everything *WILL* be stable by the time v1.0 comes around, but until then +you will have to accept that I can only deliver "hobby quality" for now. + -- 2.40.0 From 88ada2223031864fa3057b923ee7a03d6a710785 Mon Sep 17 00:00:00 2001 From: solar <> Date: Thu, 23 Dec 2010 06:15:28 +0000 Subject: [PATCH 04/16] Started out on v0.6. --- includes/ctype.h | 88 ++++++++++++++++++--- includes/errno.h | 2 +- includes/locale.h | 94 +++++++++++++++++++++++ includes/stdio.h | 2 +- includes/stdlib.h | 2 +- includes/string.h | 2 +- platform/example/includes/signal.h | 2 +- platform/example_cygwin/includes/signal.h | 2 +- 8 files changed, 179 insertions(+), 15 deletions(-) create mode 100644 includes/locale.h diff --git a/includes/ctype.h b/includes/ctype.h index 2c8071c..a4ac534 100644 --- a/includes/ctype.h +++ b/includes/ctype.h @@ -9,15 +9,85 @@ #ifndef _PDCLIB_CTYPE_H #define _PDCLIB_CTYPE_H _PDCLIB_CTYPE_H -/* ------------------------------------------------------------------------- */ -/* THIS IS A STUB - THIS IS A STUB - THIS IS A STUB - THIS IS A STUB */ -/* ------------------------------------------------------------------------- */ -/* This implements two functions that are required by / */ -/* for the C locale only. Will be replaced in v0.6 by something compliant. */ -/* ------------------------------------------------------------------------- */ - -int tolower( int c ); +/* Character classification functions */ + +/* Note that there is a difference between "whitespace" (any printing, non- + graph character, like horizontal and vertical tab), and "blank" (the literal + ' ' space character). + + There will be masking macros for each of these later on, but right now I + focus on the functions only. +*/ + +/* Returns isalpha( c ) || isdigit( c ) */ +int isalnum( int c ); + +/* Returns isupper( c ) || islower( c ) in the "C" locale. + In any other locale, also returns true for a locale-specific set of + alphabetic characters which are neither control characters, digits, + punctation, or whitespace. +*/ +int isalpha( int c ); + +/* Returns true if the character is a whitespace. In the "C" locale, only ' ' + and '\t' are considered whitespace. +*/ +int isblank( int c ); + +/* Returns true if the character is a control character. */ +int iscntrl( int c ); + +/* Returns true if the character is a decimal digit. */ +int isdigit( int c ); + +/* Returns true for every printing character except space (' '). */ +int isgraph( int c ); + +/* Returns true for lowercase letters in the "C" locale. + In any other locale, also returns true for a locale-specific set of + characters which are neither control characters, digits, punctation, or + space (' '). In a locale other than the "C" locale, a character might test + true for both islower() and isupper(). +*/ +int islower( int c ); + +/* Returns true for every printing character including space (' '). */ +int isprint( int c ); + +/* Returns true for every printing character that is neither whitespace + nor alphanumeric in the "C" locale. In any other locale, there might be + characters that are printing characters, but neither whitespace nor + alphanumeric. +*/ +int ispunct( int c ); + +/* Returns true for every standard whitespace character (' ', '\f', '\n', '\r', + '\t', '\v') in the "C" locale. In any other locale, also returns true for a + locale-specific set of characters for which isalnum() is false. +*/ int isspace( int c ); -#endif +/* Returns true for uppercase letters in the "C" locale. + In any other locale, also returns true for a locale-specific set of + characters which are neither control characters, digits, punctation, or + space (' '). In a locale other than the "C" locale, a character might test + true for both islower() and isupper(). +*/ +int isupper( int c ); + +/* Returns true for any hexadecimal-digit character. */ +int isxdigit( int c ); +/* Character case mapping functions */ + +/* Converts an uppercase letter to a corresponding lowercase letter. Input that + is not an uppercase letter remains unchanged. +*/ +int tolower( c ); + +/* Converts a lowercase letter to a corresponding uppercase letter. Input that + is not a lowercase letter remains unchanged. +*/ +int toupper( c ); + +#endif diff --git a/includes/errno.h b/includes/errno.h index 2795fdf..90c61db 100644 --- a/includes/errno.h +++ b/includes/errno.h @@ -1,6 +1,6 @@ /* $Id$ */ -/* Errors +/* 7.5 Errors This file is part of the Public Domain C Library (PDCLib). Permission is granted to use, modify, and / or redistribute at will. diff --git a/includes/locale.h b/includes/locale.h new file mode 100644 index 0000000..fd014db --- /dev/null +++ b/includes/locale.h @@ -0,0 +1,94 @@ +/* $Id$ */ + +/* 7.11 Localization + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#ifndef _PDCLIB_LOCALE_H +#define _PDCLIB_LOCALE_H _PDCLIB_LOCALE_H + +/* The structure returned by localeconv(). + + The values for *_sep_by_space: + 0 - no space + 1 - if symbol and sign are adjacent, a space seperates them from the value; + otherwise a space seperates the symbol from the value + 2 - if symbol and sign are adjacent, a space seperates them; otherwise a + space seperates the sign from the value + + The values for *_sign_posn: + 0 - Parentheses surround value and symbol + 1 - sign precedes value and symbol + 2 - sign succeeds value and symbol + 3 - sign immediately precedes symbol + 4 - sign immediately succeeds symbol +*/ +struct lconv +{ + char * decimal_point; /* decimal point character */ + char * thousands_sep; /* character for seperating groups of digits */ + char * grouping; /* string indicating the size of digit groups */ + char * mon_decimal_point; /* decimal point for monetary quantities */ + char * mon_thousands_sep; /* thousands_sep for monetary quantities */ + char * mon_grouping; /* grouping for monetary quantities */ + char * positive_sign; /* string indicating nonnegative mty. qty. */ + char * negative_sign; /* string indicating negative mty. qty. */ + char * currency_symbol; /* local currency symbol (e.g. '$') */ + char * int_curr_symbol; /* international currency symbol (e.g. "USD" */ + char frac_digits; /* fractional digits in local monetary qty. */ + char p_cs_precedes; /* if currency_symbol precedes positive qty. */ + char n_cs_precedes; /* if currency_symbol precedes negative qty. */ + char p_sep_by_space; /* if it is seperated by space from pos. qty. */ + char n_sep_by_space; /* if it is seperated by space from neg. qty. */ + char p_sign_posn; /* positioning of positive_sign for mon. qty. */ + char n_sign_posn; /* positioning of negative_sign for mon. qty. */ + char int_frac_digits; /* Same as above, for international format */ + char int_p_cs_precedes; /* Same as above, for international format */ + char int_n_cs_precedes; /* Same as above, for international format */ + char int_p_sep_by_space; /* Same as above, for international format */ + char int_n_sep_by_space; /* Same as above, for international format */ + char int_p_sign_posn; /* Same as above, for international format */ + char int_n_sign_posn; /* Same as above, for international format */ +} + +#ifndef _PDCLIB_NULL_DEFINED +#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED +#define NULL _PDCLIB_NULL +#endif + +/* LC_ALL + - entire locale + LC_COLLATE + - strcoll(), strxfrm() + LC_CTYPE + - + LC_MONETARY + - monetary formatting as returned by localeconv + LC_NUMERIC + - decimal-point character for printf() / scanf() functions, string + conversions, and nonmonetary formattign as returned by localeconv + LC_TIME + - strftime(), wcsftime() + + First arguments to setlocale(). +*/ + +/* The category parameter can be any of the LC_* macros to specify if the call + to setlocale() shall affect the entire locale or only a portion thereof. + The category locale specifies which locale should be switched to, with "C" + being the minimal default locale, and "" being the locale-specific native + environment. A NULL pointer makes setlocale() return the *current* setting. + Otherwise, returns a pointer to a string associated with the specified + category for the new locale. +*/ +char * setlocale( int category, const char * locale ); + +/* Returns a struct lconv initialized to the values appropriate for the current + locale setting. +*/ +struct lconv * localeconv( void ); + +#endif + diff --git a/includes/stdio.h b/includes/stdio.h index b9a0224..6b562d9 100644 --- a/includes/stdio.h +++ b/includes/stdio.h @@ -1,6 +1,6 @@ /* $Id$ */ -/* Input/output +/* 7.19 Input/output This file is part of the Public Domain C Library (PDCLib). Permission is granted to use, modify, and / or redistribute at will. diff --git a/includes/stdlib.h b/includes/stdlib.h index f84851b..b035c9c 100644 --- a/includes/stdlib.h +++ b/includes/stdlib.h @@ -1,6 +1,6 @@ /* $Id$ */ -/* General utilities +/* 7.20 General utilities This file is part of the Public Domain C Library (PDCLib). Permission is granted to use, modify, and / or redistribute at will. diff --git a/includes/string.h b/includes/string.h index ef70df0..c5f74b5 100644 --- a/includes/string.h +++ b/includes/string.h @@ -1,6 +1,6 @@ /* $Id$ */ -/* String handling +/* 7.21 String handling This file is part of the Public Domain C Library (PDCLib). Permission is granted to use, modify, and / or redistribute at will. diff --git a/platform/example/includes/signal.h b/platform/example/includes/signal.h index e1b10f8..9b812c9 100644 --- a/platform/example/includes/signal.h +++ b/platform/example/includes/signal.h @@ -1,6 +1,6 @@ /* $Id$ */ -/* Signal handling +/* 7.14 Signal handling This file is part of the Public Domain C Library (PDCLib). Permission is granted to use, modify, and / or redistribute at will. diff --git a/platform/example_cygwin/includes/signal.h b/platform/example_cygwin/includes/signal.h index e1b10f8..9b812c9 100644 --- a/platform/example_cygwin/includes/signal.h +++ b/platform/example_cygwin/includes/signal.h @@ -1,6 +1,6 @@ /* $Id$ */ -/* Signal handling +/* 7.14 Signal handling This file is part of the Public Domain C Library (PDCLib). Permission is granted to use, modify, and / or redistribute at will. -- 2.40.0 From be35e77c0d824e5bd545620ca81c812f9e16f0e5 Mon Sep 17 00:00:00 2001 From: solar <> Date: Thu, 23 Dec 2010 06:16:56 +0000 Subject: [PATCH 05/16] Forgot parameter type. --- includes/ctype.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/ctype.h b/includes/ctype.h index a4ac534..adf5ce2 100644 --- a/includes/ctype.h +++ b/includes/ctype.h @@ -83,11 +83,11 @@ int isxdigit( int c ); /* Converts an uppercase letter to a corresponding lowercase letter. Input that is not an uppercase letter remains unchanged. */ -int tolower( c ); +int tolower( int c ); /* Converts a lowercase letter to a corresponding uppercase letter. Input that is not a lowercase letter remains unchanged. */ -int toupper( c ); +int toupper( int c ); #endif -- 2.40.0 From 3a92b78272cd3f0f413bb1cfc0c77deef49967fd Mon Sep 17 00:00:00 2001 From: solar <> Date: Wed, 29 Dec 2010 06:25:59 +0000 Subject: [PATCH 06/16] ctype --- functions/ctype/isalnum.c | 37 +++ functions/ctype/isalpha.c | 33 +++ functions/ctype/isblank.c | 34 +++ functions/ctype/iscntrl.c | 32 +++ functions/ctype/isdigit.c | 33 +++ functions/ctype/isgraph.c | 36 +++ functions/ctype/islower.c | 34 +++ functions/ctype/isprint.c | 36 +++ functions/ctype/ispunct.c | 37 +++ functions/ctype/isspace.c | 14 +- functions/ctype/isupper.c | 34 +++ functions/ctype/isxdigit.c | 38 +++ functions/ctype/tolower.c | 6 +- functions/ctype/toupper.c | 33 +++ includes/ctype.h | 13 +- internals/_PDCLIB_int.h | 31 +++ platform/example/functions/_PDCLIB/stdinit.c | 266 +++++++++++++++++++ 17 files changed, 725 insertions(+), 22 deletions(-) create mode 100644 functions/ctype/isalnum.c create mode 100644 functions/ctype/isalpha.c create mode 100644 functions/ctype/isblank.c create mode 100644 functions/ctype/iscntrl.c create mode 100644 functions/ctype/isdigit.c create mode 100644 functions/ctype/isgraph.c create mode 100644 functions/ctype/islower.c create mode 100644 functions/ctype/isprint.c create mode 100644 functions/ctype/ispunct.c create mode 100644 functions/ctype/isupper.c create mode 100644 functions/ctype/isxdigit.c create mode 100644 functions/ctype/toupper.c diff --git a/functions/ctype/isalnum.c b/functions/ctype/isalnum.c new file mode 100644 index 0000000..d6e217b --- /dev/null +++ b/functions/ctype/isalnum.c @@ -0,0 +1,37 @@ +/* $Id$ */ + +/* isalnum( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int isalnum( int c ) +{ + return ( _PDCLIB_locale_info.ctype[c].flags & ( _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT ) ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( isalnum( 'a' ) ); + TESTCASE( isalnum( 'z' ) ); + TESTCASE( isalnum( 'A' ) ); + TESTCASE( isalnum( 'Z' ) ); + TESTCASE( isalnum( '0' ) ); + TESTCASE( isalnum( '9' ) ); + TESTCASE( ! isalnum( ' ' ) ); + TESTCASE( ! isalnum( '\n' ) ); + TESTCASE( ! isalnum( '@' ) ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/ctype/isalpha.c b/functions/ctype/isalpha.c new file mode 100644 index 0000000..2bde755 --- /dev/null +++ b/functions/ctype/isalpha.c @@ -0,0 +1,33 @@ +/* $Id$ */ + +/* isalpha( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int isalpha( int c ) +{ + return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_ALPHA ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( isalpha( 'a' ) ); + TESTCASE( isalpha( 'z' ) ); + TESTCASE( ! isalpha( ' ' ) ); + TESTCASE( ! isalpha( '1' ) ); + TESTCASE( ! isalpha( '@' ) ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/ctype/isblank.c b/functions/ctype/isblank.c new file mode 100644 index 0000000..0ad1ca1 --- /dev/null +++ b/functions/ctype/isblank.c @@ -0,0 +1,34 @@ +/* $Id$ */ + +/* isblank( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int isblank( int c ) +{ + return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_BLANK ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( isblank( ' ' ) ); + TESTCASE( isblank( '\t' ) ); + TESTCASE( ! isblank( '\v' ) ); + TESTCASE( ! isblank( '\r' ) ); + TESTCASE( ! isblank( 'x' ) ); + TESTCASE( ! isblank( '@' ) ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/ctype/iscntrl.c b/functions/ctype/iscntrl.c new file mode 100644 index 0000000..583ccb3 --- /dev/null +++ b/functions/ctype/iscntrl.c @@ -0,0 +1,32 @@ +/* $Id$ */ + +/* iscntrl( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int iscntrl( int c ) +{ + return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_CNTRL ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( iscntrl( '\a' ) ); + TESTCASE( iscntrl( '\b' ) ); + TESTCASE( iscntrl( '\n' ) ); + TESTCASE( ! iscntrl( ' ' ) ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/ctype/isdigit.c b/functions/ctype/isdigit.c new file mode 100644 index 0000000..eeeffb8 --- /dev/null +++ b/functions/ctype/isdigit.c @@ -0,0 +1,33 @@ +/* $Id$ */ + +/* isdigit( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int isdigit( int c ) +{ + return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_DIGIT ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( isdigit( '0' ) ); + TESTCASE( isdigit( '9' ) ); + TESTCASE( ! isdigit( ' ' ) ); + TESTCASE( ! isdigit( 'a' ) ); + TESTCASE( ! isdigit( '@' ) ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/ctype/isgraph.c b/functions/ctype/isgraph.c new file mode 100644 index 0000000..b2cccc8 --- /dev/null +++ b/functions/ctype/isgraph.c @@ -0,0 +1,36 @@ +/* $Id$ */ + +/* isgraph( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int isgraph( int c ) +{ + return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_GRAPH ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( isgraph( 'a' ) ); + TESTCASE( isgraph( 'z' ) ); + TESTCASE( isgraph( 'A' ) ); + TESTCASE( isgraph( 'Z' ) ); + TESTCASE( isgraph( '@' ) ); + TESTCASE( ! isgraph( '\t' ) ); + TESTCASE( ! isgraph( '\0' ) ); + TESTCASE( ! isgraph( ' ' ) ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/ctype/islower.c b/functions/ctype/islower.c new file mode 100644 index 0000000..d98069a --- /dev/null +++ b/functions/ctype/islower.c @@ -0,0 +1,34 @@ +/* $Id$ */ + +/* islower( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int islower( int c ) +{ + return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_LOWER ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( islower( 'a' ) ); + TESTCASE( islower( 'z' ) ); + TESTCASE( ! islower( 'A' ) ); + TESTCASE( ! islower( 'Z' ) ); + TESTCASE( ! islower( ' ' ) ); + TESTCASE( ! islower( '@' ) ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/ctype/isprint.c b/functions/ctype/isprint.c new file mode 100644 index 0000000..f057e00 --- /dev/null +++ b/functions/ctype/isprint.c @@ -0,0 +1,36 @@ +/* $Id$ */ + +/* isprint( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int isprint( int c ) +{ + return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_GRAPH ) || ( c == ' ' ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( isprint( 'a' ) ); + TESTCASE( isprint( 'z' ) ); + TESTCASE( isprint( 'A' ) ); + TESTCASE( isprint( 'Z' ) ); + TESTCASE( isprint( '@' ) ); + TESTCASE( ! isprint( '\t' ) ); + TESTCASE( ! isprint( '\0' ) ); + TESTCASE( isprint( ' ' ) ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/ctype/ispunct.c b/functions/ctype/ispunct.c new file mode 100644 index 0000000..2859efc --- /dev/null +++ b/functions/ctype/ispunct.c @@ -0,0 +1,37 @@ +/* $Id$ */ + +/* ispunct( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int ispunct( int c ) +{ + return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_PUNCT ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( ! ispunct( 'a' ) ); + TESTCASE( ! ispunct( 'z' ) ); + TESTCASE( ! ispunct( 'A' ) ); + TESTCASE( ! ispunct( 'Z' ) ); + TESTCASE( ispunct( '@' ) ); + TESTCASE( ispunct( '.' ) ); + TESTCASE( ! ispunct( '\t' ) ); + TESTCASE( ! ispunct( '\0' ) ); + TESTCASE( ! ispunct( ' ' ) ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/ctype/isspace.c b/functions/ctype/isspace.c index 346167e..90b6dc5 100644 --- a/functions/ctype/isspace.c +++ b/functions/ctype/isspace.c @@ -7,24 +7,12 @@ */ #include -#include #ifndef REGTEST int isspace( int c ) { - switch ( c ) - { - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - case '\v': - return true; - default: - return false; - } + return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_SPACE ); } #endif diff --git a/functions/ctype/isupper.c b/functions/ctype/isupper.c new file mode 100644 index 0000000..76c1ff1 --- /dev/null +++ b/functions/ctype/isupper.c @@ -0,0 +1,34 @@ +/* $Id$ */ + +/* isupper( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int isupper( int c ) +{ + return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_UPPER ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( isupper( 'A' ) ); + TESTCASE( isupper( 'Z' ) ); + TESTCASE( ! isupper( 'a' ) ); + TESTCASE( ! isupper( 'z' ) ); + TESTCASE( ! isupper( ' ' ) ); + TESTCASE( ! isupper( '@' ) ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/ctype/isxdigit.c b/functions/ctype/isxdigit.c new file mode 100644 index 0000000..55818df --- /dev/null +++ b/functions/ctype/isxdigit.c @@ -0,0 +1,38 @@ +/* $Id$ */ + +/* isxdigit( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int isxdigit( int c ) +{ + return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_XDIGT ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( isxdigit( '0' ) ); + TESTCASE( isxdigit( '9' ) ); + TESTCASE( isxdigit( 'a' ) ); + TESTCASE( isxdigit( 'f' ) ); + TESTCASE( ! isxdigit( 'g' ) ); + TESTCASE( isxdigit( 'A' ) ); + TESTCASE( isxdigit( 'F' ) ); + TESTCASE( ! isxdigit( 'G' ) ); + TESTCASE( ! isxdigit( '@' ) ); + TESTCASE( ! isxdigit( ' ' ) ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/ctype/tolower.c b/functions/ctype/tolower.c index 28c435d..530abf2 100644 --- a/functions/ctype/tolower.c +++ b/functions/ctype/tolower.c @@ -12,11 +12,7 @@ int tolower( int c ) { - if ( ( c >= 'A' ) && ( c <= 'Z' ) ) - { - c += ( 'a' - 'A' ); - } - return c; + return _PDCLIB_locale_info.ctype[c].lower; } #endif diff --git a/functions/ctype/toupper.c b/functions/ctype/toupper.c new file mode 100644 index 0000000..00cb203 --- /dev/null +++ b/functions/ctype/toupper.c @@ -0,0 +1,33 @@ +/* $Id$ */ + +/* toupper( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int toupper( int c ) +{ + return _PDCLIB_locale_info.ctype[c].upper; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( toupper( 'a' ) == 'A' ); + TESTCASE( toupper( 'z' ) == 'Z' ); + TESTCASE( toupper( 'A' ) == 'A' ); + TESTCASE( toupper( 'Z' ) == 'Z' ); + TESTCASE( toupper( '@' ) == '@' ); + TESTCASE( toupper( '[' ) == '[' ); + return TEST_RESULTS; +} +#endif diff --git a/includes/ctype.h b/includes/ctype.h index adf5ce2..ae95146 100644 --- a/includes/ctype.h +++ b/includes/ctype.h @@ -9,6 +9,11 @@ #ifndef _PDCLIB_CTYPE_H #define _PDCLIB_CTYPE_H _PDCLIB_CTYPE_H +#ifndef _PDCLIB_INT_H +#define _PDCLIB_INT_H _PDCLIB_INT_H +#include <_PDCLIB_int.h> +#endif + /* Character classification functions */ /* Note that there is a difference between "whitespace" (any printing, non- @@ -29,15 +34,15 @@ int isalnum( int c ); */ int isalpha( int c ); -/* Returns true if the character is a whitespace. In the "C" locale, only ' ' - and '\t' are considered whitespace. +/* Returns true if the character isspace() and used for seperating words within + a line of text. In the "C" locale, only ' ' and '\t' are considered blanks. */ int isblank( int c ); /* Returns true if the character is a control character. */ int iscntrl( int c ); -/* Returns true if the character is a decimal digit. */ +/* Returns true if the character is a decimal digit. Locale-independent. */ int isdigit( int c ); /* Returns true for every printing character except space (' '). */ @@ -75,7 +80,7 @@ int isspace( int c ); */ int isupper( int c ); -/* Returns true for any hexadecimal-digit character. */ +/* Returns true for any hexadecimal-digit character. Locale-independent. */ int isxdigit( int c ); /* Character case mapping functions */ diff --git a/internals/_PDCLIB_int.h b/internals/_PDCLIB_int.h index 0bad643..b5003af 100644 --- a/internals/_PDCLIB_int.h +++ b/internals/_PDCLIB_int.h @@ -426,3 +426,34 @@ int * _PDCLIB_errno_func( void ); /* TODO: Doing this via a static array is not the way to do it. */ char const * _PDCLIB_errno_texts[ _PDCLIB_EMAX ]; + +/* -------------------------------------------------------------------------- */ +/* lookup tables */ +/* -------------------------------------------------------------------------- */ + +#define _PDCLIB_CTYPE_ALPHA 1 +#define _PDCLIB_CTYPE_BLANK 2 +#define _PDCLIB_CTYPE_CNTRL 4 +#define _PDCLIB_CTYPE_GRAPH 8 +#define _PDCLIB_CTYPE_PUNCT 16 +#define _PDCLIB_CTYPE_SPACE 32 +#define _PDCLIB_CTYPE_LOWER 64 +#define _PDCLIB_CTYPE_UPPER 128 +#define _PDCLIB_CTYPE_DIGIT 256 +#define _PDCLIB_CTYPE_XDIGT 512 + +struct _PDCLIB_ctype_t +{ + _PDCLIB_uint16_t flags; + unsigned char upper; + unsigned char lower; + unsigned char collation; +}; + +struct _PDCLIB_locale_t +{ + struct _PDCLIB_ctype_t * ctype; +}; + +struct _PDCLIB_locale_t _PDCLIB_locale_info; + diff --git a/platform/example/functions/_PDCLIB/stdinit.c b/platform/example/functions/_PDCLIB/stdinit.c index 8ddb774..a90d283 100644 --- a/platform/example/functions/_PDCLIB/stdinit.c +++ b/platform/example/functions/_PDCLIB/stdinit.c @@ -38,6 +38,272 @@ struct _PDCLIB_file_t * stderr = &_PDCLIB_serr; /* FIXME: This approach is a possible attack vector. */ struct _PDCLIB_file_t * _PDCLIB_filelist = &_PDCLIB_sin; +/* "C" locale - defaulting to ASCII-7. + 1 kByte (+ 4 byte) of data. + Each line: flags, lowercase, uppercase, collation. +*/ +static struct _PDCLIB_ctype_t ctype_info[] = { + { /* EOF */ 0, 0, 0, 0 }, + { /* NUL */ _PDCLIB_CTYPE_CNTRL, 0x00, 0x00, 0x00 }, + { /* SOH */ _PDCLIB_CTYPE_CNTRL, 0x01, 0x01, 0x01 }, + { /* STX */ _PDCLIB_CTYPE_CNTRL, 0x02, 0x02, 0x02 }, + { /* ETX */ _PDCLIB_CTYPE_CNTRL, 0x03, 0x03, 0x03 }, + { /* EOT */ _PDCLIB_CTYPE_CNTRL, 0x04, 0x04, 0x04 }, + { /* ENQ */ _PDCLIB_CTYPE_CNTRL, 0x05, 0x05, 0x05 }, + { /* ACK */ _PDCLIB_CTYPE_CNTRL, 0x06, 0x06, 0x06 }, + { /* BEL */ _PDCLIB_CTYPE_CNTRL, 0x07, 0x07, 0x07 }, + { /* BS */ _PDCLIB_CTYPE_CNTRL, 0x08, 0x08, 0x08 }, + { /* HT */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_BLANK | _PDCLIB_CTYPE_SPACE, 0x09, 0x09, 0x09 }, + { /* LF */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0A, 0x0A, 0x0A }, + { /* VT */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0B, 0x0B, 0x0B }, + { /* FF */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0C, 0x0C, 0x0C }, + { /* CR */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0D, 0x0D, 0x0D }, + { /* SO */ _PDCLIB_CTYPE_CNTRL, 0x0E, 0x0E, 0x0E }, + { /* SI */ _PDCLIB_CTYPE_CNTRL, 0x0F, 0x0F, 0x0F }, + { /* DLE */ _PDCLIB_CTYPE_CNTRL, 0x10, 0x10, 0x10 }, + { /* DC1 */ _PDCLIB_CTYPE_CNTRL, 0x11, 0x11, 0x11 }, + { /* DC2 */ _PDCLIB_CTYPE_CNTRL, 0x12, 0x12, 0x12 }, + { /* DC3 */ _PDCLIB_CTYPE_CNTRL, 0x13, 0x13, 0x13 }, + { /* DC4 */ _PDCLIB_CTYPE_CNTRL, 0x14, 0x14, 0x14 }, + { /* NAK */ _PDCLIB_CTYPE_CNTRL, 0x15, 0x15, 0x15 }, + { /* SYN */ _PDCLIB_CTYPE_CNTRL, 0x16, 0x16, 0x16 }, + { /* ETB */ _PDCLIB_CTYPE_CNTRL, 0x17, 0x17, 0x17 }, + { /* CAN */ _PDCLIB_CTYPE_CNTRL, 0x18, 0x18, 0x18 }, + { /* EM */ _PDCLIB_CTYPE_CNTRL, 0x19, 0x19, 0x19 }, + { /* SUB */ _PDCLIB_CTYPE_CNTRL, 0x1A, 0x1A, 0x1A }, + { /* ESC */ _PDCLIB_CTYPE_CNTRL, 0x1B, 0x1B, 0x1B }, + { /* FS */ _PDCLIB_CTYPE_CNTRL, 0x1C, 0x1C, 0x1C }, + { /* GS */ _PDCLIB_CTYPE_CNTRL, 0x1D, 0x1D, 0x1D }, + { /* RS */ _PDCLIB_CTYPE_CNTRL, 0x1E, 0x1E, 0x1E }, + { /* US */ _PDCLIB_CTYPE_CNTRL, 0x1F, 0x1F, 0x1F }, + { /* SP */ _PDCLIB_CTYPE_BLANK | _PDCLIB_CTYPE_SPACE, 0x20, 0x20, 0x20 }, + { /* '!' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x21, 0x21, 0x21 }, + { /* '"' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x22, 0x22, 0x22 }, + { /* '#' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x23, 0x23, 0x23 }, + { /* '$' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x24, 0x24, 0x24 }, + { /* '%' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x25, 0x25, 0x25 }, + { /* '&' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x26, 0x26, 0x26 }, + { /* ''' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x27, 0x27, 0x27 }, + { /* '(' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x28, 0x28, 0x28 }, + { /* ')' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x29, 0x29, 0x29 }, + { /* '*' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2A, 0x2A, 0x2A }, + { /* '+' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2B, 0x2B, 0x2B }, + { /* ',' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2C, 0x2C, 0x2C }, + { /* '-' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2D, 0x2D, 0x2D }, + { /* '.' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2E, 0x2E, 0x2E }, + { /* '/' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2F, 0x2F, 0x2F }, + { /* '0' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x30, 0x30, 0x30 }, + { /* '1' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x31, 0x31, 0x31 }, + { /* '2' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x32, 0x32, 0x32 }, + { /* '3' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x33, 0x33, 0x33 }, + { /* '4' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x34, 0x34, 0x34 }, + { /* '5' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x35, 0x35, 0x35 }, + { /* '6' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x36, 0x36, 0x36 }, + { /* '7' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x37, 0x37, 0x37 }, + { /* '8' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x38, 0x38, 0x38 }, + { /* '9' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_DIGIT | _PDCLIB_CTYPE_XDIGT, 0x39, 0x39, 0x39 }, + { /* ':' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3A, 0x3A, 0x3A }, + { /* ';' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3B, 0x3B, 0x3B }, + { /* '<' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3C, 0x3C, 0x3C }, + { /* '=' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3D, 0x3D, 0x3D }, + { /* '>' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3E, 0x3E, 0x3E }, + { /* '?' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3F, 0x3F, 0x3F }, + { /* '@' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x40, 0x40, 0x40 }, + { /* 'A' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x41, 0x61, 0x41 }, + { /* 'B' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x42, 0x62, 0x42 }, + { /* 'C' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x43, 0x63, 0x43 }, + { /* 'D' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x44, 0x64, 0x44 }, + { /* 'E' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x45, 0x65, 0x45 }, + { /* 'F' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER | _PDCLIB_CTYPE_XDIGT, 0x46, 0x66, 0x46 }, + { /* 'G' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x47, 0x67, 0x47 }, + { /* 'H' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x48, 0x68, 0x48 }, + { /* 'I' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x49, 0x69, 0x49 }, + { /* 'J' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4A, 0x6A, 0x4A }, + { /* 'K' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4B, 0x6B, 0x4B }, + { /* 'L' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4C, 0x6C, 0x4C }, + { /* 'M' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4D, 0x6D, 0x4D }, + { /* 'N' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4E, 0x6E, 0x4E }, + { /* 'O' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4F, 0x6F, 0x4F }, + { /* 'P' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x50, 0x70, 0x50 }, + { /* 'Q' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x51, 0x71, 0x51 }, + { /* 'R' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x52, 0x72, 0x52 }, + { /* 'S' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x53, 0x73, 0x53 }, + { /* 'T' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x54, 0x74, 0x54 }, + { /* 'U' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x55, 0x75, 0x55 }, + { /* 'V' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x56, 0x76, 0x56 }, + { /* 'W' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x57, 0x77, 0x57 }, + { /* 'X' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x58, 0x78, 0x58 }, + { /* 'Y' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x59, 0x79, 0x59 }, + { /* 'Z' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x5A, 0x7A, 0x5A }, + { /* '[' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5B, 0x5B, 0x5B }, + { /* '\' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5C, 0x5C, 0x5C }, + { /* ']' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5D, 0x5D, 0x5D }, + { /* '^' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5E, 0x5E, 0x5E }, + { /* '_' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5F, 0x5F, 0x5F }, + { /* '`' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x60, 0x60, 0x60 }, + { /* 'a' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x41, 0x61, 0x61 }, + { /* 'b' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x42, 0x62, 0x62 }, + { /* 'c' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x43, 0x63, 0x63 }, + { /* 'd' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x44, 0x64, 0x64 }, + { /* 'e' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x45, 0x65, 0x65 }, + { /* 'f' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER | _PDCLIB_CTYPE_XDIGT, 0x46, 0x66, 0x66 }, + { /* 'g' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x47, 0x67, 0x67 }, + { /* 'h' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x48, 0x68, 0x68 }, + { /* 'i' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x49, 0x69, 0x69 }, + { /* 'j' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4A, 0x6A, 0x6A }, + { /* 'k' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4B, 0x6B, 0x6B }, + { /* 'l' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4C, 0x6C, 0x6C }, + { /* 'm' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4D, 0x6D, 0x6D }, + { /* 'n' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4E, 0x6E, 0x6E }, + { /* 'o' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4F, 0x6F, 0x6F }, + { /* 'p' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x50, 0x70, 0x70 }, + { /* 'q' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x51, 0x71, 0x71 }, + { /* 'r' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x52, 0x72, 0x72 }, + { /* 's' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x53, 0x73, 0x73 }, + { /* 't' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x54, 0x74, 0x74 }, + { /* 'u' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x55, 0x75, 0x75 }, + { /* 'v' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x56, 0x76, 0x76 }, + { /* 'w' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x57, 0x77, 0x77 }, + { /* 'x' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x58, 0x78, 0x78 }, + { /* 'y' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x59, 0x79, 0x79 }, + { /* 'z' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x5A, 0x7A, 0x7A }, + { /* '{' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7B, 0x7B, 0x7B }, + { /* '|' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7C, 0x7C, 0x7C }, + { /* '}' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7D, 0x7D, 0x7D }, + { /* '~' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7E, 0x7E, 0x7E }, + { /* DEL */ _PDCLIB_CTYPE_CNTRL, 0x7F, 0x7F, 0x7F }, + { 0x00, 0x80, 0x80, 0x80 }, + { 0x00, 0x81, 0x81, 0x81 }, + { 0x00, 0x82, 0x82, 0x82 }, + { 0x00, 0x83, 0x83, 0x83 }, + { 0x00, 0x84, 0x84, 0x84 }, + { 0x00, 0x85, 0x85, 0x85 }, + { 0x00, 0x86, 0x86, 0x86 }, + { 0x00, 0x87, 0x87, 0x87 }, + { 0x00, 0x88, 0x88, 0x88 }, + { 0x00, 0x89, 0x89, 0x89 }, + { 0x00, 0x8A, 0x8A, 0x8A }, + { 0x00, 0x8B, 0x8B, 0x8B }, + { 0x00, 0x8C, 0x8C, 0x8C }, + { 0x00, 0x8D, 0x8D, 0x8D }, + { 0x00, 0x8E, 0x8E, 0x8E }, + { 0x00, 0x8F, 0x8F, 0x8F }, + { 0x00, 0x90, 0x90, 0x90 }, + { 0x00, 0x91, 0x91, 0x91 }, + { 0x00, 0x92, 0x92, 0x92 }, + { 0x00, 0x93, 0x93, 0x93 }, + { 0x00, 0x94, 0x94, 0x94 }, + { 0x00, 0x95, 0x95, 0x95 }, + { 0x00, 0x96, 0x96, 0x96 }, + { 0x00, 0x97, 0x97, 0x97 }, + { 0x00, 0x98, 0x98, 0x98 }, + { 0x00, 0x99, 0x99, 0x99 }, + { 0x00, 0x9A, 0x9A, 0x9A }, + { 0x00, 0x9B, 0x9B, 0x9B }, + { 0x00, 0x9C, 0x9C, 0x9C }, + { 0x00, 0x9D, 0x9D, 0x9D }, + { 0x00, 0x9E, 0x9E, 0x9E }, + { 0x00, 0x9F, 0x9F, 0x9F }, + { 0x00, 0xA0, 0xA0, 0xA0 }, + { 0x00, 0xA1, 0xA1, 0xA1 }, + { 0x00, 0xA2, 0xA2, 0xA2 }, + { 0x00, 0xA3, 0xA3, 0xA3 }, + { 0x00, 0xA4, 0xA4, 0xA4 }, + { 0x00, 0xA5, 0xA5, 0xA5 }, + { 0x00, 0xA6, 0xA6, 0xA6 }, + { 0x00, 0xA7, 0xA7, 0xA7 }, + { 0x00, 0xA8, 0xA8, 0xA8 }, + { 0x00, 0xA9, 0xA9, 0xA9 }, + { 0x00, 0xAA, 0xAA, 0xAA }, + { 0x00, 0xAB, 0xAB, 0xAB }, + { 0x00, 0xAC, 0xAC, 0xAC }, + { 0x00, 0xAD, 0xAD, 0xAD }, + { 0x00, 0xAE, 0xAE, 0xAE }, + { 0x00, 0xAF, 0xAF, 0xAF }, + { 0x00, 0xB0, 0xB0, 0xB0 }, + { 0x00, 0xB1, 0xB1, 0xB1 }, + { 0x00, 0xB2, 0xB2, 0xB2 }, + { 0x00, 0xB3, 0xB3, 0xB3 }, + { 0x00, 0xB4, 0xB4, 0xB4 }, + { 0x00, 0xB5, 0xB5, 0xB5 }, + { 0x00, 0xB6, 0xB6, 0xB6 }, + { 0x00, 0xB7, 0xB7, 0xB7 }, + { 0x00, 0xB8, 0xB8, 0xB8 }, + { 0x00, 0xB9, 0xB9, 0xB9 }, + { 0x00, 0xBA, 0xBA, 0xBA }, + { 0x00, 0xBB, 0xBB, 0xBB }, + { 0x00, 0xBC, 0xBC, 0xBC }, + { 0x00, 0xBD, 0xBD, 0xBD }, + { 0x00, 0xBE, 0xBE, 0xBE }, + { 0x00, 0xBF, 0xBF, 0xBF }, + { 0x00, 0xC0, 0xC0, 0xC0 }, + { 0x00, 0xC1, 0xC1, 0xC1 }, + { 0x00, 0xC2, 0xC2, 0xC2 }, + { 0x00, 0xC3, 0xC3, 0xC3 }, + { 0x00, 0xC4, 0xC4, 0xC4 }, + { 0x00, 0xC5, 0xC5, 0xC5 }, + { 0x00, 0xC6, 0xC6, 0xC6 }, + { 0x00, 0xC7, 0xC7, 0xC7 }, + { 0x00, 0xC8, 0xC8, 0xC8 }, + { 0x00, 0xC9, 0xC9, 0xC9 }, + { 0x00, 0xCA, 0xCA, 0xCA }, + { 0x00, 0xCB, 0xCB, 0xCB }, + { 0x00, 0xCC, 0xCC, 0xCC }, + { 0x00, 0xCD, 0xCD, 0xCD }, + { 0x00, 0xCE, 0xCE, 0xCE }, + { 0x00, 0xCF, 0xCF, 0xCF }, + { 0x00, 0xD0, 0xD0, 0xD0 }, + { 0x00, 0xD1, 0xD1, 0xD1 }, + { 0x00, 0xD2, 0xD2, 0xD2 }, + { 0x00, 0xD3, 0xD3, 0xD3 }, + { 0x00, 0xD4, 0xD4, 0xD4 }, + { 0x00, 0xD5, 0xD5, 0xD5 }, + { 0x00, 0xD6, 0xD6, 0xD6 }, + { 0x00, 0xD7, 0xD7, 0xD7 }, + { 0x00, 0xD8, 0xD8, 0xD8 }, + { 0x00, 0xD9, 0xD9, 0xD9 }, + { 0x00, 0xDA, 0xDA, 0xDA }, + { 0x00, 0xDB, 0xDB, 0xDB }, + { 0x00, 0xDC, 0xDC, 0xDC }, + { 0x00, 0xDD, 0xDD, 0xDD }, + { 0x00, 0xDE, 0xDE, 0xDE }, + { 0x00, 0xDF, 0xDF, 0xDF }, + { 0x00, 0xE0, 0xE0, 0xE0 }, + { 0x00, 0xE1, 0xE1, 0xE1 }, + { 0x00, 0xE2, 0xE2, 0xE2 }, + { 0x00, 0xE3, 0xE3, 0xE3 }, + { 0x00, 0xE4, 0xE4, 0xE4 }, + { 0x00, 0xE5, 0xE5, 0xE5 }, + { 0x00, 0xE6, 0xE6, 0xE6 }, + { 0x00, 0xE7, 0xE7, 0xE7 }, + { 0x00, 0xE8, 0xE8, 0xE8 }, + { 0x00, 0xE9, 0xE9, 0xE9 }, + { 0x00, 0xEA, 0xEA, 0xEA }, + { 0x00, 0xEB, 0xEB, 0xEB }, + { 0x00, 0xEC, 0xEC, 0xEC }, + { 0x00, 0xED, 0xED, 0xED }, + { 0x00, 0xEE, 0xEE, 0xEE }, + { 0x00, 0xEF, 0xEF, 0xEF }, + { 0x00, 0xF0, 0xF0, 0xF0 }, + { 0x00, 0xF1, 0xF1, 0xF1 }, + { 0x00, 0xF2, 0xF2, 0xF2 }, + { 0x00, 0xF3, 0xF3, 0xF3 }, + { 0x00, 0xF4, 0xF4, 0xF4 }, + { 0x00, 0xF5, 0xF5, 0xF5 }, + { 0x00, 0xF6, 0xF6, 0xF6 }, + { 0x00, 0xF7, 0xF7, 0xF7 }, + { 0x00, 0xF8, 0xF8, 0xF8 }, + { 0x00, 0xF9, 0xF9, 0xF9 }, + { 0x00, 0xFA, 0xFA, 0xFA }, + { 0x00, 0xFB, 0xFB, 0xFB }, + { 0x00, 0xFC, 0xFC, 0xFC }, + { 0x00, 0xFD, 0xFD, 0xFD }, + { 0x00, 0xFE, 0xFE, 0xFE }, + { 0x00, 0xFF, 0xFF, 0xFF } +}; + +struct _PDCLIB_locale_t _PDCLIB_locale_info = { ctype_info + 1 }; + #endif #ifdef TEST -- 2.40.0 From e883af7e93561cd536df68eaf837f523e3d2594b Mon Sep 17 00:00:00 2001 From: solar <> Date: Wed, 29 Dec 2010 13:19:53 +0000 Subject: [PATCH 07/16] Moved ctype info into struct lconv. --- functions/_PDCLIB/Readme.txt | 0 functions/ctype/isalnum.c | 4 ++- functions/ctype/isalpha.c | 4 ++- functions/ctype/isblank.c | 4 ++- functions/ctype/iscntrl.c | 4 ++- functions/ctype/isdigit.c | 4 ++- functions/ctype/isgraph.c | 4 ++- functions/ctype/islower.c | 4 ++- functions/ctype/isprint.c | 4 ++- functions/ctype/ispunct.c | 4 ++- functions/ctype/isspace.c | 4 ++- functions/ctype/isupper.c | 4 ++- functions/ctype/isxdigit.c | 4 ++- functions/ctype/tolower.c | 4 ++- functions/ctype/toupper.c | 4 ++- includes/locale.h | 19 +++++++++--- internals/_PDCLIB_int.h | 7 ----- platform/example/functions/_PDCLIB/stdinit.c | 32 ++++++++++++++++++-- 18 files changed, 86 insertions(+), 28 deletions(-) mode change 100755 => 100644 functions/_PDCLIB/Readme.txt diff --git a/functions/_PDCLIB/Readme.txt b/functions/_PDCLIB/Readme.txt old mode 100755 new mode 100644 diff --git a/functions/ctype/isalnum.c b/functions/ctype/isalnum.c index d6e217b..f4969fa 100644 --- a/functions/ctype/isalnum.c +++ b/functions/ctype/isalnum.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int isalnum( int c ) { - return ( _PDCLIB_locale_info.ctype[c].flags & ( _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT ) ); + return ( _PDCLIB_lconv.ctype[c].flags & ( _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT ) ); } #endif diff --git a/functions/ctype/isalpha.c b/functions/ctype/isalpha.c index 2bde755..9dad397 100644 --- a/functions/ctype/isalpha.c +++ b/functions/ctype/isalpha.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int isalpha( int c ) { - return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_ALPHA ); + return ( _PDCLIB_lconv.ctype[c].flags & _PDCLIB_CTYPE_ALPHA ); } #endif diff --git a/functions/ctype/isblank.c b/functions/ctype/isblank.c index 0ad1ca1..cc29fa8 100644 --- a/functions/ctype/isblank.c +++ b/functions/ctype/isblank.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int isblank( int c ) { - return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_BLANK ); + return ( _PDCLIB_lconv.ctype[c].flags & _PDCLIB_CTYPE_BLANK ); } #endif diff --git a/functions/ctype/iscntrl.c b/functions/ctype/iscntrl.c index 583ccb3..8c0a4f3 100644 --- a/functions/ctype/iscntrl.c +++ b/functions/ctype/iscntrl.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int iscntrl( int c ) { - return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_CNTRL ); + return ( _PDCLIB_lconv.ctype[c].flags & _PDCLIB_CTYPE_CNTRL ); } #endif diff --git a/functions/ctype/isdigit.c b/functions/ctype/isdigit.c index eeeffb8..b122f7e 100644 --- a/functions/ctype/isdigit.c +++ b/functions/ctype/isdigit.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int isdigit( int c ) { - return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_DIGIT ); + return ( _PDCLIB_lconv.ctype[c].flags & _PDCLIB_CTYPE_DIGIT ); } #endif diff --git a/functions/ctype/isgraph.c b/functions/ctype/isgraph.c index b2cccc8..d623485 100644 --- a/functions/ctype/isgraph.c +++ b/functions/ctype/isgraph.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int isgraph( int c ) { - return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_GRAPH ); + return ( _PDCLIB_lconv.ctype[c].flags & _PDCLIB_CTYPE_GRAPH ); } #endif diff --git a/functions/ctype/islower.c b/functions/ctype/islower.c index d98069a..db0649d 100644 --- a/functions/ctype/islower.c +++ b/functions/ctype/islower.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int islower( int c ) { - return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_LOWER ); + return ( _PDCLIB_lconv.ctype[c].flags & _PDCLIB_CTYPE_LOWER ); } #endif diff --git a/functions/ctype/isprint.c b/functions/ctype/isprint.c index f057e00..50b0ad8 100644 --- a/functions/ctype/isprint.c +++ b/functions/ctype/isprint.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int isprint( int c ) { - return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_GRAPH ) || ( c == ' ' ); + return ( _PDCLIB_lconv.ctype[c].flags & _PDCLIB_CTYPE_GRAPH ) || ( c == ' ' ); } #endif diff --git a/functions/ctype/ispunct.c b/functions/ctype/ispunct.c index 2859efc..4dfd52a 100644 --- a/functions/ctype/ispunct.c +++ b/functions/ctype/ispunct.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int ispunct( int c ) { - return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_PUNCT ); + return ( _PDCLIB_lconv.ctype[c].flags & _PDCLIB_CTYPE_PUNCT ); } #endif diff --git a/functions/ctype/isspace.c b/functions/ctype/isspace.c index 90b6dc5..b443f6f 100644 --- a/functions/ctype/isspace.c +++ b/functions/ctype/isspace.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int isspace( int c ) { - return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_SPACE ); + return ( _PDCLIB_lconv.ctype[c].flags & _PDCLIB_CTYPE_SPACE ); } #endif diff --git a/functions/ctype/isupper.c b/functions/ctype/isupper.c index 76c1ff1..5953946 100644 --- a/functions/ctype/isupper.c +++ b/functions/ctype/isupper.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int isupper( int c ) { - return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_UPPER ); + return ( _PDCLIB_lconv.ctype[c].flags & _PDCLIB_CTYPE_UPPER ); } #endif diff --git a/functions/ctype/isxdigit.c b/functions/ctype/isxdigit.c index 55818df..7f5dfec 100644 --- a/functions/ctype/isxdigit.c +++ b/functions/ctype/isxdigit.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int isxdigit( int c ) { - return ( _PDCLIB_locale_info.ctype[c].flags & _PDCLIB_CTYPE_XDIGT ); + return ( _PDCLIB_lconv.ctype[c].flags & _PDCLIB_CTYPE_XDIGT ); } #endif diff --git a/functions/ctype/tolower.c b/functions/ctype/tolower.c index 530abf2..d051ba5 100644 --- a/functions/ctype/tolower.c +++ b/functions/ctype/tolower.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int tolower( int c ) { - return _PDCLIB_locale_info.ctype[c].lower; + return _PDCLIB_lconv.ctype[c].lower; } #endif diff --git a/functions/ctype/toupper.c b/functions/ctype/toupper.c index 00cb203..801c8ef 100644 --- a/functions/ctype/toupper.c +++ b/functions/ctype/toupper.c @@ -10,9 +10,11 @@ #ifndef REGTEST +#include + int toupper( int c ) { - return _PDCLIB_locale_info.ctype[c].upper; + return _PDCLIB_lconv.ctype[c].upper; } #endif diff --git a/includes/locale.h b/includes/locale.h index fd014db..0277016 100644 --- a/includes/locale.h +++ b/includes/locale.h @@ -9,6 +9,16 @@ #ifndef _PDCLIB_LOCALE_H #define _PDCLIB_LOCALE_H _PDCLIB_LOCALE_H +#ifndef _PDCLIB_INT_H +#define _PDCLIB_INT_H _PDCLIB_INT_H +#include <_PDCLIB_int.h> +#endif + +#ifndef _PDCLIB_NULL_DEFINED +#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED +#define NULL _PDCLIB_NULL +#endif + /* The structure returned by localeconv(). The values for *_sep_by_space: @@ -27,6 +37,7 @@ */ struct lconv { + struct _PDCLIB_ctype_t * ctype; /* internal information */ char * decimal_point; /* decimal point character */ char * thousands_sep; /* character for seperating groups of digits */ char * grouping; /* string indicating the size of digit groups */ @@ -51,12 +62,10 @@ struct lconv char int_n_sep_by_space; /* Same as above, for international format */ char int_p_sign_posn; /* Same as above, for international format */ char int_n_sign_posn; /* Same as above, for international format */ -} +}; -#ifndef _PDCLIB_NULL_DEFINED -#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED -#define NULL _PDCLIB_NULL -#endif +/* This is strictly internal, and visible here for technical reasons only. */ +extern struct lconv _PDCLIB_lconv; /* LC_ALL - entire locale diff --git a/internals/_PDCLIB_int.h b/internals/_PDCLIB_int.h index b5003af..2d99b91 100644 --- a/internals/_PDCLIB_int.h +++ b/internals/_PDCLIB_int.h @@ -450,10 +450,3 @@ struct _PDCLIB_ctype_t unsigned char collation; }; -struct _PDCLIB_locale_t -{ - struct _PDCLIB_ctype_t * ctype; -}; - -struct _PDCLIB_locale_t _PDCLIB_locale_info; - diff --git a/platform/example/functions/_PDCLIB/stdinit.c b/platform/example/functions/_PDCLIB/stdinit.c index a90d283..5550c4d 100644 --- a/platform/example/functions/_PDCLIB/stdinit.c +++ b/platform/example/functions/_PDCLIB/stdinit.c @@ -12,6 +12,8 @@ */ #include +#include +#include #ifndef REGTEST @@ -42,7 +44,7 @@ struct _PDCLIB_file_t * _PDCLIB_filelist = &_PDCLIB_sin; 1 kByte (+ 4 byte) of data. Each line: flags, lowercase, uppercase, collation. */ -static struct _PDCLIB_ctype_t ctype_info[] = { +static struct _PDCLIB_ctype_t _ctype[] = { { /* EOF */ 0, 0, 0, 0 }, { /* NUL */ _PDCLIB_CTYPE_CNTRL, 0x00, 0x00, 0x00 }, { /* SOH */ _PDCLIB_CTYPE_CNTRL, 0x01, 0x01, 0x01 }, @@ -302,7 +304,33 @@ static struct _PDCLIB_ctype_t ctype_info[] = { { 0x00, 0xFF, 0xFF, 0xFF } }; -struct _PDCLIB_locale_t _PDCLIB_locale_info = { ctype_info + 1 }; +struct lconv _PDCLIB_lconv = { + /* _PDCLIB_ctype */ _ctype + 1, + /* decimal_point */ (char *)".", + /* thousands_sep */ (char *)"", + /* grouping */ (char *)"", + /* mon_decimal_point */ (char *)"", + /* mon_thousands_sep */ (char *)"", + /* mon_grouping */ (char *)"", + /* positive_sign */ (char *)"", + /* negative_sign */ (char *)"", + /* currency_symbol */ (char *)"", + /* int_curr_symbol */ (char *)"", + /* frac_digits */ CHAR_MAX, + /* p_cs_precedes */ CHAR_MAX, + /* n_cs_precedes */ CHAR_MAX, + /* p_sep_by_space */ CHAR_MAX, + /* n_sep_by_space */ CHAR_MAX, + /* p_sign_posn */ CHAR_MAX, + /* n_sign_posn */ CHAR_MAX, + /* int_frac_digits */ CHAR_MAX, + /* int_p_cs_precedes */ CHAR_MAX, + /* int_n_cs_precedes */ CHAR_MAX, + /* int_p_sep_by_space */ CHAR_MAX, + /* int_n_sep_by_space */ CHAR_MAX, + /* int_p_sign_posn */ CHAR_MAX, + /* int_n_sign_posn */ CHAR_MAX, +}; #endif -- 2.40.0 From 37a19e428fd1e1b348e332fdc8ee759d13ebe88b Mon Sep 17 00:00:00 2001 From: solar <> Date: Wed, 29 Dec 2010 13:31:51 +0000 Subject: [PATCH 08/16] localeconv, and setlocale (C locale only) --- functions/locale/localeconv.c | 28 ++++++++++++++++++++++++++++ functions/locale/setlocale.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 functions/locale/localeconv.c create mode 100644 functions/locale/setlocale.c diff --git a/functions/locale/localeconv.c b/functions/locale/localeconv.c new file mode 100644 index 0000000..e23fb6a --- /dev/null +++ b/functions/locale/localeconv.c @@ -0,0 +1,28 @@ +/* $Id$ */ + +/* localeconv( void ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +struct lconv * localeconv( void ) +{ + return &_PDCLIB_lconv; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} +#endif diff --git a/functions/locale/setlocale.c b/functions/locale/setlocale.c new file mode 100644 index 0000000..9b08b93 --- /dev/null +++ b/functions/locale/setlocale.c @@ -0,0 +1,28 @@ +/* $Id$ */ + +/* setlocale( int, const char * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +char * setlocale( int category, const char * locale ) +{ + return NULL; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} +#endif -- 2.40.0 From 8cfc7f73e7baec32630b9cf55582febd41b8a684 Mon Sep 17 00:00:00 2001 From: solar <> Date: Thu, 30 Dec 2010 22:43:20 +0000 Subject: [PATCH 09/16] Addressed ticket #40 (non-standard errno values). --- functions/_PDCLIB/errno.c | 11 ---- functions/_PDCLIB/prepread.c | 6 +- functions/_PDCLIB/prepwrite.c | 6 +- functions/stdio/fclose.c | 5 +- functions/stdio/perror.c | 10 ++- functions/string/strerror.c | 11 +++- includes/locale.h | 1 + internals/_PDCLIB_int.h | 26 +++----- .../example/functions/_PDCLIB/fillbuffer.c | 8 ++- .../example/functions/_PDCLIB/flushbuffer.c | 14 +++- platform/example/functions/_PDCLIB/open.c | 10 ++- platform/example/functions/_PDCLIB/rename.c | 16 +++-- platform/example/functions/_PDCLIB/seek.c | 13 +++- platform/example/functions/_PDCLIB/stdinit.c | 6 ++ platform/example/functions/stdio/remove.c | 10 +-- platform/example/internals/_PDCLIB_config.h | 66 +++++++++++++++++++ .../functions/_PDCLIB/fillbuffer.c | 8 ++- .../functions/_PDCLIB/flushbuffer.c | 14 +++- .../example_cygwin/functions/_PDCLIB/open.c | 10 ++- .../example_cygwin/functions/_PDCLIB/rename.c | 16 +++-- .../example_cygwin/functions/_PDCLIB/seek.c | 10 ++- .../example_cygwin/functions/stdio/remove.c | 10 +-- 22 files changed, 216 insertions(+), 71 deletions(-) diff --git a/functions/_PDCLIB/errno.c b/functions/_PDCLIB/errno.c index 0c959b7..ba01c35 100644 --- a/functions/_PDCLIB/errno.c +++ b/functions/_PDCLIB/errno.c @@ -18,17 +18,6 @@ int * _PDCLIB_errno_func() return &_PDCLIB_errno; } -/* TODO: Doing this via a static array is not the way to do it. */ -char const * _PDCLIB_errno_texts[] = { - "", - "ERANGE (Range error)", - "EDOM (Domain error)", - "EIO (I/O error)", - "EUNKNOWN (Unknown error)", - "EINVAL (Invalid parameter value)", - "ERETRY (I/O retries exceeded)" -}; - #endif #ifdef TEST diff --git a/functions/_PDCLIB/prepread.c b/functions/_PDCLIB/prepread.c index ef2f70e..9111ff4 100644 --- a/functions/_PDCLIB/prepread.c +++ b/functions/_PDCLIB/prepread.c @@ -17,7 +17,11 @@ int _PDCLIB_prepread( struct _PDCLIB_file_t * stream ) ( stream->status & ( _PDCLIB_FWRITE | _PDCLIB_FAPPEND | _PDCLIB_ERRORFLAG | _PDCLIB_WIDESTREAM | _PDCLIB_EOFFLAG ) ) || ! ( stream->status & ( _PDCLIB_FREAD | _PDCLIB_FRW ) ) ) { - _PDCLIB_errno = _PDCLIB_EIO; + /* Function called on illegal (e.g. output) stream. + See comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ + _PDCLIB_errno = _PDCLIB_ERROR; stream->status |= _PDCLIB_ERRORFLAG; return EOF; } diff --git a/functions/_PDCLIB/prepwrite.c b/functions/_PDCLIB/prepwrite.c index c5a4c12..148e1c1 100644 --- a/functions/_PDCLIB/prepwrite.c +++ b/functions/_PDCLIB/prepwrite.c @@ -14,7 +14,11 @@ int _PDCLIB_prepwrite( struct _PDCLIB_file_t * stream ) ( stream->status & ( _PDCLIB_FREAD | _PDCLIB_ERRORFLAG | _PDCLIB_WIDESTREAM | _PDCLIB_EOFFLAG ) ) || ! ( stream->status & ( _PDCLIB_FWRITE | _PDCLIB_FAPPEND | _PDCLIB_FRW ) ) ) { - _PDCLIB_errno = _PDCLIB_EIO; + /* Function called on illegal (e.g. input) stream. + See the comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ + _PDCLIB_errno = _PDCLIB_ERROR; stream->status |= _PDCLIB_ERRORFLAG; return EOF; } diff --git a/functions/stdio/fclose.c b/functions/stdio/fclose.c index 3a25b52..81b57c4 100644 --- a/functions/stdio/fclose.c +++ b/functions/stdio/fclose.c @@ -58,7 +58,10 @@ int fclose( struct _PDCLIB_file_t * stream ) previous = current; current = current->next; } - _PDCLIB_errno = _PDCLIB_EIO; + /* See the comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ + _PDCLIB_errno = _PDCLIB_ERROR; return -1; } diff --git a/functions/stdio/perror.c b/functions/stdio/perror.c index bf3b3af..23ce68b 100644 --- a/functions/stdio/perror.c +++ b/functions/stdio/perror.c @@ -11,6 +11,7 @@ #ifndef REGTEST #include +#include /* TODO: Doing this via a static array is not the way to do it. */ void perror( const char * s ) @@ -19,7 +20,14 @@ void perror( const char * s ) { fprintf( stderr, "%s: ", s ); } - fprintf( stderr, "%s\n", _PDCLIB_errno_texts[ errno ] ); + if ( errno >= _PDCLIB_ERRNO_MAX ) + { + fprintf( stderr, "Unknown error\n" ); + } + else + { + fprintf( stderr, "%s\n", _PDCLIB_lconv._PDCLIB_errno_texts[errno] ); + } return; } diff --git a/functions/string/strerror.c b/functions/string/strerror.c index 89ebed0..b0ced5d 100644 --- a/functions/string/strerror.c +++ b/functions/string/strerror.c @@ -10,10 +10,19 @@ #ifndef REGTEST +#include + /* TODO: Doing this via a static array is not the way to do it. */ char * strerror( int errnum ) { - return (char *)_PDCLIB_errno_texts[ errnum ]; + if ( errnum == 0 || errnum >= _PDCLIB_ERRNO_MAX ) + { + return (char *)"Unknown error"; + } + else + { + return _PDCLIB_lconv._PDCLIB_errno_texts[errnum]; + } } #endif diff --git a/includes/locale.h b/includes/locale.h index 0277016..d849244 100644 --- a/includes/locale.h +++ b/includes/locale.h @@ -38,6 +38,7 @@ struct lconv { struct _PDCLIB_ctype_t * ctype; /* internal information */ + char * _PDCLIB_errno_texts[_PDCLIB_ERRNO_MAX]; /* strerror() / perror() */ char * decimal_point; /* decimal point character */ char * thousands_sep; /* character for seperating groups of digits */ char * grouping; /* string indicating the size of digit groups */ diff --git a/internals/_PDCLIB_int.h b/internals/_PDCLIB_int.h index 2d99b91..a46c2dc 100644 --- a/internals/_PDCLIB_int.h +++ b/internals/_PDCLIB_int.h @@ -407,25 +407,17 @@ void _PDCLIB_closeall( void ); /* errno */ /* -------------------------------------------------------------------------- */ +/* If PDCLib would call its error number "errno" directly, there would be no way + to catch its value from underlying system calls that also use it (i.e., POSIX + operating systems). That is why we use an internal name, providing a means to + access it through . +*/ extern int _PDCLIB_errno; -int * _PDCLIB_errno_func( void ); -/* ERANGE and EDOM are specified by the standard. */ -#define _PDCLIB_ERANGE 1 -#define _PDCLIB_EDOM 2 -/* Used in the example implementation for any kind of I/O error. */ -#define _PDCLIB_EIO 3 -/* Used in the example implementation for "unknown error". */ -#define _PDCLIB_EUNKNOWN 4 -/* Used in the example implementation for "invalid parameter value". */ -#define _PDCLIB_EINVAL 5 -/* Used in the example implementation for "I/O retries exceeded". */ -#define _PDCLIB_ERETRY 6 -/* One larger than the largest used errno */ -#define _PDCLIB_EMAX 7 - -/* TODO: Doing this via a static array is not the way to do it. */ -char const * _PDCLIB_errno_texts[ _PDCLIB_EMAX ]; +/* A mechanism for delayed evaluation. (Not sure if this is really necessary, so + no detailed documentation on the "why".) +*/ +int * _PDCLIB_errno_func( void ); /* -------------------------------------------------------------------------- */ /* lookup tables */ diff --git a/platform/example/functions/_PDCLIB/fillbuffer.c b/platform/example/functions/_PDCLIB/fillbuffer.c index 8da93ad..a5520a3 100644 --- a/platform/example/functions/_PDCLIB/fillbuffer.c +++ b/platform/example/functions/_PDCLIB/fillbuffer.c @@ -41,15 +41,19 @@ int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream ) /* Reading error */ switch ( errno ) { + /* See comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ case EBADF: case EFAULT: case EINTR: case EINVAL: case EIO: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should probably be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; break; } stream->status |= _PDCLIB_ERRORFLAG; diff --git a/platform/example/functions/_PDCLIB/flushbuffer.c b/platform/example/functions/_PDCLIB/flushbuffer.c index c2ac98d..e68c6c4 100644 --- a/platform/example/functions/_PDCLIB/flushbuffer.c +++ b/platform/example/functions/_PDCLIB/flushbuffer.c @@ -50,6 +50,10 @@ int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream ) /* Write error */ switch ( errno ) { + /* See <_PDCLIB_config.h>. There should be differenciated errno + handling here, possibly even a 1:1 mapping; but that is up + to the individual platform. + */ case EBADF: case EFAULT: case EFBIG: @@ -58,10 +62,11 @@ int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream ) case EIO: case ENOSPC: case EPIPE: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; break; } stream->status |= _PDCLIB_ERRORFLAG; @@ -79,7 +84,10 @@ int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream ) return 0; } } - _PDCLIB_errno = _PDCLIB_ERETRY; + /* Number of retries exceeded. You probably want a different errno value + here. + */ + _PDCLIB_errno = _PDCLIB_ERROR; stream->status |= _PDCLIB_ERRORFLAG; /* Move unwritten remains to begin of buffer. */ stream->bufidx -= written; diff --git a/platform/example/functions/_PDCLIB/open.c b/platform/example/functions/_PDCLIB/open.c index 0230558..2098dd3 100644 --- a/platform/example/functions/_PDCLIB/open.c +++ b/platform/example/functions/_PDCLIB/open.c @@ -64,6 +64,9 @@ int _PDCLIB_open( char const * const filename, unsigned int mode ) { switch ( errno ) { + /* See the comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ case EACCES: case EFAULT: case EINTR: @@ -80,9 +83,12 @@ int _PDCLIB_open( char const * const filename, unsigned int mode ) case EOVERFLOW: case EROFS: case ETXTBSY: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; + break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; + break; } } return rc; diff --git a/platform/example/functions/_PDCLIB/rename.c b/platform/example/functions/_PDCLIB/rename.c index f314e4c..a37eeb3 100644 --- a/platform/example/functions/_PDCLIB/rename.c +++ b/platform/example/functions/_PDCLIB/rename.c @@ -29,6 +29,9 @@ int _PDCLIB_rename( const char * old, const char * new ) { switch ( errno ) { + /* See the comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ case EACCES: case EFAULT: case EIO: @@ -40,10 +43,11 @@ int _PDCLIB_rename( const char * old, const char * new ) case ENOTDIR: case EPERM: case EROFS: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; break; } return -1; @@ -57,6 +61,9 @@ int _PDCLIB_rename( const char * old, const char * new ) { switch ( errno ) { + /* See the comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ case EACCES: case EEXIST: case EFAULT: @@ -71,10 +78,11 @@ int _PDCLIB_rename( const char * old, const char * new ) case EPERM: case EROFS: case EXDEV: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; break; } return EOF; diff --git a/platform/example/functions/_PDCLIB/seek.c b/platform/example/functions/_PDCLIB/seek.c index 9e2d102..b28de73 100644 --- a/platform/example/functions/_PDCLIB/seek.c +++ b/platform/example/functions/_PDCLIB/seek.c @@ -27,7 +27,10 @@ _PDCLIB_int64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int64_t of /* EMPTY - OK */ break; default: - _PDCLIB_errno = _PDCLIB_EINVAL; + /* See comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ + _PDCLIB_errno = _PDCLIB_ERROR; return EOF; break; } @@ -44,10 +47,14 @@ _PDCLIB_int64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int64_t of { case EBADF: case EFAULT: - _PDCLIB_errno = _PDCLIB_EIO; + /* See comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ + _PDCLIB_errno = _PDCLIB_ERROR; break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should probably be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; break; } return EOF; diff --git a/platform/example/functions/_PDCLIB/stdinit.c b/platform/example/functions/_PDCLIB/stdinit.c index 5550c4d..9467077 100644 --- a/platform/example/functions/_PDCLIB/stdinit.c +++ b/platform/example/functions/_PDCLIB/stdinit.c @@ -306,6 +306,12 @@ static struct _PDCLIB_ctype_t _ctype[] = { struct lconv _PDCLIB_lconv = { /* _PDCLIB_ctype */ _ctype + 1, + /* _PDCLIB_errno_texts */ + { + /* no error */ (char *)"", + /* ERANGE */ (char *)"ERANGE (Range error)", + /* EDOM */ (char *)"EDOM (Domain error)" + }, /* decimal_point */ (char *)".", /* thousands_sep */ (char *)"", /* grouping */ (char *)"", diff --git a/platform/example/functions/stdio/remove.c b/platform/example/functions/stdio/remove.c index 8bf3040..389df30 100644 --- a/platform/example/functions/stdio/remove.c +++ b/platform/example/functions/stdio/remove.c @@ -37,9 +37,8 @@ int remove( const char * pathname ) { switch ( errno ) { - /* These are the values possible on a Linux machine. Adapt the - values and their mapping to PDCLib errno values at will. (This - is an example implementation, so we keep it very simple.) + /* See the comments on implementation-defined errno values in + <_PDCLIB_config.h>. */ case EACCES: case EFAULT: @@ -52,10 +51,11 @@ int remove( const char * pathname ) case ENOTDIR: case EPERM: case EROFS: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; break; } } diff --git a/platform/example/internals/_PDCLIB_config.h b/platform/example/internals/_PDCLIB_config.h index f1d1475..0059a7f 100644 --- a/platform/example/internals/_PDCLIB_config.h +++ b/platform/example/internals/_PDCLIB_config.h @@ -32,6 +32,14 @@ /* to nothing. (This is to avoid warnings with the exit functions under GCC.) */ #define _PDCLIB_NORETURN __attribute__(( noreturn )) +/* The maximum value that errno can be set to. This is used to set the size */ +/* of the array in struct lconv () holding error messages for the */ +/* strerror() and perror() functions. (If you change this value because you */ +/* are using additional errno values, you *HAVE* to provide appropriate error */ +/* messages for *ALL* locales.) */ +/* Default is 2 (0, ERANGE, EDOM). */ +#define _PDCLIB_ERRNO_MAX 3 + /* -------------------------------------------------------------------------- */ /* Integers */ /* -------------------------------------------------------------------------- */ @@ -285,3 +293,61 @@ typedef int _PDCLIB_fd_t; this capability dependent on implementation-defined behaviour (not good). */ #define _PDCLIB_UNGETCBUFSIZE 1 + +/* errno -------------------------------------------------------------------- */ + +/* These are the values that _PDCLIB_errno can be set to by the library. + + By keeping PDCLib's errno in the _PDCLIB_* namespace, the library is capable + to "translate" between errno values used by the hosting operating system and + those used and passed out by the library. + + Example: In the example platform, the remove() function uses the unlink() + system call as backend. Linux sets its errno to EISDIR if you try to unlink() + a directory, but POSIX demands EPERM. Within the remove() function, you can + catch the 'errno == EISDIR', and set '_PDCLIB_errno = _PDCLIB_EPERM'. Anyone + using PDCLib's will "see" EPERM instead of EISDIR (the _PDCLIB_* + prefix removed by mechanics). + + If you do not want that kind of translation, you might want to "match" the + values used by PDCLib with those used by the host OS, as to avoid confusion. + + The standard only defines three distinct errno values: ERANGE, EDOM, and + EILSEQ. The standard leaves it up to "the implementation" whether there are + any more beyond those three. There is some controversy as to whether errno is + such a good idea at all, so you might want to come up with a different error + reporting facility for your platform. Since errno values beyond the three + defined by the standard are not portable anyway (unless you look at POSIX), + having your own error reporting facility would not hurt anybody either. +*/ +#define _PDCLIB_ERANGE 1 +#define _PDCLIB_EDOM 2 +#define _PDCLIB_EILSEQ 3 + +/* The following is not strictly "configuration", but there is no better place + to explain it than here. + + PDCLib strives to be as generic as possible, so by default it does NOT define + any values beyond the three standard ones above, even where it would have + been prudent and convenient to do so. Any errno "caught" from the host OS, + and some internal error conditions as well, are all lumped together into the + value of '_PDCLIB_ERROR'. + + '_PDCLIB_ERROR' is STRICLY meant as a PLACEHOLDER only. + + You should NEVER ship an adaption of PDCLib still using that particular + value. You should NEVER write code that *tests* for that value. Indeed it is + not even conforming, since errno values should be defined as beginning with + an uppercase 'E', and there is no mechanics in to unmask that + particular value (for exactly that reason). + + The idea is that you scan the source of PDCLib for occurrences of this macro + and replace _PDCLIB_ERROR with whatever additional errno value you came up + with for your platform. + + If you cannot find it within you to do that, tell your clients to check for + an errno value larger than zero. That, at least, would be standard compliant + (and fully portable). +*/ +#define _PDCLIB_ERROR 4 + diff --git a/platform/example_cygwin/functions/_PDCLIB/fillbuffer.c b/platform/example_cygwin/functions/_PDCLIB/fillbuffer.c index ecfb968..293e6c9 100644 --- a/platform/example_cygwin/functions/_PDCLIB/fillbuffer.c +++ b/platform/example_cygwin/functions/_PDCLIB/fillbuffer.c @@ -40,15 +40,19 @@ int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream ) /* Reading error */ switch ( errno ) { + /* See comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ case EBADF: case EFAULT: case EINTR: case EINVAL: case EIO: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should probably be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; break; } stream->status |= _PDCLIB_ERRORFLAG; diff --git a/platform/example_cygwin/functions/_PDCLIB/flushbuffer.c b/platform/example_cygwin/functions/_PDCLIB/flushbuffer.c index c2ac98d..e68c6c4 100644 --- a/platform/example_cygwin/functions/_PDCLIB/flushbuffer.c +++ b/platform/example_cygwin/functions/_PDCLIB/flushbuffer.c @@ -50,6 +50,10 @@ int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream ) /* Write error */ switch ( errno ) { + /* See <_PDCLIB_config.h>. There should be differenciated errno + handling here, possibly even a 1:1 mapping; but that is up + to the individual platform. + */ case EBADF: case EFAULT: case EFBIG: @@ -58,10 +62,11 @@ int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream ) case EIO: case ENOSPC: case EPIPE: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; break; } stream->status |= _PDCLIB_ERRORFLAG; @@ -79,7 +84,10 @@ int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream ) return 0; } } - _PDCLIB_errno = _PDCLIB_ERETRY; + /* Number of retries exceeded. You probably want a different errno value + here. + */ + _PDCLIB_errno = _PDCLIB_ERROR; stream->status |= _PDCLIB_ERRORFLAG; /* Move unwritten remains to begin of buffer. */ stream->bufidx -= written; diff --git a/platform/example_cygwin/functions/_PDCLIB/open.c b/platform/example_cygwin/functions/_PDCLIB/open.c index 88af3c4..4e7d2b9 100644 --- a/platform/example_cygwin/functions/_PDCLIB/open.c +++ b/platform/example_cygwin/functions/_PDCLIB/open.c @@ -66,6 +66,9 @@ int _PDCLIB_open( char const * const filename, unsigned int mode ) { switch ( errno ) { + /* See the comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ case EACCES: case EFAULT: case EINTR: @@ -82,9 +85,12 @@ int _PDCLIB_open( char const * const filename, unsigned int mode ) case EOVERFLOW: case EROFS: case ETXTBSY: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; + break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; + break; } } return rc; diff --git a/platform/example_cygwin/functions/_PDCLIB/rename.c b/platform/example_cygwin/functions/_PDCLIB/rename.c index e8e7cb1..db38afd 100644 --- a/platform/example_cygwin/functions/_PDCLIB/rename.c +++ b/platform/example_cygwin/functions/_PDCLIB/rename.c @@ -29,6 +29,9 @@ int _PDCLIB_rename( const char * old, const char * new ) { switch ( errno ) { + /* See the comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ case EACCES: case EFAULT: case EIO: @@ -40,10 +43,11 @@ int _PDCLIB_rename( const char * old, const char * new ) case ENOTDIR: case EPERM: case EROFS: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; break; } return -1; @@ -57,6 +61,9 @@ int _PDCLIB_rename( const char * old, const char * new ) { switch ( errno ) { + /* See the comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ case EACCES: case EEXIST: case EFAULT: @@ -71,10 +78,11 @@ int _PDCLIB_rename( const char * old, const char * new ) case EPERM: case EROFS: case EXDEV: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; break; } return EOF; diff --git a/platform/example_cygwin/functions/_PDCLIB/seek.c b/platform/example_cygwin/functions/_PDCLIB/seek.c index ee21f56..bc003ee 100644 --- a/platform/example_cygwin/functions/_PDCLIB/seek.c +++ b/platform/example_cygwin/functions/_PDCLIB/seek.c @@ -27,7 +27,7 @@ _PDCLIB_int64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int64_t of /* EMPTY - OK */ break; default: - _PDCLIB_errno = _PDCLIB_EINVAL; + _PDCLIB_errno = _PDCLIB_ERROR; return EOF; break; } @@ -42,12 +42,16 @@ _PDCLIB_int64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int64_t of } switch ( errno ) { + /* See comments on implementation-defined errno values in + <_PDCLIB_config.h>. + */ case EBADF: case EFAULT: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should probably be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; break; } return EOF; diff --git a/platform/example_cygwin/functions/stdio/remove.c b/platform/example_cygwin/functions/stdio/remove.c index 0e66f4c..e27dd56 100644 --- a/platform/example_cygwin/functions/stdio/remove.c +++ b/platform/example_cygwin/functions/stdio/remove.c @@ -24,9 +24,8 @@ int remove( const char * pathname ) { switch ( errno ) { - /* These are the values possible on a Linux machine. Adapt the - values and their mapping to PDCLib errno values at will. (This - is an example implementation, so we keep it very simple.) + /* See the comments on implementation-defined errno values in + <_PDCLIB_config.h>. */ case EACCES: case EFAULT: @@ -39,10 +38,11 @@ int remove( const char * pathname ) case ENOTDIR: case EPERM: case EROFS: - _PDCLIB_errno = _PDCLIB_EIO; + _PDCLIB_errno = _PDCLIB_ERROR; break; default: - _PDCLIB_errno = _PDCLIB_EUNKNOWN; + /* This should be something like EUNKNOWN. */ + _PDCLIB_errno = _PDCLIB_ERROR; break; } } -- 2.40.0 From e4a50ae15f5ea7e9e10cb8dfba8e5c1824abe4d3 Mon Sep 17 00:00:00 2001 From: solar <> Date: Thu, 30 Dec 2010 22:46:02 +0000 Subject: [PATCH 10/16] Language. --- platform/example/functions/_PDCLIB/fillbuffer.c | 2 +- platform/example/functions/_PDCLIB/seek.c | 2 +- platform/example_cygwin/functions/_PDCLIB/fillbuffer.c | 2 +- platform/example_cygwin/functions/_PDCLIB/seek.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/example/functions/_PDCLIB/fillbuffer.c b/platform/example/functions/_PDCLIB/fillbuffer.c index a5520a3..1d45025 100644 --- a/platform/example/functions/_PDCLIB/fillbuffer.c +++ b/platform/example/functions/_PDCLIB/fillbuffer.c @@ -52,7 +52,7 @@ int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream ) _PDCLIB_errno = _PDCLIB_ERROR; break; default: - /* This should probably be something like EUNKNOWN. */ + /* This should be something like EUNKNOWN. */ _PDCLIB_errno = _PDCLIB_ERROR; break; } diff --git a/platform/example/functions/_PDCLIB/seek.c b/platform/example/functions/_PDCLIB/seek.c index b28de73..b3e1830 100644 --- a/platform/example/functions/_PDCLIB/seek.c +++ b/platform/example/functions/_PDCLIB/seek.c @@ -53,7 +53,7 @@ _PDCLIB_int64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int64_t of _PDCLIB_errno = _PDCLIB_ERROR; break; default: - /* This should probably be something like EUNKNOWN. */ + /* This should be something like EUNKNOWN. */ _PDCLIB_errno = _PDCLIB_ERROR; break; } diff --git a/platform/example_cygwin/functions/_PDCLIB/fillbuffer.c b/platform/example_cygwin/functions/_PDCLIB/fillbuffer.c index 293e6c9..29808b2 100644 --- a/platform/example_cygwin/functions/_PDCLIB/fillbuffer.c +++ b/platform/example_cygwin/functions/_PDCLIB/fillbuffer.c @@ -51,7 +51,7 @@ int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream ) _PDCLIB_errno = _PDCLIB_ERROR; break; default: - /* This should probably be something like EUNKNOWN. */ + /* This should be something like EUNKNOWN. */ _PDCLIB_errno = _PDCLIB_ERROR; break; } diff --git a/platform/example_cygwin/functions/_PDCLIB/seek.c b/platform/example_cygwin/functions/_PDCLIB/seek.c index bc003ee..c1094f3 100644 --- a/platform/example_cygwin/functions/_PDCLIB/seek.c +++ b/platform/example_cygwin/functions/_PDCLIB/seek.c @@ -50,7 +50,7 @@ _PDCLIB_int64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int64_t of _PDCLIB_errno = _PDCLIB_ERROR; break; default: - /* This should probably be something like EUNKNOWN. */ + /* This should be something like EUNKNOWN. */ _PDCLIB_errno = _PDCLIB_ERROR; break; } -- 2.40.0 From fd3f9d6bac7e16b441fc6253e121177fc772d58f Mon Sep 17 00:00:00 2001 From: solar <> Date: Fri, 31 Dec 2010 08:47:37 +0000 Subject: [PATCH 11/16] I am not sure I understood strcoll() and strxfrm() correctly, but this is it for now. --- functions/string/strcoll.c | 10 ++++++++-- functions/string/strxfrm.c | 5 +++-- platform/example/functions/_PDCLIB/stdinit.c | 3 ++- platform/example/internals/_PDCLIB_config.h | 7 +++++-- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/functions/string/strcoll.c b/functions/string/strcoll.c index 58814d6..16a5680 100644 --- a/functions/string/strcoll.c +++ b/functions/string/strcoll.c @@ -10,10 +10,16 @@ #ifndef REGTEST -/* TODO: Dummy function, PDCLib does not support locales yet. */ +#include + int strcoll( const char * s1, const char * s2 ) { - return strcmp( s1, s2 ); + while ( ( *s1 ) && ( _PDCLIB_lconv.ctype[(unsigned char)*s1].collation == _PDCLIB_lconv.ctype[(unsigned char)*s2].collation ) ) + { + ++s1; + ++s2; + } + return ( _PDCLIB_lconv.ctype[(unsigned char)*s1].collation == _PDCLIB_lconv.ctype[(unsigned char)*s2].collation ); } #endif diff --git a/functions/string/strxfrm.c b/functions/string/strxfrm.c index 2f8f7a6..4f5e4a0 100644 --- a/functions/string/strxfrm.c +++ b/functions/string/strxfrm.c @@ -10,7 +10,8 @@ #ifndef REGTEST -/* TODO: Dummy function, no locale support yet. */ +#include + size_t strxfrm( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, size_t n ) { size_t len = strlen( s2 ); @@ -19,7 +20,7 @@ size_t strxfrm( char * _PDCLIB_restrict s1, const char * _PDCLIB_restrict s2, si /* Cannot use strncpy() here as the filling of s1 with '\0' is not part of the spec. */ - while ( n-- && ( *s1++ = *s2++ ) ); + while ( n-- && ( *s1++ = _PDCLIB_lconv.ctype[(unsigned char)*s2++].collation ) ); } return len; } diff --git a/platform/example/functions/_PDCLIB/stdinit.c b/platform/example/functions/_PDCLIB/stdinit.c index 9467077..2554e9f 100644 --- a/platform/example/functions/_PDCLIB/stdinit.c +++ b/platform/example/functions/_PDCLIB/stdinit.c @@ -310,7 +310,8 @@ struct lconv _PDCLIB_lconv = { { /* no error */ (char *)"", /* ERANGE */ (char *)"ERANGE (Range error)", - /* EDOM */ (char *)"EDOM (Domain error)" + /* EDOM */ (char *)"EDOM (Domain error)", + /* EILSEQ */ (char *)"EILSEQ (Illegal sequence)" }, /* decimal_point */ (char *)".", /* thousands_sep */ (char *)"", diff --git a/platform/example/internals/_PDCLIB_config.h b/platform/example/internals/_PDCLIB_config.h index 0059a7f..64cc98d 100644 --- a/platform/example/internals/_PDCLIB_config.h +++ b/platform/example/internals/_PDCLIB_config.h @@ -37,8 +37,8 @@ /* strerror() and perror() functions. (If you change this value because you */ /* are using additional errno values, you *HAVE* to provide appropriate error */ /* messages for *ALL* locales.) */ -/* Default is 2 (0, ERANGE, EDOM). */ -#define _PDCLIB_ERRNO_MAX 3 +/* Default is 4 (0, ERANGE, EDOM, EILSEQ). */ +#define _PDCLIB_ERRNO_MAX 4 /* -------------------------------------------------------------------------- */ /* Integers */ @@ -341,6 +341,9 @@ typedef int _PDCLIB_fd_t; an uppercase 'E', and there is no mechanics in to unmask that particular value (for exactly that reason). + There also is no error message available for this value through either the + strerror() or perror() functions. It is being reported as "unknown" error. + The idea is that you scan the source of PDCLib for occurrences of this macro and replace _PDCLIB_ERROR with whatever additional errno value you came up with for your platform. -- 2.40.0 From 1934ab0478f95bd0ff278fe635701c0d823a5ba8 Mon Sep 17 00:00:00 2001 From: solar <> Date: Tue, 11 Jan 2011 05:49:19 +0000 Subject: [PATCH 12/16] Fix for #41. --- functions/_PDCLIB/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/_PDCLIB/scan.c b/functions/_PDCLIB/scan.c index 15b1d50..6910aef 100644 --- a/functions/_PDCLIB/scan.c +++ b/functions/_PDCLIB/scan.c @@ -39,7 +39,7 @@ */ static int GET( struct _PDCLIB_status_t * status ) { - int rc; + int rc = EOF; if ( status->stream != NULL ) { rc = getc( status->stream ); -- 2.40.0 From 7b62ec2cf9c24cf7298855999f8974a13d72b6f1 Mon Sep 17 00:00:00 2001 From: solar <> Date: Tue, 11 Jan 2011 05:52:32 +0000 Subject: [PATCH 13/16] It seems I have to review the list of warning options if I missed this one. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2d1fa6d..da90da2 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ REGDEPFILES := $(patsubst %,%.d,$(REGFILES)) # All files belonging to the source distribution ALLFILES := $(SRCFILES) $(HDRFILES) $(AUXFILES) -WARNINGS := -Wall -Wextra -pedantic -Wno-unused-parameter -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wno-long-long -fno-builtin +WARNINGS := -Wall -Wextra -pedantic -Wno-unused-parameter -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wno-long-long -Wuninitialized -fno-builtin CFLAGS := -g -std=c99 -I./internals -I./testing $(WARNINGS) $(USERFLAGS) .PHONY: all clean srcdist bindist test tests testdrivers regtests regtestdrivers todos fixmes find links unlink help -- 2.40.0 From f12696b39491a60010cc28c029133833856b5b85 Mon Sep 17 00:00:00 2001 From: solar <> Date: Sun, 20 Feb 2011 20:48:48 +0000 Subject: [PATCH 14/16] Fix for #42 - free( NULL ) must not fail. --- functions/stdlib/free.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/functions/stdlib/free.c b/functions/stdlib/free.c index 43de129..4370487 100644 --- a/functions/stdlib/free.c +++ b/functions/stdlib/free.c @@ -22,6 +22,10 @@ extern struct _PDCLIB_headnode_t _PDCLIB_memlist; void free( void * ptr ) { + if ( ptr == NULL ) + { + return; + } ptr = (void *)( (char *)ptr - sizeof( struct _PDCLIB_memnode_t ) ); ( (struct _PDCLIB_memnode_t *)ptr )->next = NULL; if ( _PDCLIB_memlist.last != NULL ) @@ -39,10 +43,12 @@ void free( void * ptr ) #ifdef TEST #include <_PDCLIB_test.h> +#include int main( void ) { - /* tests covered in malloc test driver */ + free( NULL ); + TESTCASE( true ); return TEST_RESULTS; } -- 2.40.0 From cc5574eddc174250bb59418db3d9930d754bbeab Mon Sep 17 00:00:00 2001 From: solar <> Date: Thu, 17 Mar 2011 05:28:07 +0000 Subject: [PATCH 15/16] Backported improvements to Makefile from OSDev. --- Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index da90da2..5397eab 100644 --- a/Makefile +++ b/Makefile @@ -9,9 +9,9 @@ AUXFILES := Makefile Readme.txt # Directories belonging to the project PROJDIRS := functions includes internals # All source files of the project -SRCFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.c") +SRCFILES := $(shell find $(PROJDIRS) -type f -name "*.c") # All header files of the project -HDRFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.h") +HDRFILES := $(shell find $(PROJDIRS) -type f -name "*.h") # All .c files in functions/_PDCLIB that do not have a regression test driver INTFILES := _Exit atomax digits open print scan remove rename seed stdinit strtox_main strtox_prelim filemode eol errno seek prepread prepwrite allocpages tmpfilename closeall # All object files in the library @@ -29,8 +29,8 @@ REGDEPFILES := $(patsubst %,%.d,$(REGFILES)) # All files belonging to the source distribution ALLFILES := $(SRCFILES) $(HDRFILES) $(AUXFILES) -WARNINGS := -Wall -Wextra -pedantic -Wno-unused-parameter -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wno-long-long -Wuninitialized -fno-builtin -CFLAGS := -g -std=c99 -I./internals -I./testing $(WARNINGS) $(USERFLAGS) +WARNINGS := -Wall -Wextra -pedantic -Wno-unused-parameter -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wno-long-long -Wuninitialized -Wstrict-prototypes +CFLAGS := -fno-builtin -g -std=c99 -I./internals -I./testing $(WARNINGS) $(USERFLAGS) .PHONY: all clean srcdist bindist test tests testdrivers regtests regtestdrivers todos fixmes find links unlink help @@ -71,7 +71,7 @@ regtestdrivers: $(REGFILES) -include $(DEPFILES) $(TSTDEPFILES) $(REGDEPFILES) clean: - @for file in $(OBJFILES) $(DEPFILES) $(TSTFILES) $(TSTDEPFILES) $(REGFILES) $(REGDEPFILES) pdclib.a pdclib.tgz scanf_testdata_*; do if [ -f $$file ]; then rm $$file; fi; done + -@$(RM) $(wildcard $(OBJFILES) $(DEPFILES) $(TSTFILES) $(TSTDEPFILES) $(REGFILES) $(REGDEPFILES) pdclib.a pdclib.tgz scanf_testdata_*) srcdist: @tar czf pdclib.tgz $(ALLFILES) -- 2.40.0 From 0e276acbc1cef56e647ded916a1815eb22f27fe1 Mon Sep 17 00:00:00 2001 From: solar <> Date: Thu, 17 Mar 2011 05:47:37 +0000 Subject: [PATCH 16/16] find did not match on symlinks. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5397eab..4d9a401 100644 --- a/Makefile +++ b/Makefile @@ -9,9 +9,9 @@ AUXFILES := Makefile Readme.txt # Directories belonging to the project PROJDIRS := functions includes internals # All source files of the project -SRCFILES := $(shell find $(PROJDIRS) -type f -name "*.c") +SRCFILES := $(shell find -L $(PROJDIRS) -type f -name "*.c") # All header files of the project -HDRFILES := $(shell find $(PROJDIRS) -type f -name "*.h") +HDRFILES := $(shell find -L $(PROJDIRS) -type f -name "*.h") # All .c files in functions/_PDCLIB that do not have a regression test driver INTFILES := _Exit atomax digits open print scan remove rename seed stdinit strtox_main strtox_prelim filemode eol errno seek prepread prepwrite allocpages tmpfilename closeall # All object files in the library -- 2.40.0