Understanding the Synergy symbol table API
The Synergy symbol table API provides runtime maintenance of sets of names, along with ancillary information associated with those names. These names are simply text strings of up to 255 characters. The ancillary information associated with each name can be up to 100 characters.
Each entry within a symbol table has three components: a name, an access code, and user-defined data. Each entry is added to two lists: an access list (see Access list) and a search list (see Search list). As entries are added to a symbol table, memory is expanded as required. Deleting an item from a symbol table reclaims the memory associated with that item immediately.
Requirements
The file DBLDIR:namspc.def defines the macros and constants required by the symbol table API. You must include this file in your program using the .INCLUDE compiler directive.
All programs that use the symbol table API must be built using the compiler options -T (which trims trailing null arguments from XCALLs and function references) and -X (which automatically declares all undefined function references as external ^VAL functions).
Access list
The access list is a user-configurable list. The access code for an entry is that entry’s position within the access list. An entry is initially added at the end of the access list but can subsequently be moved anywhere within the list using %NSPC_MOVE.
Search list
The search list maintains an alphabetical order of the entries by name. This allows for high-speed lookups of entry names. This list cannot be reordered by the user.
Sample program
The following example is two functions and a subroutine that the user must call. One reads an .ini file and populates the symbol table, and the other does a search to see if a particular entry is there.
;======================================================================= ; Module: prcini.dbl ; ; Description: Process an .INI file ;======================================================================= function prcini_file ,^val ,reentrant ; Description: Read an .ini file. Returns ID of the loaded symbol table. a_file ,a ; Notes: This routine parses an .ini file and stores the initialization ; settings into a symbol table for future retrieval. .include "DBLDIR:namspc.def" .define MAXITM ,10 ;The maximum parse tokens we'll need .define MAXSECLEN ,64 ;Maximum length of a section identifier .define LINLEN ,100 ;Line size stack record chn ,i4 ;Input processing channel new_id ,i4 ;New entry id nsid ,i4 ;The symbol table ID icnt ,i4 ;Loaded item count linsiz ,i4 ;Input line length ndx ,i4 ;Item index ipos ,[MAXITM]i4 ;Item positions ilen ,[MAXITM]i4 ;Item lengths ityp ,[MAXITM]i4 ;Item types pos ,i4 ;Same as the arrays for a given entry len ,i4 typ ,i4 ix ,i4 ;A scratch integer group ident ,a ;Item storage id1 ,[MAXSECLEN]a1 endgroup group line ,a ;Input line ln1 ,[LINLEN]a1 endgroup secnam ,a(MAXSECLEN) ;The saved section name tagnam ,a(MAXSECLEN) ;The current tag name proc clear nsid, chn ;Init fields chn = 0 open(chn,i,a_file) [err=nofile] ;Open the .ini file repeat ;Skip to the first section begin call nextline if (linsiz .eq. 0) goto done if (id1 .eq. '[') exitloop end nsid = %nspc_open(D_NSPC_CASE,LINLEN,,MAXSECLEN*2) repeat begin call nextitem ;Get the section's name if ((ndx.gt.icnt) .or. (typ .ne. I_IDENT)) nextloop secnam = ident upcase secnam repeat begin call nextline ;Get next nonblank line if (linsiz .eq. 0) goto done if (id1 .eq. '[') ;Process another section exitloop tagnam = ident ;Get the tag name upcase tagnam pos = %instr(1,line,'=') + 1 new_id = %nspc_add(nsid,%atrim(secnam)+ "!" + %atrim(tagnam), line(pos,linsiz)) end end done, close chn ;Close the channel and return freturn nsid ; with success flagged nofile, freturn 0 ;Return with error flagged ; Get next nonblank line. If at EOF, linsiz will be zero. nextline, repeat begin reads(chn,line,eof) ;Get the next line if ((%rdlen .eq. 0) .or. (%atrim(line) .eq. " ")) nextloop ;Ignore empty lines linsiz = %trim(line) xcall s_parse(line(1:linsiz), 1, MAXITM, ipos, ilen, ityp, icnt, ndx) clear ndx ;Get the first item call nextitem if ((ndx .le. icnt) .and. (id1 .ne. ';')) ;Exit if not an empty line return end eof, clear linsiz ;Signal EOF return ; Get the next parsed item on the line nextitem, len = ilen[ndx += 1] ;Move to the next item pos = ipos[ndx] using (typ = ityp[ndx]) select (I_SPACE), goto nextitem ;Ignore spaces (I_ANUM,I_IDENT), begin ident = line(pos:len) ;Get case-sensitive identifier typ = I_IDENT ;Map ANUM to IDENT end (I_SPECIAL), id1 = ln1(pos) ;Get the special character (), clear id1 endusing return endfunction subroutine prcini_close ; Close the symbol table a_nsid ,n ;ID of .ini file's symbol table proc xcall nspc_close(a_nsid) xreturn endsubroutine function prcini_find ,^val ,reentrant ; Find an .ini file entry a_nsid ,n ;ID of .ini file's symbol table a_section ,a ;The section name a_entry ,a ;The entry tag a_result ,a ;Returned found entry ; Return Value: TRUE if the entry was found record result ,i4 section ,a(MAXSECLEN) entry_tag ,a(MAXSECLEN) proc clear section, entry_tag if (^passed(a_section) .and. a_section) begin section = a_section upcase section end if (^passed(a_entry) .and. a_entry) entry_tag = a_entry upcase entry_tag result = %nspc_find(a_nsid,%atrim(section)+"!"+%atrim(entry_tag), a_result) freturn(result) endfunction