home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / dev / obero / oberon-a / source / misc / stripcomments.mod < prev    next >
Encoding:
Text File  |  1995-07-02  |  10.4 KB  |  449 lines

  1. (*************************************************************************
  2.  
  3.      $RCSfile: StripComments.mod $
  4.   Description: A utility to strip comments from Oberon source files.
  5.  
  6.    Created by: fjc (Frank Copeland)
  7.     $Revision: 1.7 $
  8.       $Author: fjc $
  9.         $Date: 1995/01/26 01:05:15 $
  10.  
  11.   Copyright © 1994-1995, Frank Copeland.
  12.   This file is part of Oberon-A.
  13.   See Oberon-A.doc for conditions of use and distribution.
  14.  
  15. *************************************************************************)
  16.  
  17. <*STANDARD-*>
  18.  
  19. MODULE StripComments;
  20.  
  21. IMPORT
  22.   SYS := SYSTEM,
  23.   Kernel,
  24.   Errors,
  25.   rev := StripCommentsRev,
  26.   e := Exec,
  27.   d := Dos,
  28.   f := Files,
  29.   IO := StdIO,
  30.   Str := Strings;
  31.  
  32. CONST
  33.  
  34.   template = "FROM/A/M,TO/K,VERBOSE/S";
  35.   optFrom = 0;
  36.   optTo = 1;
  37.   optVerbose = 2;
  38.   optCount = 3;
  39.  
  40. TYPE
  41.  
  42.   StringArray = POINTER [2] TO ARRAY 32767 OF e.LSTRPTR;
  43.  
  44. VAR
  45.  
  46.   rdArgs    : d.RDArgsPtr;
  47.   fromArray : StringArray;
  48.   toDir     : e.LSTRPTR;
  49.  
  50. CONST
  51.   CopyrightStr = "Copyright © 1994, Frank Copeland\n";
  52.   UsageStr     = "see Oberon-A.doc for conditions of use\n\n";
  53.   FileTag      = "\n\n(* Comments stripped by StripComments 1.5 *)\n";
  54.  
  55. CONST
  56.  
  57.   PathLen = 255;
  58.  
  59. TYPE
  60.  
  61.   Path = ARRAY PathLen + 1 OF CHAR;
  62.  
  63. VAR
  64.  
  65.   (*
  66.     These variables are global so that they may be found by the Cleanup()
  67.     procedure in the event of an abnormal exit
  68.   *)
  69.  
  70.   input,      (* The current input file. *)
  71.   output      (* The current output file. *)
  72.     : f.File;
  73.  
  74.   r, w : f.Rider;
  75.   ch : CHAR;
  76.  
  77. CONST
  78.  
  79.   CR = 0DX; LF = 0AX; TAB = 09X; SP = " ";
  80.  
  81. VAR
  82.  
  83.   state, line, spaces, blanklines : INTEGER;
  84.   blankline : BOOLEAN;
  85.   quoteChar : CHAR;
  86.  
  87. CONST
  88.  
  89.   STARTLINE = 0;
  90.   WHITESPACE = 1;
  91.   COPYCHAR = 2;
  92.   LEFTBRACKET = 3;
  93.   STARTCOMMENT = 4;
  94.   COPYCOMMENT = 5;
  95.   SKIPCOMMENT = 6;
  96.   STAR = 7;
  97.   ENDCOMMENT = 8;
  98.   INSTRING = 9;
  99.  
  100.  
  101. (*------------------------------------*)
  102. PROCEDURE* Cleanup (VAR rc : LONGINT);
  103.  
  104. BEGIN (* Cleanup *)
  105.   IF input # NIL THEN f.Close (input) END;
  106.   IF output # NIL THEN f.Purge (output) END;
  107.   IF rdArgs # NIL THEN d.FreeArgs (rdArgs) END
  108. END Cleanup;
  109.  
  110. (*------------------------------------*)
  111. PROCEDURE Init ();
  112.  
  113. BEGIN (* Init *)
  114.   IF d.base.lib.version >= 37 THEN
  115.     rdArgs := NIL; fromArray := NIL; toDir := NIL;
  116.     Kernel.SetCleanup (Cleanup)
  117.   ELSE
  118.     IO.WriteStr (" !! StripComments requires OS release 2.04 or greater\n");
  119.     HALT (d.warn)
  120.   END
  121. END Init;
  122.  
  123. (*------------------------------------*)
  124. PROCEDURE GetArgs ();
  125.  
  126.   VAR
  127.     argArray  : ARRAY optCount OF SYS.LONGWORD;
  128.     i : INTEGER;
  129.  
  130. BEGIN (* GetArgs *)
  131.   FOR i := 0 TO optCount - 1 DO argArray [i] := NIL END;
  132.   rdArgs := d.OldReadArgs (template, argArray, NIL);
  133.   IF rdArgs # NIL THEN
  134.     (*
  135.     ** fromArray is guaranteed to contain something, because of the /A
  136.     ** toDir can be NIL
  137.     *)
  138.     fromArray := SYS.VAL (StringArray, argArray [optFrom]);
  139.     toDir := SYS.VAL (e.LSTRPTR, argArray [optTo]);
  140.   ELSE
  141.     IF d.PrintFault (d.IoErr(), "ReadArgs") THEN END;
  142.     HALT (d.error)
  143.   END
  144. END GetArgs;
  145.  
  146. (*------------------------------------*)
  147. PROCEDURE MakeOutputName
  148.   (inputName : ARRAY OF CHAR; VAR outputName : ARRAY OF CHAR);
  149.  
  150.   VAR filePart : e.LSTRPTR;
  151.  
  152. <*$CopyArrays-*>
  153. BEGIN (* MakeOutputName *)
  154.   filePart := d.FilePart (inputName);
  155.   IF toDir = NIL THEN COPY ("", outputName)
  156.   ELSE COPY (toDir^, outputName)
  157.   END;
  158.   Errors.Assert
  159.     ( d.AddPart (outputName, filePart^, PathLen),
  160.       "Output file name too big" )
  161. END MakeOutputName;
  162.  
  163. (*------------------------------------*)
  164. PROCEDURE WriteSpaces ();
  165.  
  166. BEGIN (* WriteSpaces *)
  167.   WHILE spaces > 0 DO f.Write (w, SP); DEC (spaces) END
  168. END WriteSpaces;
  169.  
  170. (*------------------------------------*)
  171. PROCEDURE WriteString (s : ARRAY OF CHAR);
  172.  
  173.   VAR i : INTEGER; ch : CHAR;
  174.  
  175. <*$CopyArrays-*>
  176. BEGIN (* WriteString *)
  177.   i := 0; ch := s [0];
  178.   WHILE ch # 0X DO f.Write (w, ch); INC (i); ch := s [i] END
  179. END WriteString;
  180.  
  181. (*------------------------------------*)
  182. PROCEDURE CopyComment ();
  183.  
  184. BEGIN (* CopyComment *)
  185.   state := COPYCOMMENT;
  186.   LOOP
  187.     f.Read (r, ch);
  188.     IF r.eof THEN
  189.       IO.WriteStr (" !! End of file encountered in CopyComment()\n"); EXIT
  190.     END;
  191.     f.Write (w, ch);
  192.     CASE ch OF
  193.       LF :
  194.         INC (line);
  195.         IF (line MOD 10) = 0 THEN IO.WriteInt (line); IO.Write (CR) END;
  196.         state := COPYCOMMENT
  197.       |
  198.       "(" : state := LEFTBRACKET
  199.       |
  200.       "*" :
  201.         IF state = LEFTBRACKET THEN CopyComment (); state := COPYCOMMENT
  202.         ELSE state := STAR
  203.         END
  204.       |
  205.       ")" : IF state = STAR THEN EXIT ELSE state := COPYCOMMENT END
  206.       |
  207.     ELSE state := COPYCOMMENT
  208.     END
  209.   END
  210. END CopyComment;
  211.  
  212. (*------------------------------------*)
  213. PROCEDURE SkipComment ();
  214.  
  215. BEGIN (* SkipComment *)
  216.   state := SKIPCOMMENT;
  217.   LOOP
  218.     CASE ch OF
  219.       LF :
  220.         INC (line); INC (blanklines);
  221.         IF (line MOD 10) = 0 THEN IO.WriteInt (line); IO.Write (CR) END;
  222.         state := SKIPCOMMENT
  223.       |
  224.       "(" : state := LEFTBRACKET
  225.       |
  226.       "*" :
  227.         IF state = LEFTBRACKET THEN SkipComment (); state := SKIPCOMMENT
  228.         ELSE state := STAR
  229.         END
  230.       |
  231.       ")" : IF state = STAR THEN EXIT ELSE state := SKIPCOMMENT END
  232.       |
  233.     ELSE state := SKIPCOMMENT
  234.     END;
  235.     f.Read (r, ch);
  236.     IF r.eof THEN
  237.       IO.WriteStr (" !! End of file encountered in SkipComment()\n"); EXIT
  238.     END;
  239.   END
  240. END SkipComment;
  241.  
  242. (*------------------------------------*)
  243. PROCEDURE ChangeState ();
  244.  
  245. BEGIN (* ChangeState *)
  246.   CASE state OF
  247.     STARTLINE :
  248.       INC (line);
  249.       IF (line MOD 10) = 0 THEN IO.WriteInt (line); IO.Write (CR) END;
  250.       IF blankline THEN INC (blanklines)
  251.       ELSE blanklines := 0; blankline := TRUE
  252.       END;
  253.       IF blanklines < 2 THEN f.Write (w, LF) END;
  254.       spaces := 0;
  255.       CASE ch OF
  256.         LF : state := STARTLINE
  257.         |
  258.         SP : INC (spaces); state := WHITESPACE
  259.         |
  260.         TAB : INC (spaces, 8); state := WHITESPACE
  261.         |
  262.         "(" : state := LEFTBRACKET
  263.         |
  264.         "'", '"' :
  265.           f.Write (w, ch); state := INSTRING; quoteChar := ch
  266.         |
  267.       ELSE
  268.         f.Write (w, ch); state := COPYCHAR
  269.       END;
  270.     |
  271.     WHITESPACE :
  272.       CASE ch OF
  273.         LF : state := STARTLINE
  274.         |
  275.         SP : INC (spaces); state := WHITESPACE
  276.         |
  277.         TAB : INC (spaces, 8); state := WHITESPACE
  278.         |
  279.         "(" : state := LEFTBRACKET
  280.         |
  281.         "'", '"' :
  282.           WriteSpaces(); f.Write (w, ch); state := INSTRING;
  283.           quoteChar := ch
  284.         |
  285.       ELSE
  286.         WriteSpaces(); f.Write (w, ch); state := COPYCHAR
  287.       END;
  288.     |
  289.     COPYCHAR :
  290.       blankline := FALSE;
  291.       CASE ch OF
  292.         LF : state := STARTLINE
  293.         |
  294.         SP : INC (spaces); state := WHITESPACE
  295.         |
  296.         TAB : INC (spaces, 8); state := WHITESPACE
  297.         |
  298.         "(" : state := LEFTBRACKET
  299.         |
  300.         "'", '"' :
  301.           f.Write (w, ch); state := INSTRING; quoteChar := ch
  302.         |
  303.       ELSE
  304.         f.Write (w, ch); state := COPYCHAR
  305.       END;
  306.     |
  307.     LEFTBRACKET :
  308.       CASE ch OF
  309.         "*" : state := STARTCOMMENT
  310.         |
  311.         LF :
  312.           WriteSpaces (); f.Write (w, "("); state := STARTLINE
  313.         |
  314.         SP :
  315.           WriteSpaces (); f.Write (w, "("); spaces := 1;
  316.           blankline := FALSE; state := WHITESPACE
  317.         |
  318.         TAB :
  319.           WriteSpaces (); f.Write (w, "("); spaces := 8;
  320.           blankline := FALSE; state := WHITESPACE
  321.         |
  322.         "(" :
  323.           WriteSpaces (); f.Write (w, "("); blankline := FALSE;
  324.           state := LEFTBRACKET
  325.         |
  326.         "'", '"' :
  327.           WriteSpaces (); f.Write (w, "("); f.Write (w, ch);
  328.           state := INSTRING; quoteChar := ch
  329.         |
  330.       ELSE
  331.         WriteSpaces (); f.Write (w, "("); f.Write (w, ch);
  332.         state := COPYCHAR
  333.       END;
  334.     |
  335.     STARTCOMMENT :
  336.       IF ch = "!" THEN
  337.         WriteSpaces(); WriteString ("(*"); CopyComment ();
  338.         blankline := FALSE
  339.       ELSE
  340.         SkipComment ()
  341.       END;
  342.       state := ENDCOMMENT
  343.     |
  344.     ENDCOMMENT :
  345.       CASE ch OF
  346.         LF : state := STARTLINE
  347.         |
  348.         SP : INC (spaces); state := WHITESPACE
  349.         |
  350.         TAB : INC (spaces, 8); state := WHITESPACE
  351.         |
  352.         "(" : state := LEFTBRACKET
  353.         |
  354.         "'", '"' :
  355.           f.Write (w, ch); state := INSTRING; quoteChar := ch
  356.         |
  357.       ELSE
  358.         f.Write (w, ch); state := COPYCHAR
  359.       END;
  360.     |
  361.     INSTRING :
  362.       f.Write (w, ch); IF ch = quoteChar THEN state := COPYCHAR END
  363.     |
  364.   END
  365. END ChangeState;
  366.  
  367. (*------------------------------------*)
  368. PROCEDURE Strip (inputName : ARRAY OF CHAR);
  369.  
  370.   VAR outputName : Path;
  371.  
  372. <*$CopyArrays-*>
  373. BEGIN (* Strip *)
  374.   input := f.Old (inputName);
  375.   IF input # NIL THEN
  376.     MakeOutputName (inputName, outputName);
  377.     output := f.New (outputName);
  378.     IF output # NIL THEN
  379.       IO.WriteF2
  380.         (" !! %s -> %s\n", SYS.ADR (inputName), SYS.ADR (outputName));
  381.       f.Set (r, input, 0);
  382.       f.Set (w, output, 0);
  383.       spaces := 0; state := WHITESPACE; line := 1; blankline := FALSE;
  384.       WHILE ~r.eof DO
  385.         f.Read (r, ch);
  386.         ChangeState ()
  387.       END;
  388.       WriteString (FileTag);
  389.       f.Close (input);
  390.       f.Register (output)
  391.     ELSE
  392.       f.Close (input);
  393.       IO.WriteF1 (" !! Could not open %s\n", SYS.ADR (outputName))
  394.     END
  395.   ELSE
  396.     IO.WriteF1 (" !! Could not open %s\n", SYS.ADR (inputName))
  397.   END;
  398.  
  399.   input := NIL; output := NIL;
  400.   f.Set (r, NIL, 0); f.Set (w, NIL, 0);
  401.   Kernel.GC
  402. END Strip;
  403.  
  404. (*------------------------------------*)
  405. PROCEDURE Main ();
  406.  
  407.   VAR
  408.     i : INTEGER;
  409.     pat : e.LSTRPTR; modName : ARRAY 32 OF CHAR;
  410.     myAnchor : d.AnchorPathPtr; result : LONGINT;
  411.     fileName : ARRAY 256 OF CHAR;
  412.  
  413. BEGIN (* Main *)
  414.   (* myAnchor is allocated because it must be longword aligned *)
  415.   <*$ < ClearVars+ *> NEW (myAnchor); <*$ > *>
  416.   myAnchor.strlen := SHORT (LEN (myAnchor.buf));
  417.   i := 0;
  418.   LOOP
  419.     (*
  420.     ** fromArray is an array of pointers to strings, each string
  421.     ** being a file name or an AmigaDOS pattern. The last entry
  422.     ** NIL.
  423.     *)
  424.     pat := fromArray [i];
  425.     IF pat = NIL THEN EXIT END;
  426.     (* Find the first file matching the pattern *)
  427.     result := d.MatchFirst (pat^, myAnchor^);
  428.     WHILE result = 0 DO
  429.       (* Strip the file and get the next name. *)
  430.       Strip (myAnchor.buf);
  431.       (* Get the next matching file *)
  432.       result := d.MatchNext (myAnchor^)
  433.     END;
  434.     d.MatchEnd (myAnchor^); (* Clean up anchor data *)
  435.     INC (i)
  436.   END;
  437. END Main;
  438.  
  439. (*------------------------------------*)
  440. BEGIN (* StripComments *)
  441.   IO.WriteStr (rev.vString);
  442.   IO.WriteStr (CopyrightStr);
  443.   IO.WriteStr (UsageStr);
  444.   Init ();
  445.   GetArgs ();
  446.   Main ();
  447.   IO.WriteStr ("\x9B\x4B !! All done\n")
  448. END StripComments.
  449.