if (stream(InFile,'C','OPEN READ') >< 'READY:') then /* if we cannot open the file for reading */
do
call stream InFile,'C','CLOSE' /* close the file */
say 'Cannot open '||InFile /* report */
return /* and return */
end
CommStart = d2c(47)||d2c(42) /* these characters (slash plus asterisk) indicating the start of a REXX comment */
CommEnd = d2c(42)||d2c(47) /* these characters (asterisk plus slash) indicating the end of a REXX comment */
Buffer.1 = linein(InFile) /* read the first line of the file into Buffer.1 */
if (substr(Buffer.1,1,2) >< CommStart) then /* if it is not a REXX comment, this is not a REXX program file */
do
call stream InFile,'C','CLOSE' /* close the file */
say InFile||' is not a REXX program file' /* report */
return /* and return */
end
say InFile /* put out the name of the file we're processing */
if (Option >< '') then /* if we have an option */
do
Option = translate(substr(Option,1,1)) /* get the first letter of option and make it uppercase */
end
NonComm. = '' /* start with no uncommented lines */
NonCommNumber = 0 /* the number of uncommented lines; start at 0 */
LineCount = 1 /* we've already collected the first line, remember? */
MaxLength = 0 /* this will eventually contain the longest program line length (without the comment); start at 0 */
do while (lines(InFile)) /* as long as we have lines left in the file */
LineCount = LineCount + 1 /* up the line counter */
Buffer.LineCount = linein(InFile) /* read the next line into Buffer */
end
Buffer.0 = LineCount /* store the total line count in Buffer.0 */
call stream InFile,'C','CLOSE' /* close the file */
CommBlock = 0 /* we're not in a multi-line comment block yet */
do LineCount = 1 to Buffer.0 /* run through the number of lines we collected in Buffer */
InTable = d2c(9) /* we will be looking for TAB characters */
OutTable = ' ' /* and converting them into spaces */
Buffer.LineCount = strip(translate(Buffer.LineCount,OutTable,InTable),'T',' ') /* do the conversion and get rid of trailing blanks */
if (\CommBlock) then /* if the line is not part of a multi-line comment block */
do
CommentPos = pos(CommStart,Buffer.LineCount) /* look for the start of a REXX comment */
if (CommentPos > 0) then /* if we found a REXX comment */
do
if (CommentPos > 1) then /* if we found a trailing REXX comment (i.e. not one starting with the first character in the line) */
do
ProgLine.LineCount = strip(substr(Buffer.LineCount,1,CommentPos-1),'T',' ') /* put the program line part into ProgLine, removing any trailing blanks */
Comment.LineCount = strip(substr(Buffer.LineCount,CommentPos),'B',' ') /* put the REXX comment part into Comment, removing both leading and trailing spaces */
end
else /* if we found a comment at the start of the line */
do
ProgLine.LineCount = '' /* there is no program line part */
Comment.LineCount = strip(substr(Buffer.LineCount,CommentPos),'T',' ') /* put the REXX comment part into Comment, removing trailing spaces */
end
CommBlock = (pos(CommEnd,Buffer.LineCount) = 0) /* if no comment end is found, this is the start of a multi-line comment block */
end
else /* if no REXX comment start was found in this line */
do
ProgLine.LineCount = Buffer.LineCount /* store the entire contents of the Buffer bit in ProgLine */
Comment.LineCount = '' /* there is no comment part for this one */
BufLine = strip(Buffer.LineCount,'B',' ') /* copy the contents of Buffer.LineCount into BufLine, removing leading and trailing blanks */
if (BufLine >< '') then /* if the line is not empty */
do
if (wordpos(BufLine,'do end') = 0) then /* if the line contains not just "do" or "end" */
do
NonCommNumber = NonCommNumber + 1 /* up NonCommNumber to show we've got another line that needs a comment */
NonComm.NonCommNumber = LineCount /* store the line number for later use */
end
end
end
end
else /* if the line is part of a multi-line comment block */
do
if (CommentPos > 1) then /* if this is a trailing comment block */
do
ProgLine.LineCount = ' ' /* we need a program line part */
end
else /* if this is not a trailing comment block */
do
ProgLine.LineCount = '' /* there is no program line part */
end
Comment.LineCount = ' '||strip(Buffer.LineCount,'B',' ') /* put the line into Comment, removing both leading and trailing spaces, and add leading whitespace */
CommBlock = (pos(CommEnd,Buffer.LineCount) = 0) /* if a comment end is found, this is the end of the multi-line comment block */
end
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) */
do
LineLength.LineCount = length(ProgLine.LineCount) /* store the length of the program line bit in LineLength */
if (LineLength.LineCount > MaxLength) then /* if the program part of the line is longer than the previous longest one */
do
MaxLength = LineLength.LineCount /* adjust MaxLength to reflect the current longest line */
end
end
end
do LineCount = 1 to Buffer.0 /* take each of the lines stored in Buffer */
if (Comment.LineCount >< '') then /* if there is a comment associated with it */
do
if (Option >< 'S') then /* if the option was not "S(trip)" */
do
if (ProgLine.LineCount >< '') then /* if there is a program line bit */
do
if ((Option = '') | (Option = 'A')) then /* if there is no option, or if the option was "A(lign)" */
do
ProgLine.LineCount = left(ProgLine.LineCount,MaxLength,' ') /* pad the program line bit with trailing spaces to equal the longest program line in length */
end
ProgLine.LineCount = ProgLine.LineCount||' '||Comment.LineCount /* stick two spaces on the end of the program line, followed by the comment line bit */
end
else /* if there is no program line bit */
do
ProgLine.LineCount = Comment.LineCount /* use just the comment line bit */
end
end
else /* if we're stripping */
do
ProgLine.1 = CommStart||' '||filespec('N',InFile)||' '||CommEnd /* add a comment line at the top of the file */
end
end
end
Location = filespec('D',InFile)||filespec('P',InFile) /* the current directory */
TempFile = systempfilename(Location||'RC_?????.TMP') /* get a unique filename to act as safety storage while we delete and rewrite the source file */
if (stream(TempFile,'C','OPEN WRITE') >< 'READY:') then /* if we cannot open the output file */
do
say 'Cannot open target file for writing' /* report */
return /* and return */
end
do LineCount = 1 to Buffer.0 /* get each of the lines in Buffer */
if (\((ProgLine.LineCount = '') & (Option = 'S'))) then /* unless the line contains no text and the Strip option has been set */
do
call lineout TempFile,ProgLine.LineCount /* write it to the output file */
end
end
call stream TempFile,'C','CLOSE' /* close the output file */
if (sysqueryealist(InFile,'EAList.') >< 0) then /* if we cannot retrieve the EA list of the source file */
do
say 'Cannot retrieve source file EA name list' /* report */
return /* and return */
end
GetIt = 0 /* start at 0 */
do EANo = 1 to EAList.0 /* for each of the EA names in the list */
GetIt = GetIt + sysgetea(InFile,EAList.EANo,HoldEA.EANo) /* get it from the source file */
end
if (GetIt > 0) then /* if the total result exceeds 0 */
do
say 'Error getting EAs from '||InFile /* report */
return /* and go back */
end
PutIt = 0 /* start at 0 */
do EANo = 1 to EAList.0 /* take each of the EA entries */
PutIt = PutIt + sysputea(TempFile,EAList.EANo,HoldEA.EANo) /* and attach it to the temp file */
end
if (PutIt > 0) then /* if the total result exceeds 0 */
do
say 'Error writing EAs to '||TempFile /* report */
return /* and go back */
end
Title = filespec('N',InFile) /* the name to use for the new file */
if (Option = 'S') then /* if the comments were stripped */
do
if (\syssetobjectdata(InFile,'Title='||Title||'.ORG')) then /* if we cannot rename the file */
do
say 'Cannot rename original file; results stored in : '||TempFile /* report */
return /* and return with an error */
end
say 'Original file stored as : '||InFile||'.ORG' /* report */
end
else /* if the comments were not stripped */
do
if (\sysdestroyobject(InFile)) then /* if we cannot get rid of the original file */
do
say 'Cannot delete source file' /* report */
return /* and return */
end
end
if (\syssetobjectdata(TempFile,'Title='||Title)) then /* if we cannot rename the target file */
do
say 'Cannot rename target file; results stored in : '||TempFile /* report */
return /* and return with an error */
end
if (NonCommNumber = 0) then /* if there are no uncommented program lines */
do
say ' O.K.' /* report */
end
else /* if uncommented lines were found */
do
say ' Uncommented lines:' /* report */
do Number = 1 to NonCommNumber /* take each of the entries */
say ' '||right(NonComm.Number,length(NonComm.NonCommNumber),' ') /* the NCLine number, padded to match the largest number , and preceded by two spaces */