Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/symt.lis
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

866 lines
26 KiB
Plaintext

1File: SYMT.C Page 1
1 /*
2 Copyright 1981
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8 #include "as68.h"
9
10 /* symbol table and misc routines*/
11
12 int errno;
13 char *ermsg[];
14 char tfilname[];
15 char initfnam[];
16 char ldfn[];
17 char tlab1[];
18 int stdofd;
19 int ftudp;
20 int poslab;
21
22 /*output it for beginning of statement*/
23 opitb()
24 {
25 stbuf[0].itty = ITBS; /*beginning of statement*/
26 stbuf[0].itop = (fchr!=EOLC) ? absln : absln-1;
27 stbuf[1].itty = ITSY; /*label entry*/
28 stbuf[1].itop.ptrw2 = lblpt; /*pointer to symbol or 0*/
29
30 /*put opcode in it buffer*/
31 stbuf[2].itty = ITSY;
32 stbuf[2].itrl = modelen; /*mode of instr(byte, word, long)*/
33 stbuf[2].itop.ptrw2 = opcpt; /*pointer to opcode in main table*/
34 stbuf[3].itty = ITCN;
35 stbuf[3].itrl = rlflg; /*relocation base*/
36 stbuf[3].itop = loctr; /*pass1 location counter*/
37 itwc = ITOP1; /*next available slot-currently 4*/
38 pitw = &stbuf[ITOP1].itty; /*init the pointer*/
39 }
40
41 /*
42 * get an input term (symbol, constant, or special character)
43 * call with:
44 * the first character in fchr
45 * returns:
46 * item type in itype
47 * item value in ival if item is a constant or special character
48 * if it is a symbol it is placed at the end of the main table
49
50 * meaning of state table:
51
52 * currently getting: symbol(0) constant(1) beginning(2)
53
54 * next char:
55 * digit(0) 0 1 1
56
57 * letter(3) 0 3 0
58
59 * special char(6) 3 3 3
1File: SYMT.C Page 2
60
61 * contents of the state table is the next state. processing stops when
62 * state 3 is encountered. state 2 is the beginning state.
63 */
64 int sttbl[] {0,1,1,0,3,0,3,3,3}; /*state table for parser*/
65
66 gterm(constpc)
67 int constpc;
68 {
69 register smode, i;
70 register char *p;
71 register int tmode;
72 register char *j;
73 long num;
74 char istr[80];
75
76 /* if(fchr == '\'' || fchr == '"') */ /* Fucking Whitesmith's */
77 if(fchr == 047 || fchr == 042)
78 if(astring()) /*maybe ascii string*/
79 return;
80 smode = 2; /*beginning state*/
81 i = 0;
82 p = istr;
83
84 /*loop to put item on istr*/
85 while(fchr>=' ') { /*until a control char*/
86 if(smode==2 && fchr=='.')
87 tmode = 3;
88 else if(isalpha(fchr) || fchr=='~' || fchr=='_' || (fchr=='$'&&i))
89 tmode=3;
90 else if(isdigit(fchr))
91 tmode=0;
92 else
93 tmode = 6;
94 tmode = sttbl[tmode+smode]; /*new state*/
95 if(tmode==3) break; /*end of item*/
96 smode = tmode;
97 *p++ = fchr; /*save character*/
98 i++;
99 fchr=gchr();
100 }
101
102 /* end of item*/
103 switch(smode) {
104
105 case 0: /*symbol*/
106 *p = '\0'; /*end of symbol*/
107 itype = ITSY; /*symbol*/
108 pack(istr,lmte); /*put symbol at end of main table*/
109 j = lemt(sirt,FALSE);
110 if(istr[0]!='~' && !poslab && (j->flags&(SYEQ|SYER))==SYEQ) {
111 itype = (j->flags&SYRM) ? ITRM : ITCN; /* [vlh] */
112 ival = j->vl1;
113 reloc = ((j->flags)&SYRO) ? TEXT : ((j->flags)&SYRA) ? DATA :
114 ((j->flags)&SYBS) ? BSS : ABS;
115 }
116 return;
117
118 case 1: /*constant*/
1File: SYMT.C Page 3
119 if(!constant(&num,istr,i)) {
120 uerr(17); /*illegal constant*/
121 num = 0;
122 }
123 ival = num;
124 itype = ITCN;
125 reloc = ABS;
126 return;
127
128 case 2: /*just a special char*/
129 switch(fchr) {
130
131 case '*': /*location counter*/
132 if(starmul) { /*multiply*/
133 starmul = 0;
134 goto specsy;
135 }
136 refpc++; /*referenced pgm ctr*/
137 reloc = rlflg; /*relocation of location counter*/
138 ival = loctr;
139 itype = (constpc) ? ITCN : ITPC;
140 break;
141
142
143 case '$': /*hex constant*/
144 oconst(16);
145 return;
146
147 case '@': /*octal const*/
148 oconst(8);
149 return;
150
151 case '%': /*binary const*/
152 oconst(2);
153 return;
154
155 case '#':
156 immed[opdix]++;
157 goto specsy;
158
159 case '(':
160 indir[opdix]++;
161 plevel++;
162 goto specsy;
163
164 case ')':
165 plevel--;
166 goto specsy;
167
168 default:
169 specsy:
170 itype = ITSP; /*return special char*/
171 ival = fchr;
172 }
173 if(fchr != EOLC)
174 fchr=gchr(); /*get next char*/
175 if((ival=='>' && fchr=='>') || (ival=='<' && fchr=='<'))
176 fchr=gchr(); /*shift op, ignore second char*/
177 return;
1File: SYMT.C Page 4
178
179 default:
180 abort(); /*not possible*/
181 }
182 }
183
184 /*check for an ascii string enclosed in single quotes*/
185
186 astring()
187 {
188 register char delim;
189
190 /* if(fchr != '\'' && fchr != '"') *//*valid delimiter*/
191 if(fchr != 047 && fchr != 042)
192 return;
193 delim = fchr;
194 if(equflg || (itype==ITSP && ival.wd2=='#')) { /*immediate operand*/
195 if(astr1(delim)) {
196 fchr = gchr();
197 if(fchr!=delim)
198 xerr(19);
199 fchr=gchr();
200 }
201 return((equflg) ? 1 : 0);
202 }
203 while(astr1(delim)) {
204 itype = ITSP;
205 ival = ','; /*separate by commas*/
206 reloc = ABS;
207 opitoo();
208 }
209 return(0);
210 }
211
212 astr1(adelim)
213 {
214 register delim,i,retv;
215 register long l;
216
217 delim = adelim;
218 i = 0; l = 0;
219 retv = 1;
220 while((fchr=gchr()) != EOF) {
221 if(fchr==delim) {
222 fchr = gchr();
223 if(fchr != delim) {
224 retv = 0; /*end of string*/
225 break;
226 }
227 }
228 if(fchr == EOLC) {
229 xerr(19);
230 retv = 0; /*end of string*/
231 break;
232 }
233 l = (l<<8) | fchr;
234 if(++i >= modelen) {
235 if((fchr=gchr()) == delim) {
236 fchr = gchr();
1File: SYMT.C Page 5
237 retv = 0; /*end of string*/
238 }
239 else
240 peekc = fchr; /*next char in string*/
241 break; /*filled one bucket*/
242 }
243 }
244 while(i < modelen) {
245 l =<< 8;
246 i++;
247 }
248 itype = ITCN;
249 ival = l;
250 reloc = ABS;
251 if(!equflg)
252 opitoo(); /*output one operand*/
253 return(retv);
254 }
255
256 /*get constant given radix*/
257 oconst(ardx)
258 {
259 register trdx,j;
260 register long i;
261
262 switch (ardx) { /* radix as power of 2 */
263 case 16 : trdx = 4; break;
264 case 8 : trdx = 3; break;
265 case 2 : trdx = 1; break;
266 default :
267 rpterr("invalid radix in oconst");
268 abort();
269 }
270 i=0;
271 while(1) {
272 fchr=gchr();
273 j=fchr;
274 if(isdigit(j))
275 j =- '0';
276 else if((j=tolower(j))>='a' && j<='f')
277 j = j-'a'+10;
278 else
279 break; /*not valid numeric char*/
280 if(j>=0 && j<ardx)
281 i = (i<<trdx)+j;
282 else
283 break;
284 }
285 ival = i;
286 itype = ITCN;
287 reloc = ABS;
288 }
289
290
291 /*convert ascii constant to binary*/
292 constant(pnum,pstr,idx)
293 long *pnum;
294 char *pstr;
295 {
1File: SYMT.C Page 6
296 register i,j;
297 register char *p;
298 register long l;
299
300 p = pstr;
301 l = 0;
302 for(i=0; i<idx; i++) {
303 j = *pstr++;
304 if(isdigit(j))
305 j =- '0';
306 if(j<0 || j>=10)
307 return(0);
308 l = (l<<3) + (l<<1) + j; /* l = l*10 + j*/
309 }
310 *pnum = l;
311 return(1);
312 }
313
314 /*
315 * method for looking up entries in the main table
316 *
317 * Note: The entry to be looked up must be placed at the end
318 * of the main table. The global cell 'lmte'(last main
319 * entry) points to the next available entry in the main
320 * table. The address of an initial reference table must
321 * also be provided.
322 *
323 * 1) Compute the hash code for the symbol and add it to the base address
324 * of the initial reference table given as input. Thus, two words are
325 * accessed which define the chain on which the symbol must be if it
326 * is in the table at all.
327 *
328 * 2) Alter the table link of the last symbol in the chain so that it
329 * points to the symbol being looked up. Note that the symbol to be
330 * looked up is always placed at the end of the main table before
331 * calling the lookup routine. This essentially adds one more element
332 * to the end of the chain, namely the symbol to be looked up.
333 *
334 * 3) Now start at the first symbol in the chain and follow the chain
335 * looking for a symbol equal to the smbol being looked up. It is
336 * guaranteed that such a symbol will be found because it is always
337 * the last symbol on the chain.
338 *
339 * 4) When the symbol is found, check to see if it is the last symbol
340 * on the chain. If not, the symbol being looked for is in the table
341 * and has been found. If it is the last symbol, the symbol being
342 * looked up is not in the table.
343 *
344 * 5) In the case the looked up symbol is not found, it is usually added
345 * to the end of the table. This is done simply b changing the
346 * initial reference table entry which points to the previous
347 * last symbol on the chain so that is now points to the symbol at the
348 * end of the main table. In case the symbol just looked up is not to
349 * be added to the main table then no action is needed . This means
350 * that the table link of the last symbol on a chain may point any-
351 * where.
352 *
353 * look up entry in the main table
354 * call with:
1File: SYMT.C Page 7
355 * address of initial reference table
356 * entry to be looked up at the end of the main table
357 * returns:
358 * a pointer to the entry. if this pointer is equal to
359 * lmte then the symbol was not previously in the table.
360 */
361
362 char *lemt(airt,oplook)
363 char **airt;
364 int oplook; /* if true then looking in opcode table */
365 {
366 register char *mtpt;
367 register int *p1, *p2;
368 register int i, j;
369
370 if (oplook) { /* [vlh] get rid of preceding '.', to lowercase */
371 if (lmte->name[0]=='.') {
372 lmte->name[NAMELEN-1] = NULL; /* in case of '.' */
373 j = 1;
374 }
375 else j = 0;
376 for (i=0; j<NAMELEN; i++, j++)
377 lmte->name[i] = tolower(lmte->name[j]);
378 }
379
380 pirt = airt + hash(); /*hashed ptr to irt*/
381 mtpt = pirt->irfe; /*pointer to first entry in chain*/
382 if(!mtpt) /*empty chain*/
383 mtpt = lmte; /*start at end of main table*/
384 else
385 (pirt->irle)->tlnk = lmte; /*last entry in chain is new symbol*/
386
387 /*loop to locate entry in main table*/
388 lemtl:
389 p1 = &mtpt->name[0];
390 p2 = &lmte->name[0];
391 i = NAMELEN/(sizeof i);
392 while(i) {
393 if(*p1++ != *p2++) {
394 mtpt = mtpt->tlnk; /*go to next entry in chain*/
395 goto lemtl;
396 }
397 i--;
398 }
399 return(mtpt);
400 }
401
402 /* compute a hash code for the last entry in the main table*/
403 /* returns the hash code*/
404 hash()
405 {
406 register int i;
407 register ht1;
408 register char *p;
409
410 ht1 = 0;
411 p = &lmte->name[0];
412 for(i=0; i<NAMELEN; i++)
413 ht1 =+ *p++;
1File: SYMT.C Page 8
414 return(ht1&(SZIRT-2)); /*make hash code even and between 0 & SZIRT-2*/
415 }
416
417 /*
418 * Make an entry in the main table
419 * assumes :
420 * entry to be made is pointed at by lmte
421 * pirt points to the correct initial reference table entry.
422 */
423 mmte()
424 {
425 pirt->irle = lmte; /*pointer to last entry in chain*/
426 if(pirt->irfe == 0) /*first entry in chain*/
427 pirt->irfe = lmte;
428 lmte =+ STESIZE; /*bump last main table entry pointer*/
429 if(lmte>=emte) { /*main table overflow*/
430 if(sbrk(STESIZE*ICRSZMT) == -1){ /*get more memory*/
431 rpterr("symbol table overflow\n");
432 endit();
433 }
434 else {
435 emte =+ STESIZE*ICRSZMT; /*move end of main table*/
436 cszmt =+ ICRSZMT;
437 }
438 }
439 }
440
441 /*
442 * make an entry in the main table for a directive
443 * call with:
444 * pointer to string containing directive name
445 * address of routine to handle directive in pass one
446 * address of routine to handle directive in pass two
447 */
448 mdemt(mdstr,dirnum)
449 char *mdstr;
450 {
451 register char *mdept;
452
453 pack(mdstr,lmte); /*pack name at end of main table*/
454 mdept=lemt(oirt,TRUE); /*look up in opcode table*/
455 if(mdept != lmte) { /*best not be there already*/
456 uerr(5);
457 abort();
458 return;
459 }
460 mmte(); /*make main table entry*/
461 mdept->flags =| OPDR|SYIN; /*directive*/
462 mdept->vl1 = dirnum; /*directive #*/
463 }
464
465 /*
466 * pack a string into an entry in the main table
467 * call with:
468 * pointer to the string
469 * pointer to desired entry in the main table
470 */
471 pack(apkstr,apkptr)
472 char *apkstr, *apkptr;
1File: SYMT.C Page 9
473 {
474 register i;
475 register char *pkstr, *pkptr;
476
477 pkstr = apkstr;
478 pkptr = apkptr;
479 i = NAMELEN;
480 while(*pkstr && i) {
481 *pkptr++ = *pkstr++;
482 i--;
483 }
484 while(i--)
485 *pkptr++ = '\0'; /*pad with nulls*/
486 }
487
488 /* function to get characters for source file*/
489 int xcol = 0; /* Column Counter */
490 int spcnt = 0; /* Space count for tab expansion */
491 gchr()
492 {
493 register chr1;
494
495 if(peekc) {
496 chr1 = peekc;
497 peekc = 0;
498 if(chr1 != SOH)
499 xcol--;
500 }
501 else if (spcnt)
502 {
503 spcnt--;
504 return(' ');
505 }
506 else
507 {
508 gchr1:
509 if(sbuflen<=0){ /*nothing on input buffer*/
510 sbuflen=read(ifn,sbuf,512); /*read in source*/
511 if(sbuflen<=0)
512 return(EOF); /*end of file*/
513 psbuf = sbuf;
514 }
515 chr1 = *psbuf++;
516 sbuflen--;
517 }
518 if (chr1 == SOH) /*preprocessor flag*/
519 goto gchr1; /*ignore it*/
520 if(chr1 == EOLC) { /*end of line*/
521 xcol = -1; /* Clear column counter */
522 if(!p2flg) /*pass 1 only*/
523 absln++;
524 }
525 if(chr1=='\t') /*convert tabs to spaces*/
526 {
527 spcnt += 7 - (xcol&7); /* This many spaces */
528 xcol += spcnt; /* New column number */
529 chr1 = ' ';
530 }
531 xcol++;
1File: SYMT.C Page 10
532 return(chr1);
533 }
534
535 /*
536 * write out intermediate text for one statement
537 * call with
538 * the it for the statement in stbuf
539 */
540 wostb()
541 {
542 register int woix;
543 register short *itwo;
544 register int i;
545
546 if(stbuf[0].itty != ITBS) abort(); /*not beginning of stmt*/
547 itwo = &stbuf;
548 woix = stbuf[0].itrl & 0377; /*unsigned byte*/
549 while(woix--) {
550 for(i=0; i<(sizeof stbuf[0])/(sizeof *itwo); i++) {
551 doitwr(*itwo++);
552 }
553 }
554 /* debug(); //call debug package*/
555 }
556
557 doitwr(word)
558 short word;
559 {
560 short i;
561
562 if( pitix < itbuf || pitix > &itbuf[ITBSZ] ) {
563 printf("doitwr: it buffer botch\n");
564 endit();
565 }
566 if( pitix >= &itbuf[ITBSZ]) {
567 if(write(itfn,itbuf,ITBSZ*(sizeof i)) != ITBSZ*(sizeof i)) {
568 rpterr("it write error errno=%o\n",errno);
569 endit();
570 }
571 pitix = itbuf;
572 }
573 *pitix++ = word;
574 }
575
576 /*
577 * user source error
578 * call with:
579 * number to indicate reason for error
580 * types the error number and the line number on which
581 * the error occured.
582 */
583 uerr(errn)
584 {
585 if(p2flg) { /*pass 2 gets two ampersands*/
586 in_err++; /* [vlh] instrlen <- pass1 estimation */
587 printf("&& %d: %s\n",p2absln,ermsg[errn-1]);
588 }
589 else
590 printf("& %d: %s\n",(fchr==EOLC)?absln-1:absln,ermsg[errn-1]);
1File: SYMT.C Page 11
591 nerror++;
592 }
593 /*
594 * user error that causes the statement to be abandoned
595 * call with:
596 * error number
597 */
598 xerr(xern)
599 {
600 uerr(xern); /*type error message*/
601 if(!p2flg) /*pass one*/
602 igrst(); /*pass rest of source*/
603 }
604
605 /* abort the assembly*/
606 abort()
607 {
608 rpterr("as68 abort\n");
609 nerror++;
610 endit();
611 }
612
613 /*ignore rest of statement*/
614 igrst()
615 {
616 while(fchr!=EOLC && fchr!=EOF) /*until end of line*/
617 fchr=gchr();
618 while((fchr=gchr())==EOLC) ; /*ignore null lines*/
619 }
620
621 /*ignore blanks after a label*/
622 ligblk()
623 {
624 if(fchr == EOF) return;
625 igblk();
626 if(fchr==EOLC) {
627 fchr=gchr();
628 ligblk();
629 }
630 }
631
632 rubout()
633 {
634 nerror = -1;
635 endit();
636 }
637
638 /* exit from the assembler*/
639 endit()
640 {
641 LASTCHTFN = itfnc;
642 unlink(tfilname); /*delete temporary files*/
643 LASTCHTFN = trbfnc;
644 unlink(tfilname);
645 LASTCHTFN = dafnc;
646 unlink(tfilname);
647 LASTCHTFN = drbfnc;
648 unlink(tfilname);
649 if(nerror != -1) { /*not rubout*/
1File: SYMT.C Page 12
650 if(ftudp)
651 putchar('\n');
652 }
653 if(nerror > 0) {
654 fprintf(stderr,"& %d errors\n",nerror);
655 }
656 if (initflg)
657 unlink(ldfn); /* [vlh] get rid of empty .o file */
658 exit(nerror!=0);
659 }
660
661 /*
662 * open files
663 * call with:
664 * pointer to name of file to open
665 * flag for how to open
666 * 0 => read
667 * 1 => write
668 */
669 openfi(pname,hflag)
670 char *pname;
671 {
672 register fd;
673
674 fd = (hflag==1) ? creat(pname,0666,1) : open(pname,hflag,1);
675 if(fd < 0) { /*open failed*/
676 rpterr("can't open %s errno=%o\n",pname,errno);
677 endit();
678 }
679 return(fd);
680 }
681
682 /* get a temp file for the intermediate text*/
683 char lastfile = 'A';
684 gettempf()
685 {
686 register i,j;
687 register char *p;
688
689 LASTCHTFN = lastfile++; /* Creat temp name */
690 if((j=creat(tfilname,0600,1)) >= 0)
691 return(j); /* File created OK */
692 rpterr("Unable to open temporary file\n");
693 endit();
694 }
695
696 /* move label name from lbt to main table entry pointed to by lmte*/
697 setname()
698 {
699 register i;
700 register int *p1, *p2;
701
702 p1 = &lmte->name[0];
703 for(p2 = &lbt[0]; p2 < &lbt[NAMELEN]; ) {
704 *p1++ = *p2;
705 *p2++ = 0;
706 }
707 }
708
1File: SYMT.C Page 13
709 /* get the initialized main table and initial reference tables from*/
710 /* the initialize file*/
711 getsymtab()
712 {
713 long j; /* length for read / write */
714 register char **p;
715 register struct symtab *p1;
716 register char *p2;
717 register fd,i;
718
719 if((fd=open(initfnam,0,1)) < 0) {
720 rerr:
721 printf("& Unable to read init file: %s\n", initfnam);
722 endit();
723 }
724 if(read(fd,sirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0])) {
725 goto rerr;
726 }
727
728 if(read(fd,oirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0]))
729 goto rerr;
730
731 if(read(fd,&j,(sizeof j)) != (sizeof j)) /* Read Count */
732 goto rerr; /* Y-U-K!!! */
733
734 if((i=read(fd,bmte,(int)j)) != j) /* Read table */
735 goto rerr;
736
737 if((i%STESIZE) != 0)
738 goto rerr;
739
740 lmte = bmte + i;
741 p2 = bmte-1;
742 for(p=sirt; p<&sirt[SZIRT]; p++) {
743 if(*p)
744 *p =+ (long)p2;
745 }
746 for(p=oirt; p<&oirt[SZIRT]; p++) {
747 if(*p)
748 *p =+ (long)p2;
749 }
750 for(p1=bmte; p1<lmte; p1++) {
751 if(p1->tlnk)
752 p1->tlnk =+ (long)p2;
753 }
754 close(fd);
755 }
756
757 /* write the initialization file*/
758 putsymtab()
759 {
760 long j;
761 register char **p;
762 register struct symtab *p1;
763 register char *p2;
764 register fd,i;
765
766 if((fd=creat(initfnam,0644,1))<0) {
767 printf("& Cannot create init: %s\n", initfnam);
1File: SYMT.C Page 14
768 return;
769 }
770 /*
771 * change all pointers so that they are relative to the beginning
772 * of the symbol table
773 */
774 p2 = bmte-1;
775 for(p=sirt; p<&sirt[SZIRT]; p++) {
776 if(*p)
777 *p =- (long)p2;
778 }
779 for(p=oirt; p<&oirt[SZIRT]; p++) {
780 if(*p)
781 *p =- (long)p2;
782 }
783 for(p1=bmte; p1<lmte; p1++) {
784 if(p1->tlnk)
785 p1->tlnk =- (long)p2;
786 }
787
788 if(write(fd,sirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0])) {
789 goto werr;
790 }
791
792 if(write(fd,oirt,SZIRT*(sizeof oirt[0])) != SZIRT*(sizeof oirt[0]))
793 goto werr;
794
795 i = lmte - bmte; /*length of current main table*/
796 if((i % STESIZE) != 0) {
797 goto werr;
798 }
799 j = i;
800 if(write(fd,&j,(sizeof j)) != (sizeof j)) /* Y-U-K!! */
801 goto werr;
802
803 if(write(fd,bmte,i) != i) {
804 werr:
805 printf("& Write error on init file: %s\n",initfnam);
806 return;
807 }
808 close(fd);
809 }
810
811 /* print an error on file descriptor 2*/
812 /* used for errors with disasterous consequences*/
813 rpterr(ptch,x1,x2,x3,x4,x5,x6)
814 char *ptch;
815 {
816 if(prtflg==0) /* Check for paging output */
817 page(); /* Perform page checks */
818 fprintf(stderr,"& %d: ",absln);
819 fprintf(stderr,ptch,x1,x2,x3,x4,x5,x6);
820 }
821
822 /* set the file name for the relocatable object file (sourcefile.o)*/
823 setldfn(ap)
824 char *ap;
825 {
826 register char *p1,*p2;
1File: SYMT.C Page 15
827
828 p1 = ap;
829 p2 = ldfn;
830 while(*p1) {
831 *p2++ = *p1++;
832 }
833 if(*(p2-2) != '.') { /*not name.?*/
834 *p2++ = '.';
835 *p2++ = 'o';
836 }
837 else { /* is name.? */
838 *(p2-1) = 'o';
839 }
840 *p2 = '\0';
841 }
842
843 savelab()
844 {
845 register int *p1, *p2;
846
847 p2 = &lmte->name[0];
848 for(p1= &tlab1[0]; p1 < &tlab1[NAMELEN]; )
849 *p1++ = *p2++;
850 }