4 * Copyright (C) 1989-2021 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 * With enhancements from
26 * John L. Hartman (JLH)
27 * jhartman at compuserve dot com
32 * - use strsto instead StoreString and include it in assym.c
33 * for compatibility with the original asxxxx
34 * - applied changes from 28-Oct-97 JLH:
35 * - lookup: Use StoreString for sym construction
36 * - change symeq() to do length-independent string compare
37 * - change hash() to do length-independent hash calculation
38 * - applied changes from 29-Oct-97 JLH:
39 * - make mnemonics case insensitive ALWAYS
40 * - make hash() case-insensitive always
41 * - replace symeq() call in mlookup with strcmpi
48 * The module assym.c contains the functions that operate
49 * on the mnemonic/directive and symbol structures.
51 * assym.c contains the following functions:
65 * assym.c contains the static variables:
68 * used by the string store function.
71 /*)Function VOID syminit()
73 * The function syminit() is called early in the game
74 * to set up the hashtables. First all buckets in a
75 * table are cleared. Then a pass is made through
76 * the respective symbol lists, linking them into
77 * their hash buckets. Finally the base area pointer
81 * int h computed hash value
82 * mne * mp pointer to a mne structure
83 * mne ** mpp pointer to an array of
84 * mne structure pointers
85 * sym * sp pointer to a sym structure
86 * sym ** spp pointer to an array of
87 * sym structure pointers
90 * area area[] single elememt area array
91 * area dca defined as area[0]
92 * mne * mnehash[] array of pointers to NHASH
93 * linked mnemonic/directive lists
94 * sym * symhash[] array of pointers to NHASH
101 * (1) The symbol hash tables are initialized,
102 * the predefined symbols are '.' and '.__.ABS.'.
103 * (2) The mnemonic/directive hash tables are
104 * initialized with the assembler directives
105 * and mnemonics found in the machine dependent
107 * (3) The area pointer is initialized to dca (area[0]).
120 while (mpp
< &mnehash
[NHASH
])
124 h
= hash(mp
->m_id
, 1);
125 mp
->m_mp
= mnehash
[h
];
127 if (mp
->m_flag
&S_EOL
)
133 while (spp
< &symhash
[NHASH
])
137 h
= hash(sp
->s_id
, zflag
);
138 sp
->s_sp
= symhash
[h
];
140 if (sp
->s_flag
&S_EOL
)
148 /*)Function area * alookup(id)
150 * char * id area name string
152 * The function alookup() searches the area list for a
153 * match with id. If the area is defined then a pointer
154 * to this area is returned else a NULL is returned.
157 * area * ap pointer to area structure
160 * area * areap pointer to an area structure
163 * int symeq() assym.c
177 * JLH: case insensitive lookup always
179 if(symeq(id
, ap
->a_id
, 1))
186 /*)Function def * dlookup(id)
188 * char * id definition name string
190 * The function dlookup() searches the definition list for a
191 * match with id. If the definition is defined then a pointer
192 * to this definition is returned else a NULL is returned.
195 * def * dp pointer to a def structure
198 * def * defp pointer to a def structure
201 * int symeq() assym.c
214 if (symeq(id
, dp
->d_id
, zflag
)) {
222 /*)Function mne * mlookup(id)
224 * char * id mnemonic/directive name string
226 * The function mlookup() searches the mnemonic/directive
227 * hash tables for a match returning a pointer to the
228 * mne structure else it returns a NULL.
231 * mne * mp pointer to mne structure
232 * int h calculated hash value
235 * mne * mnehash[] array of pointers to NHASH
236 * linked mnemonic/directive lists
252 * JLH: case insensitive lookup always
257 if(symeq(id
, mp
->m_id
, 1))
264 /*)Function sym * slookup(id)
266 * char * id symbol name string
268 * The function slookup() searches the symbol hash tables for
269 * a symbol name match returning a pointer to the sym structure
270 * else it returns a NULL.
273 * int h computed hash value
274 * sym * sp pointer to a sym structure
277 * sym * symhash[] array of pointers to NHASH
278 * linked symbol lists
279 * int zflag disable symbol case sensitivity
283 * int symeq() assym.c
298 if(symeq(id
, sp
->s_id
, zflag
))
305 /*)Function sym * lookup(id)
307 * char * id symbol name string
309 * The function lookup() searches the symbol hash tables for
310 * a symbol name match returning a pointer to the sym structure.
311 * If the symbol is not found then a sym structure is created,
312 * initialized, and linked to the appropriate hash table.
313 * A pointer to this new sym structure is returned.
316 * int h computed hash value
317 * sym * sp pointer to a sym structure
320 * sym * symhash[] array of pointers to NHASH
321 * linked symbol lists
322 * int zflag disable symbol case sensitivity
326 * char * new() assym.c
327 * char * strsto() assym.c
328 * int symeq() assym.c
331 * If the function new() fails to allocate space
332 * for the new sym structure the assembly terminates.
336 lookup(const char *id
)
344 if(symeq(id
, sp
->s_id
, zflag
))
348 sp
= (struct sym
*) new (sizeof(struct sym
));
349 sp
->s_sp
= symhash
[h
];
352 sp
->s_id
= strsto(id
);
361 /*)Function VOID symglob()
363 * The function symglob() will mark all symbols of
364 * type S_NEW as global. Called at
365 * the beginning of pass 1 if the assembly
366 * option -g was specified.
369 * sym * sp pointer to a sym structure
373 * sym * symhash[] array of pointers to NHASH
374 * linked symbol lists
380 * Symbol types changed.
389 for (i
=0; i
<NHASH
; ++i
) {
392 if (sp
->s_type
== S_NEW
)
399 /*)Function VOID allglob()
401 * The function allglob() will mark all symbols of
402 * type S_USER as global. Called at
403 * the beginning of pass 1 if the assembly
404 * option -a was specified.
407 * sym * sp pointer to a sym structure
411 * sym * symhash[] array of pointers to NHASH
412 * linked symbol lists
418 * Symbol types changed.
427 for (i
=0; i
<NHASH
; ++i
) {
430 if (sp
!= &dot
&& sp
->s_type
== S_USER
)
437 /*)Function int symeq(p1, p2, flag)
439 * int flag case sensitive flag
440 * char * p1 name string
441 * char * p2 name string
443 * The function symeq() compares the two name strings for a match.
444 * The return value is 1 for a match and 0 for no match.
446 * flag == 0 case sensitive compare
447 * flag != 0 case insensitive compare
453 * char ccase[] an array of characters which
454 * perform the case translation function
465 symeq(const char *p1
, const char *p2
, int flag
)
472 * Case Insensitive Compare
475 if (ccase
[*p1
++ & 0x007F] != ccase
[*p2
++ & 0x007F])
480 * Case Sensitive Compare
490 /*)Function int hash(p, flag)
492 * char * p pointer to string to hash
493 * int flag case sensitive flag
495 * The function hash() computes a hash code using the sum
496 * of all characters mod table size algorithm.
498 * flag == 0 case insensitve hash
499 * flag != 0 case sensitive hash
502 * int h accumulated character sum
505 * char ccase[] an array of characters which
506 * perform the case translation function
516 hash(const char *p
, int flag
)
524 * Case Insensitive Hash
526 h
+= ccase
[*p
++ & 0x007F];
529 * Case Sensitive Hash
537 /*)Function char * strsto(str)
539 * char * str pointer to string to save
541 * Allocate space for "str", copy str into new space.
542 * Return a pointer to the allocated string.
544 * This function based on code by
546 * jhartman at compuserve dot com
549 * int bytes bytes remaining in buffer area
550 * int len string length + 1
551 * char * p pointer to head of copied string
552 * char * pnext next location in buffer area
558 * char * new() assym.c
559 * char * strncpy() c_library
560 * int * strlen() c_library
563 * Space allocated for string, string copied
564 * to space. Out of Space terminates assembler.
568 * To avoid wasting memory headers on small allocations, we
569 * allocate a big chunk and parcel it out as required.
570 * These static variables remember our hunk.
575 static char * pnext
= NULL
;
576 static int bytes
= 0;
579 strsto(const char *str
)
585 * What we need, including a null.
587 len
= strlen(str
) + 1;
591 * No space. Allocate a new hunk.
592 * We lose the pointer to any old hunk.
593 * We don't care, as the names are never deleted.
595 pnext
= (char *) new (STR_SPC
);
600 * Copy the name and terminating null.
603 strncpy(p
, str
, len
);
611 /*)Function char * new(n)
613 * unsigned int n allocation size in bytes
615 * The function new() allocates n bytes of space and returns
616 * a pointer to this memory. If no space is available the
617 * assembly is terminated.
620 * VOID * p a general pointer
626 * VOID asexit() asmain.c
627 * int fprintf() c_library
628 * VOID * malloc() c_library
631 * Memory is allocated, if allocation fails
632 * the assembly is terminated.
640 if ((p
= (VOID
*) malloc(n
)) == NULL
) {
641 fprintf(stderr
, "Out of space!\n");