Sync usage with man page.
[netbsd-mini2440.git] / lib / libc / locale / ctypeio.c
blobed835c5708545cd2d9ff4e3d8405bb9234ba0789
1 /* $NetBSD: ctypeio.c,v 1.9 2009/01/11 02:46:28 christos Exp $ */
3 /*
4 * Copyright (c) 1997 Christos Zoulas. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 #if defined(LIBC_SCCS) && !defined(lint)
29 __RCSID("$NetBSD: ctypeio.c,v 1.9 2009/01/11 02:46:28 christos Exp $");
30 #endif /* LIBC_SCCS and not lint */
32 #include <sys/types.h>
33 #include <assert.h>
34 #define _CTYPE_PRIVATE
35 #include <ctype.h>
36 #include <errno.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
42 #include "bsdctype.h"
43 #include "ctypeio.h"
45 int
46 __loadctype(const char * __restrict path, _BSDCTypeLocale ** __restrict pdata)
48 FILE *fp;
49 char id[sizeof(_CTYPE_ID) - 1];
50 uint32_t i, len;
51 char *ptr;
52 uint8_t *new_ctype;
53 int16_t *new_tolower, *new_toupper;
54 _BSDCTypeLocale *data;
56 _DIAGASSERT(path != NULL);
57 _DIAGASSERT(pdata != NULL);
59 fp = fopen(path, "r");
60 if (fp == NULL)
61 return ENOENT;
63 if (fread(id, sizeof(id), 1, fp) != 1 ||
64 memcmp(id, _CTYPE_ID, sizeof(id)) != 0)
65 goto bad0;
67 if (fread(&i, sizeof(uint32_t), 1, fp) != 1 ||
68 (i = ntohl(i)) != _CTYPE_REV)
69 goto bad0;
71 if (fread(&len, sizeof(uint32_t), 1, fp) != 1 ||
72 (len = ntohl(len)) != _CTYPE_NUM_CHARS)
73 goto bad0;
75 ptr = malloc(sizeof(*data) + ((sizeof(uint8_t) +
76 sizeof(int16_t) + sizeof(int16_t)) * (len + 1)));
77 if (ptr == NULL)
78 return ENOMEM;
80 data = (_BSDCTypeLocale *)(void *)ptr;
81 ptr += sizeof(*data);
83 (new_ctype = (void *)ptr)[0] = (uint8_t)0;
84 ptr += sizeof(uint8_t);
85 if (fread((void *)ptr, sizeof(uint8_t), len, fp) != len)
86 goto bad1;
87 ptr += sizeof(uint8_t) * len;
89 (new_toupper = (void *)ptr)[0] = (int16_t)EOF;
90 ptr += sizeof(int16_t);
91 if (fread((void *)ptr, sizeof(int16_t), len, fp) != len)
92 goto bad1;
93 ptr += sizeof(int16_t) * len;
95 (new_tolower = (void *)ptr)[0] = (int16_t)EOF;
96 ptr += sizeof(int16_t);
97 if (fread((void *)ptr, sizeof(int16_t), len, fp) != len)
98 goto bad1;
100 #if BYTE_ORDER == LITTLE_ENDIAN
101 for (i = 1; i <= len; i++) {
102 new_toupper[i] = ntohs(new_toupper[i]);
103 new_tolower[i] = ntohs(new_tolower[i]);
105 #endif
107 fclose(fp);
109 data->ctype_tab = (const unsigned char *)new_ctype;
110 data->toupper_tab = (const short *)new_toupper;
111 data->tolower_tab = (const short *)new_tolower;
113 *pdata = data;
115 return 0;
117 bad1:
118 free(data);
119 bad0:
120 return EFTYPE;