7
by Arnold D. Robbins
Moved to gawk 2.11. |
1 |
/*
|
281.1.1
by john haque
Speed/memory performance improvements. |
2 |
* array.c - routines for awk arrays.
|
7
by Arnold D. Robbins
Moved to gawk 2.11. |
3 |
*/
|
4 |
||
5 |
/*
|
|
408.5.129
by Arnold D. Robbins
Update copyright years on files changed in 2014. |
6 |
* Copyright (C) 1986, 1988, 1989, 1991-2014 the Free Software Foundation, Inc.
|
7
by Arnold D. Robbins
Moved to gawk 2.11. |
7 |
*
|
8 |
* This file is part of GAWK, the GNU implementation of the
|
|
21
by Arnold D. Robbins
Move to gawk-3.0.0. |
9 |
* AWK Programming Language.
|
7
by Arnold D. Robbins
Moved to gawk 2.11. |
10 |
*
|
11 |
* GAWK is free software; you can redistribute it and/or modify
|
|
12 |
* it under the terms of the GNU General Public License as published by
|
|
34
by Arnold D. Robbins
Move to gawk-3.1.6. |
13 |
* the Free Software Foundation; either version 3 of the License, or
|
12
by Arnold D. Robbins
Move to 2.13.3 (from 2.13.tar.gz - sigh). |
14 |
* (at your option) any later version.
|
7
by Arnold D. Robbins
Moved to gawk 2.11. |
15 |
*
|
16 |
* GAWK is distributed in the hope that it will be useful,
|
|
17 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19 |
* GNU General Public License for more details.
|
|
20 |
*
|
|
21 |
* You should have received a copy of the GNU General Public License
|
|
21
by Arnold D. Robbins
Move to gawk-3.0.0. |
22 |
* along with this program; if not, write to the Free Software
|
33
by Arnold D. Robbins
Move to gawk 3.1.5. |
23 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
7
by Arnold D. Robbins
Moved to gawk 2.11. |
24 |
*/
|
25 |
||
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
26 |
#include "awk.h" |
27 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
28 |
extern FILE *output_fp; |
29 |
extern NODE **fmt_list; /* declared in eval.c */ |
|
7
by Arnold D. Robbins
Moved to gawk 2.11. |
30 |
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
31 |
static size_t SUBSEPlen; |
32 |
static char *SUBSEP; |
|
281.1.1
by john haque
Speed/memory performance improvements. |
33 |
static char indent_char[] = " "; |
34 |
||
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
35 |
static NODE **null_lookup(NODE *symbol, NODE *subs); |
36 |
static NODE **null_dump(NODE *symbol, NODE *subs); |
|
321
by john haque
Polish array handling code. |
37 |
static afunc_t null_array_func[] = { |
38 |
(afunc_t) 0, |
|
39 |
(afunc_t) 0, |
|
322
by john haque
Improve array interface. |
40 |
null_length, |
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
41 |
null_lookup, |
42 |
null_afunc, |
|
43 |
null_afunc, |
|
44 |
null_afunc, |
|
45 |
null_afunc, |
|
46 |
null_afunc, |
|
47 |
null_dump, |
|
322
by john haque
Improve array interface. |
48 |
(afunc_t) 0, |
281.1.1
by john haque
Speed/memory performance improvements. |
49 |
};
|
50 |
||
51 |
#define MAX_ATYPE 10
|
|
52 |
||
321
by john haque
Polish array handling code. |
53 |
static afunc_t *array_types[MAX_ATYPE]; |
54 |
static int num_array_types = 0; |
|
281.1.1
by john haque
Speed/memory performance improvements. |
55 |
|
349
by Arnold D. Robbins
Restore building with tcc. |
56 |
/* array func to index mapping */
|
57 |
#define AFUNC(F) (F ## _ind)
|
|
58 |
||
321
by john haque
Polish array handling code. |
59 |
/* register_array_func --- add routines to handle arrays */
|
281.1.1
by john haque
Speed/memory performance improvements. |
60 |
|
61 |
int
|
|
321
by john haque
Polish array handling code. |
62 |
register_array_func(afunc_t *afunc) |
281.1.1
by john haque
Speed/memory performance improvements. |
63 |
{
|
321
by john haque
Polish array handling code. |
64 |
if (afunc && num_array_types < MAX_ATYPE) { |
65 |
if (afunc != str_array_func && ! afunc[AFUNC(atypeof)]) |
|
319.1.9
by Arnold D. Robbins
Move to use of bool type, true, false, everywhere. |
66 |
return false; |
321
by john haque
Polish array handling code. |
67 |
array_types[num_array_types++] = afunc; |
68 |
if (afunc[AFUNC(ainit)]) /* execute init routine if any */ |
|
69 |
(void) (*afunc[AFUNC(ainit)])(NULL, NULL); |
|
319.1.9
by Arnold D. Robbins
Move to use of bool type, true, false, everywhere. |
70 |
return true; |
281.1.1
by john haque
Speed/memory performance improvements. |
71 |
}
|
319.1.9
by Arnold D. Robbins
Move to use of bool type, true, false, everywhere. |
72 |
return false; |
281.1.1
by john haque
Speed/memory performance improvements. |
73 |
}
|
74 |
||
281.1.2
by john haque
Add a test file, cleanup code and update doc. |
75 |
|
281.1.1
by john haque
Speed/memory performance improvements. |
76 |
/* array_init --- register all builtin array types */
|
30
by Arnold D. Robbins
Move to gawk-3.1.2. |
77 |
|
78 |
void
|
|
79 |
array_init() |
|
80 |
{
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
81 |
(void) register_array_func(str_array_func); /* the default */ |
302.1.1
by john haque
Finish MPFR changes and clean up code. |
82 |
if (! do_mpfr) { |
83 |
(void) register_array_func(int_array_func); |
|
84 |
(void) register_array_func(cint_array_func); |
|
85 |
}
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
86 |
}
|
87 |
||
281.1.2
by john haque
Add a test file, cleanup code and update doc. |
88 |
|
281.1.1
by john haque
Speed/memory performance improvements. |
89 |
/* make_array --- create an array node */
|
90 |
||
91 |
NODE * |
|
92 |
make_array() |
|
93 |
{
|
|
94 |
NODE *array; |
|
95 |
getnode(array); |
|
96 |
memset(array, '\0', sizeof(NODE)); |
|
97 |
array->type = Node_var_array; |
|
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
98 |
array->array_funcs = null_array_func; |
281.1.1
by john haque
Speed/memory performance improvements. |
99 |
/* vname, flags, and parent_array not set here */
|
100 |
||
101 |
return array; |
|
102 |
}
|
|
103 |
||
104 |
||
321
by john haque
Polish array handling code. |
105 |
/* null_array --- force symbol to be an empty typeless array */
|
281.1.1
by john haque
Speed/memory performance improvements. |
106 |
|
107 |
void
|
|
321
by john haque
Polish array handling code. |
108 |
null_array(NODE *symbol) |
281.1.1
by john haque
Speed/memory performance improvements. |
109 |
{
|
110 |
symbol->type = Node_var_array; |
|
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
111 |
symbol->array_funcs = null_array_func; |
281.1.1
by john haque
Speed/memory performance improvements. |
112 |
symbol->buckets = NULL; |
113 |
symbol->table_size = symbol->array_size = 0; |
|
114 |
symbol->array_capacity = 0; |
|
321
by john haque
Polish array handling code. |
115 |
symbol->flags = 0; |
408.4.24
by Arnold D. Robbins
Fix in array.c. |
116 |
|
117 |
assert(symbol->xarray == NULL); |
|
118 |
||
321
by john haque
Polish array handling code. |
119 |
/* vname, parent_array not (re)initialized */
|
281.1.1
by john haque
Speed/memory performance improvements. |
120 |
}
|
121 |
||
122 |
||
408.4.24
by Arnold D. Robbins
Fix in array.c. |
123 |
/* null_lookup --- assign type to an empty array. */
|
281.1.1
by john haque
Speed/memory performance improvements. |
124 |
|
125 |
static NODE ** |
|
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
126 |
null_lookup(NODE *symbol, NODE *subs) |
281.1.1
by john haque
Speed/memory performance improvements. |
127 |
{
|
128 |
int i; |
|
321
by john haque
Polish array handling code. |
129 |
afunc_t *afunc = NULL; |
281.1.1
by john haque
Speed/memory performance improvements. |
130 |
|
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
131 |
assert(symbol->table_size == 0); |
281.1.1
by john haque
Speed/memory performance improvements. |
132 |
|
321
by john haque
Polish array handling code. |
133 |
/*
|
134 |
* Check which array type wants to accept this sub; traverse
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
135 |
* array type list in reverse order.
|
136 |
*/
|
|
321
by john haque
Polish array handling code. |
137 |
for (i = num_array_types - 1; i >= 1; i--) { |
138 |
afunc = array_types[i]; |
|
139 |
if (afunc[AFUNC(atypeof)](symbol, subs) != NULL) |
|
281.1.1
by john haque
Speed/memory performance improvements. |
140 |
break; |
141 |
}
|
|
142 |
if (i == 0 || afunc == NULL) |
|
321
by john haque
Polish array handling code. |
143 |
afunc = array_types[0]; /* default is str_array_func */ |
281.1.1
by john haque
Speed/memory performance improvements. |
144 |
symbol->array_funcs = afunc; |
145 |
||
146 |
/* We have the right type of array; install the subscript */
|
|
147 |
return symbol->alookup(symbol, subs); |
|
148 |
}
|
|
149 |
||
322
by john haque
Improve array interface. |
150 |
/* null_length --- default function for array length interface */
|
151 |
||
152 |
NODE ** |
|
153 |
null_length(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED) |
|
154 |
{
|
|
155 |
static NODE *tmp; |
|
156 |
tmp = symbol; |
|
157 |
return & tmp; |
|
158 |
}
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
159 |
|
321
by john haque
Polish array handling code. |
160 |
/* null_afunc --- default function for array interface */
|
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
161 |
|
321
by john haque
Polish array handling code. |
162 |
NODE ** |
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
163 |
null_afunc(NODE *symbol ATTRIBUTE_UNUSED, NODE *subs ATTRIBUTE_UNUSED) |
164 |
{
|
|
165 |
return NULL; |
|
166 |
}
|
|
167 |
||
168 |
/* null_dump --- dump function for an empty array */
|
|
169 |
||
170 |
static NODE ** |
|
171 |
null_dump(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED) |
|
172 |
{
|
|
173 |
fprintf(output_fp, "array `%s' is empty\n", array_vname(symbol)); |
|
174 |
return NULL; |
|
281.1.1
by john haque
Speed/memory performance improvements. |
175 |
}
|
176 |
||
177 |
||
178 |
/* assoc_copy --- duplicate input array "symbol" */
|
|
179 |
||
180 |
NODE * |
|
181 |
assoc_copy(NODE *symbol, NODE *newsymb) |
|
182 |
{
|
|
183 |
assert(newsymb->vname != NULL); |
|
184 |
||
185 |
assoc_clear(newsymb); |
|
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
186 |
(void) symbol->acopy(symbol, newsymb); |
187 |
newsymb->array_funcs = symbol->array_funcs; |
|
188 |
newsymb->flags = symbol->flags; |
|
281.1.1
by john haque
Speed/memory performance improvements. |
189 |
return newsymb; |
190 |
}
|
|
191 |
||
192 |
||
193 |
/* assoc_dump --- dump array */
|
|
194 |
||
195 |
void
|
|
196 |
assoc_dump(NODE *symbol, NODE *ndump) |
|
197 |
{
|
|
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
198 |
if (symbol->adump) |
281.1.1
by john haque
Speed/memory performance improvements. |
199 |
(void) symbol->adump(symbol, ndump); |
200 |
}
|
|
201 |
||
30
by Arnold D. Robbins
Move to gawk-3.1.2. |
202 |
|
209
by Arnold D. Robbins
More array sorting fixes. |
203 |
/* make_aname --- construct a 'vname' for a (sub)array */
|
204 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
205 |
const char * |
209
by Arnold D. Robbins
More array sorting fixes. |
206 |
make_aname(const NODE *symbol) |
207 |
{
|
|
208 |
static char *aname = NULL; |
|
209 |
static size_t alen; |
|
210 |
static size_t max_alen; |
|
211 |
#define SLEN 256
|
|
212 |
||
213 |
if (symbol->parent_array != NULL) { |
|
214 |
size_t slen; |
|
215 |
||
216 |
(void) make_aname(symbol->parent_array); |
|
217 |
slen = strlen(symbol->vname); /* subscript in parent array */ |
|
218 |
if (alen + slen + 4 > max_alen) { /* sizeof("[\"\"]") = 4 */ |
|
219 |
max_alen = alen + slen + 4 + SLEN; |
|
220 |
erealloc(aname, char *, (max_alen + 1) * sizeof(char *), "make_aname"); |
|
221 |
}
|
|
222 |
alen += sprintf(aname + alen, "[\"%s\"]", symbol->vname); |
|
223 |
} else { |
|
224 |
alen = strlen(symbol->vname); |
|
225 |
if (aname == NULL) { |
|
226 |
max_alen = alen + SLEN; |
|
227 |
emalloc(aname, char *, (max_alen + 1) * sizeof(char *), "make_aname"); |
|
228 |
} else if (alen > max_alen) { |
|
229 |
max_alen = alen + SLEN; |
|
230 |
erealloc(aname, char *, (max_alen + 1) * sizeof(char *), "make_aname"); |
|
231 |
}
|
|
232 |
memcpy(aname, symbol->vname, alen + 1); |
|
281.1.1
by john haque
Speed/memory performance improvements. |
233 |
}
|
209
by Arnold D. Robbins
More array sorting fixes. |
234 |
return aname; |
281.1.1
by john haque
Speed/memory performance improvements. |
235 |
}
|
209
by Arnold D. Robbins
More array sorting fixes. |
236 |
#undef SLEN
|
281.1.1
by john haque
Speed/memory performance improvements. |
237 |
|
209
by Arnold D. Robbins
More array sorting fixes. |
238 |
|
31
by Arnold D. Robbins
Move to gawk-3.1.3. |
239 |
/*
|
240 |
* array_vname --- print the name of the array
|
|
241 |
*
|
|
242 |
* Returns a pointer to a statically maintained dynamically allocated string.
|
|
243 |
* It's appropriate for printing the name once; if the caller wants
|
|
244 |
* to save it, they have to make a copy.
|
|
245 |
*/
|
|
246 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
247 |
const char * |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
248 |
array_vname(const NODE *symbol) |
31
by Arnold D. Robbins
Move to gawk-3.1.3. |
249 |
{
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
250 |
static char *message = NULL; |
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
251 |
static size_t msglen = 0; |
252 |
char *s; |
|
253 |
size_t len; |
|
254 |
int n; |
|
255 |
const NODE *save_symbol = symbol; |
|
256 |
const char *from = _("from %s"); |
|
209
by Arnold D. Robbins
More array sorting fixes. |
257 |
const char *aname; |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
258 |
|
209
by Arnold D. Robbins
More array sorting fixes. |
259 |
if (symbol->type != Node_array_ref |
260 |
|| symbol->orig_array->type != Node_var_array |
|
261 |
) { |
|
262 |
if (symbol->type != Node_var_array || symbol->parent_array == NULL) |
|
263 |
return symbol->vname; |
|
264 |
return make_aname(symbol); |
|
265 |
}
|
|
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
266 |
|
267 |
/* First, we have to compute the length of the string: */
|
|
209
by Arnold D. Robbins
More array sorting fixes. |
268 |
|
269 |
len = 2; /* " (" */ |
|
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
270 |
n = 0; |
209
by Arnold D. Robbins
More array sorting fixes. |
271 |
while (symbol->type == Node_array_ref) { |
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
272 |
len += strlen(symbol->vname); |
273 |
n++; |
|
209
by Arnold D. Robbins
More array sorting fixes. |
274 |
symbol = symbol->prev_array; |
275 |
}
|
|
276 |
||
277 |
/* Get the (sub)array name */
|
|
278 |
if (symbol->parent_array == NULL) |
|
279 |
aname = symbol->vname; |
|
280 |
else
|
|
281 |
aname = make_aname(symbol); |
|
282 |
len += strlen(aname); |
|
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
283 |
/*
|
284 |
* Each node contributes by strlen(from) minus the length
|
|
285 |
* of "%s" in the translation (which is at least 2)
|
|
286 |
* plus 2 for ", " or ")\0"; this adds up to strlen(from).
|
|
287 |
*/
|
|
288 |
len += n * strlen(from); |
|
289 |
||
290 |
/* (Re)allocate memory: */
|
|
291 |
if (message == NULL) { |
|
292 |
emalloc(message, char *, len, "array_vname"); |
|
293 |
msglen = len; |
|
294 |
} else if (len > msglen) { |
|
295 |
erealloc(message, char *, len, "array_vname"); |
|
296 |
msglen = len; |
|
297 |
} /* else |
|
298 |
current buffer can hold new name */
|
|
299 |
||
300 |
/* We're ready to print: */
|
|
301 |
symbol = save_symbol; |
|
302 |
s = message; |
|
303 |
/*
|
|
304 |
* Ancient systems have sprintf() returning char *, not int.
|
|
305 |
* If you have one of those, use sprintf(..); s += strlen(s) instead.
|
|
306 |
*/
|
|
209
by Arnold D. Robbins
More array sorting fixes. |
307 |
|
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
308 |
s += sprintf(s, "%s (", symbol->vname); |
309 |
for (;;) { |
|
310 |
symbol = symbol->prev_array; |
|
311 |
if (symbol->type != Node_array_ref) |
|
312 |
break; |
|
209
by Arnold D. Robbins
More array sorting fixes. |
313 |
s += sprintf(s, from, symbol->vname); |
314 |
s += sprintf(s, ", "); |
|
31
by Arnold D. Robbins
Move to gawk-3.1.3. |
315 |
}
|
209
by Arnold D. Robbins
More array sorting fixes. |
316 |
s += sprintf(s, from, aname); |
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
317 |
strcpy(s, ")"); |
318 |
||
319 |
return message; |
|
31
by Arnold D. Robbins
Move to gawk-3.1.3. |
320 |
}
|
321 |
||
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
322 |
|
323 |
/*
|
|
321
by john haque
Polish array handling code. |
324 |
* force_array --- proceed to the actual Node_var_array,
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
325 |
* change Node_var_new to an array.
|
326 |
* If canfatal and type isn't good, die fatally,
|
|
327 |
* otherwise return the final actual value.
|
|
328 |
*/
|
|
329 |
||
330 |
NODE * |
|
327
by Arnold D. Robbins
Merge branch 'master' into array-iface |
331 |
force_array(NODE *symbol, bool canfatal) |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
332 |
{
|
333 |
NODE *save_symbol = symbol; |
|
319.1.9
by Arnold D. Robbins
Move to use of bool type, true, false, everywhere. |
334 |
bool isparam = false; |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
335 |
|
281.1.1
by john haque
Speed/memory performance improvements. |
336 |
if (symbol->type == Node_param_list) { |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
337 |
save_symbol = symbol = GET_PARAM(symbol->param_cnt); |
319.1.9
by Arnold D. Robbins
Move to use of bool type, true, false, everywhere. |
338 |
isparam = true; |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
339 |
if (symbol->type == Node_array_ref) |
340 |
symbol = symbol->orig_array; |
|
341 |
}
|
|
342 |
||
343 |
switch (symbol->type) { |
|
344 |
case Node_var_new: |
|
408.4.24
by Arnold D. Robbins
Fix in array.c. |
345 |
symbol->xarray = NULL; /* make sure union is as it should be */ |
321
by john haque
Polish array handling code. |
346 |
null_array(symbol); |
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
347 |
symbol->parent_array = NULL; /* main array has no parent */ |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
348 |
/* fall through */
|
349 |
case Node_var_array: |
|
350 |
break; |
|
351 |
||
352 |
case Node_array_ref: |
|
353 |
default: |
|
281.1.1
by john haque
Speed/memory performance improvements. |
354 |
/* notably Node_var but catches also e.g. a[1] = "x"; a[1][1] = "y" */
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
355 |
if (canfatal) { |
356 |
if (symbol->type == Node_val) |
|
357 |
fatal(_("attempt to use a scalar value as array")); |
|
281.1.1
by john haque
Speed/memory performance improvements. |
358 |
if (isparam) |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
359 |
fatal(_("attempt to use scalar parameter `%s' as an array"), |
281.1.1
by john haque
Speed/memory performance improvements. |
360 |
save_symbol->vname); |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
361 |
else
|
132
by Arnold D. Robbins
Equalize messages. New es.po file. |
362 |
fatal(_("attempt to use scalar `%s' as an array"), |
281.1.1
by john haque
Speed/memory performance improvements. |
363 |
save_symbol->vname); |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
364 |
} else |
365 |
break; |
|
366 |
}
|
|
367 |
||
368 |
return symbol; |
|
369 |
}
|
|
370 |
||
371 |
||
372 |
/* set_SUBSEP --- update SUBSEP related variables when SUBSEP assigned to */
|
|
373 |
||
374 |
void
|
|
375 |
set_SUBSEP() |
|
376 |
{
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
377 |
SUBSEP_node->var_value = force_string(SUBSEP_node->var_value); |
378 |
SUBSEP = SUBSEP_node->var_value->stptr; |
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
379 |
SUBSEPlen = SUBSEP_node->var_value->stlen; |
281.1.1
by john haque
Speed/memory performance improvements. |
380 |
}
|
381 |
||
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
382 |
|
21
by Arnold D. Robbins
Move to gawk-3.0.0. |
383 |
/* concat_exp --- concatenate expression list into a single string */
|
384 |
||
7
by Arnold D. Robbins
Moved to gawk 2.11. |
385 |
NODE * |
319.1.9
by Arnold D. Robbins
Move to use of bool type, true, false, everywhere. |
386 |
concat_exp(int nargs, bool do_subsep) |
7
by Arnold D. Robbins
Moved to gawk 2.11. |
387 |
{
|
319.1.9
by Arnold D. Robbins
Move to use of bool type, true, false, everywhere. |
388 |
/* do_subsep is false for Op_concat */
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
389 |
NODE *r; |
7
by Arnold D. Robbins
Moved to gawk 2.11. |
390 |
char *str; |
391 |
char *s; |
|
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
392 |
size_t len; |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
393 |
size_t subseplen = 0; |
394 |
int i; |
|
395 |
extern NODE **args_array; |
|
396 |
||
397 |
if (nargs == 1) |
|
398 |
return POP_STRING(); |
|
399 |
||
400 |
if (do_subsep) |
|
401 |
subseplen = SUBSEPlen; |
|
402 |
||
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
403 |
len = 0; |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
404 |
for (i = 1; i <= nargs; i++) { |
281.1.1
by john haque
Speed/memory performance improvements. |
405 |
r = TOP(); |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
406 |
if (r->type == Node_var_array) { |
407 |
while (--i > 0) |
|
408 |
DEREF(args_array[i]); /* avoid memory leak */ |
|
409 |
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(r)); |
|
281.1.1
by john haque
Speed/memory performance improvements. |
410 |
}
|
411 |
r = POP_STRING(); |
|
412 |
args_array[i] = r; |
|
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
413 |
len += r->stlen; |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
414 |
}
|
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
415 |
len += (nargs - 1) * subseplen; |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
416 |
|
417 |
emalloc(str, char *, len + 2, "concat_exp"); |
|
418 |
||
419 |
r = args_array[nargs]; |
|
420 |
memcpy(str, r->stptr, r->stlen); |
|
7
by Arnold D. Robbins
Moved to gawk 2.11. |
421 |
s = str + r->stlen; |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
422 |
DEREF(r); |
423 |
for (i = nargs - 1; i > 0; i--) { |
|
7
by Arnold D. Robbins
Moved to gawk 2.11. |
424 |
if (subseplen == 1) |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
425 |
*s++ = *SUBSEP; |
426 |
else if (subseplen > 0) { |
|
427 |
memcpy(s, SUBSEP, subseplen); |
|
7
by Arnold D. Robbins
Moved to gawk 2.11. |
428 |
s += subseplen; |
429 |
}
|
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
430 |
r = args_array[i]; |
431 |
memcpy(s, r->stptr, r->stlen); |
|
7
by Arnold D. Robbins
Moved to gawk 2.11. |
432 |
s += r->stlen; |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
433 |
DEREF(r); |
434 |
}
|
|
435 |
||
281.1.2
by john haque
Add a test file, cleanup code and update doc. |
436 |
return make_str_node(str, len, ALREADY_MALLOCED); |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
437 |
}
|
438 |
||
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
439 |
|
321
by john haque
Polish array handling code. |
440 |
/*
|
441 |
* adjust_fcall_stack: remove subarray(s) of symbol[] from
|
|
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
442 |
* function call stack.
|
443 |
*/
|
|
444 |
||
445 |
static void |
|
446 |
adjust_fcall_stack(NODE *symbol, int nsubs) |
|
447 |
{
|
|
448 |
NODE *func, *r, *n; |
|
449 |
NODE **sp; |
|
450 |
int pcount; |
|
451 |
||
452 |
/*
|
|
453 |
* Solve the nasty problem of disappearing subarray arguments:
|
|
454 |
*
|
|
455 |
* function f(c, d) { delete c; .. use non-existent array d .. }
|
|
456 |
* BEGIN { a[0][0] = 1; f(a, a[0]); .. }
|
|
457 |
*
|
|
458 |
* The fix is to convert 'd' to a local empty array; This has
|
|
459 |
* to be done before clearing the parent array to avoid referring to
|
|
460 |
* already free-ed memory.
|
|
461 |
*
|
|
462 |
* Similar situations exist for builtins accepting more than
|
|
463 |
* one array argument: split, patsplit, asort and asorti. For example:
|
|
464 |
*
|
|
465 |
* BEGIN { a[0][0] = 1; split("abc", a, "", a[0]) }
|
|
466 |
*
|
|
467 |
* These cases do not involve the function call stack, and are
|
|
468 |
* handled individually in their respective routines.
|
|
469 |
*/
|
|
470 |
||
471 |
func = frame_ptr->func_node; |
|
472 |
if (func == NULL) /* in main */ |
|
473 |
return; |
|
281.1.1
by john haque
Speed/memory performance improvements. |
474 |
pcount = func->param_cnt; |
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
475 |
sp = frame_ptr->stack; |
476 |
||
477 |
for (; pcount > 0; pcount--) { |
|
478 |
r = *sp++; |
|
479 |
if (r->type != Node_array_ref |
|
480 |
|| r->orig_array->type != Node_var_array) |
|
481 |
continue; |
|
482 |
n = r->orig_array; |
|
483 |
||
484 |
/* Case 1 */
|
|
485 |
if (n == symbol |
|
486 |
&& symbol->parent_array != NULL |
|
487 |
&& nsubs > 0 |
|
488 |
) { |
|
321
by john haque
Polish array handling code. |
489 |
/*
|
490 |
* 'symbol' is a subarray, and 'r' is the same subarray:
|
|
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
491 |
*
|
492 |
* function f(c, d) { delete c[0]; .. }
|
|
493 |
* BEGIN { a[0][0] = 1; f(a, a[0]); .. }
|
|
494 |
*
|
|
495 |
* But excludes cases like (nsubs = 0):
|
|
496 |
*
|
|
497 |
* function f(c, d) { delete c; ..}
|
|
498 |
* BEGIN { a[0][0] = 1; f(a[0], a[0]); ...}
|
|
499 |
*/
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
500 |
|
321
by john haque
Polish array handling code. |
501 |
null_array(r); |
281.1.1
by john haque
Speed/memory performance improvements. |
502 |
r->parent_array = NULL; |
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
503 |
continue; |
504 |
}
|
|
505 |
||
506 |
/* Case 2 */
|
|
507 |
for (n = n->parent_array; n != NULL; n = n->parent_array) { |
|
508 |
assert(n->type == Node_var_array); |
|
509 |
if (n == symbol) { |
|
321
by john haque
Polish array handling code. |
510 |
/*
|
511 |
* 'r' is a subarray of 'symbol':
|
|
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
512 |
*
|
513 |
* function f(c, d) { delete c; .. use d as array .. }
|
|
514 |
* BEGIN { a[0][0] = 1; f(a, a[0]); .. }
|
|
515 |
* OR
|
|
516 |
* BEGIN { a[0][0][0][0] = 1; f(a[0], a[0][0][0]); .. }
|
|
517 |
*
|
|
518 |
*/
|
|
321
by john haque
Polish array handling code. |
519 |
null_array(r); |
281.1.1
by john haque
Speed/memory performance improvements. |
520 |
r->parent_array = NULL; |
521 |
break; |
|
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
522 |
}
|
523 |
}
|
|
524 |
}
|
|
525 |
}
|
|
526 |
||
527 |
||
21
by Arnold D. Robbins
Move to gawk-3.0.0. |
528 |
/* do_delete --- perform `delete array[s]' */
|
529 |
||
30
by Arnold D. Robbins
Move to gawk-3.1.2. |
530 |
/*
|
531 |
* `symbol' is array
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
532 |
* `nsubs' is no of subscripts
|
30
by Arnold D. Robbins
Move to gawk-3.1.2. |
533 |
*/
|
534 |
||
7
by Arnold D. Robbins
Moved to gawk 2.11. |
535 |
void
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
536 |
do_delete(NODE *symbol, int nsubs) |
7
by Arnold D. Robbins
Moved to gawk 2.11. |
537 |
{
|
281.1.1
by john haque
Speed/memory performance improvements. |
538 |
NODE *val, *subs; |
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
539 |
int i; |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
540 |
|
541 |
assert(symbol->type == Node_var_array); |
|
281.1.1
by john haque
Speed/memory performance improvements. |
542 |
subs = val = NULL; /* silence the compiler */ |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
543 |
|
191
by Arnold D. Robbins
Improve saving of numeric value of index. |
544 |
/*
|
545 |
* The force_string() call is needed to make sure that
|
|
546 |
* the string subscript is reasonable. For example, with it:
|
|
547 |
*
|
|
548 |
* $ ./gawk --posix 'BEGIN { CONVFMT="%ld"; delete a[1.233]}'
|
|
549 |
* gawk: cmd. line:1: fatal: `%l' is not permitted in POSIX awk formats
|
|
550 |
*
|
|
551 |
* Without it, the code does not fail.
|
|
552 |
*/
|
|
553 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
554 |
#define free_subs(n) do { \
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
555 |
NODE *s = PEEK(n - 1); \
|
556 |
if (s->type == Node_val) { \
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
557 |
(void) force_string(s); /* may have side effects. */ \ |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
558 |
DEREF(s); \
|
559 |
} \
|
|
560 |
} while (--n > 0)
|
|
561 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
562 |
if (nsubs == 0) { |
563 |
/* delete array */
|
|
564 |
||
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
565 |
adjust_fcall_stack(symbol, 0); /* fix function call stack; See above. */ |
24
by Arnold D. Robbins
Move to gawk-3.0.3. |
566 |
assoc_clear(symbol); |
567 |
return; |
|
568 |
}
|
|
569 |
||
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
570 |
/* NB: subscripts are in reverse order on stack */
|
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
571 |
|
572 |
for (i = nsubs; i > 0; i--) { |
|
573 |
subs = PEEK(i - 1); |
|
574 |
if (subs->type != Node_val) { |
|
575 |
free_subs(i); |
|
576 |
fatal(_("attempt to use array `%s' in a scalar context"), array_vname(subs)); |
|
577 |
}
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
578 |
|
579 |
val = in_array(symbol, subs); |
|
580 |
if (val == NULL) { |
|
581 |
if (do_lint) { |
|
582 |
subs = force_string(subs); |
|
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
583 |
lintwarn(_("delete: index `%s' not in array `%s'"), |
584 |
subs->stptr, array_vname(symbol)); |
|
281.1.1
by john haque
Speed/memory performance improvements. |
585 |
}
|
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
586 |
/* avoid memory leak, free all subs */
|
587 |
free_subs(i); |
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
588 |
return; |
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
589 |
}
|
590 |
||
591 |
if (i > 1) { |
|
281.1.1
by john haque
Speed/memory performance improvements. |
592 |
if (val->type != Node_var_array) { |
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
593 |
/* e.g.: a[1] = 1; delete a[1][1] */
|
281.1.1
by john haque
Speed/memory performance improvements. |
594 |
|
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
595 |
free_subs(i); |
281.1.1
by john haque
Speed/memory performance improvements. |
596 |
subs = force_string(subs); |
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
597 |
fatal(_("attempt to use scalar `%s[\"%.*s\"]' as an array"), |
209
by Arnold D. Robbins
More array sorting fixes. |
598 |
array_vname(symbol), |
281.1.1
by john haque
Speed/memory performance improvements. |
599 |
(int) subs->stlen, |
600 |
subs->stptr); |
|
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
601 |
}
|
281.1.1
by john haque
Speed/memory performance improvements. |
602 |
symbol = val; |
603 |
DEREF(subs); |
|
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
604 |
}
|
605 |
}
|
|
606 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
607 |
if (val->type == Node_var_array) { |
608 |
adjust_fcall_stack(val, nsubs); /* fix function call stack; See above. */ |
|
609 |
assoc_clear(val); |
|
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
610 |
/* cleared a sub-array, free Node_var_array */
|
281.1.1
by john haque
Speed/memory performance improvements. |
611 |
efree(val->vname); |
612 |
freenode(val); |
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
613 |
} else |
281.1.1
by john haque
Speed/memory performance improvements. |
614 |
unref(val); |
615 |
||
616 |
(void) assoc_remove(symbol, subs); |
|
617 |
DEREF(subs); |
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
618 |
|
619 |
#undef free_subs
|
|
7
by Arnold D. Robbins
Moved to gawk 2.11. |
620 |
}
|
621 |
||
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
622 |
|
27
by Arnold D. Robbins
Move to gawk-3.0.6. |
623 |
/* do_delete_loop --- simulate ``for (iggy in foo) delete foo[iggy]'' */
|
624 |
||
625 |
/*
|
|
626 |
* The primary hassle here is that `iggy' needs to have some arbitrary
|
|
627 |
* array index put in it before we can clear the array, we can't
|
|
628 |
* just replace the loop with `delete foo'.
|
|
629 |
*/
|
|
630 |
||
631 |
void
|
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
632 |
do_delete_loop(NODE *symbol, NODE **lhs) |
27
by Arnold D. Robbins
Move to gawk-3.0.6. |
633 |
{
|
281.1.1
by john haque
Speed/memory performance improvements. |
634 |
NODE **list; |
322
by john haque
Improve array interface. |
635 |
NODE akind; |
636 |
||
637 |
akind.flags = AINDEX|ADELETE; /* need a single index */ |
|
638 |
list = symbol->alist(symbol, & akind); |
|
639 |
||
640 |
if (assoc_empty(symbol)) |
|
31
by Arnold D. Robbins
Move to gawk-3.1.3. |
641 |
return; |
27
by Arnold D. Robbins
Move to gawk-3.0.6. |
642 |
|
281.1.1
by john haque
Speed/memory performance improvements. |
643 |
unref(*lhs); |
644 |
*lhs = list[0]; |
|
645 |
efree(list); |
|
27
by Arnold D. Robbins
Move to gawk-3.0.6. |
646 |
|
647 |
/* blast the array in one shot */
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
648 |
adjust_fcall_stack(symbol, 0); |
27
by Arnold D. Robbins
Move to gawk-3.0.6. |
649 |
assoc_clear(symbol); |
650 |
}
|
|
651 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
652 |
|
653 |
/* value_info --- print scalar node info */
|
|
654 |
||
18
by Arnold D. Robbins
Move to gawk-2.15.4. |
655 |
static void |
281.1.1
by john haque
Speed/memory performance improvements. |
656 |
value_info(NODE *n) |
18
by Arnold D. Robbins
Move to gawk-2.15.4. |
657 |
{
|
281.1.5
by john haque
Add GPL notice in symbol.c. |
658 |
|
659 |
#define PREC_NUM -1
|
|
660 |
#define PREC_STR -1
|
|
661 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
662 |
if (n == Nnull_string || n == Null_field) { |
663 |
fprintf(output_fp, "<(null)>"); |
|
18
by Arnold D. Robbins
Move to gawk-2.15.4. |
664 |
return; |
665 |
}
|
|
666 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
667 |
if ((n->flags & (STRING|STRCUR)) != 0) { |
668 |
fprintf(output_fp, "<"); |
|
669 |
fprintf(output_fp, "\"%.*s\"", PREC_STR, n->stptr); |
|
302.1.1
by john haque
Finish MPFR changes and clean up code. |
670 |
if ((n->flags & (NUMBER|NUMCUR)) != 0) { |
671 |
#ifdef HAVE_MPFR
|
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
672 |
if (is_mpg_float(n)) |
673 |
fprintf(output_fp, ":%s", |
|
316
by john haque
Change MPFR variable RND_MODE to ROUND_MODE. |
674 |
mpg_fmt("%.*R*g", PREC_NUM, ROUND_MODE, n->mpg_numbr)); |
306
by john haque
Add arbitrary-precision arithmetic on integers. |
675 |
else if (is_mpg_integer(n)) |
676 |
fprintf(output_fp, ":%s", mpg_fmt("%Zd", n->mpg_i)); |
|
302.1.1
by john haque
Finish MPFR changes and clean up code. |
677 |
else
|
678 |
#endif
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
679 |
fprintf(output_fp, ":%.*g", PREC_NUM, n->numbr); |
302.1.1
by john haque
Finish MPFR changes and clean up code. |
680 |
}
|
281.1.1
by john haque
Speed/memory performance improvements. |
681 |
fprintf(output_fp, ">"); |
302.1.1
by john haque
Finish MPFR changes and clean up code. |
682 |
} else { |
683 |
#ifdef HAVE_MPFR
|
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
684 |
if (is_mpg_float(n)) |
685 |
fprintf(output_fp, "<%s>", |
|
316
by john haque
Change MPFR variable RND_MODE to ROUND_MODE. |
686 |
mpg_fmt("%.*R*g", PREC_NUM, ROUND_MODE, n->mpg_numbr)); |
306
by john haque
Add arbitrary-precision arithmetic on integers. |
687 |
else if (is_mpg_integer(n)) |
688 |
fprintf(output_fp, "<%s>", mpg_fmt("%Zd", n->mpg_i)); |
|
302.1.1
by john haque
Finish MPFR changes and clean up code. |
689 |
else
|
690 |
#endif
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
691 |
fprintf(output_fp, "<%.*g>", PREC_NUM, n->numbr); |
302.1.1
by john haque
Finish MPFR changes and clean up code. |
692 |
}
|
281.1.1
by john haque
Speed/memory performance improvements. |
693 |
|
694 |
fprintf(output_fp, ":%s", flags2str(n->flags)); |
|
695 |
||
696 |
if ((n->flags & FIELD) == 0) |
|
697 |
fprintf(output_fp, ":%ld", n->valref); |
|
26
by Arnold D. Robbins
Move to gawk-3.0.5. |
698 |
else
|
281.1.1
by john haque
Speed/memory performance improvements. |
699 |
fprintf(output_fp, ":"); |
700 |
||
701 |
if ((n->flags & (STRING|STRCUR)) == STRCUR) { |
|
702 |
fprintf(output_fp, "]["); |
|
703 |
fprintf(output_fp, "stfmt=%d, ", n->stfmt); |
|
704 |
fprintf(output_fp, "CONVFMT=\"%s\"", n->stfmt <= -1 ? "%ld" |
|
705 |
: fmt_list[n->stfmt]->stptr); |
|
706 |
}
|
|
281.1.5
by john haque
Add GPL notice in symbol.c. |
707 |
|
708 |
#undef PREC_NUM
|
|
709 |
#undef PREC_STR
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
710 |
}
|
711 |
||
712 |
||
713 |
void
|
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
714 |
indent(int indent_level) |
715 |
{
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
716 |
int i; |
717 |
for (i = 0; i < indent_level; i++) |
|
718 |
fprintf(output_fp, "%s", indent_char); |
|
26
by Arnold D. Robbins
Move to gawk-3.0.5. |
719 |
}
|
720 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
721 |
/* assoc_info --- print index, value info */
|
26
by Arnold D. Robbins
Move to gawk-3.0.5. |
722 |
|
281.1.1
by john haque
Speed/memory performance improvements. |
723 |
void
|
724 |
assoc_info(NODE *subs, NODE *val, NODE *ndump, const char *aname) |
|
26
by Arnold D. Robbins
Move to gawk-3.0.5. |
725 |
{
|
281.1.1
by john haque
Speed/memory performance improvements. |
726 |
int indent_level = ndump->alevel; |
727 |
||
728 |
indent_level++; |
|
729 |
indent(indent_level); |
|
730 |
fprintf(output_fp, "I: [%s:", aname); |
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
731 |
if ((subs->flags & (MPFN|MPZN|INTIND)) == INTIND) |
281.1.1
by john haque
Speed/memory performance improvements. |
732 |
fprintf(output_fp, "<%ld>", (long) subs->numbr); |
733 |
else
|
|
734 |
value_info(subs); |
|
735 |
fprintf(output_fp, "]\n"); |
|
736 |
||
737 |
indent(indent_level); |
|
738 |
if (val->type == Node_val) { |
|
739 |
fprintf(output_fp, "V: [scalar: "); |
|
740 |
value_info(val); |
|
741 |
} else { |
|
742 |
fprintf(output_fp, "V: ["); |
|
743 |
ndump->alevel++; |
|
744 |
ndump->adepth--; |
|
745 |
assoc_dump(val, ndump); |
|
746 |
ndump->adepth++; |
|
747 |
ndump->alevel--; |
|
748 |
indent(indent_level); |
|
749 |
}
|
|
750 |
fprintf(output_fp, "]\n"); |
|
26
by Arnold D. Robbins
Move to gawk-3.0.5. |
751 |
}
|
752 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
753 |
|
26
by Arnold D. Robbins
Move to gawk-3.0.5. |
754 |
/* do_adump --- dump an array: interface to assoc_dump */
|
755 |
||
756 |
NODE * |
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
757 |
do_adump(int nargs) |
26
by Arnold D. Robbins
Move to gawk-3.0.5. |
758 |
{
|
281.1.1
by john haque
Speed/memory performance improvements. |
759 |
NODE *symbol, *tmp; |
760 |
static NODE ndump; |
|
761 |
long depth = 0; |
|
762 |
||
321
by john haque
Polish array handling code. |
763 |
/*
|
764 |
* depth < 0, no index and value info.
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
765 |
* = 0, main array index and value info; does not descend into sub-arrays.
|
766 |
* > 0, descends into 'depth' sub-arrays, and prints index and value info.
|
|
767 |
*/
|
|
768 |
||
769 |
if (nargs == 2) { |
|
301
by john haque
New interpreter routine for MPFR. |
770 |
tmp = POP_NUMBER(); |
771 |
depth = get_number_si(tmp); |
|
281.1.1
by john haque
Speed/memory performance improvements. |
772 |
DEREF(tmp); |
773 |
}
|
|
774 |
symbol = POP_PARAM(); |
|
775 |
if (symbol->type != Node_var_array) |
|
776 |
fatal(_("adump: first argument not an array")); |
|
777 |
||
778 |
ndump.type = Node_dump_array; |
|
779 |
ndump.adepth = depth; |
|
780 |
ndump.alevel = 0; |
|
781 |
assoc_dump(symbol, & ndump); |
|
782 |
return make_number((AWKNUM) 0); |
|
28
by Arnold D. Robbins
Move to gawk-3.1.0. |
783 |
}
|
784 |
||
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
785 |
|
30
by Arnold D. Robbins
Move to gawk-3.1.2. |
786 |
/* asort_actual --- do the actual work to sort the input array */
|
28
by Arnold D. Robbins
Move to gawk-3.1.0. |
787 |
|
30
by Arnold D. Robbins
Move to gawk-3.1.2. |
788 |
static NODE * |
322
by john haque
Improve array interface. |
789 |
asort_actual(int nargs, sort_context_t ctxt) |
28
by Arnold D. Robbins
Move to gawk-3.1.0. |
790 |
{
|
181
by Arnold D. Robbins
More array sorting changes from John. |
791 |
NODE *array, *dest = NULL, *result; |
205
by Arnold D. Robbins
Revamp array sorting. |
792 |
NODE *r, *subs, *s; |
320
by john haque
Use unref when freeing a null array element. |
793 |
NODE **list = NULL, **ptr, **lhs; |
181
by Arnold D. Robbins
More array sorting changes from John. |
794 |
unsigned long num_elems, i; |
205
by Arnold D. Robbins
Revamp array sorting. |
795 |
const char *sort_str; |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
796 |
|
181
by Arnold D. Robbins
More array sorting changes from John. |
797 |
if (nargs == 3) /* 3rd optional arg */ |
205
by Arnold D. Robbins
Revamp array sorting. |
798 |
s = POP_STRING(); |
181
by Arnold D. Robbins
More array sorting changes from John. |
799 |
else
|
281.1.1
by john haque
Speed/memory performance improvements. |
800 |
s = dupnode(Nnull_string); /* "" => default sorting */ |
205
by Arnold D. Robbins
Revamp array sorting. |
801 |
|
802 |
s = force_string(s); |
|
803 |
sort_str = s->stptr; |
|
804 |
if (s->stlen == 0) { /* default sorting */ |
|
805 |
if (ctxt == ASORT) |
|
806 |
sort_str = "@val_type_asc"; |
|
807 |
else
|
|
808 |
sort_str = "@ind_str_asc"; |
|
809 |
}
|
|
810 |
||
181
by Arnold D. Robbins
More array sorting changes from John. |
811 |
if (nargs >= 2) { /* 2nd optional arg */ |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
812 |
dest = POP_PARAM(); |
813 |
if (dest->type != Node_var_array) { |
|
181
by Arnold D. Robbins
More array sorting changes from John. |
814 |
fatal(ctxt == ASORT ? |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
815 |
_("asort: second argument not an array") : |
816 |
_("asorti: second argument not an array")); |
|
817 |
}
|
|
818 |
}
|
|
819 |
||
820 |
array = POP_PARAM(); |
|
821 |
if (array->type != Node_var_array) { |
|
181
by Arnold D. Robbins
More array sorting changes from John. |
822 |
fatal(ctxt == ASORT ? |
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
823 |
_("asort: first argument not an array") : |
824 |
_("asorti: first argument not an array")); |
|
825 |
}
|
|
826 |
||
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
827 |
if (dest != NULL) { |
828 |
for (r = dest->parent_array; r != NULL; r = r->parent_array) { |
|
829 |
if (r == array) |
|
830 |
fatal(ctxt == ASORT ? |
|
831 |
_("asort: cannot use a subarray of first arg for second arg") : |
|
832 |
_("asorti: cannot use a subarray of first arg for second arg")); |
|
833 |
}
|
|
834 |
for (r = array->parent_array; r != NULL; r = r->parent_array) { |
|
835 |
if (r == dest) |
|
836 |
fatal(ctxt == ASORT ? |
|
837 |
_("asort: cannot use a subarray of second arg for first arg") : |
|
838 |
_("asorti: cannot use a subarray of second arg for first arg")); |
|
281.1.1
by john haque
Speed/memory performance improvements. |
839 |
}
|
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
840 |
}
|
841 |
||
322
by john haque
Improve array interface. |
842 |
/* sorting happens inside assoc_list */
|
843 |
list = assoc_list(array, sort_str, ctxt); |
|
205
by Arnold D. Robbins
Revamp array sorting. |
844 |
DEREF(s); |
181
by Arnold D. Robbins
More array sorting changes from John. |
845 |
|
322
by john haque
Improve array interface. |
846 |
num_elems = assoc_length(array); |
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
847 |
if (num_elems == 0 || list == NULL) { |
848 |
/* source array is empty */
|
|
849 |
if (dest != NULL && dest != array) |
|
850 |
assoc_clear(dest); |
|
408.4.32
by Arnold D. Robbins
Fixes based on problems from a static checker. |
851 |
if (list != NULL) |
852 |
efree(list); |
|
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
853 |
return make_number((AWKNUM) 0); |
854 |
}
|
|
855 |
||
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
856 |
/*
|
857 |
* Must not assoc_clear() the source array before constructing
|
|
181
by Arnold D. Robbins
More array sorting changes from John. |
858 |
* the output array. assoc_list() does not duplicate array values
|
859 |
* which are needed for asort().
|
|
860 |
*/
|
|
861 |
||
162
by Arnold D. Robbins
Fixes for asort, asorti, split, patsplit. |
862 |
if (dest != NULL && dest != array) { |
863 |
assoc_clear(dest); |
|
181
by Arnold D. Robbins
More array sorting changes from John. |
864 |
result = dest; |
865 |
} else { |
|
866 |
/* use 'result' as a temporary destination array */
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
867 |
result = make_array(); |
181
by Arnold D. Robbins
More array sorting changes from John. |
868 |
result->vname = array->vname; |
203
by Arnold D. Robbins
Fix problem with subarray of deleted array. |
869 |
result->parent_array = array->parent_array; |
28
by Arnold D. Robbins
Move to gawk-3.1.0. |
870 |
}
|
871 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
872 |
if (ctxt == ASORTI) { |
873 |
/* We want the indices of the source array. */
|
|
874 |
||
875 |
for (i = 1, ptr = list; i <= num_elems; i++, ptr += 2) { |
|
302
by john haque
Finish builtins for MPFR. |
876 |
subs = make_number(i); |
320
by john haque
Use unref when freeing a null array element. |
877 |
lhs = assoc_lookup(result, subs); |
878 |
unref(*lhs); |
|
879 |
*lhs = *ptr; |
|
322
by john haque
Improve array interface. |
880 |
if (result->astore != NULL) |
881 |
(*result->astore)(result, subs); |
|
302
by john haque
Finish builtins for MPFR. |
882 |
unref(subs); |
281.1.1
by john haque
Speed/memory performance improvements. |
883 |
}
|
884 |
} else { |
|
885 |
/* We want the values of the source array. */
|
|
886 |
||
887 |
for (i = 1, ptr = list; i <= num_elems; i++) { |
|
302
by john haque
Finish builtins for MPFR. |
888 |
subs = make_number(i); |
281.1.1
by john haque
Speed/memory performance improvements. |
889 |
|
890 |
/* free index node */
|
|
891 |
r = *ptr++; |
|
892 |
unref(r); |
|
893 |
||
894 |
/* value node */
|
|
895 |
r = *ptr++; |
|
896 |
||
320
by john haque
Use unref when freeing a null array element. |
897 |
if (r->type == Node_val) { |
898 |
lhs = assoc_lookup(result, subs); |
|
899 |
unref(*lhs); |
|
900 |
*lhs = dupnode(r); |
|
901 |
} else { |
|
281.1.1
by john haque
Speed/memory performance improvements. |
902 |
NODE *arr; |
903 |
arr = make_array(); |
|
904 |
subs = force_string(subs); |
|
905 |
arr->vname = subs->stptr; |
|
906 |
subs->stptr = NULL; |
|
907 |
subs->flags &= ~STRCUR; |
|
908 |
arr->parent_array = array; /* actual parent, not the temporary one. */ |
|
320
by john haque
Use unref when freeing a null array element. |
909 |
lhs = assoc_lookup(result, subs); |
910 |
unref(*lhs); |
|
911 |
*lhs = assoc_copy(r, arr); |
|
181
by Arnold D. Robbins
More array sorting changes from John. |
912 |
}
|
322
by john haque
Improve array interface. |
913 |
if (result->astore != NULL) |
914 |
(*result->astore)(result, subs); |
|
302
by john haque
Finish builtins for MPFR. |
915 |
unref(subs); |
181
by Arnold D. Robbins
More array sorting changes from John. |
916 |
}
|
281.1.1
by john haque
Speed/memory performance improvements. |
917 |
}
|
918 |
||
181
by Arnold D. Robbins
More array sorting changes from John. |
919 |
efree(list); |
920 |
||
921 |
if (result != dest) { |
|
922 |
/* dest == NULL or dest == array */
|
|
923 |
assoc_clear(array); |
|
924 |
*array = *result; /* copy result into array */ |
|
925 |
freenode(result); |
|
926 |
} /* else |
|
927 |
result == dest
|
|
928 |
dest != NULL and dest != array */
|
|
929 |
||
930 |
return make_number((AWKNUM) num_elems); |
|
30
by Arnold D. Robbins
Move to gawk-3.1.2. |
931 |
}
|
932 |
||
933 |
/* do_asort --- sort array by value */
|
|
934 |
||
935 |
NODE * |
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
936 |
do_asort(int nargs) |
30
by Arnold D. Robbins
Move to gawk-3.1.2. |
937 |
{
|
181
by Arnold D. Robbins
More array sorting changes from John. |
938 |
return asort_actual(nargs, ASORT); |
30
by Arnold D. Robbins
Move to gawk-3.1.2. |
939 |
}
|
940 |
||
941 |
/* do_asorti --- sort array by index */
|
|
942 |
||
943 |
NODE * |
|
40
by Arnold D. Robbins
Bring latest byte code gawk into git. Hurray! |
944 |
do_asorti(int nargs) |
30
by Arnold D. Robbins
Move to gawk-3.1.2. |
945 |
{
|
181
by Arnold D. Robbins
More array sorting changes from John. |
946 |
return asort_actual(nargs, ASORTI); |
947 |
}
|
|
948 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
949 |
|
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
950 |
/*
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
951 |
* cmp_strings --- compare two strings; logic similar to cmp_nodes() in eval.c
|
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
952 |
* except the extra case-sensitive comparison when the case-insensitive
|
953 |
* result is a match.
|
|
174
by Arnold D. Robbins
More improvements to array sorting. |
954 |
*/
|
955 |
||
956 |
static int |
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
957 |
cmp_strings(const NODE *n1, const NODE *n2) |
174
by Arnold D. Robbins
More improvements to array sorting. |
958 |
{
|
181
by Arnold D. Robbins
More array sorting changes from John. |
959 |
char *s1, *s2; |
960 |
size_t len1, len2; |
|
174
by Arnold D. Robbins
More improvements to array sorting. |
961 |
int ret; |
181
by Arnold D. Robbins
More array sorting changes from John. |
962 |
size_t lmin; |
174
by Arnold D. Robbins
More improvements to array sorting. |
963 |
|
281.1.1
by john haque
Speed/memory performance improvements. |
964 |
s1 = n1->stptr; |
965 |
len1 = n1->stlen; |
|
966 |
s2 = n2->stptr; |
|
967 |
len2 = n2->stlen; |
|
181
by Arnold D. Robbins
More array sorting changes from John. |
968 |
|
969 |
if (len1 == 0) |
|
970 |
return len2 == 0 ? 0 : -1; |
|
971 |
if (len2 == 0) |
|
972 |
return 1; |
|
973 |
||
974 |
/* len1 > 0 && len2 > 0 */
|
|
975 |
lmin = len1 < len2 ? len1 : len2; |
|
976 |
||
977 |
if (IGNORECASE) { |
|
978 |
const unsigned char *cp1 = (const unsigned char *) s1; |
|
979 |
const unsigned char *cp2 = (const unsigned char *) s2; |
|
980 |
||
277.1.31
by Arnold D. Robbins
Make no mbs support work everywhere. Sheesh. |
981 |
#if MBS_SUPPORT
|
181
by Arnold D. Robbins
More array sorting changes from John. |
982 |
if (gawk_mb_cur_max > 1) { |
983 |
ret = strncasecmpmbs((const unsigned char *) cp1, |
|
984 |
(const unsigned char *) cp2, lmin); |
|
985 |
} else |
|
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
986 |
#endif
|
181
by Arnold D. Robbins
More array sorting changes from John. |
987 |
for (ret = 0; lmin-- > 0 && ret == 0; cp1++, cp2++) |
988 |
ret = casetable[*cp1] - casetable[*cp2]; |
|
989 |
if (ret != 0) |
|
990 |
return ret; |
|
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
991 |
/*
|
992 |
* If case insensitive result is "they're the same",
|
|
993 |
* use case sensitive comparison to force distinct order.
|
|
181
by Arnold D. Robbins
More array sorting changes from John. |
994 |
*/
|
995 |
}
|
|
996 |
||
997 |
ret = memcmp(s1, s2, lmin); |
|
998 |
if (ret != 0 || len1 == len2) |
|
999 |
return ret; |
|
1000 |
return (len1 < len2) ? -1 : 1; |
|
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1001 |
}
|
1002 |
||
181
by Arnold D. Robbins
More array sorting changes from John. |
1003 |
/* sort_up_index_string --- qsort comparison function; ascending index strings. */
|
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1004 |
|
1005 |
static int |
|
1006 |
sort_up_index_string(const void *p1, const void *p2) |
|
1007 |
{
|
|
1008 |
const NODE *t1, *t2; |
|
1009 |
||
189
by Arnold D. Robbins
Code cleanups in array.c and side effects in other files. |
1010 |
/* Array indices are strings */
|
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1011 |
t1 = *((const NODE *const *) p1); |
1012 |
t2 = *((const NODE *const *) p2); |
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
1013 |
return cmp_strings(t1, t2); |
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1014 |
}
|
1015 |
||
181
by Arnold D. Robbins
More array sorting changes from John. |
1016 |
|
281.1.1
by john haque
Speed/memory performance improvements. |
1017 |
/* sort_down_index_str --- qsort comparison function; descending index strings. */
|
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1018 |
|
1019 |
static int |
|
1020 |
sort_down_index_string(const void *p1, const void *p2) |
|
1021 |
{
|
|
1022 |
/*
|
|
1023 |
* Negation versus transposed arguments: when all keys are
|
|
1024 |
* distinct, as with array indices here, either method will
|
|
1025 |
* transform an ascending sort into a descending one. But if
|
|
1026 |
* there are equal keys--such as when IGNORECASE is honored--
|
|
1027 |
* that get disambiguated into a determisitc order, negation
|
|
1028 |
* will reverse those but transposed arguments would retain
|
|
1029 |
* their relative order within the rest of the reversed sort.
|
|
1030 |
*/
|
|
1031 |
return -sort_up_index_string(p1, p2); |
|
1032 |
}
|
|
1033 |
||
181
by Arnold D. Robbins
More array sorting changes from John. |
1034 |
|
1035 |
/* sort_up_index_number --- qsort comparison function; ascending index numbers. */
|
|
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1036 |
|
1037 |
static int |
|
1038 |
sort_up_index_number(const void *p1, const void *p2) |
|
1039 |
{
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
1040 |
const NODE *t1, *t2; |
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1041 |
int ret; |
1042 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
1043 |
t1 = *((const NODE *const *) p1); |
1044 |
t2 = *((const NODE *const *) p2); |
|
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1045 |
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
1046 |
ret = cmp_numbers(t1, t2); |
302
by john haque
Finish builtins for MPFR. |
1047 |
if (ret != 0) |
302.1.1
by john haque
Finish MPFR changes and clean up code. |
1048 |
return ret; |
1049 |
||
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1050 |
/* break a tie with the index string itself */
|
302
by john haque
Finish builtins for MPFR. |
1051 |
t1 = force_string((NODE *) t1); |
1052 |
t2 = force_string((NODE *) t2); |
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
1053 |
return cmp_strings(t1, t2); |
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1054 |
}
|
1055 |
||
181
by Arnold D. Robbins
More array sorting changes from John. |
1056 |
/* sort_down_index_number --- qsort comparison function; descending index numbers */
|
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1057 |
|
1058 |
static int |
|
1059 |
sort_down_index_number(const void *p1, const void *p2) |
|
1060 |
{
|
|
1061 |
return -sort_up_index_number(p1, p2); |
|
1062 |
}
|
|
1063 |
||
181
by Arnold D. Robbins
More array sorting changes from John. |
1064 |
|
1065 |
/* sort_up_value_string --- qsort comparison function; ascending value string */
|
|
1066 |
||
1067 |
static int |
|
1068 |
sort_up_value_string(const void *p1, const void *p2) |
|
1069 |
{
|
|
1070 |
const NODE *t1, *t2; |
|
281.1.1
by john haque
Speed/memory performance improvements. |
1071 |
|
1072 |
t1 = *((const NODE *const *) p1 + 1); |
|
1073 |
t2 = *((const NODE *const *) p2 + 1); |
|
1074 |
||
1075 |
if (t1->type == Node_var_array) { |
|
1076 |
/* return 0 if t2 is a sub-array too, else return 1 */
|
|
1077 |
return (t2->type != Node_var_array); |
|
181
by Arnold D. Robbins
More array sorting changes from John. |
1078 |
}
|
281.1.1
by john haque
Speed/memory performance improvements. |
1079 |
if (t2->type == Node_var_array) |
1080 |
return -1; /* t1 (scalar) < t2 (sub-array) */ |
|
181
by Arnold D. Robbins
More array sorting changes from John. |
1081 |
|
281.1.1
by john haque
Speed/memory performance improvements. |
1082 |
/* t1 and t2 both have string values */
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
1083 |
return cmp_strings(t1, t2); |
181
by Arnold D. Robbins
More array sorting changes from John. |
1084 |
}
|
1085 |
||
1086 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
1087 |
/* sort_down_value_string --- qsort comparison function; descending value string */
|
181
by Arnold D. Robbins
More array sorting changes from John. |
1088 |
|
1089 |
static int |
|
1090 |
sort_down_value_string(const void *p1, const void *p2) |
|
1091 |
{
|
|
1092 |
return -sort_up_value_string(p1, p2); |
|
1093 |
}
|
|
1094 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
1095 |
|
181
by Arnold D. Robbins
More array sorting changes from John. |
1096 |
/* sort_up_value_number --- qsort comparison function; ascending value number */
|
1097 |
||
1098 |
static int |
|
1099 |
sort_up_value_number(const void *p1, const void *p2) |
|
1100 |
{
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
1101 |
NODE *t1, *t2; |
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1102 |
int ret; |
1103 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
1104 |
t1 = *((NODE *const *) p1 + 1); |
1105 |
t2 = *((NODE *const *) p2 + 1); |
|
1106 |
||
1107 |
if (t1->type == Node_var_array) { |
|
1108 |
/* return 0 if t2 is a sub-array too, else return 1 */
|
|
1109 |
return (t2->type != Node_var_array); |
|
181
by Arnold D. Robbins
More array sorting changes from John. |
1110 |
}
|
281.1.1
by john haque
Speed/memory performance improvements. |
1111 |
if (t2->type == Node_var_array) |
1112 |
return -1; /* t1 (scalar) < t2 (sub-array) */ |
|
181
by Arnold D. Robbins
More array sorting changes from John. |
1113 |
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
1114 |
ret = cmp_numbers(t1, t2); |
302
by john haque
Finish builtins for MPFR. |
1115 |
if (ret != 0) |
1116 |
return ret; |
|
302.1.1
by john haque
Finish MPFR changes and clean up code. |
1117 |
|
302
by john haque
Finish builtins for MPFR. |
1118 |
/*
|
1119 |
* Use string value to guarantee same sort order on all
|
|
1120 |
* versions of qsort().
|
|
1121 |
*/
|
|
1122 |
t1 = force_string(t1); |
|
1123 |
t2 = force_string(t2); |
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
1124 |
return cmp_strings(t1, t2); |
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1125 |
}
|
1126 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
1127 |
|
1128 |
/* sort_down_value_number --- qsort comparison function; descending value number */
|
|
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1129 |
|
1130 |
static int |
|
181
by Arnold D. Robbins
More array sorting changes from John. |
1131 |
sort_down_value_number(const void *p1, const void *p2) |
1132 |
{
|
|
1133 |
return -sort_up_value_number(p1, p2); |
|
1134 |
}
|
|
1135 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
1136 |
|
205
by Arnold D. Robbins
Revamp array sorting. |
1137 |
/* sort_up_value_type --- qsort comparison function; ascending value type */
|
1138 |
||
1139 |
static int |
|
1140 |
sort_up_value_type(const void *p1, const void *p2) |
|
1141 |
{
|
|
1142 |
NODE *n1, *n2; |
|
1143 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
1144 |
/* we want to compare the element values */
|
1145 |
n1 = *((NODE *const *) p1 + 1); |
|
1146 |
n2 = *((NODE *const *) p2 + 1); |
|
205
by Arnold D. Robbins
Revamp array sorting. |
1147 |
|
1148 |
/* 1. Arrays vs. scalar, scalar is less than array */
|
|
1149 |
if (n1->type == Node_var_array) { |
|
1150 |
/* return 0 if n2 is a sub-array too, else return 1 */
|
|
1151 |
return (n2->type != Node_var_array); |
|
1152 |
}
|
|
1153 |
if (n2->type == Node_var_array) { |
|
1154 |
return -1; /* n1 (scalar) < n2 (sub-array) */ |
|
1155 |
}
|
|
1156 |
||
1157 |
/* two scalars */
|
|
1158 |
/* 2. Resolve MAYBE_NUM, so that have only NUMBER or STRING */
|
|
1159 |
if ((n1->flags & MAYBE_NUM) != 0) |
|
1160 |
(void) force_number(n1); |
|
1161 |
if ((n2->flags & MAYBE_NUM) != 0) |
|
1162 |
(void) force_number(n2); |
|
1163 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
1164 |
/* 2.5. Resolve INTIND, so that is STRING, and not NUMBER */
|
1165 |
if ((n1->flags & INTIND) != 0) |
|
1166 |
(void) force_string(n1); |
|
1167 |
if ((n2->flags & INTIND) != 0) |
|
1168 |
(void) force_string(n2); |
|
1169 |
||
205
by Arnold D. Robbins
Revamp array sorting. |
1170 |
if ((n1->flags & NUMBER) != 0 && (n2->flags & NUMBER) != 0) { |
306
by john haque
Add arbitrary-precision arithmetic on integers. |
1171 |
return cmp_numbers(n1, n2); |
205
by Arnold D. Robbins
Revamp array sorting. |
1172 |
}
|
1173 |
||
1174 |
/* 3. All numbers are less than all strings. This is aribitrary. */
|
|
1175 |
if ((n1->flags & NUMBER) != 0 && (n2->flags & STRING) != 0) { |
|
1176 |
return -1; |
|
1177 |
} else if ((n1->flags & STRING) != 0 && (n2->flags & NUMBER) != 0) { |
|
1178 |
return 1; |
|
1179 |
}
|
|
1180 |
||
1181 |
/* 4. Two strings */
|
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
1182 |
return cmp_strings(n1, n2); |
205
by Arnold D. Robbins
Revamp array sorting. |
1183 |
}
|
1184 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
1185 |
/* sort_down_value_type --- qsort comparison function; descending value type */
|
205
by Arnold D. Robbins
Revamp array sorting. |
1186 |
|
1187 |
static int |
|
1188 |
sort_down_value_type(const void *p1, const void *p2) |
|
1189 |
{
|
|
1190 |
return -sort_up_value_type(p1, p2); |
|
1191 |
}
|
|
1192 |
||
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1193 |
/* sort_user_func --- user defined qsort comparison function */
|
1194 |
||
1195 |
static int |
|
1196 |
sort_user_func(const void *p1, const void *p2) |
|
1197 |
{
|
|
301
by john haque
New interpreter routine for MPFR. |
1198 |
NODE *idx1, *idx2, *val1, *val2, *r; |
1199 |
int ret; |
|
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1200 |
INSTRUCTION *code; |
1201 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
1202 |
idx1 = *((NODE *const *) p1); |
1203 |
idx2 = *((NODE *const *) p2); |
|
1204 |
val1 = *((NODE *const *) p1 + 1); |
|
1205 |
val2 = *((NODE *const *) p2 + 1); |
|
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1206 |
|
1207 |
code = TOP()->code_ptr; /* comparison function call instructions */ |
|
1208 |
||
1209 |
/* setup 4 arguments to comp_func() */
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
1210 |
UPREF(idx1); |
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1211 |
PUSH(idx1); |
1212 |
if (val1->type == Node_val) |
|
1213 |
UPREF(val1); |
|
1214 |
PUSH(val1); |
|
281.1.1
by john haque
Speed/memory performance improvements. |
1215 |
|
1216 |
UPREF(idx2); |
|
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1217 |
PUSH(idx2); |
1218 |
if (val2->type == Node_val) |
|
1219 |
UPREF(val2); |
|
1220 |
PUSH(val2); |
|
1221 |
||
1222 |
/* execute the comparison function */
|
|
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
1223 |
(void) (*interpret)(code); |
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1224 |
|
1225 |
/* return value of the comparison function */
|
|
301
by john haque
New interpreter routine for MPFR. |
1226 |
r = POP_NUMBER(); |
1227 |
#ifdef HAVE_MPFR
|
|
306
by john haque
Add arbitrary-precision arithmetic on integers. |
1228 |
/*
|
1229 |
* mpfr_sgn(mpz_sgn): Returns a positive value if op > 0,
|
|
1230 |
* zero if op = 0, and a negative value if op < 0.
|
|
1231 |
*/
|
|
1232 |
if (is_mpg_float(r)) |
|
302.1.1
by john haque
Finish MPFR changes and clean up code. |
1233 |
ret = mpfr_sgn(r->mpg_numbr); |
306
by john haque
Add arbitrary-precision arithmetic on integers. |
1234 |
else if (is_mpg_integer(r)) |
1235 |
ret = mpz_sgn(r->mpg_i); |
|
301
by john haque
New interpreter routine for MPFR. |
1236 |
else
|
1237 |
#endif
|
|
1238 |
ret = (r->numbr < 0.0) ? -1 : (r->numbr > 0.0); |
|
1239 |
DEREF(r); |
|
1240 |
return ret; |
|
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1241 |
}
|
1242 |
||
181
by Arnold D. Robbins
More array sorting changes from John. |
1243 |
|
1244 |
/* assoc_list -- construct, and optionally sort, a list of array elements */
|
|
1245 |
||
1246 |
NODE ** |
|
322
by john haque
Improve array interface. |
1247 |
assoc_list(NODE *symbol, const char *sort_str, sort_context_t sort_ctxt) |
181
by Arnold D. Robbins
More array sorting changes from John. |
1248 |
{
|
1249 |
typedef int (*qsort_compfunc)(const void *, const void *); |
|
1250 |
||
1251 |
static const struct qsort_funcs { |
|
205
by Arnold D. Robbins
Revamp array sorting. |
1252 |
const char *name; |
181
by Arnold D. Robbins
More array sorting changes from John. |
1253 |
qsort_compfunc comp_func; |
322
by john haque
Improve array interface. |
1254 |
assoc_kind_t kind; |
181
by Arnold D. Robbins
More array sorting changes from John. |
1255 |
} sort_funcs[] = { |
281.1.1
by john haque
Speed/memory performance improvements. |
1256 |
{ "@ind_str_asc", sort_up_index_string, AINDEX|AISTR|AASC }, |
1257 |
{ "@ind_num_asc", sort_up_index_number, AINDEX|AINUM|AASC }, |
|
1258 |
{ "@val_str_asc", sort_up_value_string, AVALUE|AVSTR|AASC }, |
|
1259 |
{ "@val_num_asc", sort_up_value_number, AVALUE|AVNUM|AASC }, |
|
1260 |
{ "@ind_str_desc", sort_down_index_string, AINDEX|AISTR|ADESC }, |
|
1261 |
{ "@ind_num_desc", sort_down_index_number, AINDEX|AINUM|ADESC }, |
|
1262 |
{ "@val_str_desc", sort_down_value_string, AVALUE|AVSTR|ADESC }, |
|
1263 |
{ "@val_num_desc", sort_down_value_number, AVALUE|AVNUM|ADESC }, |
|
1264 |
{ "@val_type_asc", sort_up_value_type, AVALUE|AASC }, |
|
1265 |
{ "@val_type_desc", sort_down_value_type, AVALUE|ADESC }, |
|
1266 |
{ "@unsorted", 0, AINDEX }, |
|
1267 |
};
|
|
1268 |
||
321
by john haque
Polish array handling code. |
1269 |
/*
|
1270 |
* N.B.: AASC and ADESC are hints to the specific array types.
|
|
281.1.1
by john haque
Speed/memory performance improvements. |
1271 |
* See cint_list() in cint_array.c.
|
1272 |
*/
|
|
1273 |
||
181
by Arnold D. Robbins
More array sorting changes from John. |
1274 |
NODE **list; |
322
by john haque
Improve array interface. |
1275 |
NODE akind; |
281.1.1
by john haque
Speed/memory performance improvements. |
1276 |
unsigned long num_elems, j; |
1277 |
int elem_size, qi; |
|
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1278 |
qsort_compfunc cmp_func = 0; |
1279 |
INSTRUCTION *code = NULL; |
|
1280 |
extern int currule; |
|
285
by Arnold D. Robbins
Merge branch 'gawk-4.0-stable' |
1281 |
int save_rule = 0; |
408.5.87
by Arnold D. Robbins
Lots of enum/int fixes. |
1282 |
assoc_kind_t assoc_kind = ANONE; |
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1283 |
|
281.1.1
by john haque
Speed/memory performance improvements. |
1284 |
elem_size = 1; |
1285 |
||
205
by Arnold D. Robbins
Revamp array sorting. |
1286 |
for (qi = 0, j = sizeof(sort_funcs)/sizeof(sort_funcs[0]); qi < j; qi++) { |
1287 |
if (strcmp(sort_funcs[qi].name, sort_str) == 0) |
|
1288 |
break; |
|
1289 |
}
|
|
181
by Arnold D. Robbins
More array sorting changes from John. |
1290 |
|
281.1.1
by john haque
Speed/memory performance improvements. |
1291 |
if (qi < j) { |
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1292 |
cmp_func = sort_funcs[qi].comp_func; |
322
by john haque
Improve array interface. |
1293 |
assoc_kind = sort_funcs[qi].kind; |
281.1.1
by john haque
Speed/memory performance improvements. |
1294 |
|
1295 |
if (symbol->array_funcs != cint_array_func) |
|
322
by john haque
Improve array interface. |
1296 |
assoc_kind &= ~(AASC|ADESC); |
281.1.1
by john haque
Speed/memory performance improvements. |
1297 |
|
322
by john haque
Improve array interface. |
1298 |
if (sort_ctxt != SORTED_IN || (assoc_kind & AVALUE) != 0) { |
281.1.1
by john haque
Speed/memory performance improvements. |
1299 |
/* need index and value pair in the list */
|
1300 |
||
322
by john haque
Improve array interface. |
1301 |
assoc_kind |= (AINDEX|AVALUE); |
281.1.1
by john haque
Speed/memory performance improvements. |
1302 |
elem_size = 2; |
1303 |
}
|
|
1304 |
||
1305 |
} else { /* unrecognized */ |
|
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1306 |
NODE *f; |
205
by Arnold D. Robbins
Revamp array sorting. |
1307 |
const char *sp; |
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1308 |
|
322
by john haque
Improve array interface. |
1309 |
for (sp = sort_str; *sp != '\0' && ! isspace((unsigned char) *sp); sp++) |
205
by Arnold D. Robbins
Revamp array sorting. |
1310 |
continue; |
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1311 |
|
1312 |
/* empty string or string with space(s) not valid as function name */
|
|
205
by Arnold D. Robbins
Revamp array sorting. |
1313 |
if (sp == sort_str || *sp != '\0') |
1314 |
fatal(_("`%s' is invalid as a function name"), sort_str); |
|
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1315 |
|
205
by Arnold D. Robbins
Revamp array sorting. |
1316 |
f = lookup(sort_str); |
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1317 |
if (f == NULL || f->type != Node_func) |
205
by Arnold D. Robbins
Revamp array sorting. |
1318 |
fatal(_("sort comparison function `%s' is not defined"), sort_str); |
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1319 |
|
1320 |
cmp_func = sort_user_func; |
|
281.1.1
by john haque
Speed/memory performance improvements. |
1321 |
|
1322 |
/* need index and value pair in the list */
|
|
322
by john haque
Improve array interface. |
1323 |
assoc_kind |= (AVALUE|AINDEX); |
281.1.1
by john haque
Speed/memory performance improvements. |
1324 |
elem_size = 2; |
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1325 |
|
1326 |
/* make function call instructions */
|
|
1327 |
code = bcalloc(Op_func_call, 2, 0); |
|
1328 |
code->func_body = f; |
|
1329 |
code->func_name = NULL; /* not needed, func_body already assigned */ |
|
1330 |
(code + 1)->expr_count = 4; /* function takes 4 arguments */ |
|
1331 |
code->nexti = bcalloc(Op_stop, 1, 0); |
|
1332 |
||
321
by john haque
Polish array handling code. |
1333 |
/*
|
1334 |
* make non-redirected getline, exit, `next' and `nextfile' fatal in
|
|
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1335 |
* callback function by setting currule in interpret()
|
277.1.82
by Arnold D. Robbins
Misc fixes from John. |
1336 |
* to undefined (0).
|
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1337 |
*/
|
1338 |
||
281.1.4
by john haque
Optimize tail-recursive calls. |
1339 |
save_rule = currule; /* save current rule */ |
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1340 |
currule = 0; |
1341 |
||
1342 |
PUSH_CODE(code); |
|
1343 |
}
|
|
1344 |
||
322
by john haque
Improve array interface. |
1345 |
akind.flags = (unsigned int) assoc_kind; /* kludge */ |
1346 |
list = symbol->alist(symbol, & akind); |
|
1347 |
assoc_kind = (assoc_kind_t) akind.flags; /* symbol->alist can modify it */ |
|
281.1.1
by john haque
Speed/memory performance improvements. |
1348 |
|
322
by john haque
Improve array interface. |
1349 |
if (list == NULL || ! cmp_func || (assoc_kind & (AASC|ADESC)) != 0) |
291
by Arnold D. Robbins
The grand merge: dgawk and pgawk folded into gawk. |
1350 |
return list; /* empty list or unsorted, or list already sorted */ |
281.1.1
by john haque
Speed/memory performance improvements. |
1351 |
|
322
by john haque
Improve array interface. |
1352 |
num_elems = assoc_length(symbol); |
1353 |
||
281.1.1
by john haque
Speed/memory performance improvements. |
1354 |
qsort(list, num_elems, elem_size * sizeof(NODE *), cmp_func); /* shazzam! */ |
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1355 |
|
1356 |
if (cmp_func == sort_user_func) { |
|
1357 |
code = POP_CODE(); |
|
281.1.4
by john haque
Optimize tail-recursive calls. |
1358 |
currule = save_rule; /* restore current rule */ |
183
by Arnold D. Robbins
User function sorting added, documented, tested. |
1359 |
bcfree(code->nexti); /* Op_stop */ |
1360 |
bcfree(code); /* Op_func_call */ |
|
1361 |
}
|
|
1362 |
||
322
by john haque
Improve array interface. |
1363 |
if (sort_ctxt == SORTED_IN && (assoc_kind & (AINDEX|AVALUE)) == (AINDEX|AVALUE)) { |
281.1.1
by john haque
Speed/memory performance improvements. |
1364 |
/* relocate all index nodes to the first half of the list. */
|
1365 |
for (j = 1; j < num_elems; j++) |
|
1366 |
list[j] = list[2 * j]; |
|
1367 |
||
1368 |
/* give back extra memory */
|
|
1369 |
||
1370 |
erealloc(list, NODE **, num_elems * sizeof(NODE *), "assoc_list"); |
|
1371 |
}
|
|
1372 |
||
181
by Arnold D. Robbins
More array sorting changes from John. |
1373 |
return list; |
166
by Arnold D. Robbins
Revise array sorting for PROCINFO["sorted_in"]. |
1374 |
}
|