home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ipo-101.zip / Samples.zip / imake.pas < prev    next >
Pascal/Delphi Source File  |  1998-10-20  |  9KB  |  334 lines

  1. (*
  2. ** Irie Make utility
  3. *)
  4. program imake(makefile, target, out, output);
  5. type
  6.    TokenKind = (ProjectTok, ProgramTok, BeginTok, EndTok, DoTok,
  7.                 CommaTok, SemiColonTok, StringTok, IdTok,
  8.                 EmptyTok, EOFtok);
  9.    Token = record
  10.              lineno : integer;
  11.              case kind : TokenKind of
  12.                 ProjectTok..SemiColonTok : ();
  13.                 StringTok : ( s : string);
  14.                 IdTok : (id : string);
  15.                 EOFtok, EmptyTok : ();
  16.            end;
  17. var
  18.    makefile, out : text;
  19.    target : string;
  20.    line : string;
  21.    lineno, linepos, linelen : integer;
  22.    CurrToken : Token;
  23.    whitespace : set of char;
  24.    letter : set of char;
  25.    MakeAll : boolean;
  26.    NumMade : integer;
  27.  
  28.    procedure syntax;
  29.    begin
  30.       writeln('IMAKE - Irie Make');
  31.       writeln('Usage:  imake makefile target');
  32.       writeln('  where ''makefile'' is the name of the makefile');
  33.       writeln('  and   ''target'' is the program/project to make');
  34.       halt
  35.    end;
  36.  
  37.    procedure error(s : string);
  38.    begin
  39.       writeln(out, 'ERROR: ', lineno:2, ':', s);
  40.       halt
  41.    end;
  42.  
  43.    procedure GetStringToken;
  44.    var
  45.       first, last : integer;
  46.       c : char;
  47.    begin
  48.       c := line[linepos];
  49.       first := linepos;
  50.       last := pos(c, line, first+1);
  51.       if last <= first then
  52.          error('String not terminated');
  53.       CurrToken.kind := StringTok;
  54.       CurrToken.s := copy(line, first+1, last-first-1);
  55.       CurrToken.lineno := lineno;
  56.       linepos := last+1
  57.    end;
  58.  
  59.    procedure GetIdToken;
  60.    var
  61.       first, last : integer;
  62.       c : char;
  63.       s : string;
  64.  
  65.       procedure identify(strg : string);
  66.       (*
  67.       ** Identify the following keywords
  68.       ** project, program, begin, end, do
  69.       *)
  70.       var
  71.          s : string;
  72.       begin
  73.          s := lowercase(strg);
  74.          if s = 'project' then
  75.             CurrToken.kind := ProjectTok
  76.          else if s = 'program' then
  77.             CurrToken.kind := ProgramTok
  78.          else if s = 'begin' then
  79.             CurrToken.kind := BeginTok
  80.          else if s = 'end' then
  81.             CurrToken.kind := EndTok
  82.          else if s = 'do' then
  83.             CurrToken.kind := DoTok
  84.          else
  85.             begin
  86.                CurrToken.kind := IdTok;
  87.                CurrToken.id := strg;
  88.             end;
  89.          CurrToken.lineno := lineno;
  90.       end;
  91.  
  92.    begin
  93.       c := line[linepos];
  94.       first := linepos;
  95.       last := first;
  96.       while (last+1 <= linelen) and (line[last+1] in letter) do
  97.           inc(last);
  98.       s := copy(line, first, last-first+1);
  99.       linepos := last+1;
  100.       identify(s)
  101.    end;
  102.  
  103.    procedure GetToken;
  104.  
  105.       function ProcessLine : boolean;
  106.       var
  107.          c : char;
  108.       begin
  109.          if CurrToken.kind = EOFtok then
  110.             exit(true);
  111.          while linepos <= linelen do
  112.             begin
  113.                c := line[linepos];
  114.                case c of
  115.                ',':
  116.                   begin
  117.                      inc(linepos);
  118.                      CurrToken.kind := CommaTok;
  119.                      CurrToken.lineno := lineno;
  120.                      exit(true)
  121.                   end;
  122.                ';':
  123.                   begin
  124.                      inc(linepos);
  125.                      CurrToken.kind := SemiColonTok;
  126.                      CurrToken.lineno := lineno;
  127.                      exit(true)
  128.                   end;
  129.                '{':
  130.                   begin
  131.                      inc(linepos);
  132.                      CurrToken.kind := BeginTok;
  133.                      CurrToken.lineno := lineno;
  134.                      exit(true)
  135.                   end;
  136.                '}':
  137.                   begin
  138.                      inc(linepos);
  139.                      CurrToken.kind := EndTok;
  140.                      CurrToken.lineno := lineno;
  141.                      exit(true)
  142.                   end;
  143.                '"', '''':
  144.                   begin
  145.                      GetStringToken;
  146.                      exit(true)
  147.                   end;
  148.                '/':
  149.                   if (linepos < linelen) and (line[linepos+1] = '/') then
  150.                      linepos := linelen+1
  151.                   else
  152.                      error('Text not recognized');
  153.                otherwise
  154.                   if c in letter then
  155.                      begin
  156.                         GetIdToken;
  157.                         exit(true)
  158.                      end
  159.                   else if c in whitespace then
  160.                      inc(linepos)
  161.                   else
  162.                      error('Text not recognized')
  163.                end (* case *)
  164.          end; (* while *)
  165.          exit(false)
  166.       end; (* ProcessLine *)
  167.  
  168.       procedure NewLine;
  169.       begin
  170.          if eof(makefile) then
  171.             begin
  172.                CurrToken.kind := EOFtok;
  173.                CurrToken.lineno := lineno;
  174.                exit
  175.             end;
  176.          readln(makefile, line);
  177.          linelen := length(line);
  178.          inc(lineno);
  179.          linepos := 1
  180.       end;
  181.  
  182. (*
  183.       procedure PrintToken;
  184.       begin
  185.          case CurrToken.kind of
  186.          ProjectTok:
  187.             write(out, '<PROJECT>');
  188.          ProgramTok:
  189.             write(out, '<PROGRAM>');
  190.          BeginTok:
  191.             writeln(out, '<BEGIN>');
  192.          EndTok:
  193.             begin
  194.                writeln(out);
  195.                writeln(out, '<END>')
  196.             end;
  197.          DoTok:
  198.             writeln(out, '<DO>');
  199.          CommaTok:
  200.             write(out, ', ');
  201.          SemiColonTok:
  202.             write(out, '; ');
  203.          StringTok:
  204.             write(out, '''', CurrToken.s, '''');
  205.          IdTok:
  206.             write(out, CurrToken.id);
  207.          EmptyTok:
  208.             write(out, '<EMPTY>');
  209.          EOFtok:
  210.             write(out, '<EOF>')
  211.          end
  212.       end;
  213. *)
  214.  
  215.    begin (* GetToken *)
  216.       CurrToken.kind := EmptyTok;
  217.       if lineno = 0 then
  218.          NewLine;
  219.       while not ProcessLine do
  220.          NewLine;
  221.       (* PrintToken *)
  222.    end; (* GetToken *)
  223.  
  224.    procedure skip(k : TokenKind);
  225.    begin
  226.       if CurrToken.kind <> k then
  227.          error('Invalid syntax');
  228.       GetToken
  229.    end;
  230.  
  231.    procedure run(command, name : string);
  232.    var
  233.       rc : integer;
  234.       s : string;
  235.    begin
  236.       s := command+' '+name;
  237.       writeln(out, 'Running ', s);
  238.       rc := system(s);
  239.       writeln(out, 'Exit code ', rc:3);
  240.       if rc <> 0 then
  241.          halt(rc);
  242.       inc(NumMade)
  243.    end;
  244.  
  245.    procedure parse;
  246.    var
  247.       ProjectName : string;
  248.  
  249.       function ParseName : string;
  250.       begin
  251.          case CurrToken.kind of
  252.             Idtok: ParseName := CurrToken.id;
  253.             StringTok: ParseName := CurrToken.s;
  254.             otherwise error('Illegal syntax');
  255.          end; (* case *)
  256.          skip(CurrToken.kind);
  257.       end;
  258.  
  259.       procedure ParseProjectGroup;
  260.  
  261.          procedure ParseProgramSpec;
  262.          var
  263.             ProgramName : string;
  264.             MakeProgram : boolean;
  265.  
  266.             procedure ParseProgramGroup(b : boolean);
  267.  
  268.                procedure ParseAction(b : boolean);
  269.                var
  270.                   command, fn : string;
  271.                begin (* ParseAction *)
  272.                   skip(Dotok);
  273.                   command := ParseName;
  274.                   skip(BeginTok);
  275.                   repeat
  276.                      fn := ParseName;
  277.                      if b then
  278.                         run(command, fn);
  279.                      if ((CurrToken.kind = CommaTok) or (CurrToken.kind = SemiColonTok)) then
  280.                         skip(CurrToken.kind)
  281.                   until ((CurrToken.kind <> IDtok) and (CurrToken.kind <> StringTok));
  282.                   skip(EndTok)
  283.                end; (* ParseAction *)
  284.  
  285.             begin (* ParseProgramGroup *)
  286.                skip(BeginTok);
  287.                repeat
  288.                   ParseAction(b);
  289.                until CurrToken.kind <> DoTok;
  290.                skip(EndTok);
  291.             end; (* ParseProgramGroup *)
  292.  
  293.          begin (* ParseProgramSpec *)
  294.             skip(ProgramTok);
  295.             ProgramName := ParseName;
  296.             MakeProgram := MakeAll or (lowercase(ProgramName) = lowercase(target));
  297.             if MakeProgram then
  298.                 writeln(out, 'Making ', ProgramName);
  299.             ParseProgramGroup(MakeProgram)
  300.          end; (* ParseProgramSpec *)
  301.  
  302.       begin (* ParsePojectGroup *)
  303.          skip(BeginTok);
  304.          while CurrToken.kind = ProgramTok do
  305.             ParseProgramSpec;
  306.          skip(EndTok);
  307.       end; (* ParsePojectGroup *)
  308.  
  309.    begin (* parse *)
  310.       skip(ProjectTok);
  311.       ProjectName := ParseName;
  312.       if lowercase(ProjectName) = lowercase(target) then
  313.          MakeAll := true
  314.       else
  315.          MakeAll := false;
  316.       NumMade := 0;
  317.       ParseProjectGroup;
  318.       if NumMade = 0 then
  319.          writeln(out, 'WARNING: No targets were made')
  320.    end; (* parse *)
  321.  
  322. begin
  323.    if paramcount < 2 then
  324.        syntax;
  325.    reset(makefile);
  326.    rewrite(out);
  327.    writeln(out, 'Target = ', target);
  328.    lineno := 0;
  329.    whitespace := [chr(0)..' '];
  330.    letter := ['@', 'a'..'z', 'A'..'Z', '0'..'9', '_', ':', '\', '.'];
  331.    GetToken;
  332.    parse
  333. end.
  334.