Using Config from Compiled SuperBASIC

It is often desirable or necessary to configure certain working parameters within a program. The Qjump Config "standard configuration system" is a good way of achieving this. The documentation and a program to configure programs containing Config level 1 configuration blocks may be found in the QUANTA library (disk SP0 the "Tebby Files"). A utility written by O. Fink, to include Config blocks in compiled SuperBASIC programs may be found on SP4. The method proposed here though, takes a different approach and is perhaps more appropriate in small programs.

A Config block consists of data and pointers (see below). The only problem is getting it in a suitable form into your program.

You can put anything into a SuperBASIC literal string so long as you don't violate the rules of the interpreter. Unfortunately, in the following implementation we do actually require the interpreter to produce two SuperBASIC lines that might look like this:

11 Config$="<<QCFX>>01##MYPROG##1.01..etc.. ##Edit file name####flp1_    "
13 Config$=Config$(61 to 60+CODE(Config$(60)))

Obviously the above is gobbeldygook to you and me, but as long as the configurator program understands it, so long as SuperBASIC doesn't care, and so long as it does the job, it will do.

Below follows a no-frills, compacted program in SuperBASIC (although it may not look like it!) that will produce the necessary Config block to your requirements. It takes care of avoiding awkward values (see Limitations below) and leaves you with nothing else to do but MERGE its output into your application and compile.

MkConfig

rem                 MakeConfig_bas ©PWITTE April 24th 1995
rem             Make a simple config block of type Qjump level 01
rem              for inclusion in a compiled SuperBASIC program
:
rem The following is the data that is produced:
rem       dc.b '<<QCFX>>01'                     ;Config header
rem       dc.w pl%,progname$                    ;Name of program
rem       dc.w vl%,version$                     ;Program version
rem       dc.b 0,key$                           ;Selection key for this item
rem       dc.w string-*                         ;Relative offset to item
rem       dc.w 0                                ;Ptr to pre- and post
rem       dc.w 0                                ; processing routines
rem       dc.w description-*                    ;Point to description
rem       dc.w attr-*                           ;Point to attributes
rem       dc.w -1                               ;End marker
rem attribute                                   ;Only one attribute here:
rem       dc.w attr%                            ; if 0 strip trailing spaces
rem description
rem       dc.w dl%,description$
rem string
rem       dc.w max%                             ;Max allowable length (incl lf)
rem       dc.w sl%,dstring$ + spare room        ; plus room up to max length
:
estrg$='Avoid string lengths of 10,34 and above 64'
zw$=chr$(0)&chr$(0):e$=chr$(255)&chr$(255)     :rem Word constants: 0,-1
n$='ram1_cfg_bas':cls:input'Output to (eg '&n$&')'!fnm$:if fnm$='':fnm$=n$
print \estrg$\'Enter:'                         :rem Get user settings
progname$=GetStrg$('the name of your program, eg Myprog')
version$=GetStrg$('version number, eg V1.04')
description$=GetStrg$('description of item to configure')
dstring$=GetStrg$('the default item string')
rep loop
 input'max allowable length of item string'!max%
 if max%<len(dstring$)-1:max%=len(dstring$)-1:print'Adjusted to'!max%
 if max%<>10 and max%<>34 and max%<65:exit loop
 print estrg$
end rep loop
print\'Press the selection key for this item ';:k%=code(inkey$(-1))
if k%>96 and k%<123:k%=k%-32:end if :key$=chr$(k%):print key$
print'Are trailing spaces to be stripped? <Y/n> ';:at$=inkey$(-1)
if at$ instr 'y'&chr$(10):attr%=0:print'Y':else :attr%=1:print'N'
oa%=4 : od%=8 : os%=14+len(description$)       :rem Calculate offsets
line$='11 Config$="<<QCFX>>01'                 :rem Build config block string:
line$=line$&progname$&version$                 :rem  as shown in
line$=line$&chr$(0)&key$                       :rem  assembler above
line$=line$&Int$(os%+2*(os%=34))               :rem Work around awkward value
line$=line$&zw$&zw$&Int$(od%)&Int$(oa%)&e$
line$=line$&Int$(attr%)&description$
if os%=34:line$=line$&zw$                      :rem Workaround filler bytes
line$=line$&Int$(max%):ip%=len(line$)-10       :rem Position of config item
line$=line$&dstring$                           :rem The default string
line$=line$&fill$(" ",max%-len(dstring$)+2)    :rem Room for max string + lf
line$=line$&'"'                                :rem End of SuperBASIC string
open_new#3;fnm$:print#3;line$                  :rem Write config block
print#3;'13 Config$=Config$(';ip%+1!'to'!ip%;'+code(Config$(';ip%;')))'
close                                          :rem Line 13 is to find the
:                                              :rem  string within the program
def fn  GetStrg$(tx$)
loc l%,s$,loop
rep loop
 input (tx$)!s$:l%=len(s$)
 if l%<>34 and l%<>10 and l%<65:exit loop      :rem Mustn't have quotes &
 print estrg$                                  :rem  linefeeds in a SB string!
end rep loop
ret Int$(l%)&s$&fill$(' ',l% mod 2)            :rem Convert to internal format
end def                                        :rem  padding odd lengthed strgs
:                                              :rem Integer to internal format
def fn  Int$(i%):ret chr$(i% div 256)&chr$(i% mod 256):end def
:

Top of Code

If you wish to test-configure the string in uncompiled BASIC make sure the string <<QCFX>> starts at an even character position. Counting starts at zero.

Limitations:

  1. SuperBASIC interpreter (all): No quotes or line feeds (chr's 34 and 10) must be used, nor anything that computes to those values, eg line lengths or offsets
  2. Config V1.04: Descriptions must be less than 64 chr's/line. (No sweat, see no.1)
  3. Qlib V3.35: Literal strings are truncated (without warning!) to 512 characters
OK