4 * (C) Copyright 1989-1995
12 * - use strsto instead StoreString and include it in assym.c
13 * for compatibility with the original asxxxx
14 * - applied changes from 28-Oct-97 JLH:
15 * - lookup: Use StoreString for sym construction
16 * - change symeq() to do length-independent string compare
17 * - change hash() to do length-independent hash calculation
18 * - applied changes from 29-Oct-97 JLH:
19 * - make mnemonics case insensitive ALWAYS
20 * - make hash() case-insensitive always
21 * - replace symeq() call in mlookup with strcmpi
32 * The module assym.c contains the functions that operate
33 * on the mnemonic/directive and symbol structures.
35 * assym.c contains the following functions:
46 * assym.c contains no local/static variables.
49 /*)Function VOID syminit()
51 * The function syminit() is called early in the game
52 * to set up the hashtables. First all buckets in a
53 * table are cleared. Then a pass is made through
54 * the respective symbol lists, linking them into
55 * their hash buckets. Finally the base area pointer
59 * int h computed hash value
60 * mne * mp pointer to a mne structure
61 * mne ** mpp pointer to an array of
62 * mne structure pointers
63 * sym * sp pointer to a sym structure
64 * sym ** spp pointer to an array of
65 * sym structure pointers
68 * area area[] single elememt area array
69 * area dca defined as area[0]
70 * mne * mnehash[] array of pointers to NHASH
71 * linked mnemonic/directive lists
72 * sym * symhash[] array of pointers to NHASH
79 * (1) The symbol hash tables are initialized,
80 * the only defined symbol is '.'.
81 * (2) The mnemonic/directive hash tables are
82 * initialized with the assembler directives
83 * and mnemonics found in the machine dependent
85 * (3) The area pointer is initialized to dca (area[0]).
91 register struct mne *mp;
93 register struct sym *sp;
98 while (mpp < &mnehash[NHASH])
103 mp->m_mp = mnehash[h];
105 if (mp->m_flag&S_END)
111 while (spp < &symhash[NHASH])
116 sp->s_sp = symhash[h];
118 if (sp->s_flag&S_END)
126 /*)Function area * alookup(id)
128 * char * id area name string
130 * The function alookup() searches the area list for a
131 * match with id. If the area is defined then a pointer
132 * to this area is returned else a NULL is returned.
135 * area * ap pointer to area structure
138 * area * areap pointer to an area structure
141 * int symeq() assym.c
150 register struct area *ap;
154 if (symeq(id, ap->a_id)) {
162 /*)Function mne * mlookup(id)
164 * char * id mnemonic/directive name string
166 * The function mlookup() searches the mnemonic/directive
167 * hash tables for a match returning a pointer to the
168 * mne structure else it returns a NULL.
171 * mne * mp pointer to mne structure
172 * int h calculated hash value
175 * mne * mnehash[] array of pointers to NHASH
176 * linked mnemonic/directive lists
188 register struct mne *mp;
194 if (as_strcmpi(id, mp->m_id) == 0) /* JLH: case insensitive */
201 /*)Function sym * lookup(id)
203 * char * id symbol name string
205 * The function lookup() searches the symbol hash tables for
206 * a symbol name match returning a pointer to the sym structure.
207 * If the symbol is not found then a sym structure is created,
208 * initialized, and linked to the appropriate hash table.
209 * A pointer to this new sym structure is returned.
212 * int h computed hash value
213 * sym * sp pointer to a sym structure
216 * sym * symhash[] array of pointers to NHASH
217 * linked symbol lists
221 * VOID * new() assym.c
222 * int symeq() assym.c
225 * If the function new() fails to allocate space
226 * for the new sym structure the assembly terminates.
232 register struct sym *sp;
238 if (symeq(id, sp->s_id))
242 sp = (struct sym *) new (sizeof(struct sym));
243 sp->s_sp = symhash[h];
246 sp->s_id = strsto(id);
255 /*)Function VOID symglob()
257 * The function symglob() will mark all symbols of
258 * type S_NEW as global. Called at the beginning of pass 1
259 * if the assembly option -g was specified.
262 * sym * sp pointer to a sym structure
266 * sym * symhash[] array of pointers to NHASH
267 * linked symbol lists
273 * Symbol types changed.
279 register struct sym *sp;
282 for (i=0; i<NHASH; ++i) {
285 if (sp->s_type == S_NEW)
292 /*)Function VOID allglob()
294 * The function allglob() will mark all symbols of
295 * type S_USER as global. Called at the beginning of pass 1
296 * if the assembly option -a was specified.
299 * sym * sp pointer to a sym structure
303 * sym * symhash[] array of pointers to NHASH
304 * linked symbol lists
310 * Symbol types changed.
316 register struct sym *sp;
319 for (i=0; i<NHASH; ++i) {
322 if (sp != &dot && sp->s_type == S_USER)
329 /*)Function int symeq(p1, p2)
331 * char * p1 name string
332 * char * p2 name string
334 * The function symeq() compares the two name strings for a match.
335 * The return value is 1 for a match and 0 for no match.
341 * char ccase[] an array of characters which
342 * perform the case translation function
353 symeq(char *p1, char *p2)
356 return (strcmp( p1, p2 ) == 0);
358 return (as_strcmpi( p1, p2 ) == 0);
362 /*)Function int hash(p)
364 * char * p pointer to string to hash
366 * The function hash() computes a hash code using the sum
367 * of all characters mod table size algorithm.
370 * int h accumulated character sum
374 * char ccase[] an array of characters which
375 * perform the case translation function
391 /* JLH: case insensitive hash: Doesn't much affect
392 * hashing, and allows same function for mnemonics and symbols
394 h += ccase[(int)*p++];
399 /*)Function char * strsto(str)
401 * char * str pointer to string to save
403 * Allocate space for "str", copy str into new space.
404 * Return a pointer to the allocated string.
406 * This function based on code by
408 * jhartman at compuserve dot com
411 * int l string length + 1
412 * int bytes bytes remaining in buffer area
413 * char * p pointer to head of copied string
414 * char * pnext next location in buffer area
420 * VOID * new() assym.c
421 * char * strncpy() c_library
424 * Space allocated for string, string copied
425 * to space. Out of Space terminates assembler.
429 * To avoid wasting memory headers on small allocations, we
430 * allocate a big chunk and parcel it out as required.
431 * These static variables remember our hunk
435 static char * pnext = NULL;
436 static int bytes = 0;
445 * What we need, including a null.
451 * No space. Allocate a new hunk.
452 * We lose the pointer to any old hunk.
453 * We don't care, as the names are never deleted.
455 pnext = (char *) new (STR_SPC);
460 * Copy the name and terminating null.
471 /*)Function VOID * new(n)
473 * unsigned int n allocation size in bytes
475 * The function new() allocates n bytes of space and returns
476 * a pointer to this memory. If no space is available the
477 * assembly is terminated.
480 * VOID * p a general pointer
486 * VOID asexit() asmain.c
487 * int fprintf() c_library
488 * VOID * malloc() c_library
491 * Memory is allocated, if allocation fails
492 * the assembly is terminated.
500 if ((p = (VOID *) malloc(n)) == NULL) {
501 fprintf(stderr, "Out of space!\n");