home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / PASCAL / CONV_P18.ZIP / TOKSTR18.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-11-21  |  10.5 KB  |  308 lines

  1. Program Sort_Tok;
  2. { Reads in reserved word strings from one (or more) text files,
  3.   breaks strings down into single words,
  4.   builds all these words into a dynamic linked list of token records.
  5.   Then concatenates these reserved word tokens into 255-char strings
  6.   (or as near to 255 as we can come) (suitable for incorporation
  7.   as typed constant arrays into a Pascal program),
  8.   outputs to CONV_P.DAT.
  9.  
  10.   v1.8, 21 Nov 89
  11.   - Got a suggestion from Dennis Essa (mrmarx!dennis@uunet.UU.NET)
  12.   "- Allow multiple 'token.inc' input files (even if it needed a global
  13.      token count on the command line.  This would allow for easy segregation
  14.      and upgrade of specific library and project token files."
  15.     Yeah, we can do that.  UPCONV will have a new command line switch:
  16.       /Ifilename.typ
  17.       where the "/I" means include a token string file (followed by the
  18.       name .. NO SPACE SEPARATOR!).
  19.       Multiple include files are permitted.
  20.     For THIS utility program, new command line requirement:
  21.       The name(s) of the target TEXT file with reserved words.
  22.       These files should be reserved words, separated by space(s) or tab(s),
  23.       with CR/LF End-Of-Lines (EOL).
  24.     Order of reserved words is not important for this program or UPCONV.
  25.     We aren't doing sorting or alphabetizing for now.
  26.  
  27.     We're gonna use some functions from STRINGS.TPU (in the TPSTRING
  28.     package) by
  29.          Richard Winkel
  30.          Route 1, box 193
  31.          Harrisburg, MO.   65256
  32.  
  33. function words(S : String) : byte;
  34.      Returns the number of (blank delimited) words in the string S.
  35.      Ex: words('two four six      eight') returns 4.
  36.  
  37. function Werd(S : String; n : Byte) : String;
  38.      Returns the N'th (blank delimited) word from the string S.
  39.      The strange spelling is to avoid conflict with Tpas's WORD type.
  40.      Ex: werd('two     air is humin',3) returns 'is'
  41.          werd('two     air is humin',5) returns ''
  42.  
  43. function Uppercase(S : String) : String;
  44.      Folds the argument S to uppercase.
  45.      Ex: Uppercase('abcdef123') returns 'ABCDEF123'
  46.  
  47. function firstpos(FindStr, InStr : String; start : Byte) : Byte;
  48.      This function was included for completeness.  It works exactly
  49.      the same way as Turbo's built in POS function, except for the
  50.      presence of the START option.  It is equivalent to:
  51.      start-1+pos(findstr,copy(instr,start,length(instr)-start+1));
  52.      except for being more efficient.
  53.      Ex: firstpos('he','he was the best',15) returns 0.
  54.          firstpos('he','he was the best',6) returns 9.
  55.          firstpos('he','he was the best',0) returns 1.
  56.          firstpos('he','he was the best',1) returns 1.
  57.  
  58.   v1.7
  59.   - Stupid bug in concatenating a long string of tokens.
  60.     Fixed.
  61.   v1.6
  62.   - Bug: Didn't initialize Tok string before building the string.
  63.   - Adding line counter for final screen display.
  64.   - Bumping length to full 255-char strings (was 80 char max),
  65.     no quotes before/after string.
  66. }
  67.  
  68. Uses Dos,Crt,Strings;
  69.  
  70. TYPE
  71.   TokenStr = STRING[20];
  72.  
  73.   TokenPtr = ^Str_Rec;
  74.   Str_Rec = RECORD
  75.               S : TokenStr;
  76.               next : Pointer;
  77.             END;
  78.  
  79. VAR
  80.   curr,                           {working token record ptr}
  81.   Tokens: TokenPtr;               {pointer to first dynamic
  82.                                    reserved word record}
  83.  
  84. { Multiple cmdline parm/wildcard stuff }
  85. CONST
  86.   MAXARGS = 10;                         {change as you like}
  87.  
  88. TYPE
  89.   PathStrPtr = ^PathStr;
  90.  
  91. VAR
  92.   argv, argc : Byte;
  93.   Args : ARRAY[1..MAXARGS]              {array of cmdline parm ptrs}
  94.            OF PathStrPtr;               {STRING[79]}
  95.  
  96.   Dir : DirStr;                         {STRING[79]}
  97.   Name: NameStr;                        {STRING[8]}
  98.   Ext : ExtStr;                         {STRING[4]}
  99.  
  100. {SearchRec is declared in the Dos unit:}
  101. (*
  102.  TYPE SearchRec = RECORD
  103.                     fill : ARRAY[1..21] OF Byte;
  104.                     attr : Byte;
  105.                     time : LongInt;
  106.                     size : LongInt;
  107.                     Name : STRING[12];
  108.                   END;
  109. *)
  110.     SrchRec : SearchRec;
  111.  
  112. VAR
  113.   TokenFile,           {input file of reserved words}
  114.   DataFile : TEXT;     {our output file}
  115.   Tok       : String;  {working 255-char output string}
  116.  
  117.  
  118. PROCEDURE Usage;
  119.   {Give user help, terminate.
  120.    Happens on cmd line of '?', '-?', '/?', '-h', '/h', or empty.
  121.   }
  122.   BEGIN
  123.     WRITELN(
  124. 'TOKSTR v1.8 - Convert file(s) of Pascal reserved words');
  125.     WRITELN('to a single data file (CONV_P.DAT).');
  126.     WRITELN(
  127. 'Usage:  TOKSTR file1.typ] [file2.typ ...] ');
  128.     WRITELN('where file1.typ, file2.typ, etc. are target input filenames.');
  129.     WRITELN(
  130. 'Formatted output will be CONV_P.DAT.');
  131.     WRITELN('Wildcards may be used for target input filenames.');
  132.     HALT(1);
  133.   END;  {of Usage}
  134.  
  135.  
  136. PROCEDURE Get_Args;
  137.   {Process command line for all target reserved word filenames.
  138.    Move them into a dynamic array of PathStrs (Args).
  139.   }
  140.   CONST
  141.     HelpArgs : STRING[13] =
  142.       ' -? -H /? /H ';
  143.   VAR
  144.     Ch : CHAR;
  145.   BEGIN
  146.     argc := ParamCount;
  147.     IF (argc = 0)                       {no parms at all}
  148.     OR (argc > MAXARGS)                 {or more than we can handle}
  149.     THEN Usage;                         {display help, die}
  150.  
  151.     FOR argv := 1 TO argc DO BEGIN
  152.       NEW(Args[argv]);
  153.       Args[argv]^ := Uppercase(ParamStr(argv)); {snarf parm, (uppercased)}
  154.     END;
  155.  
  156.     IF firstpos(' ' + Args[1]^ + ' ', HelpArgs, 1) <> 0   {-? -H, etc.}
  157.     THEN Usage;                         {display help, die}
  158.  
  159.     argv := 0;                          {assume we start at 1}
  160.  
  161.   END;  {of Get_Args}
  162.  
  163.  
  164. FUNCTION Open_File : BOOLEAN;
  165.   {Works FindNext if appropriate, else uses a new Arg string.
  166.    Returns TRUE or FALSE  per success/failure.
  167.   }
  168.   VAR
  169.     FName : PathStr;
  170.     Ok : BOOLEAN;
  171.   BEGIN
  172.     Open_File := FALSE;                {assume failure}
  173.  
  174.     IF SrchRec.Name = '' THEN BEGIN     {time for a new name}
  175.  
  176.       Inc(argv);                        {bump for first/next name}
  177.       IF Args[argv] = NIL THEN Exit;    {all done, return FALSE}
  178.  
  179.       FSplit(Args[argv]^, Dir, Name, Ext);  {split up the new name}
  180.       FName := Dir + Name + Ext;            {build new name}
  181.       FindFirst(FName,ReadOnly OR Archive,SrchRec)  {first time thru}
  182.     END
  183.     ELSE FindNext(SrchRec);             {working a wildcard}
  184.  
  185.     Ok := (DosError = 0);               {from FindFirst or FindNext}
  186.     IF NOT Ok THEN BEGIN                {not found}
  187.       SrchRec.Name := '';               {Flag we need a new arg
  188.                                          and FindFirst}
  189.       Exit;                             {return FALSE}
  190.     END;
  191.  
  192.     FName := Dir + SrchRec.Name;        {new name from FindFirst/FindNext}
  193.     Args[argv]^ := FName;               {Update Args for outside display}
  194.  
  195. Writeln('Opening ', FName);
  196.  
  197.     Assign(TokenFile, FName);
  198.     RESET(TokenFile);                   {open input file}
  199.  
  200.     Open_File := TRUE;                  {return TRUE}
  201.   END;  {of Open_File}
  202.  
  203.  
  204. PROCEDURE Add_To_Tokens;
  205.   {Read in our file of reserved word strings.
  206.    Add to our linked list of string records:
  207.    We just do this for each target token file.
  208.   }
  209.   VAR
  210.     p : TokenPtr;                       {working string record pointer}
  211.     FileS : STRING;                     {working string}
  212.     w,
  213.     wordcnt : BYTE;                     {nr of words in working string}
  214.  
  215.   BEGIN
  216.     WHILE NOT EOF(TokenFile) DO BEGIN   {read in all the strings}
  217.       READLN(TokenFile,FileS);
  218.       IF (FileS <> '')                  {skip blank lines}
  219.       AND (FileS[1] <> ';')             {and not a comment line}
  220.       THEN BEGIN
  221.         wordcnt := words(FileS);          {nr of words in string}
  222.         IF wordcnt <> 0                   {we got some}
  223.         THEN FOR w := 1 TO wordcnt DO BEGIN
  224.           curr^.S := Werd(FileS,w);       {bring in the string's w'th word}
  225.           NEW(p);                         {allocate new token record}
  226.           curr^.next := p;                {point current record to next one}
  227.           curr := p;                      {bump to next token record}
  228.         END;
  229.       END;
  230.     END;
  231.  
  232.     {$I-} CLOSE(TokenFile);  {$I+}      {close up}
  233.     IF IOResult <> 0 THEN ;             {we don't care}
  234.  
  235.   END;  {of Add_To_Tokens}
  236.  
  237.  
  238. PROCEDURE Build_Token_Array;
  239.   {Find all target token files.
  240.    Read in each one, adding its reserved word tokens
  241.    to our dynamic token array.
  242.   }
  243.   BEGIN
  244.     NEW(Tokens);                      {allocate first reserved string
  245.                                          record}
  246.     Tokens^.S := '';                  {build first string ptr}
  247.     Tokens^.next := NIL;              {no next}
  248.  
  249.     curr := Tokens;                   {point to first string ptr}
  250.  
  251. {Now we go into our file loop.
  252.  We continue until FindNext returns no more files.
  253.  Get_Args set argv appropriately.
  254. }
  255.  
  256.     SrchRec.Name := '';                 {clear for first file}
  257.  
  258.     WHILE (SrchRec.Name <> '')          {we're working a wildcard}
  259.     OR (argv < argc)                    {no wildcard, but still got args}
  260.     DO BEGIN
  261.  
  262.       IF Open_File                      {open Token InFile}
  263.       THEN Add_To_Tokens;               {file open, add to token array}
  264.  
  265.     END;  {until all done}
  266.     curr^.S := '';                      {last string is empty}
  267.     curr^.next := NIL;                  {..and points nowhere}
  268.  
  269.   END;  {of Build_Token_Array}
  270.  
  271.  
  272. BEGIN  {main}
  273.  
  274.   Get_Args;                   {get cmdline target text file names}
  275.   Build_Token_Array;          {read in all token files,
  276.                                building a dynamic array of tokens}
  277.  
  278.   IF curr = Tokens THEN BEGIN         {never read any}
  279.     Writeln('No tokens were found!');
  280.     Writeln('Aborting!');
  281.     Halt(2);
  282.   END;
  283.  
  284.   Assign(DataFile,'CONV_P.DAT');
  285.   Rewrite(DataFile);
  286.  
  287.   Tok := '';                            {v1.6 Initialize Token string}
  288.   curr := Tokens;                       {v1.8 point to first string ptr}
  289.  
  290.   {Remember, the LAST record has the "next" NIL ptr.
  291.    It's actually a blank string.
  292.   }
  293.   WHILE curr^.next <> NIL DO BEGIN
  294.  
  295.     IF LENGTH(Tok) + LENGTH(curr^.S) < 253  {string isn't too long}
  296.     THEN Tok := Tok + ' ' + curr^.S     {so continue to concatenate}
  297.     ELSE BEGIN                          {string is max length}
  298.       Writeln(DataFile,Tok,' ');        {write out the long string}
  299.       Tok := ' ' + curr^.S;             {pick up that last token}
  300.     END;
  301.     curr := curr^.next;                 {point to next token record}
  302.   END;
  303.  
  304.   IF Tok <> ''                          {if any remaining line}
  305.   THEN Writeln(DataFile,Tok, ' ');      {write it out}
  306.   Close(DataFile);
  307. END.
  308.