home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume3 / turbo_tools / part2 / chapter3.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1986-11-30  |  11.0 KB  |  588 lines

  1. {chapter3.pas}
  2.  
  3. {
  4.         Copyright (c) 1981
  5.         By:     Bell Telephone Laboratories, Inc. and
  6.                 Whitesmith's Ltd.,
  7.  
  8.         This software is derived from the book
  9.                 "Software Tools in Pascal", by
  10.                 Brian W. Kernighan and P. J. Plauger
  11.                 Addison-Wesley, 1981
  12.                 ISBN 0-201-10342-7
  13.  
  14.         Right is hereby granted to freely distribute or duplicate this
  15.         software, providing distribution or duplication is not for profit
  16.         or other commercial gain and that this copyright notice remains
  17.         intact.
  18. }
  19.  
  20. PROCEDURE COMPARE;FORWARD;
  21. PROCEDURE INCLUDE;FORWARD;
  22. PROCEDURE CONCAT;FORWARD;
  23.  
  24. PROCEDURE MAKECOPY;
  25. VAR
  26.   INNAME,OUTNAME:XSTRING;
  27.   FIN,FOUT:FILEDESC;
  28. BEGIN
  29.   IF(NOT GETARG(2,INNAME,MAXSTR))
  30.     OR (NOT GETARG(3,OUTNAME,MAXSTR))THEN
  31.       ERROR('USAGE:MAKECOPY OLD NEW');
  32.   FIN:=MUSTOPEN(INNAME,IOREAD);
  33.   FOUT:=MUSTCREATE(OUTNAME,IOWRITE);
  34.   FCOPY(FIN,FOUT);
  35.   XCLOSE(FIN);
  36.   XCLOSE(FOUT)
  37. END;
  38.  
  39. PROCEDURE PRINT;
  40. VAR
  41.   NAME:XSTRING;
  42.   NULL:XSTRING;
  43.   I:INTEGER;
  44.   FIN:FILEDESC;
  45.   JUNK:BOOLEAN;
  46.  
  47. PROCEDURE FPRINT(VAR NAME:XSTRING;FIN:FILEDESC);
  48. CONST
  49.   MARGIN1=2;
  50.   MARGIN2=2;
  51.   BOTTOM=64;
  52.   PAGELEN=66;
  53. VAR
  54.   LINE:XSTRING;
  55.   LINENO,PAGENO:INTEGER;
  56.  
  57. PROCEDURE SKIP(N:INTEGER);
  58. VAR
  59.   I:INTEGER;
  60. BEGIN
  61.   FOR I:=1 TO N DO
  62.     PUTC(NEWLINE)
  63. END;
  64.  
  65. PROCEDURE HEAD(VAR NAME:XSTRING;PAGENO:INTEGER);
  66. VAR
  67.   PAGE:XSTRING;
  68. BEGIN
  69.   PAGE[1]:=ORD(' ');
  70.   PAGE[2]:=ORD('P');
  71.   PAGE[3]:=ORD('a');
  72.   PAGE[4]:=ORD('g');
  73.   PAGE[5]:=ORD('e');
  74.   PAGE[6]:=ORD(' ');
  75.   PAGE[7]:=ENDSTR;
  76.   PUTSTR(NAME,STDOUT);
  77.   PUTSTR(PAGE,STDOUT);
  78.   PUTDEC(PAGENO,1);
  79.   PUTC(NEWLINE)
  80. END;
  81.  
  82. BEGIN(*FPRINT*)
  83.   PAGENO:=1;
  84.   SKIP(MARGIN1);
  85.   HEAD(NAME,PAGENO);
  86.   SKIP(MARGIN2);
  87.   LINENO:=MARGIN1+MARGIN2+1;
  88.   WHILE(GETLINE(LINE,FIN,MAXSTR))DO BEGIN
  89.     IF(LINENO=0)THEN BEGIN
  90.       SKIP(MARGIN1);;
  91.       PAGENO:=PAGENO+1;
  92.       HEAD(NAME,PAGENO);
  93.       SKIP(MARGIN2);
  94.       LINENO:=MARGIN1+MARGIN2+1
  95.     END;
  96.     PUTSTR(LINE,STDOUT);
  97.     LINENO:=LINENO+1;
  98.     IF(LINENO>=BOTTOM)THEN BEGIN
  99.       SKIP(PAGELEN-LINENO);
  100.       LINENO:=0
  101.     END
  102.   END;
  103.   IF(LINENO>0)THEN
  104.     SKIP(PAGELEN-LINENO)
  105. END;
  106.   
  107. BEGIN(*PRINT*)
  108.   NULL[1]:=ENDSTR;
  109.   IF(NARGS=1)THEN
  110.     FPRINT(NULL,STDIN)
  111.   ELSE
  112.     FOR I:=2 TO NARGS DO BEGIN
  113.       JUNK:=GETARG(I,NAME,MAXSTR);
  114.       FIN:=MUSTOPEN(NAME,IOREAD);
  115.       FPRINT(NAME,FIN);
  116.       XCLOSE(FIN)
  117.     END
  118. END;
  119.  
  120. PROCEDURE COMPARE;
  121. VAR
  122.   LINE1,LINE2:XSTRING;
  123.   ARG1,ARG2:XSTRING;
  124.   LINENO:INTEGER;
  125.   INFILE1,INFILE2:FILEDESC;
  126.   F1,F2:BOOLEAN;
  127.   
  128. PROCEDURE DIFFMSG (N:INTEGER; VAR LINE1,LINE2:XSTRING);
  129. BEGIN
  130.   PUTDEC(N,1);
  131.   PUTC(COLON);
  132.   PUTC(NEWLINE);
  133.   PUTSTR(LINE1,STDOUT);
  134.   PUTSTR(LINE2,STDOUT)
  135. END;
  136.  
  137. BEGIN(*COMPARE*)
  138.   IF (NOT GETARG(2,ARG1,MAXSTR))
  139.    OR (NOT GETARG(3,ARG2,MAXSTR)) THEN
  140.      ERROR('USAGE:COMPARE FILE1 FILE2');
  141.   INFILE1:=MUSTOPEN(ARG1,IOREAD);
  142.   INFILE2:=MUSTOPEN(ARG2,IOREAD);
  143.   LINENO:=0;
  144.   REPEAT
  145.     LINENO:=LINENO+1;
  146.     F1:=GETLINE(LINE1,INFILE1,MAXSTR);
  147.     F2:=GETLINE(LINE2,INFILE2,MAXSTR);
  148.     IF (F1 AND F2) THEN
  149.       IF (NOT EQUAL(LINE1,LINE2)) THEN
  150.         DIFFMSG(LINENO,LINE1,LINE2)
  151.   UNTIL (F1=FALSE) OR (F2=FALSE);
  152.   IF(F2 AND NOT F1) THEN
  153.   WRITELN('COMPARE:END OF FILE ON FILE 1')
  154.   ELSE IF (F1 AND NOT F2) THEN
  155.     WRITELN('COMPARE:END OF FILE ON FILE2')
  156. END;
  157.  
  158.  
  159. PROCEDURE INCLUDE;
  160. VAR
  161.   INCL:XSTRING;
  162.  
  163. PROCEDURE FINCLUDE(F:FILEDESC);
  164. VAR
  165.   LINE,STR:XSTRING;
  166.   LOC,I:INTEGER;
  167.   F1:FILEDESC;
  168. FUNCTION GETWORD(VAR S:XSTRING;I:INTEGER;
  169.   VAR OUT:XSTRING):INTEGER;
  170.  
  171. VAR
  172.   J:INTEGER;
  173. BEGIN
  174.   WHILE(S[I] IN [BLANK,TAB,NEWLINE]) DO
  175.     I:=I+1;
  176.   J:=1;
  177.   WHILE(NOT (S[I] IN [ENDSTR,BLANK,TAB,NEWLINE])) DO BEGIN
  178.     OUT[J]:=S[I];
  179.     I:=I+1;
  180.     J:=J+1
  181.   END;
  182.   OUT[J]:=ENDSTR;
  183.   IF(S[I]=ENDSTR) THEN
  184.     GETWORD:=0
  185.   ELSE
  186.     GETWORD:=I
  187. END;
  188.  
  189. BEGIN
  190.   WHILE (GETLINE(LINE,F,MAXSTR))DO BEGIN
  191.     LOC:=GETWORD(LINE,1,STR);
  192.     IF (NOT EQUAL(STR,INCL)) THEN
  193.       PUTSTR(LINE,STDOUT)
  194.     ELSE BEGIN
  195.       LOC:=GETWORD(LINE,LOC,STR);
  196.       STR[XLENGTH(STR)]:=ENDSTR;
  197.       FOR I:= 1 TO XLENGTH(STR)DO
  198.         STR[I]:=STR[I+1];
  199.       F1:=MUSTOPEN(STR,IOREAD);
  200.       FINCLUDE(F1);
  201.       XCLOSE(F1)
  202.     END
  203.   END
  204. END;
  205.  
  206. BEGIN
  207.   INCL[1]:=ORD('#');
  208.   INCL[2]:=ORD('i');
  209.   INCL[3]:=ORD('n');
  210.   INCL[4]:=ORD('c');
  211.   INCL[5]:=ORD('l');
  212.   INCL[6]:=ORD('u');
  213.   INCL[7]:=ORD('d');
  214.   INCL[8]:=ORD('e');
  215.   INCL[9]:=ENDSTR;
  216.   FINCLUDE(STDIN)
  217. END;
  218.   
  219. PROCEDURE CONCAT;
  220. VAR
  221.   I:INTEGER;
  222.   JUNK:BOOLEAN;
  223.   FD:FILEDESC;
  224.   S:XSTRING;
  225. BEGIN
  226.   FOR I:=2 TO NARGS DO BEGIN
  227.     JUNK:=GETARG(I,S,MAXSTR);
  228.     FD:=MUSTOPEN(S,IOREAD);
  229.     FCOPY(FD,STDOUT);
  230.     XCLOSE(FD)
  231.   END
  232. END;
  233.  
  234. PROCEDURE ARCHIVE;
  235. CONST
  236.   MAXFILES=10;
  237. VAR
  238.   ANAME:XSTRING;
  239.   CMD:XSTRING;
  240.   FNAME:ARRAY[1..MAXFILES]OF XSTRING;
  241.   FSTAT:ARRAY[1..MAXFILES] OF BOOLEAN;
  242.   NFILES:INTEGER;
  243.   ERRCOUNT:INTEGER;
  244.   ARCHTEMP:XSTRING;
  245.   ARCHHDR:XSTRING;
  246. FUNCTION GETWORD(VAR S:XSTRING;I:INTEGER;VAR OUT:XSTRING):INTEGER;
  247. VAR
  248.   J:INTEGER;
  249. BEGIN
  250.   WHILE (S[I] IN [BLANK,TAB,NEWLINE]) DO
  251.     I:=I+1;
  252.   J:=1;
  253.   WHILE(NOT (S[I] IN [ENDSTR,BLANK,TAB,NEWLINE])) DO BEGIN
  254.     OUT[J]:=S[I];
  255.     I:=I+1;
  256.     J:=J+1
  257.   END;
  258.   OUT[J]:=ENDSTR;
  259.   IF(S[I]=ENDSTR) THEN
  260.     GETWORD:=0
  261.   ELSE
  262.     GETWORD:=I
  263. END;
  264.  
  265.  
  266. FUNCTION GETHDR(FD:FILEDESC;VAR BUF,NAME:XSTRING;
  267.   VAR SIZE:INTEGER):BOOLEAN;
  268. VAR
  269.   TEMP:XSTRING;
  270.   I:INTEGER;
  271. BEGIN
  272.   IF(GETLINE(BUF,FD,MAXSTR)=FALSE)THEN
  273.     GETHDR:=FALSE
  274.   ELSE BEGIN
  275.     I:=GETWORD(BUF,1,TEMP);
  276.     IF(NOT EQUAL(TEMP,ARCHHDR))THEN
  277.       ERROR('ARCHIVE NOT IN PROPER FORMAT');
  278.     I:=GETWORD(BUF,I,NAME);
  279.     SIZE:=CTOI(BUF,I);
  280.     GETHDR:=TRUE
  281.   END
  282. END;
  283.  
  284. FUNCTION FILEARG (VAR NAME:XSTRING):BOOLEAN;
  285. VAR
  286.   I:INTEGER;
  287.   FOUND:BOOLEAN;
  288. BEGIN
  289.   IF(NFILES<=0)THEN
  290.     FILEARG:=TRUE
  291.   ELSE BEGIN
  292.     FOUND:=FALSE;
  293.     I:=1;
  294.     WHILE(NOT FOUND) AND (I<=NFILES)DO BEGIN
  295.       IF(EQUAL(NAME,FNAME[I])) THEN BEGIN
  296.         FSTAT[I]:=TRUE;
  297.         FOUND:=TRUE
  298.       END;
  299.       I:=I+1
  300.     END;
  301.     FILEARG:=FOUND
  302.   END
  303. END;
  304.  
  305. PROCEDURE FSKIP(FD:FILEDESC;N:INTEGER);
  306. VAR
  307.   C:CHARACTER;
  308.   I:INTEGER;
  309. BEGIN
  310.   FOR I:=1 TO N DO
  311.     IF(GETCF(C,FD)=ENDFILE)THEN
  312.       ERROR('ARCHIVE:END OF FILE IN FSKIP')
  313. END;
  314.  
  315. PROCEDURE FMOVE(VAR NAME1,NAME2:XSTRING);
  316. VAR
  317.   FD1,FD2:FILEDESC;
  318. BEGIN
  319.   FD1:=MUSTOPEN(NAME1,IOREAD);
  320.   FD2:=MUSTCREATE(NAME2,IOWRITE);
  321.   FCOPY(FD1,FD2);
  322.   XCLOSE(FD1);
  323.   XCLOSE(FD2)
  324. END;
  325.  
  326.  
  327. PROCEDURE ACOPY(FDI,FDO:FILEDESC;N:INTEGER);
  328. VAR
  329.   C:CHARACTER;
  330.   I:INTEGER;
  331. BEGIN
  332.   FOR I:=1 TO N DO
  333.     IF (GETCF(C,FDI)=ENDFILE)THEN
  334.       ERROR('ARCHIVE: END OF FILE IN ACOPY')
  335.     ELSE
  336.       PUTCF(C,FDO)
  337. END;
  338.  
  339. PROCEDURE NOTFOUND;
  340. VAR
  341.   I:INTEGER;
  342. BEGIN
  343.   FOR I := 1 TO NFILES DO
  344.     IF(FSTAT[I]=FALSE)THEN BEGIN
  345.       PUTSTR(FNAME[I],STDERR);
  346.       WRITELN(':NOT IN ARCHIVE');
  347.       ERRCOUNT:=ERRCOUNT + 1
  348.     END
  349. END;
  350.  
  351. PROCEDURE ADDFILE(VAR NAME:XSTRING;FD:FILEDESC);
  352. VAR
  353.   HEAD:XSTRING;
  354.   NFD:FILEDESC;
  355. PROCEDURE MAKEHDR(VAR NAME,HEAD:XSTRING);
  356. VAR
  357.   I:INTEGER;
  358. FUNCTION FSIZE(VAR NAME:XSTRING):INTEGER;
  359. VAR
  360.   C:CHARACTER;
  361.   FD:FILEDESC;
  362.   N:INTEGER;
  363. BEGIN
  364.   N:=0;
  365.   FD:=MUSTOPEN(NAME,IOREAD);
  366.   WHILE(GETCF(C,FD)<>ENDFILE)DO
  367.     N:=N+1;
  368.   XCLOSE(FD);
  369.   FSIZE:=N
  370. END;
  371.  
  372. BEGIN
  373.   SCOPY(ARCHHDR,1,HEAD,1);
  374.   I:=XLENGTH(HEAD)+1;
  375.   HEAD[I]:=BLANK;
  376.   SCOPY(NAME,1,HEAD,I+1);
  377.   I:=XLENGTH(HEAD)+1;
  378.   HEAD[I]:=BLANK;
  379.   I:=ITOC(FSIZE(NAME),HEAD,I+1);
  380.   HEAD[I]:=NEWLINE;
  381.   HEAD[I+1]:=ENDSTR
  382. END;
  383.  
  384. BEGIN
  385.   NFD:=OPEN(NAME,IOREAD);
  386.   IF(NFD=IOERROR)THEN BEGIN
  387.     PUTSTR(NAME,STDERR);
  388.     WRITELN(':CAN''T ADD');
  389.     ERRCOUNT:=ERRCOUNT+1
  390.   END;
  391.   IF(ERRCOUNT=0)THEN BEGIN
  392.     MAKEHDR(NAME,HEAD);
  393.     PUTSTR(HEAD,FD);
  394.     FCOPY(NFD,FD);
  395.     XCLOSE(NFD)
  396.   END
  397. END;
  398.  
  399.  
  400. PROCEDURE REPLACE(AFD,TFD:FILEDESC;CMD:INTEGER);
  401. VAR
  402.   PINLINE,UNAME:XSTRING;
  403.   SIZE:INTEGER;
  404. BEGIN
  405.   WHILE(GETHDR(AFD,PINLINE,UNAME,SIZE))DO
  406.     IF(FILEARG(UNAME))THEN BEGIN
  407.       IF(CMD=ORD('U'))THEN
  408.         ADDFILE(UNAME,TFD);
  409.       FSKIP(AFD,SIZE)
  410.     END
  411.     ELSE BEGIN
  412.       PUTSTR(PINLINE,TFD);
  413.       ACOPY(AFD,TFD,SIZE)
  414.     END
  415. END;
  416.  
  417. PROCEDURE HELP;
  418. BEGIN
  419.   ERROR('USAGE:ARCHIVE -[CDPTUX] ARCHNAME [FILES...]')
  420. END;
  421.  
  422.  
  423. PROCEDURE GETFNS;
  424. VAR
  425.   I,J:INTEGER;
  426.   JUNK:BOOLEAN;
  427. BEGIN
  428.   ERRCOUNT:=0;
  429.   NFILES:=NARGS-3;
  430.   IF(NFILES>MAXFILES)THEN
  431.     ERROR('ARCHIVE:TO MANY FILE NAMES');
  432.   FOR I:=1 TO NFILES DO
  433.     JUNK:=GETARG(I+3,FNAME[I],MAXSTR);
  434.   FOR I:=1 TO NFILES DO
  435.    FSTAT[I]:=FALSE;
  436.   FOR I:=1 TO NFILES-1 DO
  437.     FOR J:=I+1 TO NFILES DO
  438.       IF(EQUAL(FNAME[I],FNAME[J]))THEN BEGIN
  439.         PUTSTR(FNAME[I],STDERR);
  440.         ERROR(':DUPLICATE FILENAME')
  441.       END
  442. END;
  443.  
  444.  
  445. PROCEDURE UPDATE(VAR ANAME:XSTRING;CMD:CHARACTER);
  446. VAR
  447.   I:INTEGER;
  448.   AFD,TFD:FILEDESC;
  449. BEGIN
  450.   TFD:=MUSTCREATE(ARCHTEMP,IOWRITE);
  451.   IF(CMD=ORD('u')) THEN BEGIN
  452.    AFD:=MUSTOPEN(ANAME,IOREAD);
  453.    REPLACE(AFD,TFD,ORD('u'));(*UPDATE EXISTING*)
  454.    XCLOSE(AFD)
  455.  END;
  456.  FOR I:=1 TO NFILES DO
  457.    IF(FSTAT[I]=FALSE)THEN BEGIN
  458.       ADDFILE(FNAME[I],TFD);
  459.       FSTAT[I]:=TRUE
  460.     END;
  461.     XCLOSE(TFD);
  462.     IF(ERRCOUNT=0)THEN
  463.       FMOVE(ARCHTEMP,ANAME)
  464.     ELSE
  465.       WRITELN('FATAL ERRORS - ARCHIVE NOT ALTERED');
  466.     REMOVE (ARCHTEMP)
  467.   END;
  468. PROCEDURE TABLE(VAR ANAME:XSTRING);
  469. VAR
  470.   HEAD,NAME:XSTRING;
  471.   SIZE:INTEGER;
  472.   AFD:FILEDESC;
  473. PROCEDURE TPRINT(VAR BUF:XSTRING);
  474. VAR
  475.   I:INTEGER;
  476.   TEMP:XSTRING;
  477. BEGIN
  478.   I:=GETWORD(BUF,1,TEMP);
  479.   I:=GETWORD(BUF,I,TEMP);
  480.   PUTSTR(TEMP,STDOUT);
  481.   PUTC(BLANK);
  482.   I:=GETWORD(BUF,I,TEMP);(*SIZE*)
  483.   PUTSTR(TEMP,STDOUT);
  484.   PUTC(NEWLINE)
  485. END;
  486.  
  487. BEGIN
  488.   AFD:=MUSTOPEN(ANAME,IOREAD);
  489.   WHILE(GETHDR(AFD,HEAD,NAME,SIZE))DO BEGIN
  490.     IF(FILEARG(NAME))THEN
  491.       TPRINT(HEAD);
  492.     FSKIP(AFD,SIZE)
  493.   END;
  494.   NOTFOUND
  495. END;
  496.  
  497. PROCEDURE EXTRACT (VAR ANAME:XSTRING;CMD:CHARACTER);
  498. VAR
  499.   ENAME,PINLINE:XSTRING;
  500.   AFD,EFD:FILEDESC;
  501.   SIZE : INTEGER;
  502. BEGIN
  503.   AFD:=MUSTOPEN(ANAME,IOREAD);
  504.   IF (CMD=ORD('p')) THEN
  505.     EFD:=STDOUT
  506.   ELSE
  507.     EFD:=IOERROR;
  508.   WHILE (GETHDR(AFD,PINLINE,ENAME,SIZE)) DO
  509.     IF (NOT FILEARG(ENAME))THEN
  510.       FSKIP(AFD,SIZE)
  511.     ELSE
  512.       BEGIN
  513.       IF (EFD<> STDOUT) THEN
  514.         EFD:=CREATE(ENAME,IOWRITE);
  515.       IF(EFD=IOERROR) THEN BEGIN
  516.         PUTSTR(ENAME,STDERR);
  517.         WRITELN(': CANT''T CREATE');
  518.         ERRCOUNT:=ERRCOUNT+1;
  519.         FSKIP(AFD,SIZE)
  520.       END
  521.       ELSE BEGIN
  522.         ACOPY(AFD,EFD,SIZE);
  523.         IF(EFD<>STDOUT)THEN
  524.         XCLOSE(EFD)
  525.       END
  526.     END;
  527.     NOTFOUND
  528.   END;
  529.  
  530. PROCEDURE DELETE(VAR ANAME:XSTRING);
  531. VAR
  532.   AFD,TFD:FILEDESC;
  533. BEGIN
  534.   IF(NFILES<=0)THEN(*PROTECT INNOCENT*)
  535.     ERROR('ARCHIVE:-D REQUIRES EXPLICIT FILE NAMES');
  536.   AFD:=MUSTOPEN(ANAME,IOREAD);
  537.   TFD:=MUSTCREATE(ARCHTEMP,IOWRITE);
  538.   REPLACE(AFD,TFD,ORD('d'));
  539.   NOTFOUND;
  540.   XCLOSE(AFD);
  541.   XCLOSE(TFD);
  542.   IF(ERRCOUNT=0)THEN
  543.     FMOVE(ARCHTEMP,ANAME)
  544.   ELSE
  545.     WRITELN('FATAL ERRORS - ARCHIVE NOT ALTERED');
  546.   REMOVE(ARCHTEMP)
  547. END;
  548.  
  549.  
  550. PROCEDURE INITARCH;
  551. BEGIN
  552.   ARCHTEMP[1]:=ORD('A');
  553.   ARCHTEMP[2]:=ORD('R');
  554.   ARCHTEMP[3]:=ORD('T');
  555.   ARCHTEMP[4]:=ORD('E');
  556.   ARCHTEMP[5]:=ORD('M');
  557.   ARCHTEMP[6]:=ORD('P');
  558.   ARCHTEMP[7]:=ENDSTR;
  559.   ARCHHDR[1]:=ORD('-');
  560.   ARCHHDR[2]:=ORD('H');
  561.   ARCHHDR[3]:=ORD('-');
  562.   ARCHHDR[4]:=ENDSTR;
  563. END;
  564.  
  565.  
  566. BEGIN
  567.   INITARCH;
  568.   IF (NOT GETARG(2,CMD,MAXSTR))
  569.     OR(NOT GETARG(3,ANAME,MAXSTR)) THEN
  570.       HELP;
  571.   GETFNS;
  572.   IF(XLENGTH(CMD)<>2) OR(CMD[1]<>ORD('-')) THEN
  573.     HELP
  574.   ELSE IF (CMD[2]=ORD('c'))OR(CMD[2]=ORD('u'))THEN
  575.     UPDATE(ANAME,CMD[2])
  576.   ELSE IF (CMD[2]=ORD('t'))THEN
  577.     TABLE(ANAME)
  578.   ELSE IF (CMD[2]=ORD('x'))OR(CMD[2]=ORD('p'))THEN
  579.     EXTRACT(ANAME,CMD[2])
  580.   ELSE IF (CMD[2]=ORD('d'))THEN
  581.     DELETE(ANAME)
  582.   ELSE
  583.     HELP
  584. END;
  585.  
  586.  
  587.  
  588.