ChipMaster's bwBASIC This also includes history going back to v2.10. *WARN* some binary files might have been corrupted by CRLF.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bwb_var.c 73 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
v2.20pl2 Patch level 2 release by Jon B. Volkoff, 11 October 1997 LIST OF PATCHES TO 2.20: bwb_cmd.c Fixed calling stack level logic in RETURN statement to prevent erroneous "RETURN without GOSUB" messages. bwb_cnd.c bwb_stc.c Changed continuation condition for WHILE, ELSEIF, and LOOP UNTIL to be != FALSE, not == TRUE. More in line with common commercial BASIC implementations. bwb_mth.c Fixed initialization in VAL function so that old results are not later returned as values. bwb_var.c Added parenthesis level checking to dim_getparams. Using multi-level expressions as array subscripts was causing the program to bomb. bwx_iqc.c bwx_tty.c bwb_mes.h Added second copyright notice. bwb_dio.c bwb_str.c Added support for strings longer than 255 characters. bwb_prn.c Disabled tab expansion and print width checks when not printing to a file. bwb_inp.c Fixed LINE INPUT file reads to accommodate strings of length MAXSTRINGSIZE. bwx_ncu.h bwx_ncu.c New files. Code for UNIX ncurses interface, compliments of L.C. Benschop, Eindhoven, The Netherlands. Makefile.ncu New files. Sample makefile for ncurses implementation. bwbasic.h Revised defines for MININTSIZE and MAXINTSIZE from 16-bit to 32-bit limits. Revised define for MAXSTRINGSIZE from 255 to 5000 characters. Changed string length from unsigned char to unsigned int to support strings longer than 255 characters. Added support for new ncurses package. Revised VERSION define to reflect above changes. To implement these patches simply replace the old versions of the above source files with the new ones and remake bwbasic.
3 years ago
v2.20pl2 Patch level 2 release by Jon B. Volkoff, 11 October 1997 LIST OF PATCHES TO 2.20: bwb_cmd.c Fixed calling stack level logic in RETURN statement to prevent erroneous "RETURN without GOSUB" messages. bwb_cnd.c bwb_stc.c Changed continuation condition for WHILE, ELSEIF, and LOOP UNTIL to be != FALSE, not == TRUE. More in line with common commercial BASIC implementations. bwb_mth.c Fixed initialization in VAL function so that old results are not later returned as values. bwb_var.c Added parenthesis level checking to dim_getparams. Using multi-level expressions as array subscripts was causing the program to bomb. bwx_iqc.c bwx_tty.c bwb_mes.h Added second copyright notice. bwb_dio.c bwb_str.c Added support for strings longer than 255 characters. bwb_prn.c Disabled tab expansion and print width checks when not printing to a file. bwb_inp.c Fixed LINE INPUT file reads to accommodate strings of length MAXSTRINGSIZE. bwx_ncu.h bwx_ncu.c New files. Code for UNIX ncurses interface, compliments of L.C. Benschop, Eindhoven, The Netherlands. Makefile.ncu New files. Sample makefile for ncurses implementation. bwbasic.h Revised defines for MININTSIZE and MAXINTSIZE from 16-bit to 32-bit limits. Revised define for MAXSTRINGSIZE from 255 to 5000 characters. Changed string length from unsigned char to unsigned int to support strings longer than 255 characters. Added support for new ncurses package. Revised VERSION define to reflect above changes. To implement these patches simply replace the old versions of the above source files with the new ones and remake bwbasic.
3 years ago
v2.20pl2 Patch level 2 release by Jon B. Volkoff, 11 October 1997 LIST OF PATCHES TO 2.20: bwb_cmd.c Fixed calling stack level logic in RETURN statement to prevent erroneous "RETURN without GOSUB" messages. bwb_cnd.c bwb_stc.c Changed continuation condition for WHILE, ELSEIF, and LOOP UNTIL to be != FALSE, not == TRUE. More in line with common commercial BASIC implementations. bwb_mth.c Fixed initialization in VAL function so that old results are not later returned as values. bwb_var.c Added parenthesis level checking to dim_getparams. Using multi-level expressions as array subscripts was causing the program to bomb. bwx_iqc.c bwx_tty.c bwb_mes.h Added second copyright notice. bwb_dio.c bwb_str.c Added support for strings longer than 255 characters. bwb_prn.c Disabled tab expansion and print width checks when not printing to a file. bwb_inp.c Fixed LINE INPUT file reads to accommodate strings of length MAXSTRINGSIZE. bwx_ncu.h bwx_ncu.c New files. Code for UNIX ncurses interface, compliments of L.C. Benschop, Eindhoven, The Netherlands. Makefile.ncu New files. Sample makefile for ncurses implementation. bwbasic.h Revised defines for MININTSIZE and MAXINTSIZE from 16-bit to 32-bit limits. Revised define for MAXSTRINGSIZE from 255 to 5000 characters. Changed string length from unsigned char to unsigned int to support strings longer than 255 characters. Added support for new ncurses package. Revised VERSION define to reflect above changes. To implement these patches simply replace the old versions of the above source files with the new ones and remake bwbasic.
3 years ago
3 years ago
v2.20pl2 Patch level 2 release by Jon B. Volkoff, 11 October 1997 LIST OF PATCHES TO 2.20: bwb_cmd.c Fixed calling stack level logic in RETURN statement to prevent erroneous "RETURN without GOSUB" messages. bwb_cnd.c bwb_stc.c Changed continuation condition for WHILE, ELSEIF, and LOOP UNTIL to be != FALSE, not == TRUE. More in line with common commercial BASIC implementations. bwb_mth.c Fixed initialization in VAL function so that old results are not later returned as values. bwb_var.c Added parenthesis level checking to dim_getparams. Using multi-level expressions as array subscripts was causing the program to bomb. bwx_iqc.c bwx_tty.c bwb_mes.h Added second copyright notice. bwb_dio.c bwb_str.c Added support for strings longer than 255 characters. bwb_prn.c Disabled tab expansion and print width checks when not printing to a file. bwb_inp.c Fixed LINE INPUT file reads to accommodate strings of length MAXSTRINGSIZE. bwx_ncu.h bwx_ncu.c New files. Code for UNIX ncurses interface, compliments of L.C. Benschop, Eindhoven, The Netherlands. Makefile.ncu New files. Sample makefile for ncurses implementation. bwbasic.h Revised defines for MININTSIZE and MAXINTSIZE from 16-bit to 32-bit limits. Revised define for MAXSTRINGSIZE from 255 to 5000 characters. Changed string length from unsigned char to unsigned int to support strings longer than 255 characters. Added support for new ncurses package. Revised VERSION define to reflect above changes. To implement these patches simply replace the old versions of the above source files with the new ones and remake bwbasic.
3 years ago
v2.20pl2 Patch level 2 release by Jon B. Volkoff, 11 October 1997 LIST OF PATCHES TO 2.20: bwb_cmd.c Fixed calling stack level logic in RETURN statement to prevent erroneous "RETURN without GOSUB" messages. bwb_cnd.c bwb_stc.c Changed continuation condition for WHILE, ELSEIF, and LOOP UNTIL to be != FALSE, not == TRUE. More in line with common commercial BASIC implementations. bwb_mth.c Fixed initialization in VAL function so that old results are not later returned as values. bwb_var.c Added parenthesis level checking to dim_getparams. Using multi-level expressions as array subscripts was causing the program to bomb. bwx_iqc.c bwx_tty.c bwb_mes.h Added second copyright notice. bwb_dio.c bwb_str.c Added support for strings longer than 255 characters. bwb_prn.c Disabled tab expansion and print width checks when not printing to a file. bwb_inp.c Fixed LINE INPUT file reads to accommodate strings of length MAXSTRINGSIZE. bwx_ncu.h bwx_ncu.c New files. Code for UNIX ncurses interface, compliments of L.C. Benschop, Eindhoven, The Netherlands. Makefile.ncu New files. Sample makefile for ncurses implementation. bwbasic.h Revised defines for MININTSIZE and MAXINTSIZE from 16-bit to 32-bit limits. Revised define for MAXSTRINGSIZE from 255 to 5000 characters. Changed string length from unsigned char to unsigned int to support strings longer than 255 characters. Added support for new ncurses package. Revised VERSION define to reflect above changes. To implement these patches simply replace the old versions of the above source files with the new ones and remake bwbasic.
3 years ago
v2.20pl2 Patch level 2 release by Jon B. Volkoff, 11 October 1997 LIST OF PATCHES TO 2.20: bwb_cmd.c Fixed calling stack level logic in RETURN statement to prevent erroneous "RETURN without GOSUB" messages. bwb_cnd.c bwb_stc.c Changed continuation condition for WHILE, ELSEIF, and LOOP UNTIL to be != FALSE, not == TRUE. More in line with common commercial BASIC implementations. bwb_mth.c Fixed initialization in VAL function so that old results are not later returned as values. bwb_var.c Added parenthesis level checking to dim_getparams. Using multi-level expressions as array subscripts was causing the program to bomb. bwx_iqc.c bwx_tty.c bwb_mes.h Added second copyright notice. bwb_dio.c bwb_str.c Added support for strings longer than 255 characters. bwb_prn.c Disabled tab expansion and print width checks when not printing to a file. bwb_inp.c Fixed LINE INPUT file reads to accommodate strings of length MAXSTRINGSIZE. bwx_ncu.h bwx_ncu.c New files. Code for UNIX ncurses interface, compliments of L.C. Benschop, Eindhoven, The Netherlands. Makefile.ncu New files. Sample makefile for ncurses implementation. bwbasic.h Revised defines for MININTSIZE and MAXINTSIZE from 16-bit to 32-bit limits. Revised define for MAXSTRINGSIZE from 255 to 5000 characters. Changed string length from unsigned char to unsigned int to support strings longer than 255 characters. Added support for new ncurses package. Revised VERSION define to reflect above changes. To implement these patches simply replace the old versions of the above source files with the new ones and remake bwbasic.
3 years ago
v2.20pl2 Patch level 2 release by Jon B. Volkoff, 11 October 1997 LIST OF PATCHES TO 2.20: bwb_cmd.c Fixed calling stack level logic in RETURN statement to prevent erroneous "RETURN without GOSUB" messages. bwb_cnd.c bwb_stc.c Changed continuation condition for WHILE, ELSEIF, and LOOP UNTIL to be != FALSE, not == TRUE. More in line with common commercial BASIC implementations. bwb_mth.c Fixed initialization in VAL function so that old results are not later returned as values. bwb_var.c Added parenthesis level checking to dim_getparams. Using multi-level expressions as array subscripts was causing the program to bomb. bwx_iqc.c bwx_tty.c bwb_mes.h Added second copyright notice. bwb_dio.c bwb_str.c Added support for strings longer than 255 characters. bwb_prn.c Disabled tab expansion and print width checks when not printing to a file. bwb_inp.c Fixed LINE INPUT file reads to accommodate strings of length MAXSTRINGSIZE. bwx_ncu.h bwx_ncu.c New files. Code for UNIX ncurses interface, compliments of L.C. Benschop, Eindhoven, The Netherlands. Makefile.ncu New files. Sample makefile for ncurses implementation. bwbasic.h Revised defines for MININTSIZE and MAXINTSIZE from 16-bit to 32-bit limits. Revised define for MAXSTRINGSIZE from 255 to 5000 characters. Changed string length from unsigned char to unsigned int to support strings longer than 255 characters. Added support for new ncurses package. Revised VERSION define to reflect above changes. To implement these patches simply replace the old versions of the above source files with the new ones and remake bwbasic.
3 years ago
v2.20pl2 Patch level 2 release by Jon B. Volkoff, 11 October 1997 LIST OF PATCHES TO 2.20: bwb_cmd.c Fixed calling stack level logic in RETURN statement to prevent erroneous "RETURN without GOSUB" messages. bwb_cnd.c bwb_stc.c Changed continuation condition for WHILE, ELSEIF, and LOOP UNTIL to be != FALSE, not == TRUE. More in line with common commercial BASIC implementations. bwb_mth.c Fixed initialization in VAL function so that old results are not later returned as values. bwb_var.c Added parenthesis level checking to dim_getparams. Using multi-level expressions as array subscripts was causing the program to bomb. bwx_iqc.c bwx_tty.c bwb_mes.h Added second copyright notice. bwb_dio.c bwb_str.c Added support for strings longer than 255 characters. bwb_prn.c Disabled tab expansion and print width checks when not printing to a file. bwb_inp.c Fixed LINE INPUT file reads to accommodate strings of length MAXSTRINGSIZE. bwx_ncu.h bwx_ncu.c New files. Code for UNIX ncurses interface, compliments of L.C. Benschop, Eindhoven, The Netherlands. Makefile.ncu New files. Sample makefile for ncurses implementation. bwbasic.h Revised defines for MININTSIZE and MAXINTSIZE from 16-bit to 32-bit limits. Revised define for MAXSTRINGSIZE from 255 to 5000 characters. Changed string length from unsigned char to unsigned int to support strings longer than 255 characters. Added support for new ncurses package. Revised VERSION define to reflect above changes. To implement these patches simply replace the old versions of the above source files with the new ones and remake bwbasic.
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
v2.20pl2 Patch level 2 release by Jon B. Volkoff, 11 October 1997 LIST OF PATCHES TO 2.20: bwb_cmd.c Fixed calling stack level logic in RETURN statement to prevent erroneous "RETURN without GOSUB" messages. bwb_cnd.c bwb_stc.c Changed continuation condition for WHILE, ELSEIF, and LOOP UNTIL to be != FALSE, not == TRUE. More in line with common commercial BASIC implementations. bwb_mth.c Fixed initialization in VAL function so that old results are not later returned as values. bwb_var.c Added parenthesis level checking to dim_getparams. Using multi-level expressions as array subscripts was causing the program to bomb. bwx_iqc.c bwx_tty.c bwb_mes.h Added second copyright notice. bwb_dio.c bwb_str.c Added support for strings longer than 255 characters. bwb_prn.c Disabled tab expansion and print width checks when not printing to a file. bwb_inp.c Fixed LINE INPUT file reads to accommodate strings of length MAXSTRINGSIZE. bwx_ncu.h bwx_ncu.c New files. Code for UNIX ncurses interface, compliments of L.C. Benschop, Eindhoven, The Netherlands. Makefile.ncu New files. Sample makefile for ncurses implementation. bwbasic.h Revised defines for MININTSIZE and MAXINTSIZE from 16-bit to 32-bit limits. Revised define for MAXSTRINGSIZE from 255 to 5000 characters. Changed string length from unsigned char to unsigned int to support strings longer than 255 characters. Added support for new ncurses package. Revised VERSION define to reflect above changes. To implement these patches simply replace the old versions of the above source files with the new ones and remake bwbasic.
3 years ago
v2.20pl2 Patch level 2 release by Jon B. Volkoff, 11 October 1997 LIST OF PATCHES TO 2.20: bwb_cmd.c Fixed calling stack level logic in RETURN statement to prevent erroneous "RETURN without GOSUB" messages. bwb_cnd.c bwb_stc.c Changed continuation condition for WHILE, ELSEIF, and LOOP UNTIL to be != FALSE, not == TRUE. More in line with common commercial BASIC implementations. bwb_mth.c Fixed initialization in VAL function so that old results are not later returned as values. bwb_var.c Added parenthesis level checking to dim_getparams. Using multi-level expressions as array subscripts was causing the program to bomb. bwx_iqc.c bwx_tty.c bwb_mes.h Added second copyright notice. bwb_dio.c bwb_str.c Added support for strings longer than 255 characters. bwb_prn.c Disabled tab expansion and print width checks when not printing to a file. bwb_inp.c Fixed LINE INPUT file reads to accommodate strings of length MAXSTRINGSIZE. bwx_ncu.h bwx_ncu.c New files. Code for UNIX ncurses interface, compliments of L.C. Benschop, Eindhoven, The Netherlands. Makefile.ncu New files. Sample makefile for ncurses implementation. bwbasic.h Revised defines for MININTSIZE and MAXINTSIZE from 16-bit to 32-bit limits. Revised define for MAXSTRINGSIZE from 255 to 5000 characters. Changed string length from unsigned char to unsigned int to support strings longer than 255 characters. Added support for new ncurses package. Revised VERSION define to reflect above changes. To implement these patches simply replace the old versions of the above source files with the new ones and remake bwbasic.
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222
  1. /***************************************************************
  2. bwb_var.c Variable-Handling Routines
  3. for Bywater BASIC Interpreter
  4. Copyright (c) 1993, Ted A. Campbell
  5. Bywater Software
  6. email: tcamp@delphi.com
  7. Copyright and Permissions Information:
  8. All U.S. and international rights are claimed by the author,
  9. Ted A. Campbell.
  10. This software is released under the terms of the GNU General
  11. Public License (GPL), which is distributed with this software
  12. in the file "COPYING". The GPL specifies the terms under
  13. which users may copy and use the software in this distribution.
  14. A separate license is available for commercial distribution,
  15. for information on which you should contact the author.
  16. ***************************************************************/
  17. /*---------------------------------------------------------------*/
  18. /* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */
  19. /* 11/1995 (eidetics@cerf.net). */
  20. /* */
  21. /* Those additionally marked with "DD" were at the suggestion of */
  22. /* Dale DePriest (daled@cadence.com). */
  23. /* */
  24. /* Version 3.00 by Howard Wulf, AF5NE */
  25. /* */
  26. /*---------------------------------------------------------------*/
  27. #include "bwbasic.h"
  28. static int dimmed = FALSE; /* has DIM been called? */
  29. static int first, last; /* first, last for DEFxxx commands */
  30. /* Prototypes for functions visible to this file only */
  31. static int
  32. dim_check(struct bwb_variable * v, int *pp);
  33. static int
  34. var_defx(struct bwb_line * l, int type);
  35. static int
  36. var_letseq(char *buffer, int *position, int *start, int *end);
  37. static size_t
  38. dim_unit(struct bwb_variable * v, int *pp);
  39. static struct bwb_variable *
  40. var_islocal(char *buffer);
  41. /***************************************************************
  42. FUNCTION: var_init()
  43. DESCRIPTION: This function initializes the internal
  44. linked list of variables.
  45. ***************************************************************/
  46. int
  47. var_init(int task)
  48. {
  49. bwx_DEBUG(__FUNCTION__);
  50. LOCALTASK var_start.next = &(LOCALTASK var_end);
  51. strcpy(LOCALTASK var_start.name, "<START>");
  52. strcpy(LOCALTASK var_end.name, "<END>");
  53. return TRUE;
  54. }
  55. /***************************************************************
  56. FUNCTION: bwb_common()
  57. DESCRIPTION: This C function implements the BASIC
  58. COMMON command.
  59. SYNTAX: COMMON variable [, variable...]
  60. ***************************************************************/
  61. struct bwb_line *
  62. bwb_COMMON(struct bwb_line * l)
  63. {
  64. bwx_DEBUG(__FUNCTION__);
  65. /* loop while arguments are available */
  66. while (TRUE)
  67. {
  68. struct bwb_variable *v;
  69. char tbuf[BasicStringLengthMax + 1];
  70. /* get variable name and find variable */
  71. bwb_getvarname(l->buffer, tbuf, &(l->position));
  72. if ((v = var_find(tbuf)) == NULL)
  73. {
  74. bwb_error(err_syntax);
  75. return bwb_zline(l);
  76. }
  77. v->common = TRUE; /* set common flag to true */
  78. /* check for comma */
  79. adv_ws(l->buffer, &(l->position));
  80. if (l->buffer[l->position] != ',')
  81. {
  82. /* no comma; leave */
  83. return bwb_zline(l);
  84. }
  85. ++(l->position);
  86. adv_ws(l->buffer, &(l->position));
  87. }
  88. return bwb_zline(l);
  89. }
  90. /***********************************************************
  91. FUNCTION: bwb_erase()
  92. DESCRIPTION: This C function implements the BASIC
  93. ERASE command.
  94. SYNTAX: ERASE variable[, variable]...
  95. ***********************************************************/
  96. struct bwb_line *
  97. bwb_ERASE(struct bwb_line * l)
  98. {
  99. register int loop;
  100. struct bwb_variable *v;
  101. struct bwb_variable *p; /* previous variable in linked list */
  102. char tbuf[BasicStringLengthMax + 1];
  103. bstring *sp; /* JBV */
  104. register int n; /* JBV */
  105. bwx_DEBUG(__FUNCTION__);
  106. /* loop while arguments are available */
  107. loop = TRUE;
  108. while (loop == TRUE)
  109. {
  110. /* get variable name and find variable */
  111. bwb_getvarname(l->buffer, tbuf, &(l->position));
  112. if ((v = var_find(tbuf)) == NULL)
  113. {
  114. bwb_error(err_syntax);
  115. return bwb_zline(l);
  116. }
  117. /* be sure the variable is dimensioned */
  118. if ((v->dimensions < 1) || (v->array_sizes[0] < 1))
  119. {
  120. bwb_error(err_dimnotarray);
  121. return bwb_zline(l);
  122. }
  123. /* find previous variable in chain */
  124. for (p = &CURTASK var_start; p->next != v; p = p->next)
  125. {
  126. ;
  127. }
  128. /* reassign linkage */
  129. p->next = v->next;
  130. /* deallocate memory */
  131. /* Revised to FREE pass-thru calls by JBV */
  132. FREE(v->array_sizes, "bwb_erase");
  133. v->array_sizes = NULL; /* JBV */
  134. FREE(v->array_pos, "bwb_erase");
  135. v->array_pos = NULL; /* JBV */
  136. if (v->type == NUMBER)
  137. {
  138. /* Revised to FREE pass-thru call by JBV */
  139. FREE(v->memnum, "bwb_erase");
  140. v->memnum = NULL; /* JBV */
  141. }
  142. else
  143. {
  144. /* Following section added by JBV */
  145. sp = v->memstr;
  146. for (n = 0; n < (int) v->array_units; ++n)
  147. {
  148. if (sp[n].sbuffer != NULL)
  149. {
  150. /* Revised to FREE pass-thru call by
  151. * JBV */
  152. FREE(sp[n].sbuffer, "bwb_erase");
  153. sp[n].sbuffer = NULL;
  154. }
  155. sp[n].rab = FALSE;
  156. sp[n].length = 0;
  157. }
  158. /* Revised to FREE pass-thru call by JBV */
  159. FREE(v->memstr, "bwb_erase");
  160. v->memstr = NULL; /* JBV */
  161. }
  162. /* Revised to FREE pass-thru call by JBV */
  163. FREE(v, "bwb_erase");
  164. v = NULL; /* JBV */
  165. /* check for comma */
  166. adv_ws(l->buffer, &(l->position));
  167. if (l->buffer[l->position] != ',')
  168. {
  169. return bwb_zline(l); /* no comma; leave */
  170. }
  171. ++(l->position);
  172. adv_ws(l->buffer, &(l->position));
  173. }
  174. return bwb_zline(l);
  175. }
  176. /***********************************************************
  177. FUNCTION: bwb_swap()
  178. DESCRIPTION: This C function implements the BASIC
  179. SWAP command.
  180. SYNTAX: SWAP variable, variable
  181. ***********************************************************/
  182. struct bwb_line *
  183. bwb_SWAP(struct bwb_line * l)
  184. {
  185. struct bwb_variable tmp;/* temp holder */
  186. struct bwb_variable *lhs, *rhs; /* left and right- hand side of swap
  187. * statement */
  188. char tbuf[BasicStringLengthMax + 1];
  189. bwx_DEBUG(__FUNCTION__);
  190. /* get left variable name and find variable */
  191. bwb_getvarname(l->buffer, tbuf, &(l->position));
  192. if ((lhs = var_find(tbuf)) == NULL)
  193. {
  194. bwb_error(err_syntax);
  195. return bwb_zline(l);
  196. }
  197. /* check for comma */
  198. adv_ws(l->buffer, &(l->position));
  199. if (l->buffer[l->position] != ',')
  200. {
  201. bwb_error(err_syntax);
  202. return bwb_zline(l);
  203. }
  204. ++(l->position);
  205. adv_ws(l->buffer, &(l->position));
  206. /* get right variable name */
  207. bwb_getvarname(l->buffer, tbuf, &(l->position));
  208. if ((rhs = var_find(tbuf)) == NULL)
  209. {
  210. bwb_error(err_syntax);
  211. return bwb_zline(l);
  212. }
  213. /* check to be sure that both variables are of the same type */
  214. if (rhs->type != lhs->type)
  215. {
  216. bwb_error(err_mismatch);
  217. return bwb_zline(l);
  218. }
  219. /* copy lhs to temp, rhs to lhs, then temp to rhs */
  220. tmp.memnum = NULL; /* AF5NE */
  221. tmp.memstr = NULL; /* AF5NE */
  222. if (lhs->type == NUMBER)
  223. {
  224. tmp.memnum = lhs->memnum;
  225. }
  226. else
  227. {
  228. tmp.memstr = lhs->memstr;
  229. }
  230. tmp.array_sizes = lhs->array_sizes;
  231. tmp.array_units = lhs->array_units;
  232. tmp.array_pos = lhs->array_pos;
  233. tmp.dimensions = lhs->dimensions;
  234. lhs->memnum = NULL; /* AF5NE */
  235. lhs->memstr = NULL; /* AF5NE */
  236. if (lhs->type == NUMBER)
  237. {
  238. lhs->memnum = rhs->memnum;
  239. }
  240. else
  241. {
  242. lhs->memstr = rhs->memstr;
  243. }
  244. lhs->array_sizes = rhs->array_sizes;
  245. lhs->array_units = rhs->array_units;
  246. lhs->array_pos = rhs->array_pos;
  247. lhs->dimensions = rhs->dimensions;
  248. rhs->memnum = NULL; /* AF5NE */
  249. rhs->memstr = NULL; /* AF5NE */
  250. if (lhs->type == NUMBER)
  251. {
  252. rhs->memnum = tmp.memnum;
  253. }
  254. else
  255. {
  256. rhs->memstr = tmp.memstr;
  257. }
  258. rhs->array_sizes = tmp.array_sizes;
  259. rhs->array_units = tmp.array_units;
  260. rhs->array_pos = tmp.array_pos;
  261. rhs->dimensions = tmp.dimensions;
  262. /* return */
  263. return bwb_zline(l);
  264. }
  265. /***********************************************************
  266. FUNCTION: bwb_clear()
  267. DESCRIPTION: This C function implements the BASIC
  268. CLEAR command.
  269. SYNTAX: CLEAR
  270. ***********************************************************/
  271. void
  272. var_CLEAR(void)
  273. {
  274. struct bwb_variable *v;
  275. register int n;
  276. bstring *sp;
  277. BasicNumberType *np;
  278. bwx_DEBUG(__FUNCTION__);
  279. for (v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next)
  280. {
  281. if (v->preset != TRUE)
  282. {
  283. switch (v->type)
  284. {
  285. case NUMBER:
  286. np = v->memnum;
  287. for (n = 0; n < (int) v->array_units; ++n)
  288. {
  289. np[n] = (BasicNumberType) 0.0;
  290. }
  291. break;
  292. case STRING:
  293. sp = v->memstr;
  294. for (n = 0; n < (int) v->array_units; ++n)
  295. {
  296. if (sp[n].sbuffer != NULL)
  297. {
  298. /* Revised to FREE pass-thru
  299. * call by JBV */
  300. FREE(sp[n].sbuffer, "bwb_clear");
  301. sp[n].sbuffer = NULL;
  302. }
  303. sp[n].rab = FALSE;
  304. sp[n].length = 0;
  305. }
  306. break;
  307. }
  308. }
  309. }
  310. dimmed = FALSE;
  311. }
  312. struct bwb_line *
  313. bwb_CLEAR(struct bwb_line * l)
  314. {
  315. var_CLEAR();
  316. /* ignoare all parameters */
  317. adv_eos(l->buffer, &(l->position));
  318. return bwb_zline(l);
  319. }
  320. /***********************************************************
  321. FUNCTION: var_delcvars()
  322. DESCRIPTION: This function deletes all variables
  323. in memory except those previously marked
  324. as common.
  325. ***********************************************************/
  326. int
  327. var_delcvars(void)
  328. {
  329. struct bwb_variable *v;
  330. struct bwb_variable *p; /* previous variable */
  331. bstring *sp; /* JBV */
  332. register int n; /* JBV */
  333. bwx_DEBUG(__FUNCTION__);
  334. for (v = CURTASK var_start.next; (v != NULL) && (v != &CURTASK var_end); v = v->next)
  335. {
  336. if ((v->preset != TRUE) && (v->common != TRUE))
  337. {
  338. /* if the variable is dimensioned, release allocated
  339. * memory */
  340. if (v->dimensions > 0)
  341. {
  342. /* deallocate memory */
  343. /* Revised to FREE pass-thru calls by JBV */
  344. FREE(v->array_sizes, "var_delcvars");
  345. v->array_sizes = NULL; /* JBV */
  346. FREE(v->array_pos, "var_delcvars");
  347. v->array_pos = NULL; /* JBV */
  348. if (v->type == NUMBER)
  349. {
  350. /* Revised to FREE pass-thru call by
  351. * JBV */
  352. FREE(v->memnum, "var_delcvars");
  353. v->memnum = NULL; /* JBV */
  354. }
  355. else
  356. {
  357. /* Following section added by JBV */
  358. sp = v->memstr;
  359. for (n = 0; n < (int) v->array_units; ++n)
  360. {
  361. if (sp[n].sbuffer != NULL)
  362. {
  363. /* Revised to FREE
  364. * pass-thru call by
  365. * JBV */
  366. FREE(sp[n].sbuffer, "var_delcvars");
  367. sp[n].sbuffer = NULL;
  368. }
  369. sp[n].rab = FALSE;
  370. sp[n].length = 0;
  371. }
  372. /* Revised to FREE pass-thru call by
  373. * JBV */
  374. FREE(v->memstr, "var_delcvars");
  375. v->memstr = NULL; /* JBV */
  376. }
  377. }
  378. /* find previous variable in chain */
  379. for (p = &CURTASK var_start; p->next != v; p = p->next)
  380. {
  381. ;
  382. }
  383. /* reassign linkage */
  384. p->next = v->next;
  385. /* deallocate the variable itself */
  386. /* Revised to FREE pass-thru call by JBV */
  387. FREE(v, "var_delcvars");
  388. /* v = NULL; *//* Variable 'v' is reassigned a value
  389. * before the old one has been used. */
  390. v = p;
  391. }
  392. }
  393. return TRUE;
  394. }
  395. /***********************************************************
  396. FUNCTION: bwb_mid()
  397. DESCRIPTION: This function implements the BASIC
  398. MID$ command.
  399. Same as MID$ function, except it will set
  400. the desired substring and not return its
  401. value. Added by JBV 10/95
  402. SYNTAX: MID$( string-variable$, start-position-in-string
  403. [, number-of-spaces ] ) = expression
  404. ***********************************************************/
  405. struct bwb_line *
  406. bwb_MID_(struct bwb_line * l)
  407. {
  408. char tbuf[BasicStringLengthMax + 1];
  409. char source_string[BasicStringLengthMax + 1];
  410. struct bwb_variable *v;
  411. int pos;
  412. bstring *d;
  413. int *pp;
  414. int n_params;
  415. int p;
  416. register int n;
  417. int startpos;
  418. int numchars;
  419. int endpos;
  420. int source_length;
  421. int target_length;
  422. int target_terminate;
  423. struct exp_ese *e;
  424. bwx_DEBUG(__FUNCTION__);
  425. /* Get past left parenthesis */
  426. adv_ws(l->buffer, &(l->position));
  427. ++(l->position);
  428. adv_ws(l->buffer, &(l->position));
  429. /* Get variable name and find variable */
  430. bwb_getvarname(l->buffer, tbuf, &(l->position));
  431. v = var_find(tbuf);
  432. if (v == NULL)
  433. {
  434. sprintf(bwb_ebuf, "in bwb_mid(): failed to find variable");
  435. bwb_error(bwb_ebuf);
  436. return bwb_zline(l);
  437. }
  438. if (v->type != STRING)
  439. {
  440. sprintf(bwb_ebuf, "in bwb_mid(): assignment must be to string variable");
  441. bwb_error(bwb_ebuf);
  442. return bwb_zline(l);
  443. }
  444. /* read subscripts */
  445. pos = 0;
  446. if ((v->dimensions == 1) && (v->array_sizes[0] == 1))
  447. {
  448. n_params = 1;
  449. pp = &p;
  450. pp[0] = dim_base;
  451. }
  452. else
  453. {
  454. dim_getparams(l->buffer, &(l->position), &n_params, &pp);
  455. }
  456. CURTASK exps[CURTASK expsc].pos_adv = pos;
  457. for (n = 0; n < v->dimensions; ++n)
  458. {
  459. v->array_pos[n] = pp[n];
  460. }
  461. /* get bstring pointer */
  462. d = var_findsval(v, pp);
  463. /* Get past next comma and white space */
  464. adv_ws(l->buffer, &(l->position));
  465. ++(l->position);
  466. adv_ws(l->buffer, &(l->position));
  467. /* Get starting position (expression) */
  468. adv_element(l->buffer, &(l->position), tbuf);
  469. pos = 0;
  470. e = bwb_exp(tbuf, FALSE, &pos);
  471. if (ERROR_PENDING)
  472. {
  473. return bwb_zline(l);
  474. }
  475. startpos = exp_getival(e);
  476. /* Get past next comma and white space (if they exist) */
  477. adv_ws(l->buffer, &(l->position));
  478. if (l->buffer[l->position] == ',')
  479. {
  480. target_terminate = 0;
  481. ++(l->position);
  482. adv_ws(l->buffer, &(l->position));
  483. adv_element(l->buffer, &(l->position), tbuf);
  484. pos = 0;
  485. e = bwb_exp(tbuf, FALSE, &pos);
  486. if (ERROR_PENDING)
  487. {
  488. return bwb_zline(l);
  489. }
  490. numchars = exp_getival(e);
  491. if (numchars == 0)
  492. {
  493. sprintf(bwb_ebuf, "in bwb_mid(): destination string no. of chars out of range");
  494. bwb_error(bwb_ebuf);
  495. return bwb_zline(l);
  496. }
  497. }
  498. else
  499. {
  500. target_terminate = 1;
  501. numchars = 0;
  502. }
  503. if (numchars < 0)
  504. {
  505. sprintf(bwb_ebuf, "in bwb_mid(): negative string length");
  506. bwb_error(bwb_ebuf);
  507. return bwb_zline(l);
  508. }
  509. /* Get past equal sign */
  510. adv_ws(l->buffer, &(l->position));
  511. if (l->buffer[l->position] == ')')
  512. {
  513. ++(l->position);
  514. adv_ws(l->buffer, &(l->position));
  515. }
  516. ++(l->position);
  517. adv_ws(l->buffer, &(l->position));
  518. /* Evaluate string expression */
  519. e = bwb_exp(l->buffer, FALSE, &(l->position));
  520. if (ERROR_PENDING)
  521. {
  522. return bwb_zline(l);
  523. }
  524. if (e->type != STRING)
  525. {
  526. sprintf(bwb_ebuf, "in bwb_mid(): assignment must be from string expression");
  527. bwb_error(bwb_ebuf);
  528. return bwb_zline(l);
  529. }
  530. /* Prepare to MID the string */
  531. str_btoc(source_string, exp_getsval(e));
  532. str_btoc(tbuf, d);
  533. target_length = strlen(tbuf);
  534. if (startpos > (target_length + 1))
  535. {
  536. sprintf(bwb_ebuf, "in bwb_mid(): non-contiguous string created");
  537. bwb_error(bwb_ebuf);
  538. return bwb_zline(l);
  539. }
  540. if (startpos < 1)
  541. {
  542. sprintf(bwb_ebuf, "in bwb_mid(): destination string start position out of range");
  543. bwb_error(bwb_ebuf);
  544. return bwb_zline(l);
  545. }
  546. source_length = strlen(source_string);
  547. if (numchars == 0)
  548. numchars = source_length;
  549. endpos = startpos + numchars - 1;
  550. /* MID the string */
  551. if (endpos < startpos)
  552. tbuf[startpos - 1] = '\0';
  553. else
  554. {
  555. int source_counter;
  556. source_counter = 0;
  557. for (n = startpos - 1; n < endpos; ++n)
  558. {
  559. if (source_counter < source_length)
  560. tbuf[n] = source_string[source_counter];
  561. else
  562. tbuf[n] = ' ';
  563. ++source_counter;
  564. }
  565. /* Terminate if indicated or characters were added */
  566. if ((endpos > target_length) || (target_terminate == 1))
  567. tbuf[endpos] = '\0';
  568. }
  569. str_ctob(d, tbuf);
  570. adv_eos(l->buffer, &(l->position));
  571. return bwb_zline(l);
  572. }
  573. /***********************************************************
  574. FUNCTION: bwb_ddbl()
  575. DESCRIPTION: This function implements the BASIC
  576. DEFDBL command.
  577. SYNTAX: DEFDBL letter[-letter](, letter[-letter])...
  578. ***********************************************************/
  579. struct bwb_line *
  580. bwb_DEFDBL(struct bwb_line * l)
  581. {
  582. bwx_DEBUG(__FUNCTION__);
  583. /* call generalized DEF handler with DOUBLE set */
  584. var_defx(l, NUMBER);
  585. return bwb_zline(l);
  586. }
  587. /***********************************************************
  588. FUNCTION: bwb_dint()
  589. DESCRIPTION: This function implements the BASIC
  590. DEFINT command.
  591. SYNTAX: DEFINT letter[-letter](, letter[-letter])...
  592. ***********************************************************/
  593. struct bwb_line *
  594. bwb_DEFINT(struct bwb_line * l)
  595. {
  596. bwx_DEBUG(__FUNCTION__);
  597. /* call generalized DEF handler with INTEGER set */
  598. var_defx(l, NUMBER);
  599. return bwb_zline(l);
  600. }
  601. /***********************************************************
  602. FUNCTION: bwb_dsng()
  603. DESCRIPTION: This function implements the BASIC
  604. DEFSNG command.
  605. SYNTAX: DEFSNG letter[-letter](, letter[-letter])...
  606. ***********************************************************/
  607. struct bwb_line *
  608. bwb_DEFSNG(struct bwb_line * l)
  609. {
  610. bwx_DEBUG(__FUNCTION__);
  611. /* call generalized DEF handler with SINGLE set */
  612. var_defx(l, NUMBER);
  613. return bwb_zline(l);
  614. }
  615. /***********************************************************
  616. FUNCTION: bwb_dstr()
  617. DESCRIPTION: This function implements the BASIC
  618. DEFSTR command.
  619. SYNTAX: DEFSTR letter[-letter](, letter[-letter])...
  620. ***********************************************************/
  621. struct bwb_line *
  622. bwb_DEFSTR(struct bwb_line * l)
  623. {
  624. bwx_DEBUG(__FUNCTION__);
  625. /* call generalized DEF handler with STRING set */
  626. var_defx(l, STRING);
  627. return bwb_zline(l);
  628. }
  629. static
  630. int
  631. VarTypeIndex(int C)
  632. {
  633. bwx_DEBUG(__FUNCTION__);
  634. if (isalpha(C))
  635. {
  636. static char A2Z[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  637. char *P;
  638. P = strchr(A2Z, ToUpper(C));
  639. if (P == NULL)
  640. {
  641. bwb_error("INTERNAL: VarTypeIndex() called for non-char");
  642. }
  643. else
  644. {
  645. return P - A2Z;
  646. }
  647. }
  648. else
  649. {
  650. bwb_error("INTERNAL: VarTypeIndex() called for non-alpha");
  651. }
  652. return 0;
  653. }
  654. /***********************************************************
  655. Function: var_defx()
  656. DESCRIPTION: This function is a generalized DEFxxx handler.
  657. ***********************************************************/
  658. static int
  659. var_defx(struct bwb_line * l, int type)
  660. {
  661. int loop;
  662. register int c;
  663. #if 0
  664. char vname[2];
  665. struct bwb_variable *v;
  666. #endif
  667. bwx_DEBUG(__FUNCTION__);
  668. /* loop while there are variable names to process */
  669. loop = TRUE;
  670. while (loop == TRUE)
  671. {
  672. /* check for end of line or line segment */
  673. adv_ws(l->buffer, &(l->position));
  674. switch (l->buffer[l->position])
  675. {
  676. case '\0':
  677. return FALSE;
  678. }
  679. if( l->buffer[l->position] == OptionCommentChar )
  680. {
  681. return FALSE;
  682. }
  683. /* find a sequence of letters for variables */
  684. if (var_letseq(l->buffer, &(l->position), &first, &last) == FALSE)
  685. {
  686. return FALSE;
  687. }
  688. #if 0
  689. /* loop through the list getting variables */
  690. for (c = first; c <= last; ++c)
  691. {
  692. vname[0] = (char) c;
  693. vname[1] = '\0';
  694. v = var_find(vname);
  695. /* but var_find() assigns on the basis of name
  696. * endings (so all in this case should be SINGLEs),
  697. * so we must force the type of the variable */
  698. var_make(v, type);
  699. }
  700. #endif
  701. if (isalpha(first) && isalpha(last))
  702. {
  703. first = VarTypeIndex(first);
  704. last = VarTypeIndex(last);
  705. for (c = first; c <= last; c++)
  706. {
  707. DefaultVariableType[c] = type;
  708. }
  709. }
  710. }
  711. return TRUE;
  712. }
  713. /***********************************************************
  714. Function: var_letseq()
  715. DESCRIPTION: This function finds a sequence of letters
  716. for a DEFxxx command.
  717. ***********************************************************/
  718. static int
  719. var_letseq(char *buffer, int *position, int *start, int *end)
  720. {
  721. bwx_DEBUG(__FUNCTION__);
  722. /* advance beyond whitespace */
  723. adv_ws(buffer, position);
  724. /* check for end of line */
  725. switch (buffer[*position])
  726. {
  727. case '\0':
  728. return TRUE;
  729. }
  730. /* character at this position must be a letter */
  731. if (isalpha(buffer[*position]) == 0)
  732. {
  733. bwb_error(err_defchar);
  734. return FALSE;
  735. }
  736. *end = *start = buffer[*position];
  737. /* advance beyond character and whitespace */
  738. ++(*position);
  739. adv_ws(buffer, position);
  740. /* check for hyphen, indicating sequence of more than one letter */
  741. if (buffer[*position] == '-')
  742. {
  743. ++(*position);
  744. /* advance beyond whitespace */
  745. adv_ws(buffer, position);
  746. /* character at this position must be a letter */
  747. if (isalpha(buffer[*position]) == 0)
  748. {
  749. *end = *start;
  750. }
  751. else
  752. {
  753. *end = buffer[*position];
  754. ++(*position);
  755. }
  756. }
  757. /* advance beyond comma if present */
  758. if (buffer[*position] == ',')
  759. {
  760. ++(*position);
  761. }
  762. return TRUE;
  763. }
  764. /***********************************************************
  765. FUNCTION: bwb_getvarname()
  766. DESCRIPTION: This function takes the string in lb
  767. (the large buffer), finds a variable name,
  768. and returns it in sb (the small buffer),
  769. appropriately incrementing the integer
  770. pointed to by n.
  771. ***********************************************************/
  772. int
  773. bwb_getvarname(char *lb, char *sb, int *n)
  774. {
  775. /* FIXME: use BasicNameLengthMax */
  776. #if 0
  777. register int s;
  778. bwx_DEBUG(__FUNCTION__);
  779. s = 0;
  780. /* advance beyond whitespace */
  781. adv_ws(lb, n);
  782. while (TRUE)
  783. {
  784. switch (lb[*n])
  785. {
  786. case ' ': /* whitespace */
  787. case '\0':
  788. case ',':
  789. case ';':
  790. case '(': /* beginning of parameter list for
  791. * dimensioned array */
  792. case '+': /* add variables *//* FIXME: looks like a bug */
  793. case '=': /* Don't forget this one (JBV) */
  794. sb[s] = 0;
  795. return TRUE;
  796. default:
  797. sb[s] = lb[*n];
  798. break;
  799. }
  800. ++*n; /* advance to next character in large buffer */
  801. ++s; /* advance to next position in small buffer */
  802. sb[s] = 0; /* terminate with 0 */
  803. }
  804. #endif
  805. bwx_DEBUG(__FUNCTION__);
  806. /* advance beyond whitespace */
  807. adv_ws(lb, n);
  808. lb += (*n);
  809. if (isalpha(*lb))
  810. {
  811. *sb = *lb;
  812. sb++;
  813. lb++;
  814. (*n)++;
  815. if (OptionFlags & OPTION_BUGS_ON)
  816. {
  817. /* allow '.' and '_' in variable names */
  818. while (isalnum(*lb) || *lb == '.' || *lb == '_')
  819. {
  820. *sb = *lb;
  821. sb++;
  822. lb++;
  823. (*n)++;
  824. }
  825. }
  826. else
  827. {
  828. while (isalnum(*lb))
  829. {
  830. *sb = *lb;
  831. sb++;
  832. lb++;
  833. (*n)++;
  834. }
  835. }
  836. if (OptionFlags & OPTION_BUGS_ON)
  837. {
  838. /* allow '!','@','#', '%', '&' and '$' in variable names */
  839. switch (*lb)
  840. {
  841. case BasicDoubleSuffix:
  842. case BasicSingleSuffix:
  843. case BasicCurrencySuffix:
  844. case BasicLongSuffix:
  845. case BasicIntegerSuffix:
  846. case BasicStringSuffix:
  847. /* suffix IS part of the name. *
  848. * A$ is distinct from A. */
  849. *sb = *lb;
  850. sb++;
  851. lb++;
  852. (*n)++;
  853. break;
  854. }
  855. }
  856. else
  857. {
  858. switch (*lb)
  859. {
  860. case BasicStringSuffix:
  861. /* suffix IS part of the name. *
  862. * A$ is distinct from A. */
  863. *sb = *lb;
  864. sb++;
  865. lb++;
  866. (*n)++;
  867. break;
  868. }
  869. }
  870. }
  871. *sb = '\0';
  872. return TRUE;
  873. }
  874. /***************************************************************
  875. FUNCTION: var_find()
  876. DESCRIPTION: This C function attempts to find a variable
  877. name matching the argument in buffer. If
  878. it fails to find a matching name, it
  879. sets up a new variable with that name.
  880. ***************************************************************/
  881. struct bwb_variable *
  882. var_find(char *buffer)
  883. {
  884. struct bwb_variable *v;
  885. bwx_DEBUG(__FUNCTION__);
  886. /* check for NULL variable name */
  887. if (strlen(buffer) == 0)
  888. {
  889. sprintf(bwb_ebuf, "in var_find(): NULL variable name received\n");
  890. bwb_error(bwb_ebuf);
  891. return NULL;
  892. }
  893. /* check for a local variable at this EXEC level */
  894. v = var_islocal(buffer);
  895. if (v != NULL)
  896. {
  897. return v;
  898. }
  899. /* now run through the global variable list and try to find a match */
  900. for (v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next)
  901. {
  902. if (strcasecmp(v->name, buffer) == 0)
  903. {
  904. switch (v->type)
  905. {
  906. case STRING:
  907. case NUMBER:
  908. break;
  909. default:
  910. sprintf(bwb_ebuf, "in var_find(): inappropriate precision for variable <%s>",
  911. v->name);
  912. bwb_error(bwb_ebuf);
  913. return NULL;
  914. break;
  915. }
  916. return v;
  917. }
  918. }
  919. /* presume this is a new variable, so initialize it... */
  920. /* initialize new variable */
  921. v = var_new(buffer);
  922. /* set place at beginning of variable chain */
  923. v->next = CURTASK var_start.next;
  924. CURTASK var_start.next = v;
  925. /* normally not a preset */
  926. v->preset = FALSE;
  927. return v;
  928. }
  929. /***************************************************************
  930. FUNCTION: var_new()
  931. DESCRIPTION: This function assigns memory for a new variable.
  932. ***************************************************************/
  933. struct bwb_variable *
  934. var_new(char *name)
  935. {
  936. struct bwb_variable *v;
  937. char C;
  938. int type;
  939. bwx_DEBUG(__FUNCTION__);
  940. /* get memory for new variable */
  941. if (name == NULL)
  942. {
  943. bwb_error("INTERNAL ERROR - not a valid variable name - name == NULL");
  944. return NULL;
  945. }
  946. if (strlen(name) == 0)
  947. {
  948. bwb_error("INTERNAL ERROR - not a valid variable name - strlen(name) == 0");
  949. return NULL;
  950. }
  951. if (isalpha(*name))
  952. {
  953. /* OK */
  954. }
  955. else
  956. {
  957. bwb_error("INTERNAL ERROR - not a valid variable name - !isalpha(*name)");
  958. return NULL;
  959. }
  960. C = ToUpper(*name);
  961. /* Revised to CALLOC pass-thru call by JBV */
  962. if ((v = (struct bwb_variable *) CALLOC(1, sizeof(struct bwb_variable), "var_new"))
  963. == NULL)
  964. {
  965. bwb_error(err_getmem);
  966. return NULL;
  967. }
  968. /* copy the name into the appropriate structure */
  969. strcpy(v->name, name);
  970. #if 0
  971. var_make(v, (int) v->name[strlen(v->name) - 1]);
  972. #endif
  973. /* set memory in the new variable */
  974. type = NUMBER; /* DEFAULT */
  975. switch (v->name[strlen(v->name) - 1])
  976. {
  977. case BasicStringSuffix:
  978. type = STRING;
  979. break;
  980. case BasicDoubleSuffix:
  981. case BasicSingleSuffix:
  982. case BasicCurrencySuffix:
  983. case BasicLongSuffix:
  984. case BasicIntegerSuffix:
  985. type = NUMBER;
  986. break;
  987. default:
  988. type = DefaultVariableType[VarTypeIndex(C)];
  989. break;
  990. }
  991. var_make(v, type);
  992. /* and return */
  993. return v;
  994. }
  995. /***************************************************************
  996. FUNCTION: bwb_isvar()
  997. DESCRIPTION: This function determines if the string
  998. in 'buffer' is the name of a previously-
  999. existing variable.
  1000. ***************************************************************/
  1001. int
  1002. bwb_isvar(char *buffer)
  1003. {
  1004. struct bwb_variable *v;
  1005. bwx_DEBUG(__FUNCTION__);
  1006. /* run through the variable list and try to find a match */
  1007. for (v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next)
  1008. {
  1009. if (strcasecmp(v->name, buffer) == 0)
  1010. {
  1011. return TRUE;
  1012. }
  1013. }
  1014. /* search failed */
  1015. return FALSE;
  1016. }
  1017. /***************************************************************
  1018. FUNCTION: var_getnval()
  1019. DESCRIPTION: This function returns the current value of
  1020. the variable argument as a number.
  1021. ***************************************************************/
  1022. BasicNumberType
  1023. var_getnval(struct bwb_variable * nvar)
  1024. {
  1025. bwx_DEBUG(__FUNCTION__);
  1026. switch (nvar->type)
  1027. {
  1028. case NUMBER:
  1029. return *(var_findnval(nvar, nvar->array_pos));
  1030. }
  1031. sprintf(bwb_ebuf, "in var_getnval(): type is <%d>=<%c>.",
  1032. nvar->type, nvar->type);
  1033. bwb_error(bwb_ebuf);
  1034. return 0;
  1035. }
  1036. /***************************************************************
  1037. FUNCTION: var_getsval()
  1038. DESCRIPTION: This function returns the current value of
  1039. the variable argument as a pointer to a BASIC
  1040. string structure.
  1041. ***************************************************************/
  1042. bstring *
  1043. var_getsval(struct bwb_variable * nvar)
  1044. {
  1045. static bstring b;
  1046. bwx_DEBUG(__FUNCTION__);
  1047. b.rab = FALSE;
  1048. switch (nvar->type)
  1049. {
  1050. case STRING:
  1051. return var_findsval(nvar, nvar->array_pos);
  1052. case NUMBER:
  1053. sprintf(bwb_ebuf, "%*f ", prn_precision(nvar),
  1054. *(var_findnval(nvar, nvar->array_pos)));
  1055. str_ctob(&b, bwb_ebuf);
  1056. return &b;
  1057. default:
  1058. sprintf(bwb_ebuf, "in var_getsval(): type is <%d>=<%c>.",
  1059. nvar->type, nvar->type);
  1060. bwb_error(bwb_ebuf);
  1061. return NULL;
  1062. }
  1063. }
  1064. /***************************************************************
  1065. FUNCTION: bwb_dim()
  1066. DESCRIPTION: This function implements the BASIC DIM
  1067. statement, allocating memory for a
  1068. dimensioned array of variables.
  1069. SYNTAX: DIM variable(elements...)[variable(elements...)]...
  1070. ***************************************************************/
  1071. struct bwb_line *
  1072. bwb_DIM(struct bwb_line * l)
  1073. {
  1074. register int n;
  1075. static int n_params; /* number of parameters */
  1076. static int *pp; /* pointer to parameter values */
  1077. struct bwb_variable *newvar;
  1078. BasicNumberType *np;
  1079. int loop;
  1080. char tbuf[BasicStringLengthMax + 1];
  1081. bwx_DEBUG(__FUNCTION__);
  1082. loop = TRUE;
  1083. while (loop == TRUE)
  1084. {
  1085. int old_name;
  1086. int old_dimensions;
  1087. old_name = FALSE;
  1088. /* Get variable name */
  1089. adv_ws(l->buffer, &(l->position));
  1090. bwb_getvarname(l->buffer, tbuf, &(l->position));
  1091. /* check for previously used variable name */
  1092. if (bwb_isvar(tbuf) == TRUE)
  1093. {
  1094. old_name = TRUE;
  1095. }
  1096. /* get the new variable */
  1097. newvar = var_find(tbuf);
  1098. /* note that DIM has been called */
  1099. dimmed = TRUE;
  1100. /* read parameters */
  1101. old_dimensions = newvar->dimensions;
  1102. dim_getparams(l->buffer, &(l->position), &n_params, &pp);
  1103. newvar->dimensions = n_params;
  1104. /* Check parameters for an old variable name */
  1105. if (old_name == TRUE)
  1106. {
  1107. /* check to be sure the number of dimensions is the
  1108. * same */
  1109. if (newvar->dimensions != old_dimensions)
  1110. {
  1111. sprintf(bwb_ebuf, "in bwb_dim(): variable <%s> cannot be re-dimensioned",
  1112. newvar->name);
  1113. bwb_error(bwb_ebuf);
  1114. return bwb_zline(l);
  1115. }
  1116. /* check to be sure sizes for the old variable are
  1117. * the same */
  1118. for (n = 0; n < newvar->dimensions; ++n)
  1119. {
  1120. if ((pp[n] + (1 - dim_base)) != newvar->array_sizes[n])
  1121. {
  1122. sprintf(bwb_ebuf, "in bwb_dim(): variable <%s> parameter <%d> cannot be resized",
  1123. newvar->name, n);
  1124. bwb_error(bwb_ebuf);
  1125. return bwb_zline(l);
  1126. }
  1127. }
  1128. } /* end of conditional for old variable */
  1129. /* a new variable */
  1130. else
  1131. {
  1132. /* assign memory for parameters */
  1133. /* Revised to CALLOC pass-thru call by JBV */
  1134. if ((newvar->array_sizes = (int *) CALLOC(n_params, sizeof(int), "bwb_dim")) == NULL)
  1135. {
  1136. sprintf(bwb_ebuf, "in line %d: Failed to find memory for array_sizes for <%s>",
  1137. l->number, newvar->name);
  1138. bwb_error(bwb_ebuf);
  1139. return bwb_zline(l);
  1140. }
  1141. for (n = 0; n < newvar->dimensions; ++n)
  1142. {
  1143. newvar->array_sizes[n] = pp[n] + (1 - dim_base);
  1144. }
  1145. /* assign memory for current position */
  1146. /* Revised to CALLOC pass-thru call by JBV */
  1147. if ((newvar->array_pos = (int *) CALLOC(n_params, sizeof(int), "bwb_dim")) == NULL)
  1148. {
  1149. sprintf(bwb_ebuf, "in line %d: Failed to find memory for array_pos for <%s>",
  1150. l->number, newvar->name);
  1151. bwb_error(bwb_ebuf);
  1152. return bwb_zline(l);
  1153. }
  1154. for (n = 0; n < newvar->dimensions; ++n)
  1155. {
  1156. newvar->array_pos[n] = dim_base;
  1157. }
  1158. /* calculate the array size */
  1159. #define MAXINTSIZE 2147483647 /* this is a HACK */
  1160. newvar->array_units = (size_t) MAXINTSIZE; /* avoid error in
  1161. * dim_unit() */
  1162. newvar->array_units = dim_unit(newvar, pp) + 1;
  1163. /* assign array memory */
  1164. switch (newvar->type)
  1165. {
  1166. case STRING:
  1167. /*------------------------------------------------------*/
  1168. /* memnum, not memstr, was used here --
  1169. * incorrect (JBV) */
  1170. /* Revised to CALLOC pass-thru call by JBV */
  1171. /*------------------------------------------------------*/
  1172. if ((newvar->memstr = (bstring *)
  1173. CALLOC(newvar->array_units, sizeof(bstring), "bwb_dim")) == NULL)
  1174. {
  1175. sprintf(bwb_ebuf, "in line %d: Failed to find memory for array <%s>",
  1176. l->number, newvar->name);
  1177. bwb_error(bwb_ebuf);
  1178. return bwb_zline(l);
  1179. }
  1180. break;
  1181. case NUMBER:
  1182. /* Revised to CALLOC pass-thru call by JBV */
  1183. if ((np = (BasicNumberType *)
  1184. CALLOC(newvar->array_units, sizeof(BasicNumberType), "bwb_dim")) == NULL)
  1185. {
  1186. sprintf(bwb_ebuf, "in line %d: Failed to find memory for array <%s>",
  1187. l->number, newvar->name);
  1188. bwb_error(bwb_ebuf);
  1189. return bwb_zline(l);
  1190. }
  1191. newvar->memnum = np;
  1192. break;
  1193. default:
  1194. sprintf(bwb_ebuf, "in line %d: New variable has unrecognized type.",
  1195. l->number);
  1196. bwb_error(bwb_ebuf);
  1197. return bwb_zline(l);
  1198. }
  1199. } /* end of conditional for new variable */
  1200. /* now check for end of string */
  1201. if (l->buffer[l->position] == ')')
  1202. {
  1203. ++(l->position);
  1204. }
  1205. adv_ws(l->buffer, &(l->position));
  1206. if (l->buffer[l->position] == OptionCommentChar)
  1207. {
  1208. loop = FALSE;
  1209. }
  1210. else
  1211. {
  1212. switch (l->buffer[l->position])
  1213. {
  1214. case '\0': /* end of string */
  1215. loop = FALSE;
  1216. break;
  1217. case ',':
  1218. ++(l->position);
  1219. adv_ws(l->buffer, &(l->position));
  1220. loop = TRUE;
  1221. break;
  1222. default:
  1223. loop = FALSE;
  1224. sprintf(bwb_ebuf, "in bwb_dim(): unexpected end of string, buf <%s>",
  1225. &(l->buffer[l->position]));
  1226. bwb_error(bwb_ebuf);
  1227. return bwb_zline(l);
  1228. break;
  1229. }
  1230. }
  1231. } /* end of loop through variables */
  1232. /* return */
  1233. return bwb_zline(l);
  1234. }
  1235. int
  1236. DetermineNumberOfDimensions(char *expression, int LastPosition)
  1237. {
  1238. /* MUST be a dynamically created array, READ A(10) = ... ' variable
  1239. * "A" has NOT been dimensioned */
  1240. int ParenLevel = 0;
  1241. int NumDimensions = 1;
  1242. int Loop = TRUE;
  1243. bwx_DEBUG(__FUNCTION__);
  1244. while (Loop == TRUE)
  1245. {
  1246. char C;
  1247. C = expression[LastPosition];
  1248. /* check the current character */
  1249. switch (C)
  1250. {
  1251. case '\0':
  1252. return 0;
  1253. break;
  1254. case '=':
  1255. Loop = FALSE;
  1256. break;
  1257. case '(':
  1258. LastPosition++;
  1259. ParenLevel++;
  1260. break;
  1261. case ')':
  1262. LastPosition++;
  1263. ParenLevel--;
  1264. if (ParenLevel == 0)
  1265. {
  1266. Loop = FALSE;
  1267. }
  1268. break;
  1269. case ',':
  1270. LastPosition++;
  1271. if (ParenLevel == 1)
  1272. {
  1273. NumDimensions++;
  1274. }
  1275. break;
  1276. case '\"': /* embedded string constant */
  1277. LastPosition++;
  1278. while ((expression[LastPosition] != '\"')
  1279. && (expression[LastPosition] != '\0'))
  1280. {
  1281. LastPosition++;
  1282. }
  1283. if (expression[LastPosition] == '\"')
  1284. {
  1285. LastPosition++;
  1286. }
  1287. break;
  1288. default:
  1289. LastPosition++;
  1290. }
  1291. }
  1292. return NumDimensions;
  1293. }
  1294. int
  1295. ImplicitDim(char *tbuf, int n_params)
  1296. {
  1297. /* This is only for ECMA-55. ECMA-116 requires arrays to be
  1298. * dimensioned prior to being used. */
  1299. register int n; /* number of parameters */
  1300. BasicNumberType *np;
  1301. static int *pp; /* pointer to parameter values */
  1302. struct bwb_variable *newvar;
  1303. static int params[MAX_DIMS];
  1304. bwx_DEBUG(__FUNCTION__);
  1305. if (OptionFlags & OPTION_STRICT_ON)
  1306. {
  1307. /* Implicit DIM is not allowed */
  1308. return FALSE;
  1309. }
  1310. for (n = 0; n < MAX_DIMS; n++)
  1311. {
  1312. params[n] = 10; /* UBOUND() = 10, LBOUND() = OPTION BASE */
  1313. }
  1314. pp = &params[0];
  1315. /* get the new variable */
  1316. newvar = var_find(tbuf);
  1317. /* note that DIM has been (implicitly) called */
  1318. dimmed = TRUE;
  1319. newvar->dimensions = n_params;
  1320. /* assign memory for parameters */
  1321. /* Revised to CALLOC pass-thru call by JBV */
  1322. if ((newvar->array_sizes = (int *) CALLOC(n_params, sizeof(int), "bwb_dim")) == NULL)
  1323. {
  1324. bwb_error(err_getmem);
  1325. return FALSE;
  1326. }
  1327. for (n = 0; n < newvar->dimensions; ++n)
  1328. {
  1329. newvar->array_sizes[n] = pp[n] + (1 - dim_base);
  1330. }
  1331. /* assign memory for current position */
  1332. /* Revised to CALLOC pass-thru call by JBV */
  1333. if ((newvar->array_pos = (int *) CALLOC(n_params, sizeof(int), "bwb_dim")) == NULL)
  1334. {
  1335. bwb_error(err_getmem);
  1336. return FALSE;
  1337. }
  1338. for (n = 0; n < newvar->dimensions; ++n)
  1339. {
  1340. newvar->array_pos[n] = dim_base;
  1341. }
  1342. /* calculate the array size */
  1343. #define MAXINTSIZE 2147483647 /* this is a HACK */
  1344. newvar->array_units = (size_t) MAXINTSIZE; /* avoid error in
  1345. * dim_unit() */
  1346. newvar->array_units = dim_unit(newvar, pp) + 1;
  1347. /* assign array memory */
  1348. switch (newvar->type)
  1349. {
  1350. case STRING:
  1351. /*------------------------------------------------------*/
  1352. /* memnum, not memstr, was used here -- incorrect (JBV) */
  1353. /* Revised to CALLOC pass-thru call by JBV */
  1354. /*------------------------------------------------------*/
  1355. if ((newvar->memstr = (bstring *)
  1356. CALLOC(newvar->array_units, sizeof(bstring), "bwb_dim")) == NULL)
  1357. {
  1358. bwb_error(err_getmem);
  1359. return FALSE;
  1360. }
  1361. break;
  1362. case NUMBER:
  1363. /* Revised to CALLOC pass-thru call by JBV */
  1364. if ((np = (BasicNumberType *)
  1365. CALLOC(newvar->array_units, sizeof(BasicNumberType), "bwb_dim")) == NULL)
  1366. {
  1367. bwb_error(err_getmem);
  1368. return FALSE;
  1369. }
  1370. newvar->memnum = np;
  1371. break;
  1372. default:
  1373. bwb_error(err_syntax);
  1374. return FALSE;
  1375. }
  1376. return TRUE;
  1377. }
  1378. /***************************************************************
  1379. FUNCTION: dim_unit()
  1380. DESCRIPTION: This function calculates the unit
  1381. position for an array.
  1382. ***************************************************************/
  1383. static size_t
  1384. dim_unit(struct bwb_variable * v, int *pp)
  1385. {
  1386. size_t r;
  1387. size_t b;
  1388. register int n;
  1389. bwx_DEBUG(__FUNCTION__);
  1390. /* Calculate and return the address of the dimensioned array */
  1391. /* Check EACH dimension for out-of-bounds, AND check correct number
  1392. * of dimensions. NBS_P076_0250 errors correctly. */
  1393. b = 1;
  1394. r = 0;
  1395. for (n = 0; n < v->dimensions; ++n)
  1396. {
  1397. /* newvar->array_sizes[ n ] = pp[ n ] + ( 1 - dim_base ); */
  1398. if ((pp[n] < dim_base) || ((pp[n] + (1 - dim_base)) > v->array_sizes[n]))
  1399. {
  1400. sprintf(bwb_ebuf, "SUBSCRIPT OUT OF RANGE %s(%d)", v->name, pp[n]);
  1401. bwb_error(bwb_ebuf);
  1402. return 0;
  1403. }
  1404. r += b * (pp[n] - dim_base);
  1405. b *= v->array_sizes[n];
  1406. }
  1407. if (r > v->array_units)
  1408. {
  1409. sprintf(bwb_ebuf, "SUBSCRIPT OUT OF RANGE %s(%ld)", v->name, (long) r);
  1410. bwb_error(bwb_ebuf);
  1411. return 0;
  1412. }
  1413. return r;
  1414. }
  1415. /***************************************************************
  1416. FUNCTION: dim_getparams()
  1417. DESCRIPTION: This function reads a string in <buffer>
  1418. beginning at position <pos> and finds a
  1419. list of parameters surrounded by paren-
  1420. theses, returning in <n_params> the number
  1421. of parameters found, and returning in
  1422. <pp> an array of n_params integers giving
  1423. the sizes for each dimension of the array.
  1424. ***************************************************************/
  1425. int
  1426. dim_getparams_FIXED(char *buffer, int *pos, int params[ /* MAX_DIMS */ ])
  1427. {
  1428. int n_params;
  1429. int loop;
  1430. int x_pos, s_pos;
  1431. struct exp_ese *e;
  1432. char tbuf[BasicStringLengthMax + 1];
  1433. int paren_level, quote_level; /* JBV 1/97 */
  1434. bwx_DEBUG(__FUNCTION__);
  1435. /* set initial values */
  1436. n_params = 0;
  1437. /* advance and check for undimensioned variable */
  1438. adv_ws(buffer, pos);
  1439. if (buffer[*pos] != '(')
  1440. {
  1441. n_params = 1;
  1442. params[0] = dim_base;
  1443. return n_params;
  1444. }
  1445. else
  1446. {
  1447. ++(*pos);
  1448. }
  1449. /* Variable has DIMensions: Find each parameter */
  1450. s_pos = 0;
  1451. tbuf[0] = '\0';
  1452. loop = TRUE;
  1453. paren_level = 1; /* JBV 1/97 */
  1454. quote_level = 0; /* JBV 1/97 */
  1455. while (loop == TRUE)
  1456. {
  1457. switch (buffer[*pos])
  1458. {
  1459. case ')': /* end of parameter list */
  1460. /*-----------------------------------------------------*/
  1461. /* paren_level and quote_level check added by JBV
  1462. * 1/97 */
  1463. /*-----------------------------------------------------*/
  1464. if (quote_level == 0)
  1465. --paren_level;
  1466. if (paren_level != 0 || quote_level != 0) /* Still not done? */
  1467. {
  1468. tbuf[s_pos] = buffer[*pos];
  1469. ++(*pos);
  1470. ++s_pos;
  1471. tbuf[s_pos] = '\0';
  1472. break;
  1473. }
  1474. x_pos = 0;
  1475. if (tbuf[0] == '\0')
  1476. {
  1477. params[n_params] = DEF_SUBSCRIPT;
  1478. }
  1479. else
  1480. {
  1481. e = bwb_exp(tbuf, FALSE, &x_pos);
  1482. if (ERROR_PENDING)
  1483. {
  1484. return 0;
  1485. }
  1486. /* Subscripts are rounded */
  1487. params[n_params] = exp_getival(e);
  1488. }
  1489. n_params++;
  1490. loop = FALSE;
  1491. ++(*pos);
  1492. break;
  1493. case ',': /* end of a parameter */
  1494. /*-----------------------------------------------------*/
  1495. /* paren_level and quote_level check added by JBV
  1496. * 1/97 */
  1497. /*-----------------------------------------------------*/
  1498. if (paren_level != 1 || quote_level != 0) /* Still not done? */
  1499. {
  1500. tbuf[s_pos] = buffer[*pos];
  1501. ++(*pos);
  1502. ++s_pos;
  1503. tbuf[s_pos] = '\0';
  1504. break;
  1505. }
  1506. x_pos = 0;
  1507. if (tbuf[0] == '\0')
  1508. {
  1509. params[n_params] = DEF_SUBSCRIPT;
  1510. }
  1511. else
  1512. {
  1513. e = bwb_exp(tbuf, FALSE, &x_pos);
  1514. if (ERROR_PENDING)
  1515. {
  1516. return 0;
  1517. }
  1518. /* Subscripts are rounded */
  1519. params[n_params] = exp_getival(e);
  1520. }
  1521. n_params++;
  1522. tbuf[0] = '\0';
  1523. ++(*pos);
  1524. s_pos = 0;
  1525. break;
  1526. case ' ': /* whitespace -- skip */
  1527. ++(*pos);
  1528. break;
  1529. default:
  1530. if (buffer[*pos] == '(' && quote_level == 0)
  1531. ++paren_level; /* JBV 1/97 */
  1532. if (buffer[*pos] == (char) 34)
  1533. {
  1534. if (quote_level == 0)
  1535. quote_level = 1;
  1536. else
  1537. quote_level = 0;
  1538. }
  1539. tbuf[s_pos] = buffer[*pos];
  1540. ++(*pos);
  1541. ++s_pos;
  1542. tbuf[s_pos] = '\0';
  1543. break;
  1544. }
  1545. if (n_params >= MAX_DIMS)
  1546. {
  1547. loop = FALSE;
  1548. }
  1549. }
  1550. /* return params stack */
  1551. return n_params;
  1552. }
  1553. int
  1554. dim_getparams(char *buffer, int *pos, int *n_params, int **pp)
  1555. {
  1556. int loop;
  1557. static int params[MAX_DIMS]; /* can NOT be called via
  1558. * bwb_exp() */
  1559. int x_pos, s_pos;
  1560. struct exp_ese *e;
  1561. char tbuf[BasicStringLengthMax + 1];
  1562. int paren_level, quote_level; /* JBV 1/97 */
  1563. bwx_DEBUG(__FUNCTION__);
  1564. /* set initial values */
  1565. *n_params = 0;
  1566. /* advance and check for undimensioned variable */
  1567. adv_ws(buffer, pos);
  1568. if (buffer[*pos] != '(')
  1569. {
  1570. *n_params = 1;
  1571. params[0] = dim_base;
  1572. *pp = params;
  1573. return TRUE;
  1574. }
  1575. else
  1576. {
  1577. ++(*pos);
  1578. }
  1579. /* Variable has DIMensions: Find each parameter */
  1580. s_pos = 0;
  1581. tbuf[0] = '\0';
  1582. loop = TRUE;
  1583. paren_level = 1; /* JBV 1/97 */
  1584. quote_level = 0; /* JBV 1/97 */
  1585. while (loop == TRUE)
  1586. {
  1587. switch (buffer[*pos])
  1588. {
  1589. case ')': /* end of parameter list */
  1590. /*-----------------------------------------------------*/
  1591. /* paren_level and quote_level check added by JBV
  1592. * 1/97 */
  1593. /*-----------------------------------------------------*/
  1594. if (quote_level == 0)
  1595. --paren_level;
  1596. if (paren_level != 0 || quote_level != 0) /* Still not done? */
  1597. {
  1598. tbuf[s_pos] = buffer[*pos];
  1599. ++(*pos);
  1600. ++s_pos;
  1601. tbuf[s_pos] = '\0';
  1602. break;
  1603. }
  1604. x_pos = 0;
  1605. if (tbuf[0] == '\0')
  1606. {
  1607. params[*n_params] = DEF_SUBSCRIPT;
  1608. }
  1609. else
  1610. {
  1611. e = bwb_exp(tbuf, FALSE, &x_pos);
  1612. if (ERROR_PENDING)
  1613. {
  1614. return FALSE;
  1615. }
  1616. /* Subscripts are rounded */
  1617. params[*n_params] = exp_getival(e);
  1618. }
  1619. ++(*n_params);
  1620. loop = FALSE;
  1621. ++(*pos);
  1622. break;
  1623. case ',': /* end of a parameter */
  1624. /*-----------------------------------------------------*/
  1625. /* paren_level and quote_level check added by JBV
  1626. * 1/97 */
  1627. /*-----------------------------------------------------*/
  1628. if (paren_level != 1 || quote_level != 0) /* Still not done? */
  1629. {
  1630. tbuf[s_pos] = buffer[*pos];
  1631. ++(*pos);
  1632. ++s_pos;
  1633. tbuf[s_pos] = '\0';
  1634. break;
  1635. }
  1636. x_pos = 0;
  1637. if (tbuf[0] == '\0')
  1638. {
  1639. params[*n_params] = DEF_SUBSCRIPT;
  1640. }
  1641. else
  1642. {
  1643. e = bwb_exp(tbuf, FALSE, &x_pos);
  1644. if (ERROR_PENDING)
  1645. {
  1646. return FALSE;
  1647. }
  1648. /* Subscripts are rounded */
  1649. params[*n_params] = exp_getival(e);
  1650. }
  1651. ++(*n_params);
  1652. tbuf[0] = '\0';
  1653. ++(*pos);
  1654. s_pos = 0;
  1655. break;
  1656. case ' ': /* whitespace -- skip */
  1657. ++(*pos);
  1658. break;
  1659. default:
  1660. if (buffer[*pos] == '(' && quote_level == 0)
  1661. ++paren_level; /* JBV 1/97 */
  1662. if (buffer[*pos] == (char) 34)
  1663. {
  1664. if (quote_level == 0)
  1665. quote_level = 1;
  1666. else
  1667. quote_level = 0;
  1668. }
  1669. tbuf[s_pos] = buffer[*pos];
  1670. ++(*pos);
  1671. ++s_pos;
  1672. tbuf[s_pos] = '\0';
  1673. break;
  1674. }
  1675. }
  1676. /* return params stack */
  1677. *pp = params;
  1678. return TRUE;
  1679. }
  1680. /***************************************************************
  1681. FUNCTION: bwb_option()
  1682. DESCRIPTION: This function implements the BASIC OPTION
  1683. BASE statement, designating the base (1 or
  1684. 0) for addressing DIM arrays.
  1685. SYNTAX: OPTION BASE number
  1686. ***************************************************************/
  1687. void
  1688. OptionBaseHelper(int newval, struct bwb_line * l /* just for error
  1689. messages */ )
  1690. {
  1691. struct bwb_variable *current;
  1692. bwx_DEBUG(__FUNCTION__);
  1693. /* OPTION BASE ... */
  1694. /* If DIM has already been called, do not allow OPTION BASE */
  1695. if (dimmed != FALSE)
  1696. {
  1697. sprintf(bwb_ebuf, "at line %d: OPTION BASE must be called before DIM.",
  1698. l->number);
  1699. bwb_error(bwb_ebuf);
  1700. return;
  1701. }
  1702. /* Test the new value. */
  1703. if ((newval < 0) || (newval > 1))
  1704. {
  1705. sprintf(bwb_ebuf, "at line %d: value for OPTION BASE must be 1 or 0.",
  1706. l->number);
  1707. bwb_error(bwb_ebuf);
  1708. return;
  1709. }
  1710. /* Set the new value. */
  1711. dim_base = newval;
  1712. /* run through the variable list and change any positions that had
  1713. * set 0 before OPTION BASE was run */
  1714. for (current = CURTASK var_start.next; current != &CURTASK var_end; current = current->next)
  1715. {
  1716. current->array_pos[0] = dim_base;
  1717. }
  1718. }
  1719. void
  1720. OptionVersionSet(int i)
  1721. {
  1722. bwx_DEBUG(__FUNCTION__);
  1723. OptionVersion = bwb_vertable[i].OptionVersionBitmask;
  1724. OptionFlags = bwb_vertable[i].OptionFlags;
  1725. OptionCommentChar = bwb_vertable[i].OptionCommentChar;
  1726. OptionStatementChar = bwb_vertable[i].OptionStatementChar;
  1727. strcpy(OptionDateFormat,bwb_vertable[i].OptionDateFormat);
  1728. strcpy(OptionTimeFormat,bwb_vertable[i].OptionTimeFormat);
  1729. }
  1730. struct bwb_line *
  1731. bwb_OPTION(struct bwb_line * l)
  1732. {
  1733. bwx_DEBUG(__FUNCTION__);
  1734. /* OPTION ... */
  1735. bwb_error(err_syntax);
  1736. return bwb_zline(l);
  1737. }
  1738. struct bwb_line *
  1739. bwb_OPTION_ANGLE_DEGREES(struct bwb_line * l)
  1740. {
  1741. bwx_DEBUG(__FUNCTION__);
  1742. /* OPTION ANGLE DEGREES */
  1743. OptionFlags |= OPTION_ANGLE_DEGREES;
  1744. return bwb_zline(l);
  1745. }
  1746. struct bwb_line *
  1747. bwb_OPTION_ANGLE_RADIANS(struct bwb_line * l)
  1748. {
  1749. bwx_DEBUG(__FUNCTION__);
  1750. /* OPTION ANGLE RADIANS */
  1751. OptionFlags &= ~OPTION_ANGLE_DEGREES;
  1752. return bwb_zline(l);
  1753. }
  1754. struct bwb_line *
  1755. bwb_OPTION_ARITHMETIC_DECIMAL(struct bwb_line * l)
  1756. {
  1757. bwx_DEBUG(__FUNCTION__);
  1758. /* OPTION ARITHMETIC DECIMAL */
  1759. return bwb_zline(l);
  1760. }
  1761. struct bwb_line *
  1762. bwb_OPTION_ARITHMETIC_FIXED(struct bwb_line * l)
  1763. {
  1764. bwx_DEBUG(__FUNCTION__);
  1765. /* OPTION ARITHMETIC FIXED */
  1766. return bwb_zline(l);
  1767. }
  1768. struct bwb_line *
  1769. bwb_OPTION_ARITHMETIC_NATIVE(struct bwb_line * l)
  1770. {
  1771. bwx_DEBUG(__FUNCTION__);
  1772. /* OPTION ARITHMETIC NATIVE */
  1773. return bwb_zline(l);
  1774. }
  1775. struct bwb_line *
  1776. bwb_OPTION_BASE_1(struct bwb_line * l)
  1777. {
  1778. bwx_DEBUG(__FUNCTION__);
  1779. /* OPTION BASE 1 */
  1780. OptionFlags |= OPTION_BASE_ONE;
  1781. OptionBaseHelper(1, l);
  1782. return bwb_zline(l);
  1783. }
  1784. struct bwb_line *
  1785. bwb_OPTION_BASE_0(struct bwb_line * l)
  1786. {
  1787. bwx_DEBUG(__FUNCTION__);
  1788. /* OPTION BASE 0 */
  1789. OptionFlags &= ~OPTION_BASE_ONE;
  1790. OptionBaseHelper(0, l);
  1791. return bwb_zline(l);
  1792. }
  1793. struct bwb_line *
  1794. bwb_OPTION_BUGS_ON(struct bwb_line * l)
  1795. {
  1796. bwx_DEBUG(__FUNCTION__);
  1797. /* OPTION BUGS ON */
  1798. OptionFlags |= OPTION_BUGS_ON;
  1799. return bwb_zline(l);
  1800. }
  1801. struct bwb_line *
  1802. bwb_OPTION_BUGS_OFF(struct bwb_line * l)
  1803. {
  1804. bwx_DEBUG(__FUNCTION__);
  1805. /* OPTION BUGS OFF */
  1806. OptionFlags &= ~OPTION_BUGS_ON;
  1807. return bwb_zline(l);
  1808. }
  1809. struct bwb_line *
  1810. bwb_OPTION_COMMENT(struct bwb_line * l)
  1811. {
  1812. bwx_DEBUG(__FUNCTION__);
  1813. /* OPTION COMMENT char */
  1814. OptionCommentChar = l->buffer[l->position];
  1815. if( OptionCommentChar != '\0' )
  1816. {
  1817. l->position++;
  1818. }
  1819. return bwb_zline(l);
  1820. }
  1821. struct bwb_line *
  1822. bwb_OPTION_COMPARE_BINARY(struct bwb_line * l)
  1823. {
  1824. bwx_DEBUG(__FUNCTION__);
  1825. /* OPTION COMPARE BINARY */
  1826. OptionFlags &= ~OPTION_COMPARE_TEXT;
  1827. return bwb_zline(l);
  1828. }
  1829. struct bwb_line *
  1830. bwb_OPTION_COMPARE_DATABASE(struct bwb_line * l)
  1831. {
  1832. bwx_DEBUG(__FUNCTION__);
  1833. /* OPTION COMPARE DATABASE */
  1834. OptionFlags |= OPTION_COMPARE_TEXT;
  1835. return bwb_zline(l);
  1836. }
  1837. struct bwb_line *
  1838. bwb_OPTION_COMPARE_TEXT(struct bwb_line * l)
  1839. {
  1840. bwx_DEBUG(__FUNCTION__);
  1841. /* OPTION COMPARE TEXT */
  1842. OptionFlags |= OPTION_COMPARE_TEXT;
  1843. return bwb_zline(l);
  1844. }
  1845. struct bwb_line *
  1846. bwb_OPTION_COVERAGE_ON(struct bwb_line * l)
  1847. {
  1848. bwx_DEBUG(__FUNCTION__);
  1849. /* OPTION COVERAGE ON */
  1850. OptionFlags |= OPTION_COVERAGE_ON;
  1851. return bwb_zline(l);
  1852. }
  1853. struct bwb_line *
  1854. bwb_OPTION_COVERAGE_OFF(struct bwb_line * l)
  1855. {
  1856. bwx_DEBUG(__FUNCTION__);
  1857. /* OPTION COVERAGE OFF */
  1858. OptionFlags &= ~OPTION_COVERAGE_ON;
  1859. return bwb_zline(l);
  1860. }
  1861. static void
  1862. StripQuotes( char * tbuf )
  1863. {
  1864. /* Remove Leading & Trailing Quotes */
  1865. if( tbuf[0] == '"' )
  1866. {
  1867. char * Q;
  1868. strcpy( tbuf, &(tbuf[1]) );
  1869. Q = strchr( tbuf, '"' );
  1870. if( Q != NULL )
  1871. {
  1872. *Q = '\0';
  1873. }
  1874. }
  1875. }
  1876. struct bwb_line *
  1877. bwb_OPTION_DATE(struct bwb_line * l)
  1878. {
  1879. /* OPTION DATE format */
  1880. char tbuf[BasicStringLengthMax + 1];
  1881. bwx_DEBUG(__FUNCTION__);
  1882. /* Get FORMAT */
  1883. adv_element(l->buffer, &(l->position), tbuf);
  1884. StripQuotes( tbuf );
  1885. tbuf[ 80 ] = '\0';
  1886. strcpy( OptionDateFormat, tbuf );
  1887. return bwb_zline(l);
  1888. }
  1889. struct bwb_line *
  1890. bwb_OPTION_DISABLE_COMMAND(struct bwb_line * l)
  1891. {
  1892. /* OPTION DISABLE COMMAND ... */
  1893. int IsFound;
  1894. char tbuf[BasicStringLengthMax + 1];
  1895. bwx_DEBUG(__FUNCTION__);
  1896. IsFound = FALSE;
  1897. /* Get COMMAND */
  1898. adv_element(l->buffer, &(l->position), tbuf);
  1899. StripQuotes( tbuf );
  1900. {
  1901. /* Name */
  1902. int i;
  1903. for( i = 0; i < NUM_COMMANDS; i++ )
  1904. {
  1905. if( strcasecmp( tbuf, bwb_cmdtable[i].name ) == 0 )
  1906. {
  1907. /* FOUND */
  1908. /* DISABLE COMMAND */
  1909. bwb_cmdtable[i].OptionVersionBitmask &= ~OptionVersion;
  1910. IsFound = TRUE;
  1911. }
  1912. }
  1913. }
  1914. if( IsFound == FALSE )
  1915. {
  1916. /* display warning message */
  1917. sprintf( bwb_ebuf, "IGNORED: %s", l->buffer);
  1918. puts(bwb_ebuf);
  1919. }
  1920. return bwb_zline(l);
  1921. }
  1922. struct bwb_line *
  1923. bwb_OPTION_DISABLE_FUNCTION(struct bwb_line * l)
  1924. {
  1925. /* OPTION DISABLE FUNCTION ... */
  1926. int IsFound;
  1927. char tbuf[BasicStringLengthMax + 1];
  1928. bwx_DEBUG(__FUNCTION__);
  1929. IsFound = FALSE;
  1930. /* Get FUNCTION */
  1931. adv_element(l->buffer, &(l->position), tbuf);
  1932. StripQuotes( tbuf );
  1933. {
  1934. /* Name */
  1935. int i;
  1936. for( i = 0; i < NUM_FUNCTIONS; i++ )
  1937. {
  1938. if( strcasecmp( tbuf, bwb_prefuncs[i].Name ) == 0 )
  1939. {
  1940. /* FOUND */
  1941. /* DISABLE FUNCTION */
  1942. bwb_prefuncs[i].OptionVersionBitmask &= ~OptionVersion;
  1943. IsFound = TRUE;
  1944. }
  1945. }
  1946. }
  1947. if( IsFound == FALSE )
  1948. {
  1949. /* display warning message */
  1950. sprintf( bwb_ebuf, "IGNORED: %s", l->buffer);
  1951. puts(bwb_ebuf);
  1952. }
  1953. return bwb_zline(l);
  1954. }
  1955. struct bwb_line *
  1956. bwb_OPTION_DISABLE_OPERATOR(struct bwb_line * l)
  1957. {
  1958. /* OPTION DISABLE OPERATOR ... */
  1959. int IsFound;
  1960. char tbuf[BasicStringLengthMax + 1];
  1961. bwx_DEBUG(__FUNCTION__);
  1962. IsFound = FALSE;
  1963. /* Get OPERATOR */
  1964. adv_element(l->buffer, &(l->position), tbuf);
  1965. StripQuotes( tbuf );
  1966. {
  1967. /* Name */
  1968. int i;
  1969. for( i = 0; i < NUM_OPERATORS; i++ )
  1970. {
  1971. if( strcasecmp( tbuf, exp_ops[i].symbol ) == 0 )
  1972. {
  1973. /* FOUND */
  1974. /* DISABLE OPERATOR */
  1975. exp_ops[i].OptionVersionBitmask &= ~OptionVersion;
  1976. IsFound = TRUE;
  1977. }
  1978. }
  1979. }
  1980. if( IsFound == FALSE )
  1981. {
  1982. /* display warning message */
  1983. sprintf( bwb_ebuf, "IGNORED: %s", l->buffer);
  1984. puts(bwb_ebuf);
  1985. }
  1986. return bwb_zline(l);
  1987. }
  1988. struct bwb_line *
  1989. bwb_OPTION_ENABLE_COMMAND(struct bwb_line * l)
  1990. {
  1991. /* OPTION ENABLE COMMAND ... */
  1992. int IsFound;
  1993. char tbuf[BasicStringLengthMax + 1];
  1994. bwx_DEBUG(__FUNCTION__);
  1995. IsFound = FALSE;
  1996. /* Get COMMAND */
  1997. adv_element(l->buffer, &(l->position), tbuf);
  1998. StripQuotes( tbuf );
  1999. {
  2000. /* Name */
  2001. int i;
  2002. for( i = 0; i < NUM_COMMANDS; i++ )
  2003. {
  2004. if( strcasecmp( tbuf, bwb_cmdtable[i].name ) == 0 )
  2005. {
  2006. /* FOUND */
  2007. /* ENABLE COMMAND */
  2008. bwb_cmdtable[i].OptionVersionBitmask |= OptionVersion;
  2009. IsFound = TRUE;
  2010. }
  2011. }
  2012. }
  2013. if( IsFound == FALSE )
  2014. {
  2015. /* display warning message */
  2016. sprintf( bwb_ebuf, "IGNORED: %s", l->buffer);
  2017. puts(bwb_ebuf);
  2018. }
  2019. return bwb_zline(l);
  2020. }
  2021. struct bwb_line *
  2022. bwb_OPTION_ENABLE_FUNCTION(struct bwb_line * l)
  2023. {
  2024. /* OPTION ENABLE FUNCTION ... */
  2025. int IsFound;
  2026. char tbuf[BasicStringLengthMax + 1];
  2027. bwx_DEBUG(__FUNCTION__);
  2028. IsFound = FALSE;
  2029. /* Get FUNCTION */
  2030. adv_element(l->buffer, &(l->position), tbuf);
  2031. StripQuotes( tbuf );
  2032. {
  2033. /* Name */
  2034. int i;
  2035. for( i = 0; i < NUM_FUNCTIONS; i++ )
  2036. {
  2037. if( strcasecmp( tbuf, bwb_prefuncs[i].Name ) == 0 )
  2038. {
  2039. /* FOUND */
  2040. /* ENABLE FUNCTION */
  2041. bwb_prefuncs[i].OptionVersionBitmask |= OptionVersion;
  2042. IsFound = TRUE;
  2043. }
  2044. }
  2045. }
  2046. if( IsFound == FALSE )
  2047. {
  2048. /* display warning message */
  2049. sprintf( bwb_ebuf, "IGNORED: %s", l->buffer);
  2050. puts(bwb_ebuf);
  2051. }
  2052. return bwb_zline(l);
  2053. }
  2054. struct bwb_line *
  2055. bwb_OPTION_ENABLE_OPERATOR(struct bwb_line * l)
  2056. {
  2057. /* OPTION ENABLE OPERATOR ... */
  2058. int IsFound;
  2059. char tbuf[BasicStringLengthMax + 1];
  2060. bwx_DEBUG(__FUNCTION__);
  2061. IsFound = FALSE;
  2062. /* Get OPERATOR */
  2063. adv_element(l->buffer, &(l->position), tbuf);
  2064. StripQuotes( tbuf );
  2065. {
  2066. /* Name */
  2067. int i;
  2068. for( i = 0; i < NUM_OPERATORS; i++ )
  2069. {
  2070. if( strcasecmp( tbuf, exp_ops[i].symbol ) == 0 )
  2071. {
  2072. /* FOUND */
  2073. /* ENABLE OPERATOR */
  2074. exp_ops[i].OptionVersionBitmask |= OptionVersion;
  2075. IsFound = TRUE;
  2076. }
  2077. }
  2078. }
  2079. if( IsFound == FALSE )
  2080. {
  2081. /* display warning message */
  2082. sprintf( bwb_ebuf, "IGNORED: %s", l->buffer);
  2083. puts(bwb_ebuf);
  2084. }
  2085. return bwb_zline(l);
  2086. }
  2087. struct bwb_line *
  2088. bwb_OPTION_ERROR_GOSUB(struct bwb_line * l)
  2089. {
  2090. bwx_DEBUG(__FUNCTION__);
  2091. /* OPTION ERROR GOSUB */
  2092. OptionFlags |= OPTION_ERROR_GOSUB;
  2093. return bwb_zline(l);
  2094. }
  2095. struct bwb_line *
  2096. bwb_OPTION_ERROR_GOTO(struct bwb_line * l)
  2097. {
  2098. bwx_DEBUG(__FUNCTION__);
  2099. /* OPTION ERROR GOTO */
  2100. OptionFlags &= ~OPTION_ERROR_GOSUB;
  2101. return bwb_zline(l);
  2102. }
  2103. struct bwb_line *
  2104. bwb_OPTION_INDENT(struct bwb_line * l)
  2105. {
  2106. /* OPTION VERSION ... */
  2107. char tbuf[BasicStringLengthMax + 1];
  2108. struct exp_ese *e;
  2109. int pos;
  2110. /* Get starting position (expression) */
  2111. adv_element(l->buffer, &(l->position), tbuf);
  2112. pos = 0;
  2113. e = bwb_exp(tbuf, FALSE, &pos);
  2114. if (ERROR_PENDING)
  2115. {
  2116. return bwb_zline(l);
  2117. }
  2118. if (e->type == STRING)
  2119. {
  2120. sprintf(bwb_ebuf, "Type Mismatch");
  2121. bwb_error(bwb_ebuf);
  2122. return bwb_zline(l);
  2123. }
  2124. OptionIndentValue = exp_getival(e);
  2125. return bwb_zline(l);
  2126. }
  2127. struct bwb_line *
  2128. bwb_OPTION_LABELS_ON(struct bwb_line * l)
  2129. {
  2130. bwx_DEBUG(__FUNCTION__);
  2131. /* OPTION LABELS ON */
  2132. OptionFlags |= OPTION_LABELS_ON;
  2133. return bwb_zline(l);
  2134. }
  2135. struct bwb_line *
  2136. bwb_OPTION_LABELS_OFF(struct bwb_line * l)
  2137. {
  2138. bwx_DEBUG(__FUNCTION__);
  2139. /* OPTION LABELS OFF */
  2140. OptionFlags &= ~OPTION_LABELS_ON;
  2141. return bwb_zline(l);
  2142. }
  2143. struct bwb_line *
  2144. bwb_OPTION_STATEMENT(struct bwb_line * l)
  2145. {
  2146. bwx_DEBUG(__FUNCTION__);
  2147. /* OPTION STATEMENT char */
  2148. OptionStatementChar = l->buffer[l->position];
  2149. if( OptionStatementChar != '\0' )
  2150. {
  2151. l->position++;
  2152. }
  2153. return bwb_zline(l);
  2154. }
  2155. struct bwb_line *
  2156. bwb_OPTION_STRICT_ON(struct bwb_line * l)
  2157. {
  2158. bwx_DEBUG(__FUNCTION__);
  2159. /* OPTION STRICT ON */
  2160. OptionFlags |= OPTION_STRICT_ON;
  2161. return bwb_zline(l);
  2162. }
  2163. struct bwb_line *
  2164. bwb_OPTION_STRICT_OFF(struct bwb_line * l)
  2165. {
  2166. bwx_DEBUG(__FUNCTION__);
  2167. /* OPTION STRICT OFF */
  2168. OptionFlags &= ~OPTION_STRICT_ON;
  2169. return bwb_zline(l);
  2170. }
  2171. struct bwb_line *
  2172. bwb_OPTION_TERMINAL_NONE(struct bwb_line * l)
  2173. {
  2174. bwx_DEBUG(__FUNCTION__);
  2175. /* OPTION TERMINAL NONE */
  2176. OptionTerminalType = C_OPTION_TERMINAL_NONE;
  2177. return bwb_zline(l);
  2178. }
  2179. struct bwb_line *
  2180. bwb_OPTION_TERMINAL_ADM_3A(struct bwb_line * l)
  2181. {
  2182. bwx_DEBUG(__FUNCTION__);
  2183. /* OPTION TERMINAL ADM-3A */
  2184. OptionTerminalType = C_OPTION_TERMINAL_ADM_3A;
  2185. return bwb_zline(l);
  2186. }
  2187. struct bwb_line *
  2188. bwb_OPTION_TERMINAL_ANSI(struct bwb_line * l)
  2189. {
  2190. bwx_DEBUG(__FUNCTION__);
  2191. /* OPTION TERMINAL ANSI */
  2192. OptionTerminalType = C_OPTION_TERMINAL_ANSI;
  2193. return bwb_zline(l);
  2194. }
  2195. struct bwb_line *
  2196. bwb_OPTION_TIME(struct bwb_line * l)
  2197. {
  2198. /* OPTION TIME format */
  2199. char tbuf[BasicStringLengthMax + 1];
  2200. bwx_DEBUG(__FUNCTION__);
  2201. /* Get FORMAT */
  2202. adv_element(l->buffer, &(l->position), tbuf);
  2203. StripQuotes( tbuf );
  2204. tbuf[80] = '\0';
  2205. strcpy( OptionTimeFormat, tbuf );
  2206. return bwb_zline(l);
  2207. }
  2208. struct bwb_line *
  2209. bwb_OPTION_TRACE_ON(struct bwb_line * l)
  2210. {
  2211. bwx_DEBUG(__FUNCTION__);
  2212. /* OPTION TRACE ON */
  2213. OptionFlags |= OPTION_TRACE_ON;
  2214. return bwb_zline(l);
  2215. }
  2216. struct bwb_line *
  2217. bwb_OPTION_TRACE_OFF(struct bwb_line * l)
  2218. {
  2219. bwx_DEBUG(__FUNCTION__);
  2220. /* OPTION TRACE OFF */
  2221. OptionFlags &= ~OPTION_TRACE_ON;
  2222. return bwb_zline(l);
  2223. }
  2224. struct bwb_line *
  2225. bwb_OPTION_VERSION(struct bwb_line * l)
  2226. {
  2227. /* OPTION VERSION ... */
  2228. char tbuf[BasicStringLengthMax + 1];
  2229. int i;
  2230. bwx_DEBUG(__FUNCTION__);
  2231. adv_element(l->buffer, &(l->position), tbuf);
  2232. for (i = 0; i < NUM_VERSIONS; i++)
  2233. {
  2234. if (strcasecmp(tbuf, bwb_vertable[i].Name) == 0)
  2235. {
  2236. /* FOUND */
  2237. OptionVersionSet(i);
  2238. return bwb_zline(l);
  2239. }
  2240. }
  2241. /* NOT FOUND */
  2242. sprintf(bwb_ebuf, "OPTION VERSION %s IS INVALID. VALID CHOICES ARE:", tbuf);
  2243. puts(bwb_ebuf);
  2244. for (i = 0; i < NUM_VERSIONS; i++)
  2245. {
  2246. sprintf(bwb_ebuf, "OPTION VERSION %s ' %s",
  2247. bwb_vertable[i].Name, bwb_vertable[i].Description);
  2248. puts(bwb_ebuf);
  2249. }
  2250. return bwb_zline(l);
  2251. }
  2252. /***************************************************************
  2253. FUNCTION: var_findnval()
  2254. DESCRIPTION: This function returns the address of
  2255. the number for the variable <v>. If
  2256. <v> is a dimensioned array, the address
  2257. returned is for the BasicNumberType at the
  2258. position indicated by the integer array
  2259. <pp>.
  2260. ***************************************************************/
  2261. BasicNumberType *
  2262. var_findnval(struct bwb_variable * v, int *pp)
  2263. {
  2264. size_t offset;
  2265. BasicNumberType *p;
  2266. bwx_DEBUG(__FUNCTION__);
  2267. /* Check for appropriate type */
  2268. if (v->type != NUMBER)
  2269. {
  2270. sprintf(bwb_ebuf, "in var_findnval(): Variable <%s> is not a number.",
  2271. v->name);
  2272. bwb_error(bwb_ebuf);
  2273. return NULL;
  2274. }
  2275. /* Check subscripts */
  2276. if (dim_check(v, pp) == FALSE)
  2277. {
  2278. return NULL;
  2279. }
  2280. /* Calculate and return the address of the dimensioned array */
  2281. offset = dim_unit(v, pp);
  2282. p = v->memnum;
  2283. return (p + offset);
  2284. }
  2285. /***************************************************************
  2286. FUNCTION: var_findsval()
  2287. DESCRIPTION: This function returns the address of
  2288. the string for the variable <v>. If
  2289. <v> is a dimensioned array, the address
  2290. returned is for the string at the
  2291. position indicated by the integer array
  2292. <pp>.
  2293. ***************************************************************/
  2294. bstring *
  2295. var_findsval(struct bwb_variable * v, int *pp)
  2296. {
  2297. size_t offset;
  2298. bstring *p;
  2299. bwx_DEBUG(__FUNCTION__);
  2300. /* Check for appropriate type */
  2301. if (v->type != STRING)
  2302. {
  2303. sprintf(bwb_ebuf, "in var_findsval(): Variable <%s> is not a string.", v->name);
  2304. bwb_error(bwb_ebuf);
  2305. return NULL;
  2306. }
  2307. /* Check subscripts */
  2308. if (dim_check(v, pp) == FALSE)
  2309. {
  2310. return NULL;
  2311. }
  2312. /* Calculate and return the address of the dimensioned array */
  2313. offset = dim_unit(v, pp);
  2314. p = v->memstr;
  2315. return (p + offset);
  2316. }
  2317. /***************************************************************
  2318. FUNCTION: dim_check()
  2319. DESCRIPTION: This function checks subscripts of a
  2320. specific variable to be sure that they
  2321. are within the correct range.
  2322. ***************************************************************/
  2323. static int
  2324. dim_check(struct bwb_variable * v, int *pp)
  2325. {
  2326. register int n;
  2327. /* Check for dimensions */
  2328. if (v->dimensions < 1)
  2329. {
  2330. sprintf(bwb_ebuf, "in dim_check(): var <%s> dimensions <%d>",
  2331. v->name, v->dimensions);
  2332. bwb_error(bwb_ebuf);
  2333. return FALSE;
  2334. }
  2335. /* Check for validly allocated array */
  2336. if ((v->type == NUMBER) && (v->memnum == NULL))
  2337. {
  2338. sprintf(bwb_ebuf, "in dim_check(): numerical var <%s> memnum not allocated",
  2339. v->name);
  2340. bwb_error(bwb_ebuf);
  2341. return FALSE;
  2342. }
  2343. if ((v->type == STRING) && (v->memstr == NULL))
  2344. {
  2345. sprintf(bwb_ebuf, "in dim_check(): string var <%s> memstr not allocated",
  2346. v->name);
  2347. bwb_error(bwb_ebuf);
  2348. return FALSE;
  2349. }
  2350. /* Now check subscript values */
  2351. for (n = 0; n < v->dimensions; ++n)
  2352. {
  2353. if ((pp[n] < dim_base) || ((pp[n] + (1 - dim_base)) > v->array_sizes[n]))
  2354. {
  2355. sprintf(bwb_ebuf, "SUBSCRIPT OUT OF RANGE %s(%d)", v->name, pp[n]);
  2356. bwb_error(bwb_ebuf);
  2357. return FALSE;
  2358. }
  2359. }
  2360. /* No problems found */
  2361. return TRUE;
  2362. }
  2363. /***************************************************************
  2364. FUNCTION: var_make()
  2365. DESCRIPTION: This function initializes a variable,
  2366. allocating necessary memory for it.
  2367. ***************************************************************/
  2368. int
  2369. var_make(struct bwb_variable * v, int type)
  2370. {
  2371. bwx_DEBUG(__FUNCTION__);
  2372. switch (type)
  2373. {
  2374. case STRING:
  2375. v->type = STRING;
  2376. break;
  2377. default:
  2378. v->type = NUMBER;
  2379. break;
  2380. }
  2381. /* get memory for array */
  2382. /* First kleanup the joint (JBV) */
  2383. if (v->memnum != NULL)
  2384. {
  2385. /* Revised to FREE pass-thru call by JBV */
  2386. FREE(v->memnum, "var_make");
  2387. v->memnum = NULL;
  2388. }
  2389. if (v->memstr != NULL)
  2390. {
  2391. /* Remember to deallocate those far-flung branches! (JBV) */
  2392. bstring *sp; /* JBV */
  2393. register int n; /* JBV */
  2394. sp = v->memstr;
  2395. for (n = 0; n < (int) v->array_units; ++n)
  2396. {
  2397. if (sp[n].sbuffer != NULL)
  2398. {
  2399. /* Revised to FREE pass-thru call by JBV */
  2400. FREE(sp[n].sbuffer, "var_make");
  2401. sp[n].sbuffer = NULL;
  2402. }
  2403. sp[n].rab = FALSE;
  2404. sp[n].length = 0;
  2405. }
  2406. /* Revised to FREE pass-thru call by JBV */
  2407. FREE(v->memstr, "var_make");
  2408. v->memstr = NULL;
  2409. }
  2410. /* Revised to FREE pass-thru calls by JBV */
  2411. if (v->array_sizes != NULL)
  2412. {
  2413. FREE(v->array_sizes, "var_make");
  2414. v->array_sizes = NULL; /* JBV */
  2415. }
  2416. if (v->array_pos != NULL)
  2417. {
  2418. FREE(v->array_pos, "var_make");
  2419. v->array_pos = NULL; /* JBV */
  2420. }
  2421. if (v->type == NUMBER)
  2422. {
  2423. /* Revised to CALLOC pass-thru call by JBV */
  2424. if ((v->memnum = CALLOC(2, sizeof(BasicNumberType), "var_make")) == NULL)
  2425. {
  2426. bwb_error(err_getmem);
  2427. return FALSE;
  2428. }
  2429. }
  2430. else
  2431. {
  2432. /* Revised to CALLOC pass-thru call by JBV */
  2433. if ((v->memstr = CALLOC(2, sizeof(bstring), "var_make")) == NULL)
  2434. {
  2435. bwb_error(err_getmem);
  2436. return FALSE;
  2437. }
  2438. }
  2439. /* get memory for array_sizes and array_pos */
  2440. /* Revised to CALLOC pass-thru call by JBV */
  2441. if ((v->array_sizes = (int *) CALLOC(2, sizeof(int), "var_make")) == NULL)
  2442. {
  2443. bwb_error(err_getmem);
  2444. return FALSE;
  2445. }
  2446. /* Revised to CALLOC pass-thru call by JBV */
  2447. if ((v->array_pos = (int *) CALLOC(2, sizeof(int), "var_make")) == NULL)
  2448. {
  2449. bwb_error(err_getmem);
  2450. return FALSE;
  2451. }
  2452. v->array_pos[0] = dim_base;
  2453. v->array_sizes[0] = 1;
  2454. v->dimensions = 1;
  2455. v->common = FALSE;
  2456. v->array_units = 1;
  2457. v->IsInDim = 0;
  2458. if (type == STRING)
  2459. {
  2460. bstring *b;
  2461. b = var_findsval(v, v->array_pos);
  2462. b->rab = FALSE;
  2463. }
  2464. return TRUE;
  2465. }
  2466. /***************************************************************
  2467. FUNCTION: var_islocal()
  2468. DESCRIPTION: This function determines whether the string
  2469. pointed to by 'buffer' has the name of
  2470. a local variable at the present EXEC stack
  2471. level.
  2472. ***************************************************************/
  2473. static struct bwb_variable *
  2474. var_islocal(char *buffer)
  2475. {
  2476. struct bwb_variable *v;
  2477. bwx_DEBUG(__FUNCTION__);
  2478. /* Prevent the expression in the initial value of the for loop below
  2479. * from violating the lower bound of the "excs" array. This would
  2480. * happen during startup when "exsc" is initially set to -1 and
  2481. * bwbasic.exe would fail with a memory exception when compiled with
  2482. * Open Watcom C. */
  2483. if (CURTASK exsc >= 0)
  2484. {
  2485. int i;
  2486. for (i = CURTASK exsc; i >= 0; i--)
  2487. {
  2488. for (v = CURTASK excs[i].local_variable; v != NULL; v = v->next)
  2489. {
  2490. if (strcasecmp(v->name, buffer) == 0)
  2491. {
  2492. /* FOUND */
  2493. return v;
  2494. }
  2495. }
  2496. if (CURTASK excs[i].LoopTopLine != NULL)
  2497. {
  2498. switch (CURTASK excs[i].LoopTopLine->cmdnum)
  2499. {
  2500. case C_FUNCTION:
  2501. case C_SUB:
  2502. /* we have checked all the way to a
  2503. * FUNCTION or SUB boundary */
  2504. /* NOT FOUND */
  2505. return NULL;
  2506. break;
  2507. }
  2508. }
  2509. }
  2510. }
  2511. /* NOT FOUND */
  2512. return NULL;
  2513. }
  2514. /***************************************************************
  2515. FUNCTION: bwb_vars()
  2516. DESCRIPTION: This function implements the Bywater-
  2517. specific debugging command VARS, which
  2518. gives a list of all variables defined
  2519. in memory.
  2520. ***************************************************************/
  2521. struct bwb_line *
  2522. bwb_VARS(struct bwb_line * l)
  2523. {
  2524. struct bwb_variable *v;
  2525. char tbuf[BasicStringLengthMax + 1];
  2526. bwx_DEBUG(__FUNCTION__);
  2527. /* run through the variable list and print variables */
  2528. for (v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next)
  2529. {
  2530. sprintf(bwb_ebuf, "variable <%s>\t", v->name);
  2531. prn_xprintf(bwb_ebuf);
  2532. switch (v->type)
  2533. {
  2534. case STRING:
  2535. str_btoc(tbuf, var_getsval(v));
  2536. sprintf(bwb_ebuf, "STRING\tval: <%s>\n", tbuf);
  2537. prn_xprintf(bwb_ebuf);
  2538. break;
  2539. case NUMBER:
  2540. sprintf(bwb_ebuf, "NUMBER\tval: <" BasicNumberPrintFormat ">\n", var_getnval(v));
  2541. prn_xprintf(bwb_ebuf);
  2542. break;
  2543. default:
  2544. sprintf(bwb_ebuf, "ERROR: type is <%c>", (char) v->type);
  2545. prn_xprintf(bwb_ebuf);
  2546. break;
  2547. }
  2548. }
  2549. return bwb_zline(l);
  2550. }
  2551. /* EOF */