home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rexxcomm.zip / RexxComm.CMD
OS/2 REXX Batch file  |  1999-07-21  |  20KB  |  300 lines

  1. /* RexxComm - Formats comments in REXX files
  2.    (converting TAB characters into spaces)
  3.    and reports the number of uncommented program lines.
  4.  
  5.    Use it if you like it. Don't if you don't. No legalese.
  6.  
  7.    (c) 1999 Marcus de Geus
  8.             marcus@degeus.com
  9.             http://www.degeus.com
  10.  
  11.    *****************************************************************/
  12.  
  13. signal on halt                                                                      /* handles halt condition */
  14.  
  15. parse arg Filespec Option                                                           /* get the file spec */
  16.  
  17. if (Filespec = '') then                                                             /* if we have no file spec */
  18. do
  19.  parse source . . ProgSpec                                                          /* get ProgSpec */
  20.  ProgName = filespec('N',ProgSpec)                                                  /* get the program name */
  21.  say ProgName||'  : Usage = '||ProgName||' Filespec [A(lign)|U(nalign)|S(trip)]'    /* put out a message */
  22.  say '  Align   : trailing comments are vertically aligned (default)'               /* another message line */
  23.  say '  Unalign : trailing comments follow code'                                    /* another message line */
  24.  say '  Strip   : Trailing comments are stripped; original file in {filename}.ORG'  /* another message line */
  25.  call Halt                                                                          /* and quit */
  26. end
  27.  
  28. if (\LoadREXXUtils()) then                                                          /* if we cannot load the REXX utilities */
  29. do
  30.  call Halt                                                                          /* quit */
  31. end
  32.  
  33. Filespec = strip(Filespec,'B','"')                                                  /* get rid of any quotes */
  34. Filespec = strip(Filespec,'B',' ')                                                  /* get rid of any spaces */
  35.  
  36. call sysfiletree Filespec,'Files.','FO'                                             /* look for the file spec*/
  37. if (Files.0 = 0) then                                                               /* if no files were found */
  38. do
  39.  say 'No files found.'                                                              /* report */
  40.  exit                                                                               /* and quit */
  41. end
  42.  
  43. do Index = 1 to Files.0                                                             /* take each file */
  44.  call Process Files.Index,Option                                                    /* and process it */
  45. end
  46.  
  47. call Halt                                                                           /* That's all, folks! */
  48.  
  49.  
  50. /*****************************************************************/
  51.  
  52. Process: procedure                                                                  /* processes a file */
  53.  
  54. parse arg InFile,Option                                                             /* get the arguments */
  55.  
  56. if (stream(InFile,'C','OPEN READ') >< 'READY:') then                                /* if we cannot open the file for reading */
  57. do
  58.  call stream InFile,'C','CLOSE'                                                     /* close the file */
  59.  say 'Cannot open '||InFile                                                         /* report */
  60.  return                                                                             /* and return */
  61. end
  62.  
  63. CommStart = d2c(47)||d2c(42)                                                        /* these characters (slash plus asterisk) indicating the start of a REXX comment */
  64. CommEnd = d2c(42)||d2c(47)                                                          /* these characters (asterisk plus slash) indicating the end of a REXX comment */
  65.  
  66. Buffer.1 = linein(InFile)                                                           /* read the first line of the file into Buffer.1 */
  67. if (substr(Buffer.1,1,2) >< CommStart) then                                         /* if it is not a REXX comment, this is not a REXX program file */
  68. do
  69.  call stream InFile,'C','CLOSE'                                                     /* close the file */
  70.  say InFile||' is not a REXX program file'                                          /* report */
  71.  return                                                                             /* and return */
  72. end
  73.  
  74. say InFile                                                                          /* put out the name of the file we're processing */
  75.  
  76. if (Option >< '') then                                                              /* if we have an option */
  77. do
  78.  Option = translate(substr(Option,1,1))                                             /* get the first letter of option and make it uppercase */
  79. end
  80.  
  81. NonComm. = ''                                                                       /* start with no uncommented lines */
  82. NonCommNumber = 0                                                                   /* the number of uncommented lines; start at 0 */
  83. LineCount = 1                                                                       /* we've already collected the first line, remember? */
  84. MaxLength = 0                                                                       /* this will eventually contain the longest program line length (without the comment); start at 0 */
  85.  
  86. do while (lines(InFile))                                                            /* as long as we have lines left in the file */
  87.  LineCount = LineCount + 1                                                          /* up the line counter */
  88.  Buffer.LineCount = linein(InFile)                                                  /* read the next line into Buffer */
  89. end
  90.  
  91. Buffer.0 = LineCount                                                                /* store the total line count in Buffer.0 */
  92. call stream InFile,'C','CLOSE'                                                      /* close the file */
  93.  
  94. CommBlock = 0                                                                       /* we're not in a multi-line comment block yet */
  95.  
  96. do LineCount = 1 to Buffer.0                                                        /* run through the number of lines we collected in Buffer */
  97.  
  98.  InTable = d2c(9)                                                                   /* we will be looking for TAB characters */
  99.  OutTable = ' '                                                                     /* and converting them into spaces */
  100.  Buffer.LineCount = strip(translate(Buffer.LineCount,OutTable,InTable),'T',' ')     /* do the conversion and get rid of trailing blanks */
  101.  
  102.  if (\CommBlock) then                                                               /* if the line is not part of a multi-line comment block */
  103.  do
  104.   CommentPos = pos(CommStart,Buffer.LineCount)                                      /* look for the start of a REXX comment */
  105.   if (CommentPos > 0) then                                                          /* if we found a REXX comment */
  106.   do
  107.    if (CommentPos > 1) then                                                         /* if we found a trailing REXX comment (i.e. not one starting with the first character in the line) */
  108.    do
  109.     ProgLine.LineCount = strip(substr(Buffer.LineCount,1,CommentPos-1),'T',' ')     /* put the program line part into ProgLine, removing any trailing blanks */
  110.     Comment.LineCount = strip(substr(Buffer.LineCount,CommentPos),'B',' ')          /* put the REXX comment part into Comment, removing both leading and trailing spaces */
  111.    end
  112.    else                                                                             /* if we found a comment at the start of the line */
  113.    do
  114.     ProgLine.LineCount = ''                                                         /* there is no program line part */
  115.     Comment.LineCount = strip(substr(Buffer.LineCount,CommentPos),'T',' ')          /* put the REXX comment part into Comment, removing trailing spaces */
  116.    end
  117.    CommBlock = (pos(CommEnd,Buffer.LineCount) = 0)                                  /* if no comment end is found, this is the start of a multi-line comment block */
  118.   end
  119.   else                                                                              /* if no REXX comment start was found in this line */
  120.   do
  121.    ProgLine.LineCount = Buffer.LineCount                                            /* store the entire contents of the Buffer bit in ProgLine */
  122.    Comment.LineCount = ''                                                           /* there is no comment part for this one */
  123.    BufLine = strip(Buffer.LineCount,'B',' ')                                        /* copy the contents of Buffer.LineCount into BufLine, removing leading and trailing blanks */
  124.    if (BufLine >< '') then                                                          /* if the line is not empty */
  125.    do
  126.     if (wordpos(BufLine,'do end') = 0) then                                         /* if the line contains not just "do" or "end" */
  127.     do
  128.      NonCommNumber = NonCommNumber + 1                                              /* up NonCommNumber to show we've got another line that needs a comment */
  129.      NonComm.NonCommNumber = LineCount                                              /* store the line number for later use */
  130.     end
  131.    end
  132.   end
  133.  end
  134.  else                                                                               /* if the line is part of a multi-line comment block */
  135.  do
  136.   if (CommentPos > 1) then                                                          /* if this is a trailing comment block */
  137.   do
  138.    ProgLine.LineCount = ' '                                                         /* we need a program line part */
  139.   end
  140.   else                                                                              /* if this is not a trailing comment block */
  141.   do
  142.    ProgLine.LineCount = ''                                                          /* there is no program line part */
  143.   end
  144.   Comment.LineCount = '   '||strip(Buffer.LineCount,'B',' ')                        /* put the line into Comment, removing both leading and trailing spaces, and add leading whitespace */
  145.   CommBlock = (pos(CommEnd,Buffer.LineCount) = 0)                                   /* if a comment end is found, this is the end of the multi-line comment block */
  146.  end
  147.  
  148.  if (CommentPos >< 1) then                                                          /* if there is no comment, or if it is a trailing comment (i.e. not starting at the first position of the line) */
  149.  do
  150.   LineLength.LineCount = length(ProgLine.LineCount)                                 /* store the length of the program line bit in LineLength */
  151.   if (LineLength.LineCount > MaxLength) then                                        /* if the program part of the line is longer than the previous longest one */
  152.   do
  153.    MaxLength = LineLength.LineCount                                                 /* adjust MaxLength to reflect the current longest line */
  154.   end
  155.  end
  156.  
  157. end
  158.  
  159. do LineCount = 1 to Buffer.0                                                        /* take each of the lines stored in Buffer */
  160.  if (Comment.LineCount >< '') then                                                  /* if there is a comment associated with it */
  161.  do
  162.   if (Option >< 'S') then                                                           /* if the option was not "S(trip)" */
  163.   do
  164.    if (ProgLine.LineCount >< '') then                                               /* if there is a program line bit */
  165.    do
  166.     if ((Option = '') | (Option = 'A')) then                                        /* if there is no option, or if the option was "A(lign)" */
  167.     do
  168.      ProgLine.LineCount = left(ProgLine.LineCount,MaxLength,' ')                    /* pad the program line bit with trailing spaces to equal the longest program line in length */
  169.     end
  170.     ProgLine.LineCount = ProgLine.LineCount||'  '||Comment.LineCount                /* stick two spaces on the end of the program line, followed by the comment line bit */
  171.    end
  172.    else                                                                             /* if there is no program line bit */
  173.    do
  174.     ProgLine.LineCount = Comment.LineCount                                          /* use just the comment line bit */
  175.    end
  176.   end
  177.   else                                                                              /* if we're stripping */
  178.   do
  179.    ProgLine.1 = CommStart||' '||filespec('N',InFile)||' '||CommEnd                  /* add a comment line at the top of the file */
  180.   end
  181.  end
  182. end
  183.  
  184. Location = filespec('D',InFile)||filespec('P',InFile)                               /* the current directory */
  185. TempFile = systempfilename(Location||'RC_?????.TMP')                                /* get a unique filename to act as safety storage while we delete and rewrite the source file */
  186.  
  187. if (stream(TempFile,'C','OPEN WRITE') >< 'READY:') then                             /* if we cannot open the output file */
  188. do
  189.  say 'Cannot open target file for writing'                                          /* report */
  190.  return                                                                             /* and return */
  191. end
  192.  
  193. do LineCount = 1 to Buffer.0                                                        /* get each of the lines in Buffer */
  194.  if (\((ProgLine.LineCount = '') & (Option = 'S'))) then                            /* unless the line contains no text and the Strip option has been set */
  195.  do
  196.   call lineout TempFile,ProgLine.LineCount                                          /* write it to the output file */
  197.  end
  198. end
  199.  
  200. call stream TempFile,'C','CLOSE'                                                    /* close the output file */
  201.  
  202. if (sysqueryealist(InFile,'EAList.') >< 0) then                                     /* if we cannot retrieve the EA list of the source file */
  203. do
  204.  say 'Cannot retrieve source file EA name list'                                     /* report */
  205.  return                                                                             /* and return */
  206. end
  207.  
  208. GetIt = 0                                                                           /* start at 0 */
  209. do EANo = 1 to EAList.0                                                             /* for each of the EA names in the list */
  210.  GetIt = GetIt + sysgetea(InFile,EAList.EANo,HoldEA.EANo)                           /* get it from the source file */
  211. end
  212. if (GetIt > 0) then                                                                 /* if the total result exceeds 0 */
  213. do
  214.  say 'Error getting EAs from '||InFile                                              /* report */
  215.  return                                                                             /* and go back */
  216. end
  217.  
  218. PutIt = 0                                                                           /* start at 0 */
  219. do EANo = 1 to EAList.0                                                             /* take each of the EA entries */
  220.  PutIt = PutIt + sysputea(TempFile,EAList.EANo,HoldEA.EANo)                         /* and attach it to the temp file */
  221. end
  222. if (PutIt > 0) then                                                                 /* if the total result exceeds 0 */
  223. do
  224.  say 'Error writing EAs to '||TempFile                                              /* report */
  225.  return                                                                             /* and go back */
  226. end
  227.  
  228. Title = filespec('N',InFile)                                                        /* the name to use for the new file */
  229.  
  230. if (Option = 'S') then                                                              /* if the comments were stripped */
  231. do
  232.  if (\syssetobjectdata(InFile,'Title='||Title||'.ORG')) then                        /* if we cannot rename the file */
  233.  do
  234.   say 'Cannot rename original file; results stored in : '||TempFile                 /* report */
  235.   return                                                                            /* and return with an error */
  236.  end
  237.  say 'Original file stored as : '||InFile||'.ORG'                                   /* report */
  238. end
  239. else                                                                                /* if the comments were not stripped */
  240. do
  241.  if (\sysdestroyobject(InFile)) then                                                /* if we cannot get rid of the original file */
  242.  do
  243.   say 'Cannot delete source file'                                                   /* report */
  244.   return                                                                            /* and return */
  245.  end
  246. end
  247.  
  248. if (\syssetobjectdata(TempFile,'Title='||Title)) then                               /* if we cannot rename the target file */
  249. do
  250.  say 'Cannot rename target file; results stored in : '||TempFile                    /* report */
  251.  return                                                                             /* and return with an error */
  252. end
  253.  
  254. if (NonCommNumber = 0) then                                                         /* if there are no uncommented program lines */
  255. do
  256.  say ' O.K.'                                                                        /* report */
  257. end
  258. else                                                                                /* if uncommented lines were found */
  259. do
  260.  say ' Uncommented lines:'                                                          /* report */
  261.  do Number = 1 to NonCommNumber                                                     /* take each of the entries */
  262.   say '  '||right(NonComm.Number,length(NonComm.NonCommNumber),' ')                 /* the NCLine number, padded to match the largest number , and preceded by two spaces */
  263.  end
  264. end
  265.  
  266. return                                                                              /* end of Process */
  267.  
  268.  
  269. /***************************************************************/
  270.  
  271. LoadREXXUtils: procedure                                                            /* loads the REXX utilities library */
  272.  
  273. Result = 1                                                                          /* start with a good result */
  274.  
  275. if rxfuncquery('SysLoadFuncs') then                                                 /* if it is not already loaded */
  276. do
  277.  if (rxfuncadd('SysLoadFuncs','RexxUtil','SysLoadFuncs') >< 0) then                 /* if we cannot add it */
  278.  do
  279.   call beep 333,333                                                                 /* signal */
  280.   say 'Error : Cannot register Rexx Utilities library'                              /* report */
  281.   Result = 0                                                                        /* bad result */
  282.  end
  283.  else                                                                               /* if we can add it */
  284.  do
  285.   if (SysLoadFuncs() = 0) then                                                      /* if we cannot load it */
  286.   do
  287.    say 'Error : Cannot load Rexx Utilities library'                                 /* report */
  288.    Result = 0                                                                       /* bad result */
  289.   end
  290.  end
  291. end
  292.  
  293. return Result                                                                       /* end of LoadREXXUtils */
  294.  
  295. /*****************************************************************/
  296.  
  297. Halt:                                                                               /* handles halt condition */
  298.  
  299. exit                                                                                /* just quit */
  300.