1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2005, 2009, 2010, 2011 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* This file implements parts of identifier.h that call the msg() function.
18 This allows test programs that do not use those functions to avoid linking
19 additional object files. */
23 #include "data/identifier.h"
28 #include "libpspp/cast.h"
29 #include "libpspp/i18n.h"
30 #include "libpspp/message.h"
32 #include "gl/c-ctype.h"
35 #define _(msgid) gettext (msgid)
38 error_to_bool (char *error)
49 /* Checks whether if UTF-8 string ID is an acceptable identifier in encoding
50 DICT_ENCODING (UTF-8 if null). Returns NULL if it is acceptable, otherwise
51 an error message that the caller must free(). */
52 char * WARN_UNUSED_RESULT
53 id_is_valid__ (const char *id, const char *dict_encoding)
55 char *error = id_is_plausible__ (id);
60 if (dict_encoding != NULL)
62 /* XXX need to reject recoded strings that contain the fallback
64 dict_len = recode_string_len (dict_encoding, "UTF-8", id, -1);
67 dict_len = strlen (id);
69 if (dict_len > ID_MAX_LEN)
70 return xasprintf (_("Identifier `%s' exceeds %d-byte limit."),
76 /* Returns true if UTF-8 string ID is an acceptable identifier in encoding
77 DICT_ENCODING (UTF-8 if null), false otherwise. */
79 id_is_valid (const char *id, const char *dict_encoding)
81 return error_to_bool (id_is_valid__ (id, dict_encoding));
84 /* Checks whether UTF-8 string ID is an plausible identifier. Returns NULL if
85 it is, otherwise an error message that the caller must free(). */
86 char * WARN_UNUSED_RESULT
87 id_is_plausible__ (const char *id)
89 /* ID cannot be the empty string. */
91 return xstrdup (_("Identifier cannot be empty string."));
93 /* ID cannot be a reserved word. */
94 if (lex_id_to_token (ss_cstr (id)) != T_ID)
95 return xasprintf (_("`%s' may not be used as an identifier because it "
96 "is a reserved word."), id);
98 const uint8_t *bad_unit = u8_check (CHAR_CAST (const uint8_t *, id),
100 if (bad_unit != NULL)
102 /* If this message ever appears, it probably indicates a PSPP bug since
103 it shouldn't be possible to get invalid UTF-8 this far. */
104 return xasprintf (_("`%s' may not be used as an identifier because it "
105 "contains ill-formed UTF-8 at byte offset %tu."),
106 id, CHAR_CAST (const char *, bad_unit) - id);
109 /* Check that it is a valid identifier. */
111 int mblen = u8_strmbtouc (&uc, CHAR_CAST (uint8_t *, id));
112 if (!lex_uc_is_id1 (uc))
115 return xasprintf (_("Character %s (in `%s') may not appear "
116 "as the first character in a identifier."),
117 uc_name (uc, ucname), id);
120 for (const uint8_t *s = CHAR_CAST (uint8_t *, id + mblen);
121 (mblen = u8_strmbtouc (&uc, s)) != 0;
123 if (!lex_uc_is_idn (uc))
126 return xasprintf (_("Character %s (in `%s') may not appear in an "
128 uc_name (uc, ucname), id);
134 /* Returns true if UTF-8 string ID is an plausible identifier, false
137 id_is_plausible (const char *id)
139 return error_to_bool (id_is_plausible__ (id));