#include <perms.h> #undef Itos #undef Trim _imp_string Itos(int i) { } void Trim(_imp_string S, int *Flag) { } // *********************************************************************** // * SOAP80 - IMP80 formatter * // * Last altered 15/06/83 * // * * // * Created by E.N.Gregory, UKC. * // * All syntax directed sections rewritten by P.D.S., ERCC * // * using IMP80 syntax version 02. * // * User interface and parameters revised by J.M.M., ERCC. * // * * // *********************************************************************** // We''ll need to supply some lookalike routines for the various // EMAS system library calls below. I''ve converted the external specs // into bodies, but haven''t written them yet. - GT //_imp_string Cliparam(void); //void Prompt(_imp_string *S) {} // *********************************************************************** // * * // * Record formats. * // * * // *********************************************************************** typedef struct Fhdr { int Dataend; int Datastart; int Filesize; int Filetype; } Fhdr; typedef struct Chdr { int Conad; int Filetype; int Datastart; int Dataend; } Chdr; static const int Maxopt = 16; static const int Numopt = 3; typedef struct Pformat { unsigned char Tab[21 /*0:20*/]; union { struct { union { struct { unsigned char dummy, Line, Icontin, Poscom, Movecom, Uckey, Sepkey, Expkey, Lcasnam, Spacnam, Spacass, Spacop, Lclist, Iblock, Istat, Seplab, Spcomma; }; unsigned char Optarr[1+ 16/*Maxopt*/]; }; }; unsigned char A[1+ 21+16/*Maxopt*/]; }; } Pformat; // *********************************************************************** // * * // * System routines. * // * * // *********************************************************************** void Connect(_imp_string *Name, int Mode, int Hole, int Prot, Chdr *Rec, int *Eflag) {} void Setfname(_imp_string File) {} _imp_string Nexttemp(void) { return (_imp_str_literal("")); } void Sendfile(_imp_string File, _imp_string Device, _imp_string Header, int Copies, int Form, int *Eflag) {} int Devcode(_imp_string Name) { return (0); } void Disconnect(_imp_string *Filename, int *Eflag) {} _imp_string Failuremessage(int Type) { return (_imp_str_literal("")); } void Changefilesize(_imp_string *Filename, int Filesize, int *Eflag) {} void Newgen(_imp_string *Filename, _imp_string *Newfilename, int *Eflag) {} void Outfile(_imp_string *Filename, int Size, int Hole, int Prot, int *Conad, int *Eflag) {} void Readprofile(_imp_string Key, Pformat *Info, int *Version, int *Uflag) {} void Writeprofile(_imp_string *Key, Pformat *Info, int *Version, int *Uflag) {} int _imp_mainep(int _imp_argc, char **_imp_argv) { _imp_string S; // argv[1] // %external %routine soap80(%string (255) s) int Ptr; int Dataend; int Inptr; int Z; int In; int Obp; int Eflag; int Writeaddress; int Wa0; int Filesize; int Conad; int Errors; int Line; int Erptr; int Startline; int Stream; int Filesizeptr; int Ssalt; int Strdelimiter; int Str; int Semicolon; int Colon; int Maxptr; int Maxitem; int Level; int Stop; int Increm; int Inlabel; int Charsin; int Ersave; int Inconst; int Bheading; int Inline; _imp_string Outf; _imp_string Workfile; _imp_string Infile; _imp_string Percentc; Pformat P; Chdr Rec; Chdr Rr; Fhdr *Outrec; static const int Ccsize = 16384; short Outbuf[16585 /*0:16584*/]; unsigned char Sc[16385 /*0:16384*/]; static const _imp_string Optname[1+16 /*1:16*/] = { _imp_str_literal(""), _imp_str_literal("LINE"), _imp_str_literal("ICONTIN"), _imp_str_literal("POSCOM"), _imp_str_literal("MOVECOM"), _imp_str_literal("UCKEY"), _imp_str_literal("SEPKEY"), _imp_str_literal("EXPKEY"), _imp_str_literal("LCASNAM"), _imp_str_literal("SPACNAM"), _imp_str_literal("SPACASS"), _imp_str_literal("SPACOP"), _imp_str_literal("LCLIST"), _imp_str_literal("IBLOCK"), _imp_str_literal("ISTAT"), _imp_str_literal("SEPLAB"), _imp_str_literal("SPCOMMA")}; // !%constant %string (255) %array optmess(0:1, 1:maxopt)= ... static const _imp_string Optmess[2+32 /*2:33*/] = { _imp_str_literal(""),_imp_str_literal(""), _imp_str_literal("Line length zero (!!!)"), _imp_str_literal("Maximum line length"), _imp_str_literal("Continued lines not indented"), _imp_str_literal("Indentation of continued lines"), _imp_str_literal("Right hand comments not positioned"), _imp_str_literal("Right hand comment position"), _imp_str_literal("Whole line comments indented normally"), _imp_str_literal("Whole line comments moved to POSCOM"), _imp_str_literal("Keywords output in lower case"), _imp_str_literal("Keywords output in upper case"), _imp_str_literal("Keywords not split"), _imp_str_literal("Keywords split"), _imp_str_literal("%FN, %CONST, %ELSE not expanded"), _imp_str_literal("%FN, %CONST, (sometimes) %ELSE expanded"), _imp_str_literal("Case of names controlled by UCKEY"), _imp_str_literal("Case of names left alone"), _imp_str_literal("Spaces removed from names"), _imp_str_literal("Spaces preserved within names"), _imp_str_literal("No spaces round assignment operators"), _imp_str_literal("Spaces added round assignment operators"), _imp_str_literal("No spaces round operators"), _imp_str_literal("Spaces added round operators"), _imp_str_literal("Constant lists formatted"), _imp_str_literal("Constant lists left alone"), _imp_str_literal("Block not indented w.r.t. block heading"), _imp_str_literal("Block indented w.r.t. block heading"), _imp_str_literal("Statements aligned with declarations"), _imp_str_literal("Statements indented w.r.t. declarations"), _imp_str_literal("Labels not on lines by themselves"), _imp_str_literal("Labels on lines by themselves"), _imp_str_literal("No space character after commas"), _imp_str_literal("Space character after commas")}; static const int Charfile = 3; // Code for a character file. static const int Underline = 128; static const int Instring = 256; static const int Incurly = 512; static const int Bpoint = 1024; static const int Bpoint2 = 2048; static const int Terminal = 1; static const int File = 2; static const int Samefile = 3; static const int Device = 4; static const int True = 255; static const int False = 0; // Synthetic boolean values. // static const int Nl = 10; static const int Dquotes = 34; static const int Squotes = 39; static const int Rs = 30; // RECORD SEPARATOR IS USED AS A DELETED(BY %c) Nl static const int Rem = 0b00000001; static const int Constart = 0b00000010; static const int Quotes = 0b00000100; static const int Endst = 0b00001000; static const int Number = 0b00010000; static const int Letter = 0b00100000; static const unsigned char Constfirst = 0b01000000; static const int Constcont = 0b10000000; // static const unsigned char Onecase[128 /*0:127*/] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127}; static const unsigned char Chartype[256 /*0:255*/] = { 0b00000001, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00001000, [11 ... 32] = 0b00000000, 0b00000001, 0b00000100, 0b01000000, 0b00000000, 0b00000001, 0b00000000, 0b00000100, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b11000000, 0b00000000, [48 ... 57] = 0b11010000, 0b00000000, 0b00001000, 0b01000000, 0b01000000, 0b01000000, 0b00000000, 0b00000000, 0b00100000, 0b00100010, 0b00100010, 0b00100010, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100010, 0b00100000, 0b00100010, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100010, 0b00100000, 0b00100000, 0b00100000, [86 ... 87] = 0b00100000, 0b00100010, 0b00100000, 0b00100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00100000, 0b00100010, 0b00100010, 0b00100010, [101 ... 106] = 0b00100000, 0b00100010, 0b00100000, 0b00100010, [110 ... 113] = 0b00100000, 0b00100010, [115 ... 119] = 0b00100000, 0b00100010, [121 ... 122] = 0b00100000, 0b00000000, 0b00000001, 0b00000000, 0b00000000, 0b00000000, [128 ... 194] = 0b0, 0b00000001, [196 ... 255] = 0b0}; static const unsigned char Keycom[8 /*0:7*/] = {'%', 'C', 'O', 'M', 'M', 'E', 'N', 'T'}; static const int Fstable[1+ 3 /*1:3*/] = {0, 4096, 16384, 65536}; // // Special delimiters noted by SOAP80. // static const int Offile = 133; static const int Ofprogram = 123; static const int Equals = 38; static const int Comma = 10; static const int If = 12; static const int Unless = 15; static const int While = 22; static const int Until = 28; static const int Else = 227; static const int Then = 222; static const int And = 158; static const int Or = 162; static const int Const = 204; static const int Constant = 195; static const int Fn = 96; static const int Function = 103; // // static const _imp_string Snl = _imp_str_literal("\n"); // static const _imp_string Fault[1+ 4 /*1:4*/] = {_imp_str_literal(""), _imp_str_literal("Statement is too long and could not be compiled."), _imp_str_literal( "End of file reached before end of program terminator found."), _imp_str_literal( "%END found, but could not match it to a start of routine."), _imp_str_literal("Disaster *** Indentation too near line length limit.")}; // // // auto void Fail(int Type, int Action); auto void Opt(_imp_string Parm, Pformat * P); // // Produced by oldps from impalgs_imp80ps04 on 19/01/83 static const unsigned char Clett[435 /*0:434*/] = { 1, 43, 1, 45, 1, 40, 1, 41, 1, 42, 1, 44, 2, 201, 198, 6, 213, 206, 204, 197, 211, 211, 5, 215, 200, 201, 204, 197, 5, 213, 206, 212, 201, 204, 3, 198, 207, 210, 1, 61, 5, 193, 204, 201, 193, 211, 7, 201, 206, 212, 197, 199, 197, 210, 4, 210, 197, 193, 204, 4, 204, 207, 206, 199, 4, 194, 217, 212, 197, 6, 211, 212, 210, 201, 206, 199, 4, 200, 193, 204, 198, 6, 210, 197, 195, 207, 210, 196, 7, 210, 207, 213, 212, 201, 206, 197, 2, 198, 206, 3, 205, 193, 208, 8, 198, 213, 206, 195, 212, 201, 207, 206, 4, 206, 193, 205, 197, 5, 193, 210, 210, 193, 217, 9, 207, 198, 208, 210, 207, 199, 210, 193, 205, 6, 207, 198, 198, 201, 204, 197, 6, 207, 198, 204, 201, 211, 212, 6, 198, 207, 210, 205, 193, 212, 3, 206, 207, 212, 3, 193, 206, 196, 2, 207, 210, 1, 58, 4, 211, 208, 197, 195, 3, 207, 215, 206, 8, 197, 216, 212, 197, 210, 206, 193, 204, 9, 197, 216, 212, 210, 201, 206, 211, 201, 195, 8, 195, 207, 206, 211, 212, 193, 206, 212, 5, 195, 207, 206, 211, 212, 5, 197, 214, 197, 206, 212, 5, 211, 212, 193, 210, 212, 4, 212, 200, 197, 206, 4, 197, 204, 211, 197, 1, 95, 6, 211, 217, 211, 212, 197, 205, 7, 196, 217, 206, 193, 205, 201, 195, 4, 80, 85, 84, 95, 5, 67, 78, 79, 80, 95, 2, 204, 61, 1, 60, 1, 62, 4, 40, 196, 210, 43, 2, 196, 210, 1, 194, 3, 212, 207, 211, 3, 204, 206, 194, 3, 216, 206, 194, 2, 208, 195, 3, 195, 212, 194, 2, 45, 62, 6, 210, 197, 212, 213, 210, 206, 6, 210, 197, 211, 213, 204, 212, 7, 205, 207, 206, 201, 212, 207, 210, 4, 211, 212, 207, 208, 6, 211, 201, 199, 206, 193, 204, 4, 197, 216, 201, 212, 8, 195, 207, 206, 212, 201, 206, 213, 197, 6, 198, 201, 206, 201, 211, 200, 5, 195, 217, 195, 204, 197, 6, 210, 197, 208, 197, 193, 212, 3, 197, 206, 196, 7, 201, 206, 195, 204, 213, 196, 197, 5, 194, 197, 199, 201, 206, 2, 207, 206, 6, 211, 215, 201, 212, 195, 200, 4, 204, 201, 211, 212, 14, 212, 210, 213, 211, 212, 197, 196, 208, 210, 207, 199, 210, 193, 205, 6, 205, 193, 201, 206, 197, 208, 7, 195, 207, 206, 212, 210, 207, 204, 4, 40, 42, 41, 58}; static const int Symbol[1300+ 868 /*1300:2167*/] = {[0 ... 1299] = 0, 1307, 1303, 0, 1305, 2, 1307, 1000, 1319, 1312, 1001, 1366, 1786, 1315, 1003, 1020, 1319, 4, 1345, 6, 1329, 1323, 1001, 1014, 1325, 1003, 1329, 4, 1329, 6, 1336, 1336, 1010, 1028, 1319, 1011, 1359, 1345, 1343, 1010, 1028, 1319, 1011, 1359, 1345, 8, 1352, 1352, 1010, 1028, 1307, 1011, 1352, 1359, 1357, 1026, 1307, 999, 1359, 1000, 1366, 1364, 1026, 1319, 999, 1366, 1000, 1374, 1372, 4, 1345, 1374, 6, 1374, 1000, 1381, 1379, 10, 1345, 999, 1381, 1000, 1386, 1384, 12, 1386, 15, 1410, 1393, 22, 1010, 1536, 1556, 1011, 1399, 28, 1010, 1536, 1556, 1011, 1410, 34, 1010, 1001, 38, 1345, 10, 1345, 10, 1345, 1011, 1416, 1414, 40, 1013, 1416, 1000, 1423, 1421, 10, 1001, 999, 1423, 1000, 1428, 1426, 46, 1428, 1000, 1436, 1431, 54, 1433, 46, 1436, 59, 54, 1458, 1439, 46, 1441, 54, 1444, 59, 1428, 1447, 64, 1423, 1450, 69, 1689, 1453, 76, 1423, 1458, 81, 4, 1848, 6, 1465, 1461, 88, 1465, 1004, 1436, 1465, 1472, 1468, 96, 1470, 99, 1472, 103, 1488, 1478, 1436, 1493, 1001, 1416, 1484, 1458, 1488, 1001, 1416, 1501, 1488, 112, 1001, 1416, 1493, 1491, 112, 1493, 1000, 1501, 1497, 117, 112, 1499, 112, 1501, 1000, 1511, 1509, 4, 1010, 1472, 1011, 1511, 6, 1511, 1000, 1520, 1518, 1030, 1010, 1472, 1011, 999, 1520, 1000, 1531, 1524, 123, 1016, 1526, 133, 1529, 140, 1018, 1531, 1016, 1536, 1534, 147, 1536, 1000, 1550, 1542, 1345, 1032, 1345, 1550, 1547, 4, 1536, 1556, 6, 1550, 154, 1536, 1556, 1554, 1037, 1345, 1556, 1000, 1567, 1561, 158, 1536, 1567, 1565, 162, 1536, 1574, 1567, 1000, 1574, 1572, 158, 1536, 999, 1574, 1000, 1581, 1579, 162, 1536, 999, 1581, 1000, 1589, 1585, 1033, 1345, 1587, 165, 1589, 1000, 1595, 1593, 167, 1008, 1595, 1015, 1599, 1598, 167, 1599, 1608, 1606, 10, 1345, 165, 1345, 1599, 1608, 1000, 1617, 1613, 1493, 1001, 1416, 1617, 117, 1531, 1617, 1623, 1623, 1001, 1416, 1794, 1623, 1629, 1627, 10, 1617, 1629, 1000, 1646, 1639, 1493, 1595, 1010, 1001, 1410, 1802, 1011, 1646, 1646, 117, 1531, 1595, 1001, 1794, 1668, 1657, 1655, 10, 1010, 1001, 1410, 1802, 1011, 1646, 1657, 1000, 1668, 1660, 172, 1662, 176, 1664, 185, 1666, 195, 1668, 204, 1679, 1677, 38, 1012, 1028, 1319, 1359, 1689, 1679, 1679, 1000, 1689, 1687, 10, 1028, 1319, 1359, 1689, 999, 1689, 1000, 1696, 1694, 4, 1336, 6, 1696, 1000, 1703, 1701, 10, 1329, 999, 1703, 1000, 1708, 1706, 210, 1708, 1000, 1714, 1712, 10, 1345, 1714, 1000, 1727, 1725, 10, 1001, 1416, 4, 1345, 165, 1345, 6, 999, 1727, 1000, 1734, 1732, 28, 1536, 1556, 1734, 1000, 1747, 1737, 1019, 1739, 1006, 1744, 1381, 1536, 1556, 1006, 1747, 1386, 1006, 1761, 1751, 216, 1034, 1755, 222, 216, 1034, 1761, 222, 1010, 2008, 1011, 1767, 1767, 1765, 158, 2008, 1767, 1000, 1773, 1771, 227, 1773, 1773, 1000, 1786, 1777, 216, 1034, 1784, 1381, 1010, 1536, 1556, 1011, 1747, 1786, 2008, 1794, 1792, 232, 1001, 1366, 1786, 1794, 1000, 1802, 1802, 4, 1345, 165, 1345, 1599, 6, 1810, 1808, 38, 1028, 1319, 1359, 1810, 1000, 1819, 1813, 234, 1815, 176, 1817, 241, 1819, 1000, 1830, 1828, 1001, 38, 1345, 10, 1345, 10, 1345, 1830, 1000, 1837, 1835, 10, 1855, 999, 1837, 1000, 1848, 1841, 167, 1001, 1848, 1001, 4, 1855, 1830, 1873, 6, 1855, 1851, 1001, 1855, 1855, 1830, 1873, 1865, 1859, 1436, 1865, 1865, 4, 1855, 1830, 1873, 6, 1873, 1870, 1493, 1001, 1416, 1873, 117, 1617, 1881, 1879, 162, 1855, 1830, 999, 1881, 1000, 1898, 1886, 249, 1002, 1006, 1890, 1022, 1898, 1006, 1896, 254, 1009, 10, 1009, 1006, 1898, 1031, 1912, 1902, 1023, 1912, 1907, 1024, 260, 1951, 1956, 1912, 1025, 1005, 10, 1935, 1935, 1917, 263, 1001, 265, 1919, 1984, 1924, 4, 1984, 1973, 6, 1928, 267, 1984, 6, 1933, 4, 272, 1973, 6, 1935, 275, 1951, 1940, 263, 1001, 265, 1942, 1984, 1947, 4, 272, 1973, 6, 1951, 267, 1005, 6, 1956, 1954, 272, 1956, 1005, 1964, 1962, 10, 1005, 10, 1005, 1964, 1000, 1973, 1968, 0, 1005, 1971, 2, 1005, 1973, 1000, 1979, 1977, 0, 275, 1979, 1000, 1984, 1982, 38, 1984, 1000, 1999, 1989, 1979, 1300, 1003, 1992, 1001, 1964, 1997, 4, 1999, 1964, 6, 1999, 277, 2008, 2002, 281, 2004, 285, 2006, 289, 2008, 292, 2041, 2017, 1010, 1001, 1366, 1786, 1011, 1581, 1761, 2021, 296, 1001, 1366, 2023, 299, 2027, 306, 1033, 1345, 2030, 313, 1761, 2032, 321, 2037, 326, 1703, 1329, 1708, 2039, 333, 2041, 338, 2168, 2048, 1027, 1010, 2008, 1011, 1734, 2050, 1007, 2058, 1381, 1010, 1536, 1556, 1011, 1747, 1006, 2063, 347, 1035, 1767, 1006, 2068, 354, 1029, 1819, 1006, 2073, 360, 1036, 1727, 1006, 2078, 1386, 354, 1029, 1006, 2086, 1004, 1008, 1010, 1436, 1011, 1608, 1006, 2090, 367, 1520, 1006, 2095, 81, 147, 1837, 1006, 2105, 1010, 1810, 1458, 1011, 1589, 1001, 1410, 1501, 1006, 2110, 1657, 1436, 1629, 1006, 2114, 371, 1003, 1038, 2118, 379, 1015, 1006, 2127, 385, 1021, 1703, 1329, 1696, 216, 1034, 1006, 2138, 388, 1001, 1416, 4, 1345, 165, 1345, 6, 1714, 1006, 2142, 395, 1006, 1017, 2148, 227, 1035, 1039, 1034, 1006, 2151, 8, 1881, 2154, 400, 1006, 2158, 415, 1001, 1006, 2162, 422, 1003, 1006, 2166, 1001, 430, 1019, 2168, 1006}; static const int Ss = 2041; static const int Comment = 2; // alt of p<SS> of %comment static const int Ownalt = 12; // alt of p<SS> for owns static const int Eisss = 0x00017F00; // Flag declarative ss alts // MAY CHANGE WITH NEW SYNTAX static const int Opc[128 /*0:127*/] = { 0, ' JCC', ' JAT', ' JAF', [4 ... 7] = 0, ' VAL', ' CYD', 'INCA', 'MODD', 'PRCL', ' J', ' JLK', 'CALL', ' ADB', ' SBB', 'DEBJ', ' CPB', ' SIG', ' MYB', ' VMY', 'CPIB', ' LCT', 'MPSR', 'CPSR', 'STCT', 'EXIT', 'ESEX', ' OUT', ' ACT', ' SL', 'SLSS', 'SLSD', 'SLSQ', ' ST', 'STUH', 'STXN', 'IDLE', ' SLD', ' SLB', 'TDEC', 'INCT', ' STD', ' STB', 'STLN', 'STSF', ' L', ' LSS', ' LSD', ' LSQ', 'RRTC', ' LUH', 'RALN', ' ASF', 'LDRL', ' LDA', 'LDTB', ' LDB', ' LD', ' LB', ' LLN', ' LXN', ' TCH', 'ANDS', ' ORS', 'NEQS', 'EXPA', ' AND', ' OR', ' NEQ', ' PK', ' INS', 'SUPK', ' EXP', 'COMA', ' DDV', 'DRDV', 'DMDV', 'SWEQ', 'SWNE', ' CPS', ' TTR', ' FLT', ' IDV', 'IRDV', 'IMDV', ' MVL', ' MV', 'CHOV', ' COM', ' FIX', ' RDV', 'RRDV', 'RDVD', ' UAD', ' USB', 'URSB', ' UCP', ' USH', ' ROT', ' SHS', ' SHZ', ' DAD', ' DSB', 'DRSB', ' DCP', ' DSH', ' DMY', 'DMYD', 'CBIN', ' IAD', ' ISB', 'IRSB', ' ICP', ' ISH', ' IMY', 'IMYD', 'CDEC', ' RAD', ' RSB', 'RRSB', ' RCP', ' RSC', ' RMY', 'RMYD', ' PUT'}; void Cnptf( void) { // *********************************************************************** // * Create New Page To File :- This is called when the output // file * // * is full and must be extended to a new page. * // *********************************************************************** if (Filesizeptr < 3) { Filesizeptr++; Filesize = Fstable[Filesizeptr]; } else Filesize += Fstable[3]; Changefilesize(&Workfile, Filesize, &Eflag); if (Eflag == 261) { // V.M. hole is too small for the new file size. Disconnect(&Workfile, &Eflag); if (Eflag) Fail(Eflag, 5); Changefilesize(&Workfile, Filesize, &Eflag); if (!Eflag) { Writeaddress -= Conad; Connect(&Workfile, 3, 0, 0, &Rr, &Eflag); if (Eflag) Fail(Eflag, 5); Conad = Rr.Conad; Writeaddress += Conad; Outrec = Record(Conad); } } if (Eflag) Fail(Eflag, 5); Outrec->Filesize = Filesize; // Update file size in header. } void Transfer( int From, int To) { // *********************************************************************** // * Transfer copies the contents of OUTBUF from FROM to TO // into the * // * output file or channel. * // *********************************************************************** int I; int Ch; int Last; if (Stream != Terminal) { Last = To - From + 1 + Writeaddress - Conad; if (Last > Filesize) Cnptf(); Outrec->Dataend = Last; } for (I = From; I <= To; I++) { Ch = Outbuf[I] & 0x7F; if ((Ch & 127) == Rs) continue; if (Ch == Nl) { Charsin = 0; Line++; if (Stream != Terminal) while (Writeaddress > Wa0 && *Byteinteger(Writeaddress - 1) == ' ') Writeaddress--; } else Charsin++; if (Stream == Terminal) Printsymbol(Ch); else { *Byteinteger(Writeaddress) = Ch; Writeaddress++; } } } void Outstring( _imp_string Text) { // *********************************************************************** // * Outstring copies TEXT to the output file or channel. // * // *********************************************************************** int I; int Ch; int Last; if (Stream != Terminal) { Last = *Length(Text) + Writeaddress - Conad; if (Last > Filesize) Cnptf(); Outrec->Dataend = Last; } for (I = 1; I <= *Length(Text); I++) { Ch = *Charno(Text, I); if (Ch == Nl) { Charsin = 0; Line++; } else Charsin++; if (Stream == Terminal) Printsymbol(Ch); else { *Byteinteger(Writeaddress) = Ch; Writeaddress++; } } } void Dupl( int Char, int Times) { // *********************************************************************** // * Dupl copies CHAR, TIMES times to the output file or // channel. * // *********************************************************************** int I; int Last; if (Times <= 0) return; Charsin += Times; if (Stream != Terminal) { Last = Times + Writeaddress - Conad; if (Last > Filesize) Cnptf(); Outrec->Dataend = Last; } for (I = 1; I <= Times; I++) if (Stream == Terminal) Printsymbol(Char); else { *Byteinteger(Writeaddress) = Char; Writeaddress++; } } void Insert( int Chars, int Lsflag, int Rsflag) { // *********************************************************************** // * This will place upto four characters into the OUTBUF // buffer this * // * includes the option of have spaces around the // characters. * // *********************************************************************** if (Lsflag == True && True != Inconst) { Outbuf[Obp] = ' '; Obp++; } do { Outbuf[Obp] = Chars & 0xFF; Chars = (unsigned)Chars >> 8; Obp++; } while (Chars); if (Rsflag == True && True != Inconst) { Outbuf[Obp] = ' '; Obp++; } } void Closedown( int Success) { // *********************************************************************** // * Closedown is called when the program is to // terminate execution * // * and is to print a suitable message and to close // the output file * // * if any. * // *********************************************************************** if (Success == True) Printstring(_imp_join( Itos(Line), _imp_join(_imp_str_literal(" lines have been processed"), Snl))); else { Printstring( _imp_join(_imp_str_literal("Soap80 fails :- "), Itos(Errors))); if (Errors == 1) Printstring(_imp_join(_imp_str_literal(" error."), Snl)); else Printstring(_imp_join(_imp_str_literal(" errors."), Snl)); } // Is there a file to close? if (Stream != Terminal) { Outrec->Dataend = Writeaddress - Conad; Trim(Workfile, &Eflag); Disconnect(&Workfile, &Eflag); if (Stream == Samefile) if (Errors > 0) Printstring(_imp_join( _imp_str_literal("Output stored in "), _imp_join(Workfile, _imp_join(_imp_str_literal(", since "), _imp_join(Infile, _imp_join(_imp_str_literal( " contains errors."), Snl)))))); else { Newgen(&Workfile, &Outf, &Eflag); if (Eflag) { Printstring(_imp_join( _imp_str_literal("Attempt to create "), _imp_join(Outf, _imp_join(_imp_str_literal(" failed because "), _imp_join(Failuremessage(Eflag), Snl))))); Printstring(_imp_join( _imp_str_literal("Output stored in "), _imp_join(Workfile, _imp_join(_imp_str_literal("."), Snl)))); } } else if (Stream == Device) { if (*Length(Infile) > 8) *Length(Infile) = 8; Sendfile(Workfile, Outf, _imp_join(_imp_str_literal("Soap80: "), Infile), 1, 0, &Eflag); if (Eflag) Fail(Eflag, 5); } } // ! pprofile REMOVED GT exit(0); // Exit from SOAP80. } void Punch( void) { // *********************************************************************** // * PUNCH is for tranferring the contents of the OUTBUF array * // * to the output file or channel, using TRANSFER, OUTSTRING and DUPL.* // * * // * PUNCH decides where to break a line if it is too long. * // *********************************************************************** int Lst; int Bk; int I; int Ubp; int Lbp; int Bbp; int Tp; int Inn; int Ch; int Curlend; Inn = In; if ((1 << Ssalt & Eisss) == 0 && P.Istat == True) Inn++; if (Ssalt != Comment && Semicolon == False) Dupl(' ', P.Tab[Inn] - Charsin); /*%if ssalt#comment %and semicolon=false %then dupl(' ', p_tab(inn)-charsin)*/ if (Outbuf[Obp - 1] == ';') Semicolon = True; else Semicolon = False; if (Semicolon == True && P.Line - 20 < Charsin + Obp) { Semicolon = False; Outbuf[Obp - 1] = Nl; } if (Semicolon == True) { Outbuf[Obp] = ' '; Obp++; } if (Increm == True) { Increm = False; // Is indenting value too near the line length limit? if (P.Tab[In+1] + 20 > P.Line) /*%if p_tab(in+1)+20>p_line %then fail(4, 2) %else in = in+1*/ Fail(4, 2); else In++; } Lst = 1; if (Ssalt == Comment) { // Look for RS in comment. If found, output as // more than one line. for (;;) { if ((Chartype[Sc[1]] & Rem) == 0 || Semicolon == True) { // Comment does not start in column 1. if ((Semicolon | Colon) == False && P.Movecom == False) Dupl(' ', P.Tab[Inn] - Charsin); /*dupl(' ', p_tab(inn)-charsin) %else dupl(' ', p_poscom-charsin)*/ else Dupl(' ', P.Poscom - Charsin); } I = Lst; while (I < Obp && (Outbuf[I] & 127) != Rs) I++; if (I == Obp) goto Finalpart; Transfer(Lst, I - 1); if ((Outbuf[I - 1] & 127) == ',') Outstring(Snl); else Outstring(_imp_join(Percentc, Snl)); do I++; while (I != Obp && Outbuf[I] == ' '); Lst = I; } } for (;;) { Ubp = P.Line + Lst - Charsin - 4; // RHMOST BREAK POINT Lbp = (Ubp + Lst) / 2; Bbp = (Ubp + 3 * Lst) / 4; Curlend = 0; // First check for nl in string const or list for (Bk = Lst; Bk <= Ubp + 3; Bk++) { if (Bk >= Obp) break; Ch = Outbuf[Bk]; if ((Ch & 127) == Nl || ((Ch & 127) == Rs && Ssalt == Ownalt && P.Lclist == True)) goto Printpart; } if (Obp < Ubp + 3) break; // 3 FOR " %C" for (Bk = Ubp; Bk >= Bbp; Bk--) { // CHECK FOR PRIMARY BREAK POINTS if (Outbuf[Bk] & Bpoint) { while (Outbuf[Bk + 1] == ' ') Bk++; goto Printpart; } } for (Bk = Ubp; Bk >= Bbp; Bk--) { // CHECK FOR SECONDARY BREAK POINT if (Outbuf[Bk] & Bpoint2) { while (Outbuf[Bk + 1] == ' ') Bk++; goto Printpart; } } for (Bk = Ubp; Bk >= Bbp; Bk--) if (Outbuf[Bk] == ',') goto Printpart; if (Outbuf[Ubp] & Incurly) { // IN A CURLY COMMENT Curlend = 1; for (Bk = Ubp; Bk <= Obp - 2; Bk++) if (!(Outbuf[Bk] & Incurly)) { Curlend = 0; break; } // curlend indicates whether the curly comment goes to the end of // the line. for (Bk = Ubp; Bk >= Bbp; Bk--) if (!(Outbuf[Bk] & Incurly)) { Bk--; goto Printpart; } if (Curlend == 1) goto Finalpart; // Overlong curly comment. for (Bk = Ubp; Bk <= Obp - 2; Bk++) if (!(Outbuf[Bk] & Incurly)) goto Printpart; } for (Bk = Ubp + 1; Bk >= Lbp; Bk--) if (Outbuf[Bk] == ' ' && (Outbuf[Bk - 1] & Underline) != 0) goto Printpart; if (!P.Spacnam) { // MUST OMIT IF NAMES ARE SPACED for (Bk = Ubp + 1; Bk >= Lbp; Bk--) if (Outbuf[Bk] == ' ') goto Printpart; } for (Bk = Ubp; Bk >= Lbp; Bk--) if (Outbuf[Bk] == '%') { Bk--; goto Printpart; } for (Bk = Ubp; Bk >= Lbp; Bk--) { if (Outbuf[Bk] == '.' || Outbuf[Bk] == ')') goto Printpart; if (Outbuf[Bk] == '(') { Bk--; goto Printpart; } } if (Outbuf[Ubp] & Instring) { // Break point is inside a string. for (Bk = Ubp; Bk >= Bbp; Bk--) if (Outbuf[Bk] == ',' || Outbuf[Bk] == '.' || Outbuf[Bk] == '=') goto Printpart; for (I = Ubp; I >= Lst + 3; I--) if (Outbuf[I] == Dquotes) { Bk = I - 1; goto Printpart; } for (I = Bk; I >= Lst; I--) if (Outbuf[I] == Squotes) { if (!(Chartype[Outbuf[I - 1]] & Constart)) Bk = I - 1; else Bk = I - 2; goto Printpart; } // Break string. Printstring( _imp_join(_imp_str_literal("Line:"), _imp_join(Itos(Line), _imp_str_literal(" problem:")))); for (I = Lst; I <= Ubp; I++) Printsymbol(Outbuf[I]); Printstring(Snl); Tp = Ubp - 1; Transfer(Lst, Tp); Outstring(_imp_join(_imp_str_literal("\"."), _imp_join(Percentc, Snl))); Dupl(' ', P.Tab[Inn] + P.Icontin); /*dupl(' ', p_tab(inn)+p_icontin)*/ Outstring(_imp_str_literal("\"")); Lst = Tp + 1; continue; } else Bk = Ubp; Printstring( _imp_join(_imp_str_literal("Line:"), _imp_join(Itos(Line), _imp_str_literal(" problem:")))); for (I = Lst; I <= Ubp; I++) Printsymbol(Outbuf[I]); Printstring(Snl); Printpart:; I = Bk; while (Outbuf[I] == ' ' || (Outbuf[I] & 127) == Rs) I--; Transfer(Lst, I); if (I < Lst || (Outbuf[I] & 127) != Nl) { // NOT NATURAL BREAK if ((Outbuf[I] & 127) != ',' && Outbuf[Bk] != (Rs | 128) && Curlend == 0) Outstring(_imp_join(_imp_str_literal(" "), Percentc)); Outstring(Snl); if (!Inconst) Dupl(' ', P.Tab[Inn] + P.Icontin); /*dupl(' ', p_tab(inn)+p_icontin) %if inconst=false*/ if ((Outbuf[Bk + 1] & Underline) != 0 && Outbuf[Bk + 1] != (Rs | 128)) Outstring(_imp_str_literal("%")); } Lst = Bk + 1; } Finalpart:; Transfer(Lst, Obp - 1); Obp = 1; } int Nextnonsp( int Print) { // If PRINT is True then ' ' or '%' or RS are transferred // to the output buffer when encountered. int Ch; for (;;) { Ch = Sc[Ptr]; if (Ch == '{') { if (Obp > 1 && Print == False) { Outbuf[Obp] = ' '; Obp++; } Outbuf[Obp] = '{'; Obp++; Ptr++; do { Ch = Sc[Ptr]; Outbuf[Obp] = Ch | Incurly; Obp++; Ptr++; } while (Ch != '}'); continue; } if (Ch != ' ' && Ch != '%' && (Ch & 127) != Rs) break; if (Print == True) { Outbuf[Obp] = Ch; Obp++; } Ptr++; } return (Ch); } void Getline( int Initptr) { // *********************************************************************** // * GETLINE :- take from the input file and processes // the data and * // * it into the array SC. * // * * // * The following processing is done: * // * 1) All delimiters have 128 added to each // character in the word* // * 2) Lines are joined togther if there is a %c or // ',' at the end* // * of the first line. The newline position is // marked by RS. * // *********************************************************************** static const unsigned char Itoi[256 /*0:255*/] = {[0 ... 9] = 32, 10, [11 ... 24] = 32, 25, 26, [27 ... 31] = 32, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 32, [128 ... 132] = 26, 10, [134 ... 143] = 26, [144 ... 159] = 26, [160 ... 173] = 26, 92, 38, [176 ... 186] = 26, 35, [188 ... 191] = 26, [192 ... 207] = 26, [208 ... 216] = 26, 35, [218 ... 222] = 26, 94, [224 ... 255] = 26}; short Scurl[1+ 20 /*1:20*/]; short Ecurl[1+ 20 /*1:20*/]; int Inkeyword; int Char; int P; int Ncurl; static int Strdelimiter; if (Initptr == 1) Startline = Inptr; Ptr = Initptr; for (;;) { Inkeyword = False; Ncurl = 0; for (;;) { if (Ptr > Ccsize) { Fail(1, 1); break; } if (Inptr > Dataend) Fail(2, 1); Char = Itoi[*Byteinteger(Inptr)]; Inptr++; if (Char == Nl) { Inline++; Sc[Ptr] = Nl; Ptr++; break; } if (Str == True) { Sc[Ptr] = Char; Ptr++; if (Char == Strdelimiter) Str = False; continue; } if (Chartype[Char] & Endst) { Sc[Ptr] = Char; Ptr++; break; } // Deal with curly bracket comments noting start so as to permit // continuations of the form ...,{...}. // Note that any missing closing brace is replaced. if (Char == '{') { Ncurl++; Scurl[Ncurl] = Ptr; Sc[Ptr] = Char; Ptr++; for (;;) { Char = Itoi[*Byteinteger(Inptr)]; if (Char == Nl) Char = '}'; else Inptr++; if (Char == '}') break; Sc[Ptr] = Char; Ptr++; } Ecurl[Ncurl] = Ptr; } if (Inkeyword == True) if (!(Chartype[Char] & Letter)) Inkeyword = False; else { Sc[Ptr] = Onecase[Char] | Underline; Ptr++; continue; } if (Char == '%') Inkeyword = True; if (Char == Squotes || Char == Dquotes) { Str = True; Strdelimiter = Char; } Sc[Ptr] = Char; Ptr++; } if (Char == Nl) { // TRAILING SPACES Check while (Ptr > 2 && Sc[Ptr - 2] == ' ') Ptr--; Sc[Ptr - 1] = Nl; if (!Str) { P = Ptr - 2; while (Ncurl > 0 && Ecurl[Ncurl] == P) { // Step past curly bracket. P = Scurl[Ncurl] - 1; Ncurl--; while (P > 0 && Sc[P] == ' ') P--; } // Now p points at character determining continuation. if (P > 0) { Char = Sc[P]; if (Char == ',') { Sc[Ptr - 1] = Rs | 128; continue; } if (Char == 'C' + Underline) { if (P > 1 && Sc[P - 1] == '%') Sc[P - 1] = ' '; Sc[P] = ' '; Sc[Ptr - 1] = Rs; continue; } if ((Char & 127) == Rs) { Sc[Ptr - 1] = Rs | 128; continue; } } } } break; } Ptr = Initptr; } int Compare(int Test) { int I; int Ch; int Key; int J; for (I = 1; I <= Clett[Test]; I++) { Ch = Nextnonsp(Inconst); if (Ch != Clett[I + Test]) return (False); Ptr++; } if (Test == Offile || Test == Ofprogram) Stop = True; if (Test == Comma) { Insert(',', False, P.Spcomma); return (True); } if (Test == Equals) { if (Ssalt == Ownalt) Inconst = P.Lclist; // If in own or const declaration and p_lclist is // set, then set // inconst to true. The effect of this is leave the declaration // unformatted. Inconst is not set earlier as we do not wish the // leading spaces in the statement to be preserved - i.e. the first // line of the statement is indented with the rest of the program. Insert('=', P.Spacass, P.Spacass); return (True); } if (P.Expkey == True) { if (Test == Fn) Test = Function; if (Test == Const) Test = Constant; } if (Obp == 1 || ((Outbuf[Obp - 1] & Underline) == 0 && (Outbuf[Obp - 1] & 127) != '%')) Key = False; else Key = True; // Current state of outbuf. for (I = 1; I <= Clett[Test]; I++) { Ch = Clett[Test + I]; if (Ch < Underline && Key == True) { Outbuf[Obp] = ' '; Obp++; Key = False; } else if (Ch > Underline) if (!Key) { if (Obp > 1 && '(' != Outbuf[Obp - 1] && Outbuf[Obp - 1] != ' ') { Outbuf[Obp] = ' '; Obp++; } Outbuf[Obp] = '%'; Obp++; Key = True; } else if (I == 1 && P.Sepkey == True) { Outbuf[Obp] = ' '; Outbuf[Obp + 1] = '%'; Obp += 2; } if ((Ch & Underline) != 0 && P.Uckey == False && Ch != (Rs | 128)) Ch = Ch | 32; Outbuf[Obp] = Ch; Obp++; } if ((Test == Offile || Test == Ofprogram) && P.Sepkey == True) { if (Test == Offile) J = 4; else J = 7; Obp += 2; for (I = 1; I <= J; I++) Outbuf[Obp - I] = Outbuf[Obp - I - 2]; Outbuf[Obp - J - 2] = ' '; Outbuf[Obp - J - 1] = '%'; } if (Test == If || Test == Unless || Test == While || Test == Until || Test == Else || Test == Then) Outbuf[Obp - 1] = Ch | Bpoint; if (Test == And || Test == Or) Outbuf[Obp - 1] = Ch | Bpoint2; return (True); } int Check(int Pos) { int Defend; int Subdefend; int Subdefstart; int Res; int Item; int Rsptr; int Z; int Strdelimiter; int Ch; int Rsobj; int Alt; int I; int J; static _imp_string Fes = _imp_str_literal("FINISH %ELSE %START"); static int Uci; static int Depth = 0; static int Bip_sw; static void *Bip[41 /*999:1039*/] = { &&Bip_999, &&Bip_1000, &&Bip_1001, &&Bip_1002, &&Bip_1003, &&Bip_1004, &&Bip_1005, &&Bip_1006, &&Bip_1007, &&Bip_1008, &&Bip_1009, &&Bip_1010, &&Bip_1011, &&Bip_1012, &&Bip_1013, &&Bip_1014, &&Bip_1015, &&Bip_1016, &&Bip_1017, &&Bip_1018, &&Bip_1019, &&Bip_1020, &&Bip_1021, &&Bip_1022, &&Bip_1023, &&Bip_1024, &&Bip_1025, &&Bip_1026, &&Bip_1027, &&Bip_1028, &&Bip_1029, &&Bip_1030, &&Bip_1031, &&Bip_1032, &&Bip_1033, &&Bip_1034, &&Bip_1035, &&Bip_1036, &&Bip_1037, &&Bip_1038, &&Bip_1039, }; // Built-in phrases. Alt = 0; Depth++; // Depth of recursion in check. if (Depth == 1) Ssalt = 0; // Initialise ssalt if in top-level call. Rsptr = Ptr; Rsobj = Obp; Defend = Symbol[Pos]; Pos++; while (Pos < Defend) { Alt++; if (Depth == 1) { // Outer level - i.e. trying ss alternatives. Ssalt++; Inconst = False; } Subdefend = Symbol[Pos]; Pos++; Res = True; Subdefstart = Pos; while (Pos < Subdefend) { Item = Symbol[Pos]; if (999 <= Item && Item < 1300) goto *Bip[Bip_sw = (Item)-999]; if (Item < 999) Res = Compare(Item); if (Item >= 1300) Res = Check(Item); Pos++; goto Bypass; Bip_999:; Pos = Subdefstart; // Star function. Rsptr = Ptr; Rsobj = Obp; goto Bypass; Bip_1000:; Depth--; return (True); Bip_1001:; // Name Ch = Nextnonsp(Inconst); J = Ptr; Ptr++; I = Obp; if (!(Chartype[Ch] & Letter)) { Res = False; goto Inc; } if ((Chartype[Ch] & Constart) != 0 && Nextnonsp(Inconst | P.Spacnam) == Squotes) { Res = False; goto Inc; } Ptr = J; Obp = I; J = Outbuf[Obp - 1]; // LAST CHAR OUT if (J > 128 || (Chartype[J] & Letter) != 0 || J == ')') { Outbuf[Obp] = ' '; Obp++; } while (Chartype[Ch] & (Letter | Number)) { if ((Chartype[Ch] & Letter) != 0 && P.Lcasnam == False) { // Letter case in names to be controlled // by P_UCKEY. if (P.Uckey == True) Ch = Ch & (~32); else Ch = Ch | 32; } Outbuf[Obp] = Ch; Obp++; J = Obp; // Position after latest character of name. Ptr++; Ch = Nextnonsp(Inconst | P.Spacnam); } // Now j gives posn in outbuf after last character of name, and obp // gives next free posn in outbuf. if (P.Spacnam == True && Inconst == False && J < Obp) { // Throw away bytes after name, apart from curly // comments. I = J; for (;;) { while (I < Obp && (Outbuf[I] & 127) != '{') I++; if (I == Obp) break; if (J < I) { Outbuf[J] = ' '; do { J++; Outbuf[J] = Outbuf[I]; I++; } while ((Outbuf[J] & 127) != '}'); } else { do J++; while ((Outbuf[J] & 127) != '}'); I = J + 1; } J++; } Obp = J; } goto Inc; Bip_1005:; // N - Number. Ch = Nextnonsp(Inconst); if (!(Chartype[Ch] & Number)) { Res = False; goto Inc; } Bip_1002:; // Iconst. Bip_1003:; // Const. Ch = Nextnonsp(Inconst); Ptr++; if ((Chartype[Ch] & (Quotes | Constfirst)) == 0 && ((Chartype[Ch] & Constart) == 0 || Nextnonsp(Inconst) != Squotes)) { Res = False; goto Inc; } if (Outbuf[Obp - 1] > 128 || (Chartype[Outbuf[Obp - 1]] & Letter) != 0) { Outbuf[Obp] = ' '; Obp++; } if (!(Chartype[Ch] & Constfirst)) { if (Chartype[Ch] & Constart) { Outbuf[Obp] = Ch; Obp++; Strdelimiter = Nextnonsp(Inconst); Ptr++; } else Strdelimiter = Ch; Outbuf[Obp] = Strdelimiter; Obp++; for (;;) if (Sc[Ptr] == Strdelimiter) { Outbuf[Obp] = Strdelimiter | Instring; if (Sc[Ptr + 1] != Strdelimiter) break; Outbuf[Obp + 1] = Strdelimiter | Instring; Obp += 2; Ptr += 2; } else { Ch = Sc[Ptr]; Outbuf[Obp] = Ch | Instring; Obp++; Ptr++; if (Ch == Nl) Getline(Ptr); } Ptr++; Obp++; } else { Ptr--; for (;;) { for (;;) { if (!(Chartype[Ch] & Constcont)) break; Outbuf[Obp] = Ch; Obp++; Ptr++; Ch = Nextnonsp(Inconst); } if ('_' != Ch && Ch != '@') break; if (Ch == '@') J = Number; else J = Number | Letter; // Second part of @ and radix consts do { Outbuf[Obp] = Ch; Obp++; Ptr++; Ch = Nextnonsp(Inconst); } while (Chartype[Ch] & J); } } goto Inc; Bip_1004: // Phrase check extended type Ch = Nextnonsp(Inconst); if (Ch <= Underline || ((unsigned)0x80000000 >> (Ch & 31) & 0x20C83000) == 0) Res = False; goto Inc; Bip_1038: // Include Bip_1006: // S - End statement. Ch = Nextnonsp(Inconst); if (!(Chartype[Ch] & Endst)) { Res = False; goto Inc; } while (Obp > 1 && Outbuf[Obp - 1] == ' ') Obp--; Outbuf[Obp] = Ch; Obp++; goto Inc; Bip_1007: // Text - comment string. Ch = Nextnonsp(Inconst); if (!(Chartype[Ch] & Rem)) { Res = False; goto Inc; } if ((Ch & Underline) != 0 && ((Outbuf[Obp - 1] & Underline) == 0)) { Outbuf[Obp] = '%'; Obp++; } Outbuf[Obp] = Ch; Obp++; Ptr++; if (Ch == 'C' + Underline) { if (!P.Uckey) Outbuf[Obp - 1] = Ch | 32; for (I = 2; I <= 7; I++) { Ch = Nextnonsp(Inconst); if (Ch != Keycom[I] + Underline) { Res = False; goto Inc; } if (!P.Uckey) Ch = Ch | 32; Outbuf[Obp] = Ch; Obp++; Ptr++; } } Str = False; for (;;) { while (Sc[Ptr] != Nl && (Str == True || Sc[Ptr] != ';')) { Ch = Sc[Ptr]; if (Ch == Squotes || Ch == Dquotes) if (!Str) { Strdelimiter = Ch; Str = True; } else if (Ch == Strdelimiter) Str = False; if ((Ch & Underline) != 0 && P.Uckey == False && Ch != (Rs | 128)) Ch = Ch | 32; Outbuf[Obp] = Ch; Obp++; Ptr++; } Outbuf[Obp] = Sc[Ptr]; Obp++; Ptr++; if (Outbuf[Obp - 1] == Nl) break; // Semi-colon terminated input - carry on reading. Getline(1); } Str = False; goto Inc; Bip_1009: // N255 - Test string declaration length. Ch = Nextnonsp(Inconst); if ('0' > Ch || Ch > '9') { Res = False; goto Inc; } Z = 0; while ('0' <= Ch && Ch <= '9') { Z = Z * 10 + Ch - '0'; Outbuf[Obp] = Ch; Obp++; Ptr++; Ch = Nextnonsp(Inconst); } if (Z > 255) Res = False; goto Inc; Bip_1012: // Readline? Ch = Nextnonsp(Inconst); // Deal with "FRED(1:10) = <nl> .. init vals // .." constructions. if (Ch == Nl) { Outbuf[Obp] = Nl; Obp++; Sc[Ptr] = Rs | 128; Getline(Ptr + 1); } goto Inc; Bip_1015: // Down. Level++; Bheading = True; if (P.Iblock == True) Increm = True; goto Inc; Bip_1016: // Up. Level--; Bheading = True; if (P.Iblock == True && In > 0) In--; goto Inc; Bip_1019: // Colon - Is previous character a colon ':'? if (Sc[Ptr - 1] != ':') { Res = False; goto Inc; } if (Charsin > 0) Outstring(Snl); Ch = Nextnonsp(Inconst); Transfer(1, Obp - 1); Obp = 1; if (P.Seplab == True && Ch != Nl) Outstring(Snl); Inlabel = True; goto Inc; Bip_1022: // Setnem. Ch = Nextnonsp(Inconst); Z = ' '; while (Chartype[Ch] & Letter) { Z = Z << 8 | Onecase[Ch]; Outbuf[Obp] = Ch; Obp++; Ptr++; Ch = Nextnonsp(Inconst); } if (Ch != '_' || Z == ' ') { Res = False; goto Inc; } Outbuf[Obp] = '_'; Obp++; Uci = Z; Ptr++; goto Inc; Bip_1023: // Primform for (I = 7; I <= 127; I++) if (Opc[I] == Uci) goto Pfnd; Res = False; goto Inc; Pfnd: // Mnemonic found if (8 <= (unsigned)I >> 3 && (unsigned)I >> 3 <= 11 && (I & 7) <= 3) Res = False; goto Inc; Bip_1024: // Sectform. for (I = 64; I <= 88; I += 8) for (J = 0; J <= 3; J++) if (Opc[I + J] == Uci) goto Inc; Res = False; goto Inc; Bip_1025: // Tertform. for (I = 3; I >= 1; I--) if (Opc[I] == Uci) goto Inc; Res = False; goto Inc; Bip_1026: // Op. Ch = Nextnonsp(Inconst); Ptr++; if (32 >= Ch || Ch >= 127 || ((unsigned)0x80000000 >> (Ch & 31) & 0x4237000A) == 0) { Res = False; goto Inc; } if (Ch == '&' || Ch == '+' || Ch == '-') { Insert(Ch, P.Spacop, P.Spacop); goto Inc; } if (Ch == '*') { if (Ch != Nextnonsp(Inconst)) { Insert('*', P.Spacop, P.Spacop); goto Inc; } Ptr++; J = Ptr; Ch = Nextnonsp(Inconst); Ptr++; if ('*' == Ch && Ch == Nextnonsp(Inconst)) { Insert('****', P.Spacop, P.Spacop); Ptr++; goto Inc; } Insert('**', P.Spacop, P.Spacop); Ptr = J; goto Inc; } if (Ch == '/') { if (Ch != Nextnonsp(Inconst)) { Insert('/', P.Spacop, P.Spacop); goto Inc; } Insert('//', P.Spacop, P.Spacop); Ptr++; goto Inc; } if (Ch == '!') { if (Ch != Nextnonsp(Inconst)) { Insert('!', P.Spacop, P.Spacop); goto Inc; } Insert('!!', P.Spacop, P.Spacop); Ptr++; goto Inc; } if (Ch == '.') { Outbuf[Obp] = '.'; Obp++; goto Inc; } if (Ch == Nextnonsp(Inconst) && Nextnonsp(Inconst) == '>') { Insert('>>', P.Spacop, P.Spacop); Ptr++; goto Inc; } if (Ch == Nextnonsp(Inconst) && Nextnonsp(Inconst) == '<') { Insert('<<', P.Spacop, P.Spacop); Ptr++; goto Inc; } if (Ch == '\\') { if (Ch != Nextnonsp(Inconst)) { Insert('\\', P.Spacop, P.Spacop); goto Inc; } Insert('\\', P.Spacop, P.Spacop); Ptr++; goto Inc; } Res = False; goto Inc; Bip_1027: // Chui. Ch = Nextnonsp(Inconst); if ((Chartype[Ch] & Letter) == 0 && Ch != '-' && ((unsigned)0x80000000 >> (Ch & 31) & 0x14043000) == 0) Res = False; goto Inc; Bip_1028: // +''. Ch = Nextnonsp(Inconst); if (Ch == '+' || Ch == '-' || Ch == '\\' || Ch == 0x7E) { Insert(Ch, P.Spacop, P.Spacop); Ptr++; } goto Inc; Bip_1031: // Ucwrong (unknown user code format - allow it through). for (;;) { Ch = Nextnonsp(Inconst); Outbuf[Obp] = Ch; Obp++; if (Chartype[Ch] & Endst) goto Inc; Ptr++; } Bip_1030: // ,''. Ch = Nextnonsp(Inconst); if (Ch == ')') Res = False; if (Res == True) Insert(',', False, P.Spcomma); if (Ch == ',') Ptr++; goto Inc; Bip_1032: // Chcomp. Bip_1037: // Comp2 Ch = Nextnonsp(Inconst); Ptr++; if (32 >= Ch || Ch > 92 || ((unsigned)0x80000000 >> (Ch & 31) & 0x1004000E) == 0) { Res = False; goto Inc; } if (Ch == '=') { if (Nextnonsp(Inconst) == Ch) { Ptr++; Insert('==', P.Spacop, P.Spacop); goto Inc; } Insert('=', P.Spacop, P.Spacop); goto Inc; } if (Ch == '#') { if (Nextnonsp(Inconst) == Ch) { Ptr++; Insert('##', P.Spacop, P.Spacop); goto Inc; } Insert('#', P.Spacop, P.Spacop); goto Inc; } if (Ch == '\\' && Nextnonsp(Inconst) == '=') { Ptr++; if (Nextnonsp(Inconst) == '=') { Ptr++;Insert('==\\',P.Spacop,P.Spacop);goto Inc; } Insert('=\\',P.Spacop,P.Spacop);goto Inc; } if (Ch == '>') { if (Nextnonsp(Inconst) == '=') { Ptr++; Insert('=>', P.Spacop, P.Spacop); goto Inc; } Insert('>', P.Spacop, P.Spacop); goto Inc; } if (Ch == '<') { if (Nextnonsp(Inconst) == '=') { Ptr++; Insert('=<', P.Spacop, P.Spacop); goto Inc; } if (Nextnonsp(Inconst) == '>') { Ptr++; Insert('><', P.Spacop, P.Spacop); goto Inc; } Insert('<', P.Spacop, P.Spacop); goto Inc; } if (Ch == '-' && Nextnonsp(Inconst) == '>') { Ptr++; Insert('>-', P.Spacop, P.Spacop); goto Inc; } Res = False; goto Inc; Bip_1033: // Assop. Ch = Nextnonsp(Inconst); Ptr++; if (Ch == '=') { if (Nextnonsp(Inconst) == '=') { Ptr++; Insert('==', P.Spacass, P.Spacass); goto Inc; } Insert('=', P.Spacass, P.Spacass); goto Inc; } if (Ch == '<' && Nextnonsp(Inconst) == '-') { Ptr++; Insert('-<', P.Spacass, P.Spacass); goto Inc; } if (Ch == '-' && Nextnonsp(Inconst) == '>') { Ptr++; Insert('>-', P.Spacass, P.Spacass); goto Inc; } Res = False; Bip_1008: // Bighole. goto Inc; Bip_1010: // Hole. Bip_1011: // Mark. goto Inc; Bip_1013: // Alias. Ch = Nextnonsp(Inconst); Ptr++; if (Ch != '"') { Res = False; goto Inc; } Outbuf[Obp] = ' '; Obp++; Outbuf[Obp] = '"'; Obp++; for (;;) if (Sc[Ptr] == '"') { Outbuf[Obp] = '"' | Instring; if (Sc[Ptr + 1] != '"') break; Outbuf[Obp + 1] = '"' | Instring; Obp += 2; Ptr += 2; } else { Ch = Sc[Ptr]; Outbuf[Obp] = Ch | Instring; Obp++; Ptr++; if (Ch == Nl) Getline(Ptr); } Ptr++; Obp++; goto Inc; Bip_1014: // Dummyapp. Bip_1017: // Liston. Bip_1018: // List off. Bip_1020: // Note const. Bip_1021: // Trace. goto Inc; Bip_1039: // Dummy start if (P.Expkey == True) { // Expand %else to %finish %else %start Obp -= 4; for (I = 1; I <= 19; I++) { J = *Charno(Fes, I); if (P.Sepkey == False && (J == ' ' || J == '%')) continue; if (P.Uckey == False && 'A' <= J && J <= 'Z') J = J | 32; Outbuf[Obp] = J; Obp++; } } Bip_1029: // Note cycle Bip_1034: // Note start Increm = True; goto Inc; Bip_1035: // Note finish Bip_1036: // Note repeat if (In > 0) In--; goto Inc; Inc:; Pos++; Bypass:; if (!Res) { Pos = Subdefend; Obp = Rsobj; if (Ptr > Maxptr) { Maxptr = Ptr; Maxitem = Item; } Ptr = Rsptr; } } if (Res == True) { Depth--; return (True); } } Ptr = Rsptr; Obp = Rsobj; Depth--; return (False); } // *********************************************************************** // * * // * Main calling routine. * // * * // *********************************************************************** S = _imp_str_literal( "test.imp,.out,SPCOMMA=Y,EXPKEY=Y"); // cliparam // printstring("preopt".snl) Opt(S, &P); // Call option setting routine to set parameters. // printstring("preconnect ".infile.snl) Connect(&Infile, 0, 0, 0, &Rec, &Eflag); // Open input file. // printstring("postconnect".snl) if (Eflag) Fail(Eflag, 5); if (Rec.Filetype != Charfile) { Setfname(Infile); Fail(267, 5); } Inptr = Rec.Conad + Rec.Datastart; // Start of data. Dataend = Rec.Conad + Rec.Dataend; // End of data. // Set output stream, possibilities are: // Terminal, file, same file or output device. if (_imp_strcmp(Outf, _imp_str_literal(".OUT")) == 0) Stream = Terminal; else if (_imp_strcmp(Infile, Outf) == 0) Stream = Samefile; else if (*Charno(Outf, 1) == '.') if (Devcode(Outf) <= 0) { // Invalid output device. Setfname(Outf); Fail(264, 5); } else Stream = Device; else Stream = File; // Create tempory output file? if (Stream == Samefile || Stream == Device) Workfile = _imp_join(_imp_str_literal("T#"), Nexttemp()); else Workfile = Outf; if (Stream != Terminal) { Filesizeptr = 1; Filesize = Fstable[Filesizeptr]; // printstring("outfile: ".workfile.snl) Outfile(&Workfile, Filesize, 0, 0, &Conad, &Eflag); if (Eflag) Fail(Eflag, 5); Outrec = Record(Conad); Writeaddress = Conad + Outrec->Datastart; Wa0 = Writeaddress; Outrec->Filetype = Charfile; // Rest of record elements to be fill in at // end of indentation. } Outbuf[0] = 0; Sc[0] = 0; Level = 0; Obp = 1; In = 0; Inline = 1; Line = 0; Errors = 0; Erptr = 0; Charsin = 0; Str = False; Stop = False; Semicolon = False; Increm = False; Inlabel = False; Ersave = False; if (P.Uckey == True) Percentc = _imp_str_literal("%C"); else Percentc = _imp_str_literal("%c"); for (;;) { Bheading = False; Maxptr = 0; // Is there more to analyse in this statement. Colon = Inlabel; if (!Inlabel) Getline(1); else Inlabel = False; if (!Check(Ss)) { Printstring(_imp_join( Snl, _imp_join(_imp_str_literal("Syntax analysis fails on input line "), Itos(Inline - 1)))); Printstring(_imp_join( _imp_str_literal(" (output line "), _imp_join(Itos(Line + 1), _imp_join(_imp_str_literal(")"), Snl)))); Z = 1; while (!(Chartype[Sc[Z]] & Endst)) { if ((Sc[Z] & 127) == Rs) Printstring(Snl); else Printsymbol(Sc[Z] & 127); Z++; } if (Sc[Z] == ';') Printsymbol(';'); Printstring(Snl); Spaces(Maxptr - 1); Printsymbol('!'); Printstring(Snl); while (*Byteinteger(Startline) == ' ') Startline++; if (Stream != Terminal) { Obp = 1; // Line failed - Input line to output routine. Z = *Byteinteger(Startline); while (!(Chartype[Z] & Endst)) { if (Chartype[Z] & Quotes) { Strdelimiter = Z; Outbuf[Obp] = Strdelimiter; Obp++; Startline++; Z = *Byteinteger(Startline); while (Z != Strdelimiter) { Outbuf[Obp] = Z; Obp++; Startline++; Z = *Byteinteger(Startline); } } Outbuf[Obp] = Z; Obp++; Startline++; Z = *Byteinteger(Startline); } Outbuf[Obp] = Z; Obp++; Punch(); } Str = False; Errors++; } else if (!Inlabel) Punch(); if (Stop == True) if (!Errors) Closedown(True); else Closedown(False); } // DOES NOT COME THROUGH HERE void Fail(int Type, int Action) { if (Action != 5) if (!(Action & 2)) { Printstring(_imp_join(Snl, _imp_str_literal("*** Error: "))); Errors++; } else Printstring(_imp_join(Snl, _imp_str_literal("*** Warning: "))); if (!(Action & 4)) { Printstring(_imp_join(Fault[Type], Snl)); Printstring(_imp_join( _imp_str_literal("*** In input line "), _imp_join( Itos(Inline), _imp_join(_imp_str_literal(" (output line "), _imp_join(Itos(Line), _imp_join(_imp_str_literal(")"), Snl)))))); } else { Printstring(_imp_join(_imp_str_literal("*** Soap80 fails -"), Failuremessage(Type))); exit(0); } if ((Action & 1) == 1) Closedown(False); } void Opt( _imp_string Parm, Pformat * P) { // *********************************************************************** // * THIS ROUTINE PROCESSES THE USER OPTION LIST * // *********************************************************************** auto void Readline(void); auto void Setline(void); auto int Stoi(_imp_string Snum); auto void Ask(int Optno); int I; int J; int Temp; int Flag; int Profvsn; _imp_string Line; _imp_string Option; _imp_string Value; _imp_string Filename; static const int Progvsn = 3; static int Prof_sw; static void *Prof[4 /*0:3*/] = { &&Prof_0, &&Prof_1, &&Prof_2, &&Prof_3, }; Profvsn = 0; Flag = 5; // read profile("Soap80key", p, prof vsn, flag) if (Flag > 4) Printstring(_imp_join( _imp_str_literal( "Failed to read file SS#PROFILE. Defaults options assumed."), Snl)); goto *Prof[Prof_sw = Profvsn]; // In the following profile-handling code, we work with array p_a // (alternative format) rather than the actual option names (p_sepkey // etc.). This is because the p_a operations remain valid even if the // record format is subsequently changed. Prof_0 :; // Code to set up profile vsn 1 data: // This consists of 14 options followed by 21 tab values. // original defaults // p_a(1) = 80; %comment line - lines are broken into two if length // is greater than 80. p_a(2) = 3; %comment icontin - continuation of // line have an addition indentation of 3. p_a(3) = 41; %comment // poscom - position for right hand comments. p_a(4) = true; %comment // movecom - main comment are indented to POSCOM. p_a(5) = true; // %comment uckey - keywords output in upper case. p_a(6) = false; // %comment sepkey - adjacent keywords are compounded. p_a(7) = true; // %comment lcasnam - case of names left alone. p_a(8) = true; // %comment spacnam - spaces are left within names. p_a(9) = true; // %comment spacass - spaces are added round assignment operators. // p_a(10) = false; %comment spacop - spaces are not added round // other operators. p_a(11) = true; %comment lclist - const lists to // be left alone. p_a(12) = true; %comment iblock - block contents // are indented w.r.t. block heading. p_a(13) = false; %comment istat // - statements are aligned with declarations. p_a(14) = false; // %comment seplab - Labels and statements may occupy the same line. // graham''s preferred defaults P->A[1] = 80; // line - lines are broken into two if length is greater than 80. P->A[2] = 2; // icontin - continuation of line have an addition indentation of 3. P->A[3] = 41; // poscom - position for right hand comments. P->A[4] = False; // movecom - main comment are indented to POSCOM. P->A[5] = False; // uckey - keywords output in upper case. P->A[6] = True; // sepkey - adjacent keywords are compounded. P->A[7] = False; // lcasnam - case of names left alone. P->A[8] = True; // spacnam - spaces are left within names. P->A[9] = True; // spacass - spaces are added round assignment operators. P->A[10] = False; // spacop - spaces are not added round other operators. P->A[11] = True; // lclist - const lists to be left alone. P->A[12] = True; // iblock - block contents are indented w.r.t. block heading. P->A[13] = False; // istat - statements are aligned with declarations. P->A[14] = False; // seplab - Labels and statements may occupy the same line. // Set default indentation values. for (I = 0; I <= 10; I++) P->A[I+15] = 3 * I; for (I = 11; I <= 20; I++) P->A[I+15] = 5 * I - 20; Prof_1:; // Code to set up profile vsn 2 data: // This consists of 15 options followed by 21 tab values. for (I = 36; I >= 16; I--) P->A[I] = P->A[I=1]; // Move tab values down to make room. Printstring( _imp_join(_imp_str_literal("**New parameter available: SPCOMMA"), Snl)); Printstring( _imp_join(_imp_str_literal( " Y : One space character inserted after commas."), Snl)); Printstring(_imp_join( _imp_str_literal( " N : No space character inserted after commas (default)."), _imp_join(Snl, Snl))); P->A[15] = False; // spcomma - default false. Prof_2:; // Code to set up profile vsn 3 data: // This consists of 21 tab values followed by 16 options. { int I; unsigned char Tab[21 /*0:20*/]; for (I = 0; I <= 20; I++) /*tab(i) = p_a(i+16) %for i = 0, 1, 20; %comment Copy tab values out.*/ Tab[I] = P->A[I+16]; // Copy tab values out. for (I = 1; I <= 6; I++) P->A[I+21] = P->A[I]; // Move options down. // Item _a(28) will be the new parameter (expkey). for (I = 7; I <= 15; I++) P->A[I+22] = P->A[I]; // Move options down. for (I = 0; I <= 20; I++) /*p_a(i+1) = tab(i) %for i = 0, 1, 20; %comment Copy tab values back.*/ P->A[I+1] = Tab[I]; // Copy tab values back. } Printstring( _imp_join(_imp_str_literal("**New parameter available: EXPKEY"), Snl)); Printstring(_imp_join( _imp_str_literal( " Y : Keywords %FN, %CONST and (sometimes) %ELSE expanded."), Snl)); Printstring( _imp_join(_imp_str_literal( " N : %FN, %CONST and %ELSE left alone (default)."), _imp_join(Snl, Snl))); P->A[28] = False; // expkey default - false. // The following two lines should always be just before the final 'prof' // switch label. Profvsn = Progvsn; { _imp_string Key; Key = _imp_str_literal("Soap80key"); Writeprofile(&Key, P, &Profvsn, &Flag); } Prof_3:; // Split up parameters and change default values. if (_imp_resolve(Parm, &Filename, _imp_str_literal(","), &Outf)) { if (!_imp_resolve(Outf, &Outf, _imp_str_literal(","), &Parm)) Parm = _imp_str_literal(""); } else { Filename = Parm; Outf = Parm; Parm = _imp_str_literal(""); } Infile = Filename; if (_imp_strcmp(Outf, _imp_str_literal("")) == 0) Outf = Filename; if (_imp_strcmp(Parm, _imp_str_literal("")) == 0) return; Temp = *Charno(Parm, *Length(Parm)); if (Temp != '*' && Temp != '?') Parm = _imp_join(Parm, _imp_str_literal(",END")); for (;;) { if (_imp_strcmp(Parm, _imp_str_literal("")) == 0) { { _imp_string S; S = _imp_str_literal("Soap80: "); Prompt(S); // not a real imp prompt unfortunately } Readline(); } else Setline(); if (_imp_strcmp(Line, _imp_str_literal("END")) == 0 || _imp_strcmp(Line, _imp_str_literal(".END")) == 0) return; // End of parameter settings. if (_imp_strcmp(Line, _imp_str_literal("GO")) == 0 || _imp_strcmp(Line, _imp_str_literal(".GO")) == 0) return; // End of parameter settings. if (_imp_strcmp(Line, _imp_str_literal("STOP")) == 0 || _imp_strcmp(Line, _imp_str_literal(".STOP")) == 0) exit(0); // Abandon Soap80. if (_imp_strcmp(Line, _imp_str_literal("SAVE")) == 0 || _imp_strcmp(Line, _imp_str_literal(".SAVE")) == 0) { { _imp_string Key; Key = _imp_str_literal("Soap80key"); Writeprofile(&Key, P, &Profvsn, &Flag); } if (Flag == 1) Printstring( _imp_join(_imp_str_literal( "Profile file SS#PROFILE created and cherished."), Snl)); } else if (_imp_strcmp(Line, _imp_str_literal("?")) == 0) { // Print options so far. Printstring(_imp_join( _imp_str_literal( "Option name:{current setting}Meaning of current setting"), Snl)); for (I = 1; I <= Maxopt; I++) { Printstring(Optname[I]); Spaces(7 - *Length(Optname[I])); Printstring(_imp_str_literal(":{")); J = P->Optarr[I]; if (!J) Printsymbol('N'); else if (J == True) Printsymbol('Y'); else Printstring(Itos(J)); if (J > 0) J = 1; Printstring(_imp_join(_imp_str_literal("}"), _imp_join(Optmess[J + I * 2], Snl))); } Printstring(_imp_str_literal("TAB :{")); for (I = 1; I <= 20; I++) { Printstring(Itos(P->Tab[I])); /*printstring(itos(p_tab(i)))*/ if (I != 20) Printsymbol(':'); } Printsymbol('}'); Printstring(Snl); Printstring( _imp_join(_imp_str_literal(" Indenting values"), Snl)); Printstring(_imp_join( _imp_str_literal( "SAVE : Save current option settings, for defaults " "henceforth.\nGO or END: Cause SOAP80 to start processing the " "input.\nSTOP : Cause SOAP80 to stop immediately."), Snl)); } else if (_imp_resolve(Line, &Option, _imp_str_literal("="), &Value) && _imp_strcmp(Value, _imp_str_literal("")) != 0) { Flag = 0; for (I = 1; I <= Maxopt; I++) { if (_imp_strcmp(Option, Optname[I]) != 0) continue; Flag = 1; // Option identified. if (_imp_strcmp(Value, _imp_str_literal("?")) == 0) { Printstring(Optname[I]); Spaces(7 - *Length(Optname[I])); Printstring(_imp_str_literal(":{")); J = P->Optarr[I]; if (!J) Printsymbol('N'); else if (J == True) Printsymbol('Y'); else Printstring(Itos(J)); if (J > 0) J = 1; Printstring(_imp_join(_imp_str_literal("}"), _imp_join(Optmess[J + I * 2], Snl))); } else if (I <= Numopt) { // Numerical value. Temp = Stoi(Value); if (_imp_strcmp(Option, _imp_str_literal("LINE")) == 0 && (Temp < 30 || Temp > 160)) { Printstring(_imp_join( _imp_str_literal("Bad line length - Only from 30 to 160"), Snl)); break; } if (Temp > 255) Temp = -1; if (Temp == -1) Printstring(_imp_join(Value, _imp_join(_imp_str_literal(" - "), Failuremessage(320)))); else P->Optarr[I] = Temp; } else Ask(I); break; } if (Flag == 1) continue; // Cycle found option name. if (_imp_strcmp(Option, _imp_str_literal("TAB"))) { // Set indenting value. if (_imp_strcmp(Value, _imp_str_literal("?")) == 0) { Printstring(_imp_str_literal("TAB :{")); for (I = 1; I <= 20; I++) { Printstring(Itos(P->Tab[I])); if (I != 20) Printsymbol(':'); } Printsymbol('}'); Printstring(Snl); Printstring( _imp_join(_imp_str_literal(" Indenting values"), Snl)); } else { I = 1; while (I <= 20 && _imp_strcmp(Value, _imp_str_literal("")) != 0) { Temp = Stoi(Value); if (Temp == -1) { Printstring(_imp_join(Value, _imp_join(_imp_str_literal(" - "), Failuremessage(320)))); break; } P->Tab[I] = Temp; /*p_tab(i) = temp*/ if (!*Length(Value)) { I++; break; } if (*Charno(Value, 1) != ':') { Printstring(_imp_join(Value, _imp_join(_imp_str_literal(" - "), Failuremessage(320)))); I = 21; } else Value = Substring(Value, 2, *Length(Value)); I++; } // End of indenting value, make up the rest for (J = I; J <= 20; J++) { P->Tab[J] = 2 * P->Tab[J-1] - P->Tab[J-2]; /*p_tab(j) = 2*p_tab(j-1)-p_tab(j-2)*/ if (P->Tab[J] > P->Line) /*%if p_tab(j)>p_line %then p_tab(j) = p_line*/ P->Tab[J] = P->Line; } } continue; } Printstring(_imp_join( Option, _imp_join(_imp_str_literal(" - "), Failuremessage(322)))); // Keyword not recognised. } else Printstring(_imp_join( Line, _imp_join( _imp_str_literal( " - invalid: format should be\n 'keyword = value' " " or 'keyword = ?' or '?' or\n 'SAVE' " " or 'END' or 'GO' or 'STOP'"), Snl))); } // %return void Readline( void) { // *********************************************************************** // * READLINE creates a line from the input device, // converting all * // * lower case characters to upper case. * // *********************************************************************** int Ch; for (;;) { Line = _imp_str_literal(""); for (;;) { Readsymbol(&Ch); if (Ch == Nl) break; if (Ch == ' ') continue; // Convert lower to upper. Line = _imp_join(Line, Tostring(Onecase[Ch])); } // Return only if the line has some thing on it. if (*Length(Line) > 0) return; } } void Setline( void) { // *********************************************************************** // * SETLINE breaks the parameter list into single commands. // * // ************************************************************************ if (!_imp_resolve(Parm, &Line, _imp_str_literal(","), &Parm)) { // Last command in parameter. if (*Charno(Parm, *Length(Parm)) == '*') Readline(); else Line = Parm; Parm = _imp_str_literal(""); } } void Ask( int I) { // *********************************************************************** // * ASK checks that value starts with Y or N and * // * assigns True or False accordingly to P_OPTARR(I). * // *********************************************************************** int S; S = *Charno(Value, 1); if (S == 'Y') P->Optarr[I] = True; else if (S == 'N') P->Optarr[I] = False; else Printstring(_imp_join(_imp_str_literal("Answer Yes or No or ?"), Snl)); } int Stoi( _imp_string Snum) { // *********************************************************************** // * STOI builts up an integer in INUM from the string SNUM, in * // * doing so characters are deleted from this string. * // * It is an error if the first character of the string is not a * // * number. This is signalled by returning -1. * // *********************************************************************** int I; int Inum; if ('0' > *Charno(Snum, 1) || *Charno(Snum, 1) > '9') return (-1); I = 1; Inum = 0; while ('0' <= *Charno(Snum, I) && *Charno(Snum, I) <= '9') { Inum = Inum * 10 + *Charno(Snum, I) - '0'; I++; if (I > *Length(Snum)) break; } if (I >= *Length(Snum)) Snum = _imp_str_literal(""); else Snum = Substring(Snum, I, *Length(Snum)); return (Inum); } } exit(0); return (1); }