# Almost Comma Delimited Ordinary comma delimited data is easy to parse with INPUT CSV, but what do you do when the comma delimited file contains commented lines? A good example is the A-Shell INI.CLR file, which looks something like this: ; Color Definitions (for a primarily blue background) ; Color legend: 0=blk, 1=wht, 2=blu, 3=mag, 4=red, 5=yel, 6=grn, 7=cyn ; VUECLR=override?,edit fg,edit bg, command fg, command bg, help fg, help bg, status/info fg,bg ; Use the following for a reasonable scheme using blue background. VUECLR=Y, 1,2, 5,2, 7,2, 6,2 ; Use the following to disable VUE colors, i.e. use current colors only. ;VUECLR=Y,-1,-1,-1,-1,-1,-1,-1,-1 ; EZCLR=override?,text fg,bg, border fg,bg, cmd fg,bg, sts fg,bg, help fg,bg, highlight fg,bg, menu fg,bg, brief menu fg,bg EZCLR=Y, 1,2, 1,2, 5,2, 0,9, 1,3, 1,4, 5,2, 7,2 ; INFCLR=override?,display fg,bg, edit fg,bg, negative fg,bg, update fg,bg, message fg,bg, original msg line fg,bg, forms fg,bg INFCLR=Y, 5,2, 1,10, 4,2, 7,2, 7,2, 1,2, 0,2 ; MMOCLR=Y,border fg,bg, text fg,bg, arrows fg,bg, prompt fg,bg, status line fg,bg, protected fg,bg MMOCLR=Y, 6,2, 5,10, 6,2, 7,2, 1,2, 7,2 ; SCNCLR=override?,screen text (fg), screen background ; The following sets up white on blue SCNCLR=Y,1,2 This seems like a simple enough format, but the unpredictable presence of the commented lines (marked by a semicolon), and the equal sign make it difficult or impossible to use INPUT CSV. STRTOK comes in handy here because it can be used on a string, allowing you to first input the entire line to check for commented out lines, then pass it to STRTOK. Also, it eliminates the need to deal with special tests for prematurely terminated lines, lines with comments in them, uneven spacing, etc. The following code parses the input, putting into the MAP structures: MAP1 VUECLR'OVR,S,1 MAP1 VUECLR(4,2),S,1 \! 4 pairs MAP1 EZCLR'OVR,S,1 MAP1 EZCLR(8,2),S,1 \! 8 pairs MAP1 INFCLR'OVR,S,1 MAP1 INFCLR(7,2),S,1 \! 7 pairs MAP1 MMOCLR'OVR,S,1 MAP1 MMOCLR(6,2),S,1 \! 6 pairs MAP1 SCNCLR'OVR,S,1 MAP1 SCNCLR(2),S,1 \! 1 pair MAP1 PLINE,S,100 MAP1 STATE,F,6,1 \! 1)VUECLR, 2)EZCLR, etc. MAP1 RDELIM,S,2 MAP1 FDELIM,S,3,"=," MAP1 OPCODE,B,1,0 OPEN #1, "LIB:INI.CLR", INPUT LOOP: INPUT LINE #1, PLINE IF EOF(1)=1 AND PLINE="" GOTO PREMATURE'END xcall TRIM,PLINE,1 IF PLINE="" OR PLINE\[1,1\]=";" GOTO LOOP OPCODE = 0 ON STATE CALL PVUE,PEZ,PINF,PMMO,PSCN IF STATE < 5 GOTO LOOP PREMATURE'END: PRINT "PREMATURE END OF FILE" DONE: CLOSE #1 END PVUE: \! parse VUECLR line RDELIM = ";" + CHR(10) xcall STRTOK,OPCODE,PLINE,FDELIM,VUECLR'OVR,RDELIM, \& VUECLR(1,1),VUECLR(1,2),VUECLR(2,1),VUECLR(2,2), \& VUECLR(3,1),VUECLR(3,2),VUECLR(4,1),VUECLR(4,2) STATE = STATE + 1 RETURN PEZ: \! parse EZCLR line RDELIM = ";" + CHR(10) xcall STRTOK,OPCODE,PLINE,FDELIM,EZCLR'OVR,RDELIM, \& EZCLR(1,1),EZCLR(1,2),EZCLR(2,1),EZCLR(2,2), \& EZCLR(3,1),EZCLR(3,2),EZCLR(4,1),EZCLR(4,2), \& EZCLR(5,1),EZCLR(5,2),EZCLR(6,1),EZCLR(6,2), \& EZCLR(7,1),EZCLR(7,2),EZCLR(8,1),EZCLR(8,2) STATE = STATE + 1 RETURN PINF: \! parse INFCLR line RDELIM = ";" + CHR(10) xcall STRTOK,OPCODE,PLINE,FDELIM,INFCLR'OVR,RDELIM, \& INFCLR(1,1),INFCLR(1,2),INFCLR(2,1),INFCLR(2,2), \& INFCLR(3,1),INFCLR(3,2),INFCLR(4,1),INFCLR(4,2), \& INFCLR(5,1),INFCLR(5,2),INFCLR(6,1),INFCLR(6,2), \& INFCLR(7,1),INFCLR(7,2) STATE = STATE + 1 RETURN PMMO: \! parse MMOCLR line RDELIM = ";" + CHR(10) xcall STRTOK,OPCODE,PLINE,FDELIM,MMOCLR'OVR,RDELIM, \& MMOCLR(1,1),MMOCLR(1,2),MMOCLR(2,1),MMOCLR(2,2), \& MMOCLR(3,1),MMOCLR(3,2),MMOCLR(4,1),MMOCLR(4,2), \& MMOCLR(5,1),MMOCLR(5,2),MMOCLR(6,1),MMOCLR(6,2), \& MMOCLR(7,1),MMOCLR(7,2) STATE = STATE + 1 RETURN PSCN: \! parse SCNCLR line RDELIM = ";" + CHR(10) xcall STRTOK,OPCODE,PLINE,FDELIM,SCNCLR'OVR,RDELIM, \& SCNCLR(1),SCNCLR(2) STATE = STATE + 1 RETURN The example above was complicated by the fact that every line of the file contained a different format and needed to be put into different variables. So we needed a lot of individual STRTOK commands. But we did not need any complicated substring processing–it was all very straightforward.