#include "awk.h"Go to the source code of this file.
Defines | |
| #define | NVAL (sizeof(values)/sizeof(values[0])) |
| #define | NODECHUNK 100 |
Functions | |
| AWKNUM | r_force_number (register NODE *n) |
| NODE * | format_val (const char *format, int index, register NODE *s) |
| NODE * | r_force_string (register NODE *s) |
| NODE * | r_dupnode (NODE *n) |
| NODE * | copynode (NODE *old) |
| NODE * | mk_number (AWKNUM x, unsigned int flags) |
| NODE * | make_str_node (char *s, unsigned long len, int flags) |
| NODE * | tmp_string (char *s, size_t len) |
| NODE * | more_nodes () |
| void | unref (register NODE *tmp) |
| int | parse_escape (const char **string_ptr) |
Variables | |
| static const char *const | values [] |
| NODE * | nextfree = NULL |
|
|
Definition at line 388 of file node.c. Referenced by more_nodes(). |
|
|
|
|
|
Definition at line 292 of file node.c. References dupnode, exp_node::flags, MALLOC, NULL, and PERM. Referenced by sub_common(). 00293 { 00294 NODE *new; 00295 int saveflags; 00296 00297 assert(old != NULL); 00298 saveflags = old->flags; 00299 old->flags &= ~(MALLOC|PERM); 00300 new = dupnode(old); 00301 old->flags = saveflags; 00302 return new; 00303 }
|
|
||||||||||||||||
|
Definition at line 144 of file node.c. References dgettext, do_traditional, double_to_int(), emalloc, fmt_list, format_tree(), freenode, getnode, INTLSTR, LONG_MAX, memcpy, Node_expression_list, NULL, PERM, stlen, STRCUR, TEXTDOMAIN, tmp_string(), exp_node::type, and values. Referenced by do_print(), and r_force_string(). 00145 { 00146 char buf[BUFSIZ]; 00147 register char *sp = buf; 00148 double val; 00149 char *orig, *trans, save; 00150 00151 if (! do_traditional && (s->flags & INTLSTR) != 0) { 00152 save = s->stptr[s->stlen]; 00153 s->stptr[s->stlen] = '\0'; 00154 00155 orig = s->stptr; 00156 trans = dgettext(TEXTDOMAIN, orig); 00157 00158 s->stptr[s->stlen] = save; 00159 return tmp_string(trans, strlen(trans)); 00160 } 00161 00162 /* not an integral value, or out of range */ 00163 if ((val = double_to_int(s->numbr)) != s->numbr 00164 || val < LONG_MIN || val > LONG_MAX) { 00165 /* 00166 * Once upon a time, if GFMT_WORKAROUND wasn't defined, 00167 * we just blindly did this: 00168 * sprintf(sp, format, s->numbr); 00169 * s->stlen = strlen(sp); 00170 * s->stfmt = (char) index; 00171 * but that's no good if, e.g., OFMT is %s. So we punt, 00172 * and just always format the value ourselves. 00173 */ 00174 00175 NODE *dummy, *r; 00176 unsigned short oflags; 00177 extern NODE **fmt_list; /* declared in eval.c */ 00178 00179 /* create dummy node for a sole use of format_tree */ 00180 getnode(dummy); 00181 dummy->type = Node_expression_list; 00182 dummy->lnode = s; 00183 dummy->rnode = NULL; 00184 oflags = s->flags; 00185 s->flags |= PERM; /* prevent from freeing by format_tree() */ 00186 r = format_tree(format, fmt_list[index]->stlen, dummy, 2); 00187 s->flags = oflags; 00188 s->stfmt = (char) index; 00189 s->stlen = r->stlen; 00190 s->stptr = r->stptr; 00191 freenode(r); /* Do not free_temp(r)! We want */ 00192 freenode(dummy); /* to keep s->stptr == r->stpr. */ 00193 00194 goto no_malloc; 00195 } else { 00196 /* integral value */ 00197 /* force conversion to long only once */ 00198 register long num = (long) val; 00199 if (num < NVAL && num >= 0) { 00200 sp = (char *) values[num]; 00201 s->stlen = 1; 00202 } else { 00203 (void) sprintf(sp, "%ld", num); 00204 s->stlen = strlen(sp); 00205 } 00206 s->stfmt = -1; 00207 } 00208 emalloc(s->stptr, char *, s->stlen + 2, "format_val"); 00209 memcpy(s->stptr, sp, s->stlen+1); 00210 no_malloc: 00211 s->stref = 1; 00212 s->flags |= STRCUR; 00213 return s; 00214 }
|
|
||||||||||||||||
|
Definition at line 327 of file node.c. References _, ALREADY_MALLOCED, do_lint, emalloc, erealloc, exp_node::flags, getnode, lintwarn, MALLOC, memcpy, Node_val, parse_escape(), PERM, SCAN, STRCUR, STRING, and exp_node::type. Referenced by arg_assign(), assoc_sort_inplace(), cmdline_fs(), concat_exp(), format_tree(), r_tree_eval(), rebuild_record(), and yylex(). 00328 { 00329 register NODE *r; 00330 00331 getnode(r); 00332 r->type = Node_val; 00333 r->flags = (STRING|STRCUR|MALLOC); 00334 if (flags & ALREADY_MALLOCED) 00335 r->stptr = s; 00336 else { 00337 emalloc(r->stptr, char *, len + 2, s); 00338 memcpy(r->stptr, s, len); 00339 } 00340 r->stptr[len] = '\0'; 00341 00342 if ((flags & SCAN) != 0) { /* scan for escape sequences */ 00343 const char *pf; 00344 register char *ptm; 00345 register int c; 00346 register const char *end; 00347 00348 end = &(r->stptr[len]); 00349 for (pf = ptm = r->stptr; pf < end;) { 00350 c = *pf++; 00351 if (c == '\\') { 00352 c = parse_escape(&pf); 00353 if (c < 0) { 00354 if (do_lint) 00355 lintwarn(_("backslash at end of string")); 00356 c = '\\'; 00357 } 00358 *ptm++ = c; 00359 } else 00360 *ptm++ = c; 00361 } 00362 len = ptm - r->stptr; 00363 erealloc(r->stptr, char *, len + 1, "make_str_node"); 00364 r->stptr[len] = '\0'; 00365 r->flags |= PERM; 00366 } 00367 r->stlen = len; 00368 r->stref = 1; 00369 r->stfmt = -1; 00370 00371 return r; 00372 }
|
|
||||||||||||
|
Definition at line 308 of file node.c. References exp_node::flags, getnode, Node_val, NULL, and exp_node::type. 00309 { 00310 register NODE *r; 00311 00312 getnode(r); 00313 r->type = Node_val; 00314 r->numbr = x; 00315 r->flags = flags; 00316 #ifdef GAWKDEBUG 00317 r->stref = 1; 00318 r->stptr = NULL; 00319 r->stlen = 0; 00320 #endif 00321 return r; 00322 }
|
|
|
Definition at line 393 of file node.c. References emalloc, exp_node::flags, NODECHUNK, and NULL. 00394 { 00395 register NODE *np; 00396 00397 /* get more nodes and initialize list */ 00398 emalloc(nextfree, NODE *, NODECHUNK * sizeof(NODE), "more_nodes"); 00399 for (np = nextfree; np <= &nextfree[NODECHUNK - 1]; np++) { 00400 np->flags = 0; 00401 #ifndef NO_PROFILING 00402 np->exec_count = 0; 00403 #endif 00404 np->nextp = np + 1; 00405 } 00406 --np; 00407 np->nextp = NULL; 00408 np = nextfree; 00409 nextfree = nextfree->nextp; 00410 return np; 00411 }
|
|
|
Definition at line 487 of file node.c. References _, BELL, do_lint, do_posix, FALSE, i, ISDIGIT, ISUPPER, ISXDIGIT, lintwarn, TRUE, and warning(). Referenced by make_regexp(), make_str_node(), and vms_arg_fixup(). 00488 { 00489 register int c = *(*string_ptr)++; 00490 register int i; 00491 register int count; 00492 00493 switch (c) { 00494 case 'a': 00495 return BELL; 00496 case 'b': 00497 return '\b'; 00498 case 'f': 00499 return '\f'; 00500 case 'n': 00501 return '\n'; 00502 case 'r': 00503 return '\r'; 00504 case 't': 00505 return '\t'; 00506 case 'v': 00507 return '\v'; 00508 case '\n': 00509 return -2; 00510 case 0: 00511 (*string_ptr)--; 00512 return -1; 00513 case '0': 00514 case '1': 00515 case '2': 00516 case '3': 00517 case '4': 00518 case '5': 00519 case '6': 00520 case '7': 00521 i = c - '0'; 00522 count = 0; 00523 while (++count < 3) { 00524 if ((c = *(*string_ptr)++) >= '0' && c <= '7') { 00525 i *= 8; 00526 i += c - '0'; 00527 } else { 00528 (*string_ptr)--; 00529 break; 00530 } 00531 } 00532 return i; 00533 case 'x': 00534 if (do_lint) { 00535 static int didwarn = FALSE; 00536 00537 if (! didwarn) { 00538 didwarn = TRUE; 00539 lintwarn(_("POSIX does not allow `\\x' escapes")); 00540 } 00541 } 00542 if (do_posix) 00543 return ('x'); 00544 if (! ISXDIGIT((*string_ptr)[0])) { 00545 warning(_("no hex digits in `\\x' escape sequence")); 00546 return ('x'); 00547 } 00548 i = 0; 00549 for (;;) { 00550 /* do outside test to avoid multiple side effects */ 00551 c = *(*string_ptr)++; 00552 if (ISXDIGIT(c)) { 00553 i *= 16; 00554 if (ISDIGIT(c)) 00555 i += c - '0'; 00556 else if (ISUPPER(c)) 00557 i += c - 'A' + 10; 00558 else 00559 i += c - 'a' + 10; 00560 } else { 00561 (*string_ptr)--; 00562 break; 00563 } 00564 } 00565 return i; 00566 case '\\': 00567 case '"': 00568 return c; 00569 default: 00570 { 00571 static short warned[256]; 00572 unsigned char uc = (unsigned char) c; 00573 00574 /* N.B.: use unsigned char here to avoid Latin-1 problems */ 00575 00576 if (! warned[uc]) { 00577 warned[uc] = TRUE; 00578 00579 warning(_("escape sequence `\\%c' treated as plain `%c'"), uc, uc); 00580 } 00581 } 00582 return c; 00583 } 00584 }
|
|
|
Definition at line 245 of file node.c. References emalloc, FIELD, exp_node::flags, getnode, LONG_MAX, MALLOC, memcpy, Node_ahash, Node_val, PERM, STRCUR, TEMP, and exp_node::type. 00246 { 00247 register NODE *r; 00248 00249 #ifndef DUPNODE_MACRO 00250 if ((n->flags & TEMP) != 0) { 00251 n->flags &= ~TEMP; 00252 n->flags |= MALLOC; 00253 return n; 00254 } 00255 if ((n->flags & PERM) != 0) 00256 return n; 00257 #endif 00258 if ((n->flags & (MALLOC|STRCUR)) == (MALLOC|STRCUR)) { 00259 if (n->stref < LONG_MAX) 00260 n->stref++; 00261 else 00262 n->flags |= PERM; 00263 return n; 00264 } else if ((n->flags & MALLOC) != 0 && n->type == Node_ahash) { 00265 if (n->ahname_ref < LONG_MAX) 00266 n->ahname_ref++; 00267 else 00268 n->flags |= PERM; 00269 return n; 00270 } 00271 getnode(r); 00272 *r = *n; 00273 r->flags &= ~(PERM|TEMP|FIELD); 00274 r->flags |= MALLOC; 00275 if (n->type == Node_val && (n->flags & STRCUR) != 0) { 00276 r->stref = 1; 00277 emalloc(r->stptr, char *, r->stlen + 2, "dupnode"); 00278 memcpy(r->stptr, n->stptr, r->stlen); 00279 r->stptr[r->stlen] = '\0'; 00280 } else if (n->type == Node_ahash && (n->flags & MALLOC) != 0) { 00281 r->ahname_ref = 1; 00282 emalloc(r->ahname_str, char *, r->ahname_len + 2, "dupnode"); 00283 memcpy(r->ahname_str, n->ahname_str, r->ahname_len); 00284 r->ahname_str[r->ahname_len] = '\0'; 00285 } 00286 return r; 00287 }
|
|
|
Definition at line 31 of file node.c. References _, AWKNUM, cant_happen, do_lint, do_non_decimal_data, do_traditional, errno, ISALPHA, ISDIGIT, isnondecimal, ISSPACE, lintwarn, MAYBE_NUM, Node_val, nondec2awknum(), NULL, NUMBER, and NUMCUR. 00032 { 00033 register char *cp; 00034 register char *cpend; 00035 char save; 00036 char *ptr; 00037 unsigned int newflags; 00038 extern double strtod(); 00039 00040 #ifdef GAWKDEBUG 00041 if (n == NULL) 00042 cant_happen(); 00043 if (n->type != Node_val) 00044 cant_happen(); 00045 if (n->flags == 0) 00046 cant_happen(); 00047 if (n->flags & NUMCUR) 00048 return n->numbr; 00049 #endif 00050 00051 /* all the conditionals are an attempt to avoid the expensive strtod */ 00052 00053 n->numbr = 0.0; 00054 n->flags |= NUMCUR; 00055 00056 if (n->stlen == 0) { 00057 if (0 && do_lint) 00058 lintwarn(_("can't convert string to float")); 00059 return 0.0; 00060 } 00061 00062 cp = n->stptr; 00063 if (ISALPHA(*cp)) { 00064 if (0 && do_lint) 00065 lintwarn(_("can't convert string to float")); 00066 return 0.0; 00067 } 00068 00069 cpend = cp + n->stlen; 00070 while (cp < cpend && ISSPACE(*cp)) 00071 cp++; 00072 if (cp == cpend || ISALPHA(*cp)) { 00073 if (0 && do_lint) 00074 lintwarn(_("can't convert string to float")); 00075 return 0.0; 00076 } 00077 00078 if (n->flags & MAYBE_NUM) { 00079 newflags = NUMBER; 00080 n->flags &= ~MAYBE_NUM; 00081 } else 00082 newflags = 0; 00083 if (cpend - cp == 1) { 00084 if (ISDIGIT(*cp)) { 00085 n->numbr = (AWKNUM)(*cp - '0'); 00086 n->flags |= newflags; 00087 } else if (0 && do_lint) 00088 lintwarn(_("can't convert string to float")); 00089 return n->numbr; 00090 } 00091 00092 if (do_non_decimal_data) { 00093 errno = 0; 00094 if (! do_traditional && isnondecimal(cp)) { 00095 n->numbr = nondec2awknum(cp, cpend - cp); 00096 goto finish; 00097 } 00098 } 00099 00100 errno = 0; 00101 save = *cpend; 00102 *cpend = '\0'; 00103 n->numbr = (AWKNUM) strtod((const char *) cp, &ptr); 00104 00105 /* POSIX says trailing space is OK for NUMBER */ 00106 while (ISSPACE(*ptr)) 00107 ptr++; 00108 *cpend = save; 00109 finish: 00110 /* the >= should be ==, but for SunOS 3.5 strtod() */ 00111 if (errno == 0 && ptr >= cpend) { 00112 n->flags |= newflags; 00113 } else { 00114 if (0 && do_lint && ptr < cpend) 00115 lintwarn(_("can't convert string to float")); 00116 errno = 0; 00117 } 00118 00119 return n->numbr; 00120 }
|
|
|
Definition at line 219 of file node.c. References cant_happen, CONVFMT, CONVFMTidx, format_val(), Node_val, NULL, and STRCUR. Referenced by r_tree_eval(). 00220 { 00221 NODE *ret; 00222 #ifdef GAWKDEBUG 00223 if (s == NULL) 00224 cant_happen(); 00225 if (s->type != Node_val) 00226 cant_happen(); 00227 if (s->stref <= 0) 00228 cant_happen(); 00229 if ((s->flags & STRCUR) != 0 00230 && (s->stfmt == -1 || s->stfmt == CONVFMTidx)) 00231 return s; 00232 #endif 00233 00234 ret = format_val(CONVFMT, CONVFMTidx, s); 00235 return ret; 00236 }
|
|
||||||||||||
|
Definition at line 377 of file node.c. References exp_node::flags, make_string, and TEMP. Referenced by do_bindtextdomain(), do_chr(), do_dcgettext(), do_dcngettext(), do_fork(), do_match(), do_readfile(), do_stat(), do_strftime(), do_substr(), do_tolower(), do_toupper(), format_val(), load_environ(), load_procinfo(), pty_vs_pipe(), and update_PROCINFO(). 00378 { 00379 register NODE *r; 00380 00381 r = make_string(s, len); 00382 r->flags |= TEMP; 00383 return r; 00384 }
|
|
|
Definition at line 437 of file node.c. References FIELD, free(), freenode, MALLOC, Node_ahash, NULL, PERM, STRCUR, and TEMP. Referenced by arg_assign(), assign_val(), assoc_clear(), assoc_sort_inplace(), cmdline_fs(), do_close(), do_delete(), do_delete_loop(), do_ext(), do_getline(), do_match(), do_print(), do_split(), format_tree(), interpret(), iop_close(), nextfile(), op_assign(), pop_fcall(), pop_forloop(), r_get_lhs(), r_tree_eval(), re_update(), rebuild_record(), release_all_vars(), reset_record(), set_FS(), set_NF(), set_record(), set_RS(), sub_common(), and update_ERRNO(). 00438 { 00439 if (tmp == NULL) 00440 return; 00441 if ((tmp->flags & PERM) != 0) 00442 return; 00443 tmp->flags &= ~TEMP; 00444 if ((tmp->flags & MALLOC) != 0) { 00445 if (tmp->type == Node_ahash) { 00446 if (tmp->ahname_ref > 1) { 00447 tmp->ahname_ref--; 00448 return; 00449 } 00450 free(tmp->ahname_str); 00451 } else if ((tmp->flags & STRCUR) != 0) { 00452 if (tmp->stref > 1) { 00453 tmp->stref--; 00454 return; 00455 } 00456 free(tmp->stptr); 00457 } 00458 freenode(tmp); 00459 return; 00460 } 00461 if ((tmp->flags & FIELD) != 0) { 00462 freenode(tmp); 00463 return; 00464 } 00465 }
|
|
|
|
|
|
Initial value: {
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
}
Definition at line 127 of file node.c. Referenced by format_val(). |