Thu Jan 18 00:32:43 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
[kopensolaris-gnu/glibc.git] / locale / monetary.c
1 /* Copyright (C) 1995 Free Software Foundation, Inc.
2
3 The GNU C Library is free software; you can redistribute it and/or
4 modify it under the terms of the GNU Library General Public License as
5 published by the Free Software Foundation; either version 2 of the
6 License, or (at your option) any later version.
7
8 The GNU C Library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public
14 License along with the GNU C Library; see the file COPYING.LIB.  If
15 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
16 Cambridge, MA 02139, USA.  */
17
18 #include <langinfo.h>
19 #include <libintl.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include "localedef.h"
24 #include "token.h"
25
26
27 /* The content iof the field int_curr_symbol has to be taken from
28    ISO-4217.  We test for correct values.  */
29 #define DEFINE_INT_CURR(str) str,
30 static const char *const valid_int_curr[] =
31   {
32 #   include "iso-4217.def"
33   };
34 #define NVALID_INT_CURR ((sizeof (valid_int_curr) \
35                          / sizeof (valid_int_curr[0])))
36 #undef DEFINE_INT_CURR
37
38
39 /* These are defined in locfile-parse.c.  */
40 extern struct cat_item LC_MONETARY_desc[];
41 extern char *LC_MONETARY_values[];
42
43 static int _curr_strcmp(const char *s1, const char **s2);
44
45
46
47 void
48 monetary_check(void)
49 {
50   int item_no, val;
51
52   for (item_no = 0; LC_MONETARY_desc[item_no].item_id != 0; ++item_no)
53     /* Test whether the entry has been defined.  Byte values are simply
54        stored.  */
55     if (LC_MONETARY_values[item_no] == NULL)
56       {
57         int errcode;
58
59         errcode = LC_MONETARY_desc[item_no].status = std ? 5 : 0;
60
61         error (errcode, 0, gettext ("item `%s' of category `%s' undefined"),
62                LC_MONETARY_desc[item_no].name, "LC_MONETARY");
63       }
64     else
65       switch (LC_MONETARY_desc[item_no].item_id)
66         {
67         case INT_CURR_SYMBOL:
68           if (strlen (LC_MONETARY_values[item_no]) != 4)
69             error (0, 0,
70                    gettext ("item `%s' of category `%s' has wrong length"),
71                    LC_MONETARY_desc[item_no].name, "LC_MONETARY");
72           else if (bsearch (LC_MONETARY_values[item_no], valid_int_curr,
73                        NVALID_INT_CURR, sizeof (char *),
74                        (comparison_fn_t) _curr_strcmp) == NULL)
75             error (0, 0, gettext ("item `%s' does not correspond to any "
76                                   "valid name in ISO-4217"),
77                    LC_MONETARY_desc[item_no].name);
78           break;
79         case P_CS_PRECEDES:
80         case P_SEP_BY_SPACE:
81         case N_CS_PRECEDES:
82         case N_SEP_BY_SPACE:
83         case  P_SIGN_POSN:
84         case N_SIGN_POSN:
85           val = (int) *(char *) LC_MONETARY_values[item_no];
86           if (val < LC_MONETARY_desc[item_no].min
87               || val > LC_MONETARY_desc[item_no].max)
88             error (0, 0, gettext ("value for item `%s' in category `%s' "
89                                   "must be in range %d...%d"),
90                    LC_MONETARY_desc[item_no].name, "LC_MONETARY",
91                    LC_MONETARY_desc[item_no].min,
92                    LC_MONETARY_desc[item_no].max);
93           break;
94         case MON_DECIMAL_POINT:
95           /* The decimal point must not be empty.  This is not said
96              explicitly in POSIX but ANSI C (ISO/IEC 9899) says in
97              4.4.2.1 it has to be != "".  */
98           if (LC_MONETARY_values[item_no][0] == '\0')
99             error (0, 0,
100                    gettext ("item `%s' in category `%s' must not be empty"),
101                    LC_MONETARY_desc[item_no].name, "LC_MONETARY");
102           break;
103         case CURRENCY_SYMBOL:
104         case MON_THOUSANDS_SEP:
105         case MON_GROUPING:
106         case POSITIVE_SIGN:
107         case NEGATIVE_SIGN:
108         case INT_FRAC_DIGITS:
109         case FRAC_DIGITS:
110           /* Everything is ok for these values.  */
111           break;
112         default:
113           error (5, 0, gettext ("Internal error in %s, line %u"),
114                  __FUNCTION__, __LINE__);
115           /* NOTREACHED */
116         }
117
118 }
119
120
121 static int
122 _curr_strcmp(const char *s1, const char **s2)
123 {
124   return strcmp (s1, *s2);
125 }
126
127 /*
128  * Local Variables:
129  *  mode:c
130  *  c-basic-offset:2
131  * End:
132  */