1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 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/>. */
19 #include "language/lexer/token.h"
25 #include "data/identifier.h"
26 #include "libpspp/assertion.h"
27 #include "libpspp/cast.h"
28 #include "libpspp/misc.h"
30 #include "gl/ftoastr.h"
31 #include "gl/xalloc.h"
33 /* Initializes DST as a copy of SRC. */
35 token_copy (struct token *dst, const struct token *src)
37 *dst = (struct token) {
39 .number = src->number,
40 .string = ss_clone (src->string),
44 /* Frees the string that TOKEN contains. */
46 token_uninit (struct token *token)
50 ss_dealloc (&token->string);
51 *token = (struct token) { .type = T_STOP };
55 /* Returns true if A and B are the same token, false otherwise. */
57 token_equal (const struct token *a, const struct token *b)
59 if (a->type != b->type)
66 return a->number == b->number;
72 return ss_equals (a->string, b->string);
80 number_token_to_string (const struct token *token)
82 char buffer[DBL_BUFSIZE_BOUND];
84 c_dtoastr (buffer, sizeof buffer, 0, 0, fabs (token->number));
85 return (token->type == T_POS_NUM
87 : xasprintf ("-%s", buffer));
91 quoted_string_representation (struct substring ss, size_t n_quotes)
97 p = rep = xmalloc (1 + ss.length + n_quotes + 1 + 1);
99 for (i = 0; i < ss.length; i++)
101 uint8_t c = ss.string[i];
113 hex_string_representation (struct substring ss)
119 p = rep = xmalloc (2 + 2 * ss.length + 1 + 1);
122 for (i = 0; i < ss.length; i++)
124 static const char hex_digits[] = "0123456789abcdef";
125 uint8_t c = ss.string[i];
126 *p++ = hex_digits[c >> 4];
127 *p++ = hex_digits[c & 15];
136 string_representation (struct substring ss)
143 for (ofs = 0; ofs < ss.length; ofs += mblen)
147 mblen = u8_mbtoucr (&uc,
148 CHAR_CAST (const uint8_t *, ss.string + ofs),
150 if (mblen < 0 || !uc_is_print (uc))
151 return hex_string_representation (ss);
155 return quoted_string_representation (ss, n_quotes);
158 /* Returns a UTF-8 string that would yield TOKEN if it appeared in a syntax
159 file. The caller should free the returned string, with free(), when it is
162 The T_STOP token has no representation, so this function returns NULL. */
164 token_to_string (const struct token *token)
170 return number_token_to_string (token);
175 return ss_xstrdup (token->string);
178 return string_representation (token->string);
181 return xstrdup_if_nonnull (token_type_to_string (token->type));
185 /* Prints TOKEN on STREAM, for debugging. */
187 token_print (const struct token *token, FILE *stream)
189 fputs (token_type_to_name (token->type), stream);
190 if (token->type == T_POS_NUM || token->type == T_NEG_NUM
191 || token->number != 0.0)
193 char s[DBL_BUFSIZE_BOUND];
195 c_dtoastr (s, sizeof s, 0, 0, token->number);
196 fprintf (stream, "\t%s", s);
198 if (token->type == T_ID || token->type == T_STRING || token->string.length)
199 fprintf (stream, "\t\"%.*s\"",
200 (int) token->string.length, token->string.string);
204 /* Returns true if T is a numeric token for an integer in the range of "long",
205 except that LONG_MIN is excluded. */
207 token_is_integer (const struct token *t)
209 return (token_is_number (t)
210 && t->number > LONG_MIN
211 && t->number <= LONG_MAX
212 && floor (t->number) == t->number);
215 /* Returns the "long int" value of T, which must satisfy token_is_integer(T). */
217 token_integer (const struct token *t)
219 assert (token_is_integer (t));