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
