perl 3.0 patch #26 patch #19, continued
[p5sagit/p5-mst-13.2.git] / stab.c
CommitLineData
00bf170e 1/* $Header: stab.c,v 3.0.1.7 90/08/09 05:17:48 lwall Locked $
a687059c 2 *
3 * Copyright (c) 1989, Larry Wall
4 *
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
8d063cd8 7 *
8 * $Log: stab.c,v $
00bf170e 9 * Revision 3.0.1.7 90/08/09 05:17:48 lwall
10 * patch19: fixed double include of <signal.h>
11 * patch19: $' broke on embedded nulls
12 * patch19: $< and $> better supported on machines without setreuid
13 * patch19: Added support for linked-in C subroutines
14 * patch19: %ENV wasn't forced to be global like it should
15 * patch19: $| didn't work before the filehandle was opened
16 * patch19: $! now returns "" in string context if errno == 0
17 *
0f85fab0 18 * Revision 3.0.1.6 90/03/27 16:22:11 lwall
19 * patch16: support for machines that can't cast negative floats to unsigned ints
20 *
79a0689e 21 * Revision 3.0.1.5 90/03/12 17:00:11 lwall
22 * patch13: undef $/ didn't work as advertised
23 *
9f68db38 24 * Revision 3.0.1.4 90/02/28 18:19:14 lwall
25 * patch9: $0 is now always the command name
26 * patch9: you may now undef $/ to have no input record separator
27 * patch9: local($.) didn't work
28 * patch9: sometimes perl thought ordinary data was a symbol table entry
29 * patch9: stab_array() and stab_hash() weren't defined on MICROPORT
30 *
663a0e37 31 * Revision 3.0.1.3 89/12/21 20:18:40 lwall
32 * patch7: ANSI strerror() is now supported
33 * patch7: errno may now be a macro with an lvalue
34 * patch7: in stab.c, sighandler() may now return either void or int
35 *
ffed7fef 36 * Revision 3.0.1.2 89/11/17 15:35:37 lwall
37 * patch5: sighandler() needed to be static
38 *
ae986130 39 * Revision 3.0.1.1 89/11/11 04:55:07 lwall
40 * patch2: sys_errlist[sys_nerr] is illegal
41 *
a687059c 42 * Revision 3.0 89/10/18 15:23:23 lwall
43 * 3.0 baseline
8d063cd8 44 *
45 */
46
8d063cd8 47#include "EXTERN.h"
8d063cd8 48#include "perl.h"
49
00bf170e 50#ifndef NSIG
378cc40b 51#include <signal.h>
00bf170e 52#endif
378cc40b 53
8d063cd8 54static char *sig_name[] = {
a687059c 55 SIG_NAME,0
56};
8d063cd8 57
663a0e37 58#ifdef VOIDSIG
59#define handlertype void
60#else
61#define handlertype int
62#endif
2e1b3b7e 63
8d063cd8 64STR *
a687059c 65stab_str(str)
66STR *str;
8d063cd8 67{
a687059c 68 STAB *stab = str->str_u.str_stab;
8d063cd8 69 register int paren;
70 register char *s;
378cc40b 71 register int i;
8d063cd8 72
a687059c 73 if (str->str_rare)
74 return stab_val(stab);
75
76 switch (*stab->str_magic->str_ptr) {
9f68db38 77 case '1': case '2': case '3': case '4':
8d063cd8 78 case '5': case '6': case '7': case '8': case '9': case '&':
79 if (curspat) {
a687059c 80 paren = atoi(stab_name(stab));
378cc40b 81 getparen:
82 if (curspat->spat_regexp &&
83 paren <= curspat->spat_regexp->nparens &&
84 (s = curspat->spat_regexp->startp[paren]) ) {
85 i = curspat->spat_regexp->endp[paren] - s;
86 if (i >= 0)
a687059c 87 str_nset(stab_val(stab),s,i);
378cc40b 88 else
a687059c 89 str_sset(stab_val(stab),&str_undef);
8d063cd8 90 }
378cc40b 91 else
a687059c 92 str_sset(stab_val(stab),&str_undef);
8d063cd8 93 }
94 break;
95 case '+':
96 if (curspat) {
378cc40b 97 paren = curspat->spat_regexp->lastparen;
98 goto getparen;
8d063cd8 99 }
100 break;
a687059c 101 case '`':
102 if (curspat) {
103 if (curspat->spat_regexp &&
104 (s = curspat->spat_regexp->subbase) ) {
105 i = curspat->spat_regexp->startp[0] - s;
106 if (i >= 0)
107 str_nset(stab_val(stab),s,i);
108 else
109 str_nset(stab_val(stab),"",0);
110 }
111 else
112 str_nset(stab_val(stab),"",0);
113 }
114 break;
115 case '\'':
116 if (curspat) {
117 if (curspat->spat_regexp &&
118 (s = curspat->spat_regexp->endp[0]) ) {
00bf170e 119 str_nset(stab_val(stab),s, curspat->spat_regexp->subend - s);
a687059c 120 }
121 else
122 str_nset(stab_val(stab),"",0);
123 }
124 break;
8d063cd8 125 case '.':
a687059c 126#ifndef lint
8d063cd8 127 if (last_in_stab) {
a687059c 128 str_numset(stab_val(stab),(double)stab_io(last_in_stab)->lines);
8d063cd8 129 }
a687059c 130#endif
8d063cd8 131 break;
132 case '?':
a687059c 133 str_numset(stab_val(stab),(double)statusvalue);
8d063cd8 134 break;
135 case '^':
a687059c 136 s = stab_io(curoutstab)->top_name;
137 str_set(stab_val(stab),s);
8d063cd8 138 break;
139 case '~':
a687059c 140 s = stab_io(curoutstab)->fmt_name;
141 str_set(stab_val(stab),s);
8d063cd8 142 break;
a687059c 143#ifndef lint
8d063cd8 144 case '=':
a687059c 145 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page_len);
8d063cd8 146 break;
147 case '-':
a687059c 148 str_numset(stab_val(stab),(double)stab_io(curoutstab)->lines_left);
8d063cd8 149 break;
150 case '%':
a687059c 151 str_numset(stab_val(stab),(double)stab_io(curoutstab)->page);
8d063cd8 152 break;
a687059c 153#endif
8d063cd8 154 case '/':
9f68db38 155 if (record_separator != 12345) {
156 *tokenbuf = record_separator;
157 tokenbuf[1] = '\0';
158 str_nset(stab_val(stab),tokenbuf,rslen);
159 }
8d063cd8 160 break;
161 case '[':
a687059c 162 str_numset(stab_val(stab),(double)arybase);
8d063cd8 163 break;
164 case '|':
00bf170e 165 if (!stab_io(curoutstab))
166 stab_io(curoutstab) = stio_new();
a687059c 167 str_numset(stab_val(stab),
168 (double)((stab_io(curoutstab)->flags & IOF_FLUSH) != 0) );
8d063cd8 169 break;
170 case ',':
a687059c 171 str_nset(stab_val(stab),ofs,ofslen);
8d063cd8 172 break;
173 case '\\':
a687059c 174 str_nset(stab_val(stab),ors,orslen);
8d063cd8 175 break;
176 case '#':
a687059c 177 str_set(stab_val(stab),ofmt);
8d063cd8 178 break;
179 case '!':
a687059c 180 str_numset(stab_val(stab), (double)errno);
00bf170e 181 str_set(stab_val(stab), errno ? strerror(errno) : "");
a687059c 182 stab_val(stab)->str_nok = 1; /* what a wonderful hack! */
378cc40b 183 break;
184 case '<':
a687059c 185 str_numset(stab_val(stab),(double)uid);
378cc40b 186 break;
187 case '>':
a687059c 188 str_numset(stab_val(stab),(double)euid);
378cc40b 189 break;
190 case '(':
a687059c 191 s = buf;
192 (void)sprintf(s,"%d",(int)gid);
378cc40b 193 goto add_groups;
194 case ')':
a687059c 195 s = buf;
196 (void)sprintf(s,"%d",(int)egid);
378cc40b 197 add_groups:
198 while (*s) s++;
199#ifdef GETGROUPS
200#ifndef NGROUPS
201#define NGROUPS 32
202#endif
203 {
204 GIDTYPE gary[NGROUPS];
205
206 i = getgroups(NGROUPS,gary);
207 while (--i >= 0) {
a687059c 208 (void)sprintf(s," %ld", (long)gary[i]);
378cc40b 209 while (*s) s++;
210 }
211 }
212#endif
a687059c 213 str_set(stab_val(stab),buf);
8d063cd8 214 break;
00bf170e 215 default:
216 {
217 struct ufuncs *uf = (struct ufuncs *)str->str_ptr;
218
219 if (uf && uf->uf_val)
220 uf->uf_val(uf->uf_index, stab_val(stab));
221 }
222 break;
8d063cd8 223 }
a687059c 224 return stab_val(stab);
8d063cd8 225}
226
a687059c 227stabset(mstr,str)
228register STR *mstr;
8d063cd8 229STR *str;
230{
a687059c 231 STAB *stab = mstr->str_u.str_stab;
8d063cd8 232 char *s;
233 int i;
663a0e37 234 static handlertype sighandler();
8d063cd8 235
a687059c 236 switch (mstr->str_rare) {
237 case 'E':
238 setenv(mstr->str_ptr,str_get(str));
239 /* And you'll never guess what the dog had */
240 break; /* in its mouth... */
241 case 'S':
242 s = str_get(str);
243 i = whichsig(mstr->str_ptr); /* ...no, a brick */
244 if (strEQ(s,"IGNORE"))
245#ifndef lint
246 (void)signal(i,SIG_IGN);
247#else
248 ;
249#endif
250 else if (strEQ(s,"DEFAULT") || !*s)
251 (void)signal(i,SIG_DFL);
252 else
253 (void)signal(i,sighandler);
254 break;
255#ifdef SOME_DBM
256 case 'D':
257 hdbmstore(stab_hash(stab),mstr->str_ptr,mstr->str_cur,str);
258 break;
259#endif
260 case '#':
261 afill(stab_array(stab), (int)str_gnum(str) - arybase);
262 break;
263 case 'X': /* merely a copy of a * string */
264 break;
265 case '*':
266 s = str_get(str);
9f68db38 267 if (strNE(s,"StB") || str->str_cur != sizeof(STBP)) {
a687059c 268 if (!*s) {
269 STBP *stbp;
270
271 (void)savenostab(stab); /* schedule a free of this stab */
272 if (stab->str_len)
273 Safefree(stab->str_ptr);
274 Newz(601,stbp, 1, STBP);
275 stab->str_ptr = stbp;
276 stab->str_len = stab->str_cur = sizeof(STBP);
277 stab->str_pok = 1;
9f68db38 278 strcpy(stab_magic(stab),"StB");
a687059c 279 stab_val(stab) = Str_new(70,0);
00bf170e 280 stab_line(stab) = curcmd->c_line;
a687059c 281 }
00bf170e 282 else {
a687059c 283 stab = stabent(s,TRUE);
00bf170e 284 if (!stab_xarray(stab))
285 aadd(stab);
286 if (!stab_xhash(stab))
287 hadd(stab);
288 if (!stab_io(stab))
289 stab_io(stab) = stio_new();
290 }
a687059c 291 str_sset(str,stab);
292 }
293 break;
294 case 's': {
295 struct lstring *lstr = (struct lstring*)str;
296
297 mstr->str_rare = 0;
298 str->str_magic = Nullstr;
299 str_insert(mstr,lstr->lstr_offset,lstr->lstr_len,
300 str->str_ptr,str->str_cur);
301 }
302 break;
303
304 case 'v':
305 do_vecset(mstr,str);
306 break;
307
308 case 0:
309 switch (*stab->str_magic->str_ptr) {
9f68db38 310 case '.':
311 if (localizing)
312 savesptr((STR**)&last_in_stab);
313 break;
8d063cd8 314 case '^':
a687059c 315 Safefree(stab_io(curoutstab)->top_name);
316 stab_io(curoutstab)->top_name = s = savestr(str_get(str));
317 stab_io(curoutstab)->top_stab = stabent(s,TRUE);
8d063cd8 318 break;
319 case '~':
a687059c 320 Safefree(stab_io(curoutstab)->fmt_name);
321 stab_io(curoutstab)->fmt_name = s = savestr(str_get(str));
322 stab_io(curoutstab)->fmt_stab = stabent(s,TRUE);
8d063cd8 323 break;
324 case '=':
a687059c 325 stab_io(curoutstab)->page_len = (long)str_gnum(str);
8d063cd8 326 break;
327 case '-':
a687059c 328 stab_io(curoutstab)->lines_left = (long)str_gnum(str);
329 if (stab_io(curoutstab)->lines_left < 0L)
330 stab_io(curoutstab)->lines_left = 0L;
8d063cd8 331 break;
332 case '%':
a687059c 333 stab_io(curoutstab)->page = (long)str_gnum(str);
8d063cd8 334 break;
335 case '|':
00bf170e 336 if (!stab_io(curoutstab))
337 stab_io(curoutstab) = stio_new();
a687059c 338 stab_io(curoutstab)->flags &= ~IOF_FLUSH;
8d063cd8 339 if (str_gnum(str) != 0.0) {
a687059c 340 stab_io(curoutstab)->flags |= IOF_FLUSH;
8d063cd8 341 }
342 break;
343 case '*':
a687059c 344 i = (int)str_gnum(str);
345 multiline = (i != 0);
8d063cd8 346 break;
347 case '/':
79a0689e 348 if (str->str_pok) {
9f68db38 349 record_separator = *str_get(str);
350 rslen = str->str_cur;
351 }
352 else {
353 record_separator = 12345; /* fake a non-existent char */
354 rslen = 1;
355 }
8d063cd8 356 break;
357 case '\\':
358 if (ors)
a687059c 359 Safefree(ors);
8d063cd8 360 ors = savestr(str_get(str));
a687059c 361 orslen = str->str_cur;
8d063cd8 362 break;
363 case ',':
364 if (ofs)
a687059c 365 Safefree(ofs);
8d063cd8 366 ofs = savestr(str_get(str));
a687059c 367 ofslen = str->str_cur;
8d063cd8 368 break;
369 case '#':
370 if (ofmt)
a687059c 371 Safefree(ofmt);
8d063cd8 372 ofmt = savestr(str_get(str));
373 break;
374 case '[':
375 arybase = (int)str_gnum(str);
376 break;
378cc40b 377 case '?':
0f85fab0 378 statusvalue = U_S(str_gnum(str));
378cc40b 379 break;
8d063cd8 380 case '!':
381 errno = (int)str_gnum(str); /* will anyone ever use this? */
382 break;
378cc40b 383 case '<':
378cc40b 384 uid = (int)str_gnum(str);
a687059c 385#ifdef SETREUID
386 if (delaymagic) {
387 delaymagic |= DM_REUID;
388 break; /* don't do magic till later */
389 }
390#endif /* SETREUID */
391#ifdef SETRUID
392 if (setruid((UIDTYPE)uid) < 0)
393 uid = (int)getuid();
394#else
395#ifdef SETREUID
396 if (setreuid((UIDTYPE)uid, (UIDTYPE)-1) < 0)
378cc40b 397 uid = (int)getuid();
398#else
00bf170e 399 if (uid == euid) /* special case $< = $> */
400 setuid(uid);
401 else
402 fatal("setruid() not implemented");
378cc40b 403#endif
a687059c 404#endif
378cc40b 405 break;
406 case '>':
378cc40b 407 euid = (int)str_gnum(str);
a687059c 408#ifdef SETREUID
409 if (delaymagic) {
410 delaymagic |= DM_REUID;
411 break; /* don't do magic till later */
412 }
413#endif /* SETREUID */
414#ifdef SETEUID
415 if (seteuid((UIDTYPE)euid) < 0)
416 euid = (int)geteuid();
417#else
418#ifdef SETREUID
419 if (setreuid((UIDTYPE)-1, (UIDTYPE)euid) < 0)
378cc40b 420 euid = (int)geteuid();
421#else
00bf170e 422 if (euid == uid) /* special case $> = $< */
423 setuid(euid);
424 else
425 fatal("seteuid() not implemented");
378cc40b 426#endif
a687059c 427#endif
378cc40b 428 break;
429 case '(':
a687059c 430 gid = (int)str_gnum(str);
431#ifdef SETREGID
432 if (delaymagic) {
433 delaymagic |= DM_REGID;
434 break; /* don't do magic till later */
435 }
436#endif /* SETREGID */
378cc40b 437#ifdef SETRGID
a687059c 438 (void)setrgid((GIDTYPE)gid);
439#else
440#ifdef SETREGID
441 (void)setregid((GIDTYPE)gid, (GIDTYPE)-1);
378cc40b 442#else
443 fatal("setrgid() not implemented");
444#endif
a687059c 445#endif
378cc40b 446 break;
447 case ')':
a687059c 448 egid = (int)str_gnum(str);
449#ifdef SETREGID
450 if (delaymagic) {
451 delaymagic |= DM_REGID;
452 break; /* don't do magic till later */
453 }
454#endif /* SETREGID */
378cc40b 455#ifdef SETEGID
a687059c 456 (void)setegid((GIDTYPE)egid);
457#else
458#ifdef SETREGID
459 (void)setregid((GIDTYPE)-1, (GIDTYPE)egid);
378cc40b 460#else
461 fatal("setegid() not implemented");
462#endif
a687059c 463#endif
464 break;
465 case ':':
466 chopset = str_get(str);
378cc40b 467 break;
00bf170e 468 default:
469 {
470 struct ufuncs *uf = (struct ufuncs *)str->str_magic->str_ptr;
471
472 if (uf && uf->uf_set)
473 uf->uf_set(uf->uf_index, str);
474 }
475 break;
8d063cd8 476 }
a687059c 477 break;
378cc40b 478 }
8d063cd8 479}
480
378cc40b 481whichsig(sig)
482char *sig;
8d063cd8 483{
484 register char **sigv;
485
486 for (sigv = sig_name+1; *sigv; sigv++)
378cc40b 487 if (strEQ(sig,*sigv))
8d063cd8 488 return sigv - sig_name;
a687059c 489#ifdef SIGCLD
490 if (strEQ(sig,"CHLD"))
491 return SIGCLD;
492#endif
493#ifdef SIGCHLD
494 if (strEQ(sig,"CLD"))
495 return SIGCHLD;
496#endif
8d063cd8 497 return 0;
498}
499
663a0e37 500static handlertype
8d063cd8 501sighandler(sig)
502int sig;
503{
504 STAB *stab;
505 ARRAY *savearray;
506 STR *str;
378cc40b 507 char *oldfile = filename;
508 int oldsave = savestack->ary_fill;
a687059c 509 ARRAY *oldstack = stack;
378cc40b 510 SUBR *sub;
8d063cd8 511
00bf170e 512#ifdef OS2 /* or anybody else who requires SIG_ACK */
513 signal(sig, SIG_ACK);
514#endif
a687059c 515 stab = stabent(
516 str_get(hfetch(stab_hash(sigstab),sig_name[sig],strlen(sig_name[sig]),
517 TRUE)), TRUE);
518 sub = stab_sub(stab);
519 if (!sub && *sig_name[sig] == 'C' && instr(sig_name[sig],"LD")) {
520 if (sig_name[sig][1] == 'H')
521 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CLD",3,TRUE)),
522 TRUE);
523 else
524 stab = stabent(str_get(hfetch(stab_hash(sigstab),"CHLD",4,TRUE)),
525 TRUE);
526 sub = stab_sub(stab); /* gag */
527 }
378cc40b 528 if (!sub) {
529 if (dowarn)
530 warn("SIG%s handler \"%s\" not defined.\n",
a687059c 531 sig_name[sig], stab_name(stab) );
378cc40b 532 return;
533 }
a687059c 534 savearray = stab_xarray(defstab);
535 stab_xarray(defstab) = stack = anew(defstab);
536 stack->ary_flags = 0;
537 str = Str_new(71,0);
8d063cd8 538 str_set(str,sig_name[sig]);
a687059c 539 (void)apush(stab_xarray(defstab),str);
378cc40b 540 sub->depth++;
541 if (sub->depth >= 2) { /* save temporaries on recursion? */
542 if (sub->depth == 100 && dowarn)
a687059c 543 warn("Deep recursion on subroutine \"%s\"",stab_name(stab));
378cc40b 544 savelist(sub->tosave->ary_array,sub->tosave->ary_fill);
545 }
546 filename = sub->filename;
547
a687059c 548 (void)cmd_exec(sub->cmd,G_SCALAR,1); /* so do it already */
378cc40b 549
550 sub->depth--; /* assuming no longjumps out of here */
a687059c 551 str_free(stack->ary_array[0]); /* free the one real string */
552 afree(stab_xarray(defstab)); /* put back old $_[] */
553 stab_xarray(defstab) = savearray;
554 stack = oldstack;
378cc40b 555 filename = oldfile;
556 if (savestack->ary_fill > oldsave)
557 restorelist(oldsave);
8d063cd8 558}
559
8d063cd8 560STAB *
561aadd(stab)
562register STAB *stab;
563{
a687059c 564 if (!stab_xarray(stab))
565 stab_xarray(stab) = anew(stab);
8d063cd8 566 return stab;
567}
568
569STAB *
570hadd(stab)
571register STAB *stab;
572{
a687059c 573 if (!stab_xhash(stab))
574 stab_xhash(stab) = hnew(COEFFSIZE);
8d063cd8 575 return stab;
576}
378cc40b 577
578STAB *
579stabent(name,add)
580register char *name;
581int add;
582{
583 register STAB *stab;
a687059c 584 register STBP *stbp;
585 int len;
586 register char *namend;
587 HASH *stash;
588 char *sawquote = Nullch;
589 char *prevquote = Nullch;
590 bool global = FALSE;
378cc40b 591
a687059c 592 if (isascii(*name) && isupper(*name)) {
593 if (*name > 'I') {
594 if (*name == 'S' && (
595 strEQ(name, "SIG") ||
596 strEQ(name, "STDIN") ||
597 strEQ(name, "STDOUT") ||
598 strEQ(name, "STDERR") ))
599 global = TRUE;
378cc40b 600 }
a687059c 601 else if (*name > 'E') {
602 if (*name == 'I' && strEQ(name, "INC"))
603 global = TRUE;
604 }
00bf170e 605 else if (*name > 'A') {
a687059c 606 if (*name == 'E' && strEQ(name, "ENV"))
607 global = TRUE;
608 }
609 else if (*name == 'A' && (
610 strEQ(name, "ARGV") ||
611 strEQ(name, "ARGVOUT") ))
612 global = TRUE;
613 }
614 for (namend = name; *namend; namend++) {
615 if (*namend == '\'' && namend[1])
616 prevquote = sawquote, sawquote = namend;
617 }
618 if (sawquote == name && name[1]) {
619 stash = defstash;
620 sawquote = Nullch;
621 name++;
622 }
623 else if (!isalpha(*name) || global)
624 stash = defstash;
625 else
626 stash = curstash;
627 if (sawquote) {
628 char tmpbuf[256];
629 char *s, *d;
630
631 *sawquote = '\0';
632 if (s = prevquote) {
633 strncpy(tmpbuf,name,s-name+1);
634 d = tmpbuf+(s-name+1);
635 *d++ = '_';
636 strcpy(d,s+1);
637 }
638 else {
639 *tmpbuf = '_';
640 strcpy(tmpbuf+1,name);
641 }
642 stab = stabent(tmpbuf,TRUE);
643 if (!(stash = stab_xhash(stab)))
644 stash = stab_xhash(stab) = hnew(0);
645 name = sawquote+1;
646 *sawquote = '\'';
378cc40b 647 }
a687059c 648 len = namend - name;
649 stab = (STAB*)hfetch(stash,name,len,add);
650 if (!stab)
651 return Nullstab;
652 if (stab->str_pok) {
653 stab->str_pok |= SP_MULTI;
654 return stab;
655 }
656 else {
657 if (stab->str_len)
658 Safefree(stab->str_ptr);
659 Newz(602,stbp, 1, STBP);
660 stab->str_ptr = stbp;
661 stab->str_len = stab->str_cur = sizeof(STBP);
662 stab->str_pok = 1;
9f68db38 663 strcpy(stab_magic(stab),"StB");
a687059c 664 stab_val(stab) = Str_new(72,0);
00bf170e 665 stab_line(stab) = curcmd->c_line;
a687059c 666 str_magic(stab,stab,'*',name,len);
378cc40b 667 return stab;
668 }
378cc40b 669}
670
671STIO *
672stio_new()
673{
a687059c 674 STIO *stio;
378cc40b 675
a687059c 676 Newz(603,stio,1,STIO);
378cc40b 677 stio->page_len = 60;
678 return stio;
679}
680
681stab_check(min,max)
682int min;
683register int max;
684{
a687059c 685 register HENT *entry;
378cc40b 686 register int i;
687 register STAB *stab;
688
689 for (i = min; i <= max; i++) {
a687059c 690 for (entry = defstash->tbl_array[i]; entry; entry = entry->hent_next) {
691 stab = (STAB*)entry->hent_val;
692 if (stab->str_pok & SP_MULTI)
378cc40b 693 continue;
00bf170e 694 curcmd->c_line = stab_line(stab);
a687059c 695 warn("Possible typo: \"%s\"", stab_name(stab));
378cc40b 696 }
697 }
698}
a687059c 699
700static int gensym = 0;
701
702STAB *
703genstab()
704{
705 (void)sprintf(tokenbuf,"_GEN_%d",gensym++);
706 return stabent(tokenbuf,TRUE);
707}
708
709/* hopefully this is only called on local symbol table entries */
710
711void
712stab_clear(stab)
713register STAB *stab;
714{
715 STIO *stio;
716 SUBR *sub;
717
718 afree(stab_xarray(stab));
719 (void)hfree(stab_xhash(stab));
720 str_free(stab_val(stab));
721 if (stio = stab_io(stab)) {
722 do_close(stab,FALSE);
723 Safefree(stio->top_name);
724 Safefree(stio->fmt_name);
725 }
726 if (sub = stab_sub(stab)) {
727 afree(sub->tosave);
728 cmd_free(sub->cmd);
729 }
730 Safefree(stab->str_ptr);
731 stab->str_ptr = Null(STBP*);
732 stab->str_len = 0;
733 stab->str_cur = 0;
734}
735
9f68db38 736#if defined(CRIPPLED_CC) && (defined(iAPX286) || defined(M_I286) || defined(I80286))
737#define MICROPORT
738#endif
739
740#ifdef MICROPORT /* Microport 2.4 hack */
741ARRAY *stab_array(stab)
742register STAB *stab;
743{
744 if (((STBP*)(stab->str_ptr))->stbp_array)
745 return ((STBP*)(stab->str_ptr))->stbp_array;
746 else
747 return ((STBP*)(aadd(stab)->str_ptr))->stbp_array;
748}
749
750HASH *stab_hash(stab)
751register STAB *stab;
752{
753 if (((STBP*)(stab->str_ptr))->stbp_hash)
754 return ((STBP*)(stab->str_ptr))->stbp_hash;
755 else
756 return ((STBP*)(hadd(stab)->str_ptr))->stbp_hash;
757}
758#endif /* Microport 2.4 hack */