home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / PASEDIT.ZIP / EDIT-MOD.PAS next >
Encoding:
Pascal/Delphi Source File  |  1988-07-29  |  20.6 KB  |  611 lines

  1. {  $LIST+, $DEBUG+, $BRAVE+, $LINESIZE:132, $PAGESIZE:77, $OCODE+   }
  2. {  $NILCK+, $MATHCK+, $RANGECK+, $INITCK+, $INDEXCK+, $ENTRY+    }
  3. {  $LINE+, $RUNTIME+, $SYMTAB+, $WARN+, $GOTO+     }
  4. {  $TITLE:'EDITOR MODULE:  MODULE.PAS  - AEM$SCRATCH ' }
  5. {  $MESSAGE:'PASCAL - COMPILATION OPTIONS SET'     }
  6. {  $MESSAGE:'SYSTEM - COMPILATION BEGINS'          }
  7. {  $message:'PASCAL - MODULE COMPILATION LINKAGE SET' }
  8.  
  9.  
  10.  
  11. const
  12.    charspernode    = 34;
  13.    debug   = true;
  14.    maxcharp1   = 201;
  15.    maxchars    = 200;
  16.    maxcommandlength    = 7;
  17.    numberlongcommands  =17;
  18.    numbershortcommands =18;
  19.    off = false;
  20.    on  = true;
  21.  
  22. type
  23.    linecharptr  =   ^linecharnode;
  24.    lineptr     =   ^lineptrnode;
  25.    lineptrnode =   record
  26.        length  :   0 .. maxchars;
  27.        nextline:   lineptr;
  28.        previousline    :   lineptr;
  29.        firstnode   : linecharptr
  30.    end;    {   record   }
  31.    linecharnode    =   record
  32.        nextnode    : linecharptr;
  33.        chars       : packed array [ 1 .. charspernode] of char
  34.    end;  { record  }
  35.    linelengthdef   = 0 .. maxchars;
  36.    linedef = record
  37.        length  : linelengthdef;
  38.        position : 0 .. maxcharp1;
  39.        chars   : array [ 1 .. maxcharp1] of char
  40.    end;   { record  }
  41.    messagetype = string[30];
  42.    commanddef  = record
  43.        length  : linelengthdef;
  44.        position: 0 .. maxcharp1;
  45.        chars   : packed array [ 1 .. maxcommandlength] of char
  46.    end;   { record  }
  47.    stringdef   = record
  48.        first   : 0 .. maxcharp1;
  49.        last    : linelengthdef;
  50.        length  : linelengthdef
  51.    end;
  52.    commandtable    = record
  53.        shortcommands : array [ 1 .. numbershortcommands ] of char;
  54.        longcommands  : array [ 1 .. numberlongcommands ] of
  55.                            packed array [ 1 .. maxcommandlength ] of char
  56.    end;   { record  }
  57.  
  58.  
  59.  
  60. var
  61.    edfile : text;
  62.    currentline : lineptr;
  63.  
  64.  
  65. function min ( x, y : integer) : integer; 
  66. begin
  67.    if x < y then min := x else min := y
  68. end;   { function  }
  69.  
  70. procedure readline (var line : linedef);  
  71. begin
  72.    with line do
  73.        begin
  74.            length := 0;
  75.            while not eoln (edfile) do
  76.                begin
  77.                    length := length + 1;
  78.                    read (edfile, chars[length])
  79.                end  { eoln  }
  80.        end;   { with }
  81.    readln (edfile)
  82. end;   { procedure   }
  83.  
  84. procedure insertline (currentline, newline : lineptr); 
  85. begin
  86.    newline^.nextline := currentline^.nextline;
  87.    newline^.previousline := currentline;
  88.    newline^.nextline^.previousline := newline;
  89.    currentline^.nextline := newline
  90. end;   { insertline  }
  91.  
  92. procedure packline (line : linedef; packedline : lineptr);    
  93.  
  94. var
  95.    charnum : 1 .. charspernode;
  96.    charspacked : integer;
  97.    node, oldnode : linecharptr;
  98.  
  99. begin
  100.    packedline^.length := line.length;
  101.    if line.length <> 0 then
  102.        begin
  103.            new (node);
  104.            packedline^.firstnode := node;
  105.            for charnum := 1 to min (line.length,charspernode) do
  106.                node^.chars [charnum] := line.chars [charnum];
  107.            charspacked := charspernode;
  108.            while charspacked < line.length do
  109.                begin
  110.                    oldnode := node;
  111.                    new (node);
  112.                    oldnode^.nextnode := node;
  113.                    for charnum := 1 to min (line.length-charspacked,charspernode) do
  114.                        node^.chars [charnum] := line.chars [charspacked+charnum];
  115.                    charspacked := charspacked+charspernode
  116.                end;  { while  }
  117.            node^.nextnode := nil
  118.        end
  119.  else
  120.        packedline^.firstnode := nil
  121. end;  { procedure packline  }
  122.  
  123. procedure readfile (var currentline, sentinel : lineptr);    
  124.  
  125. var
  126.    line    : linedef;   { scratch buffer  }
  127.    newline : lineptr;   { new line to insert }
  128.  
  129. begin
  130.    reset (edfile);
  131.    new(currentline);
  132.    sentinel := currentline;
  133.    with sentinel^ do
  134.        begin
  135.            length := 0;
  136.            previousline := currentline;
  137.            nextline := currentline;
  138.            firstnode := nil
  139.        end;
  140.    while not eof (edfile) do
  141.        begin
  142.            readline (line);
  143.            new (newline);
  144.            insertline (currentline,newline);
  145.            currentline := newline;
  146.            packline (line,currentline)
  147.        end  { while  }
  148. end;    { procedure  }
  149.  
  150. procedure errormessage (var noerror : boolean; message : messagetype); 
  151. begin
  152.    writeln ('*** ',message);
  153.    noerror := false
  154. end;   {  error handler  }
  155.  
  156. procedure checkempty (sentinel : lineptr; var noerror : boolean);  
  157. begin
  158.    if noerror and (sentinel^.nextline = sentinel) then
  159.        errormessage (noerror, 'EDIT FILE EMPTY')
  160. end;   {   check empty }
  161.  
  162. procedure removetrailingblanks (var line : linedef);   
  163. var
  164.    done : boolean;
  165.  index : integer;
  166.  
  167. begin
  168.    with line do
  169.        begin
  170.            done := false;
  171.            index := 1;
  172.            while not done and (index <= length) do
  173.                if chars[index] <> ' ' then
  174.                        index := index + 1
  175.                else
  176.                    done := true;
  177.            if done then
  178.                  length := index;
  179.            position := 1;
  180.            chars[length+1] := ' ';
  181.            if (length = 0) then length := 1
  182.        end    { with  }
  183. end;   {  procedure  }
  184.  
  185. procedure readcommand (prompt : char; var line : linedef);    
  186. begin
  187.    with line do
  188.        begin
  189.            write (prompt,' ');
  190.            length := 0;    { assume null command on input  }
  191.            while not eoln do
  192.                begin
  193.                    length := length + 1;
  194.                    read (chars [length])
  195.                end;
  196.             if prompt = '>' then
  197.                 removetrailingblanks (line)     { skip proc call }
  198.    end;                                         { if inserting lines }
  199.     readln;
  200.     writeln
  201. end;   { procedure  }
  202.  
  203. procedure skipblanks (var line : linedef);   
  204. begin
  205.    with line do
  206.        begin
  207.            while (position <= length) and (chars [position] = ' ') do
  208.                position := position + 1
  209.    end  { while }
  210. end;  { procedure  }
  211.  
  212. procedure movelinepointer (var currentline : lineptr; linestomove : integer;
  213.                            sentinel : lineptr; var noerror : boolean); 
  214.  
  215. var
  216.    bottomoffile,topoffile : lineptr;
  217. begin
  218.    checkempty (sentinel, noerror);
  219.    if noerror then
  220.        begin
  221.            topoffile := sentinel^.nextline;
  222.            bottomoffile := sentinel^.previousline;
  223.            while ((currentline <> topoffile) and (linestomove < 0)) or
  224.                ((currentline <> bottomoffile) and (linestomove > 0)) do
  225.                begin
  226.                    if linestomove < 0 then
  227.                        begin
  228.                            linestomove := linestomove +1 ;
  229.                            currentline := currentline^.previousline
  230.                        end
  231.                    else
  232.                        begin
  233.                            linestomove := linestomove - 1 ;
  234.                            currentline := currentline^.nextline
  235.                        end
  236.                end; { while  }
  237.            if linestomove <> 0 then
  238.                if linestomove > 0 then
  239.                    errormessage (noerror, 'END OF INPUT FILE')
  240.                else
  241.                    errormessage (noerror, 'TOP OF INPUT FILE')
  242.        end
  243. end;   { procedure }
  244.  
  245. function numeric ( ch : char) : boolean;  
  246. begin
  247.    numeric := (ch >= '0') and (ch <= '9')
  248. end;   { function }
  249.  
  250. procedure getnumber (var line : linedef; var number : integer;
  251.                  var legalnumber : boolean);     
  252. var
  253.    sign : integer;
  254. begin
  255.    number := 0;
  256.    legalnumber := false;
  257.    skipblanks (line);
  258.    with line do
  259.        begin
  260.            if position <= length then
  261.                begin
  262.                    if chars [position] = '!' then
  263.                        begin
  264.                            position := position + 1;
  265.                            number := maxint;
  266.                            legalnumber := true
  267.                        end
  268.                     else
  269.                        begin
  270.                            sign := 1;
  271.                            if chars [position] = '-' then
  272.                                begin
  273.                                    sign := -1;
  274.                                    position := position + 1
  275.                                end
  276.                            else
  277.                                if chars [position] = '+' then
  278.                                    begin
  279.                                        sign := 1;
  280.                                        position := position + 1
  281.                                    end;
  282.                            while (position <= length) and numeric(chars[position]) do
  283.                                begin
  284.                                    number := 10*number+ord(chars[position])-ord('0');
  285.                                    position := position + 1;
  286.                                    legalnumber := true
  287.                                end;
  288.                            number := sign * number
  289.                        end
  290.                end
  291.        end
  292. end;   { procedure  }
  293.  
  294. procedure processprefix (var commandline : linedef; var currentline : lineptr;
  295.                      sentinel : lineptr; var noerror : boolean); 
  296. var
  297.    bottomoffile, topoffile : lineptr;
  298.    stillprefix,legalnumber : boolean;
  299.  number : integer;
  300. begin
  301.    bottomoffile := sentinel^.previousline;
  302.    topoffile := sentinel^.nextline;
  303.    skipblanks (commandline);
  304.    with commandline do
  305.        begin
  306.            if (position <= length) and (chars[position] <>'=') then
  307.                begin
  308.                    stillprefix := true;
  309.                    while (position <= length) and stillprefix and noerror do
  310.                        begin
  311.                            if chars [position] = '!' then
  312.                                begin
  313.                                    currentline := bottomoffile;
  314.                                    checkempty (sentinel,noerror)
  315.                                end
  316.                            else
  317.                                if (chars[position]='+') or (chars[position]='-') then
  318.                                    begin
  319.                                        getnumber(commandline,number,legalnumber);
  320.                                        if legalnumber then
  321.                                            movelinepointer(currentline,number,sentinel,noerror)
  322.                                    else
  323.                                            errormessage (noerror,'ILLEGAL SYMBOL IN PREFIX');
  324.                                        stillprefix := false
  325.                                    end
  326.                                else
  327.                                    if chars[position]='^' then
  328.                                        begin
  329.                                            checkempty(sentinel,noerror);
  330.                                            currentline := topoffile
  331.                                        end
  332.                                    else
  333.                                    if (chars[position] <> ' ') then stillprefix := false;
  334.                                if stillprefix then position := position + 1
  335.                        end
  336.                end
  337.        end
  338. end;  { procedure }
  339.  
  340. function alphabetic (ch : char) : boolean;  
  341. begin
  342.    alphabetic := (ch >= 'a') and (ch <= 'z')
  343. end;  { function }
  344.  
  345. procedure getcommand(var commandline : linedef; var command : commanddef;
  346.                      var legalcommand, noerror : boolean); 
  347. var
  348.    commandchar : integer;
  349. begin
  350.    command.length := 0;
  351.  skipblanks (commandline);
  352.    legalcommand := true;
  353.    for commandchar := 1  to maxcommandlength do
  354.            command.chars[commandchar] := ' ';
  355.    with commandline do
  356.        begin
  357.        if position > length then
  358.        begin
  359.            legalcommand := true;
  360.            command.chars [1] := 'p';  { assume null, print command }
  361.            command.length := 1
  362.        end
  363.        else
  364.            if not (alphabetic(chars[position]) or  numeric(chars[position])) then
  365.                begin
  366.                    legalcommand := true;
  367.                    command.chars[1] := 'f';   { assume delimiter, find command }
  368.                    command.length := 1
  369.            end
  370.        else if chars[position] = '=' then
  371.                begin  { process equals command  }
  372.                    legalcommand := true;
  373.                    command.chars[1] := '=';
  374.                    command.length := 1;
  375.                    position := position + 1
  376.                end
  377.            else   {  build a normal command, other than default  }
  378.                begin
  379.                    while alphabetic(chars[position]) and (position <= length) and noerror do
  380.                        begin
  381.                            if command.length < maxcommandlength then
  382.                                begin
  383.                                    command.length := command.length + 1;
  384.                                    command.chars[command.length] := chars[position];
  385.                                    position := position + 1;
  386.                                    legalcommand := true
  387.                                end
  388.                            else  { bad input line }
  389.                                errormessage (noerror, 'NO SUCH COMMAND')
  390.                    end  { while  }
  391.                end
  392.        end { with  }
  393. end;   { procedure  }
  394.  
  395. procedure commandordinal (command : commanddef; var ordinal : integer;
  396.                       var tablecommands : commandtable; var noerror : boolean); 
  397. var
  398.    index : integer;
  399. begin
  400.    index := 1;
  401.    if command.length = 1 then
  402.        begin
  403.            tablecommands.shortcommands[numbershortcommands] := command.chars[1];
  404.            while command.chars[1] <> tablecommands.shortcommands[index] do
  405.                    index := index + 1;
  406.            if index = numbershortcommands then
  407.                errormessage (noerror, 'NO SUCH COMMAND')
  408.        end
  409.    else
  410.        begin
  411.            while command.chars <> tablecommands.longcommands[index] do
  412.                index := index + 1;
  413.            if index = numberlongcommands then
  414.                errormessage (noerror, 'NO SUCH COMMAND')
  415.        end;  { if  }
  416.    ordinal := index
  417. end;   {  procedure  }
  418.  
  419. procedure endparse (commandline : linedef; var noerror : boolean); 
  420. begin
  421.    if noerror then
  422.    begin
  423.            skipblanks (commandline);
  424.            if commandline.position <= commandline.length then
  425.                errormessage (noerror, 'INVALID COMMAND PARAMETER')
  426.    end  { if }
  427. end;   { procedure  }
  428.  
  429. procedure getstring (var commandline : linedef; var strng : stringdef;
  430.                      var legalstring : boolean); 
  431. var
  432.    delimiter : char;
  433. begin
  434.    skipblanks (commandline);
  435.    legalstring := false;
  436.    strng.length := 0;
  437.    with commandline do
  438.        if position <= length then begin
  439.        begin
  440.            if (not alphabetic(chars[position])) and (not numeric(chars[position])) and
  441.                 (chars[position] <> '+') and (chars[position] <> '-') and (chars[position] <> '!') then
  442.                begin
  443.                    delimiter := chars[position];
  444.                    legalstring := true;
  445.                    position := position + 1;
  446.                    strng.first := position;
  447.                    while (chars[position] <> delimiter) and (position <= length) do
  448.                        position := position +1 ;
  449.                    strng.last := position -1;
  450.                    strng.length := strng.last - strng.first + 1
  451.                end
  452.        end
  453.    end; {  if position }
  454.    if strng.length = 0 then
  455.        begin
  456.            strng.first := 1;
  457.            strng.last := 0
  458.        end
  459. end;  { procedure  }
  460.  
  461. procedure unpackline(var line : linedef; pline : lineptr);
  462. var
  463.    charnum : 1 .. charspernode;
  464.    node    : linecharptr;
  465.    unpackcount : integer;
  466.  
  467. begin
  468.    with line do
  469.        begin
  470.            length := pline^.length;
  471.            if length <> 0 then
  472.                begin
  473.                    node := pline^.firstnode;
  474.                    unpackcount := 0;
  475.                    repeat
  476.                        for charnum := 1 to min(charspernode,length-unpackcount) do
  477.                            chars[unpackcount+charnum] := node^.chars[charnum];
  478.                        unpackcount := unpackcount + charspernode;
  479.                        node := node^.nextnode
  480.                    until node = nil
  481.                end  { if  }
  482.        end  { with  }
  483. end;  { procedure }
  484.  
  485. procedure stringin(var line : linedef; strng : stringdef;
  486.                    var commandline : linedef; var found : boolean);   
  487. var
  488.    done,stringthere : boolean;  index : integer;
  489. begin
  490.    line.position := 0;
  491.    if strng.length = 0 then stringthere := true
  492.    else
  493.        begin
  494.            with line do
  495.                begin
  496.                    stringthere := false;
  497.                    done := false;
  498.                    chars[length+1] := commandline.chars[strng.first];
  499.                    repeat
  500.                        position := position + 1;
  501.                        if (position+strng.length-1) > length then
  502.                            begin
  503.                                done := true
  504.                            end
  505.                        else
  506.                            begin
  507.                                stringthere := true;
  508.                                index := strng.first;
  509.                                while stringthere and (index <= strng.last) do
  510.                                    begin
  511.                                        if commandline.chars[index] <> line.chars[line.position+index-strng.first] then
  512.                                            stringthere := false
  513.                                        else index := index + 1
  514.                                    end
  515.                            end
  516.                    until done or stringthere
  517.                end  { with  }
  518.        end; { if }
  519.    found := stringthere
  520. end;  { procedure  }
  521.  
  522. procedure locate (strng : stringdef; var pline : lineptr;
  523.               var count :integer; increment : integer; sentinel : lineptr;
  524.                    var commandline : linedef; var noerror : boolean);  
  525. var
  526.    found : boolean;    scratchline : linedef;
  527. begin
  528.    found := false;
  529.    count := increment;
  530.    repeat
  531.        movelinepointer(pline,increment,sentinel,noerror);
  532.        count := count + increment;
  533.        if noerror then
  534.            begin
  535.                unpackline(scratchline,pline);
  536.                stringin(scratchline,strng,commandline,found)
  537.            end
  538.    until found or (not noerror)
  539. end;  { procedure  }
  540.  
  541. procedure getparameter(var commandline : linedef; sentinel : lineptr;
  542.                        var count : integer; var noerror : boolean);  
  543. var
  544.    legalnumber, legalstring : boolean;
  545.    sign : integer;   pline : lineptr;  strng : stringdef;
  546. begin
  547.    with commandline do
  548.        begin
  549.            if position <= length then
  550.                begin
  551.                    if chars[position]='-' then
  552.                        begin
  553.                            sign := -1;
  554.                        position := position + 1
  555.                        end
  556.                    else sign := 1;
  557.                    getstring(commandline,strng,legalstring);
  558.                    if legalstring then
  559.                        begin
  560.                            position := position + 1;
  561.                            pline := currentline;
  562.                            locate(strng,pline,count,sign,sentinel,commandline,noerror)
  563.                        end
  564.                    else
  565.                        begin
  566.                            getnumber(commandline,count,legalnumber);
  567.                            if legalnumber then count := count*sign else count := sign
  568.                        end
  569.                end
  570.            else count := 1
  571.    end
  572. end;  { procedure }
  573.  
  574. procedure printline(line : linedef);
  575. var charnum : linelengthdef;
  576. begin
  577.    for charnum := 1 to line.length do write (line.chars[charnum]);
  578.  writeln
  579. end;
  580.  
  581. procedure printpackedline (pline : lineptr); 
  582. var
  583.    index : linelengthdef;    scratchline : linedef;
  584. begin
  585.    unpackline(scratchline,pline);
  586.  printline (scratchline)
  587. end;
  588.  
  589. procedure freetext (pline : lineptr);  
  590. var
  591.    node, nodegone : linecharptr;
  592. begin
  593.    node := pline^.firstnode;
  594.    pline^.length := 0;
  595.    pline^.firstnode := nil;
  596.    while node <> nil do
  597.        begin
  598.            nodegone := node;
  599.            node := nodegone^.nextnode;
  600.            dispose (nodegone)
  601.        end  { while }
  602. end;  { proc  }
  603.  
  604. procedure deleteline (pline : lineptr);
  605. begin
  606.    pline^.previousline^.nextline := pline^.nextline;
  607.    pline^.nextline^.previousline := pline^.previousline;
  608.    freetext (pline);
  609.    dispose (pline)
  610. end;  { delete  }
  611.