'===========================================================================
' Subject: RECOMMENT YOUR SOURCE CODES        Date: 07-05-97 (15:34)       
'  Author: Tika Carr                          Code: QB, PDS                
'  Origin: t.carr@pobox.com                 Packet: MISC.ABC
'===========================================================================
'                      ******* ReCom 1.1 *******
'
'ReCom 1.1: Utility to recomment source files
'March 4, 1997, July 1, 1997 by Tika Carr (some code by Joe Negron)
'
'No warranties or guarantees are expressed or implied. Free for your own
'use & modification, just give the author(s) proper credit.
'
'NOTES: This Source will work only in QuickBasic 4.5.
'       Start with QB /L QB.QLB
'
'Recomments C/C++/ASM/BASIC Headers and Source Files, as well as GW-BASIC,
'*.SYS (ie. CONFIG.SYS), BATch and Windows INI files. Example: You want
'to comment each line of a C program so you can load it into QuickBasic and
'work on each line to convert it to QuickBasic. You would do this:
'
'                    recom /qs hello.c
'
'This says to take the file hello.c and recomment each line with a ' and
'have the output file named hello.bas. The original source is supposed to
'be (and usually is) left untouched (unless some unforseen error I refuse
'to be held responsible for happens).
'
'History & Credits:
'
'1.0
'   I lost the original source code to this one and it didn't have any file
'   checking capabilities.
'1.1
'   I rewrote this from memory (not the computer's :) and I think I added
'   some more user error checking and file checking (can't recomment a C
'   file to a C Source file, for example). Thanks goes to Joe Negron who wrote 
'   the Exist code (checks to see if a file exists). 
'
'QUIRKS in the source/operation:
'  /g, /b, /i, /s: if you pass another letter with it (ie. /gh) then the
'  file is processed and the second letter ignored. However, due to some
'  parameter checking, you will get a help screen and no conversion if
'  you pass a /ss (since both the Lang$ and Source$ are the same). Some may
'  prefer to fix this quirk. I didn't think it would be a problem though
'  as you're really only supposed to use the one letter anyway. :)
'
'  If you are converting an ANSI C source to an ANSI C header, no conversion
'  is made. Basically, it just copies the file to another *.H file. I
'  figured for that, you might not even use this utility, just rename or
'  copy the source. It would take more code to parse out comments in the
'  C Source and adjust while commenting the header. Something I'm not up
'  to but if anyone else would like to add it in, feel free to do so.
'
'USAGE: recom /switch infile.ext
'
'infile.ext is the filename and extension of the source code file you want
'to convert. The output file is determined by the use of one of the
'following switches (only one switch can be used):
'
'/qx  QBasic/QuickBasic 4.5
'/cx  ANSI C
'/px  C++
'/ax  Assembly Language
'/g   GWBASIC
'/b   Batch File (.BAT)
'/i   .INI File
'/s   .SYS File
'
'NOTE: x must be either an 's' (for source) or 'h' (for header)
'
'Here's a chart of what can be converted:
'(Note that QB stands for QuickBasic 4.5 or QBasic 1.1)
'
'Destination File      Switch Used
'QB *.BAS              /qs
'QB *.BI               /qh
'ANSI C *.c            /cs
'ANSI C *.h            /ch
'C++ *.CPP             /ps
'C++ Header *.H        /ph
'Assembly *.ASM        /as
'Assebmly *.INC        /ah
'GW-BASIC  *.BAS       /g
'Batch File *.BAT      /b
'Windows *.INI         /i
'CONFIG.SYS (or *.sys) /s
'
'DISCLAIMER:
'ReCom 1.1 is distributed on an "AS IS" basis. The author(s) disclaim all
'warranties, expressed or implied, including but not limited to the
'warranties of merchantability and of fitness for any purpose. The author(s) 
'assume no liability for damages, direct or consequential, which may
'result from use of this program or any accompanying source(s).

DEFINT A-Z

'$INCLUDE: 'qb.bi'

DECLARE FUNCTION Exist% (FileName$)
DECLARE SUB Help ()

DIM arg$(1 TO 85)

'Program ID
PRINT
PRINT "ReCom 1.1: Utility to recomment your source files"
PRINT "March 4, 1997, July 1, 1997 by Tika Carr"
PRINT

'Get Paramters:

IF COMMAND$ <> "" THEN
    I = 1: j = 1
    DO UNTIL I >= LEN(COMMAND$)
        WHILE MID$(COMMAND$, I, 1) <> " " AND MID$(COMMAND$, I, 1) <> ""
            arg$(j) = arg$(j) + MID$(COMMAND$, I, 1)
            I = I + 1
        WEND
        I = I + 1: j = j + 1
    LOOP
END IF

'Check Paramters
IF arg$(1) = "" THEN Help       ' No paramters found
IF INSTR("/-", LEFT$(arg$(1), 1)) = 0 THEN
    Help  'First parameter a switch?
ELSE    'Parse Parameter
    Lang$ = MID$(arg$(1), 2, 1)
    Source$ = RIGHT$(arg$(1), 1)
    IF Lang$ = Source$ AND LEN(arg$(1)) > 2 THEN Help   ' Bad format
    IF INSTR("QCPA", Lang$) = 0 THEN Source$ = "" 'One-letter switch
END IF

'Check Filename
IF Exist(arg$(2)) >= 0 THEN PRINT arg$(2); " not found.": Help

'All tests pass. Figure new filename based on Lang$ and arg$(2)

'Check for a "." and if there, chop off extension
I = INSTR(arg$(2), ".")
IF I THEN
    OutFile$ = LEFT$(arg$(2), I)
ELSE
    OutFile$ = arg$(2) + "."
END IF
'Check filename size (8-char filename plus ".")
IF LEN(OutFile$) > 9 THEN Help

'Check Lang$ and add extension, and set up comment string

'QBasic/QuickBasic 4.5/GWBASIC
IF INSTR("QGCPABIS", Lang$) = 0 THEN Help     ' Wrong Language Parameter
IF INSTR("QG", Lang$) THEN
    ' No Header/Source Specified
    IF Lang$ = "Q" AND INSTR("SH", Source$) = 0 OR LEN(Source$) = 0 AND Lang$ <> "G" THEN Help
    IF Source$ = "H" THEN OutFile$ = OutFile$ + "BI" ELSE OutFile$ = OutFile$ + "BAS"
END IF
IF Lang$ = "Q" THEN
    Comment$ = "'"
ELSEIF Lang$ = "G" THEN Comment$ = "REM"
END IF

'C/C++ Header/Source
'Note that a * is used for ANSI C and will be fixed as needed for /**/_
' later.
IF INSTR("CP", Lang$) THEN
    ' No Header/Source specified
    IF INSTR("SH", Source$) = 0 OR LEN(Source$) = 0 THEN Help
    IF Source$ = "H" THEN
        IF Lang$ = "P" THEN Comment$ = "//" ELSE Comment$ = "*"
        OutFile$ = OutFile$ + "H"
    ELSE
        IF Lang$ = "C" THEN
            OutFile$ = OutFile$ + "C": Comment$ = "*"
        ELSE OutFile$ = OutFile$ + "CPP": Comment$ = "//"
        END IF
    END IF
END IF

'Assembly Language
IF Lang$ = "A" THEN
    ' No Header/Source specified
    IF INSTR("SH", Source$) = 0 OR LEN(Source$) = 0 THEN Help
    Comment$ = "#"
    IF Source$ = "H" THEN
        OutFile$ = OutFile$ + "INC"
    ELSE OutFile$ = OutFile$ + "ASM"
    END IF
END IF

IF Lang$ = "B" THEN OutFile$ = OutFile$ + "BAT": Comment$ = "REM" 'BAT File
IF Lang$ = "I" THEN OutFile$ = OutFile$ + "INI": Comment$ = ";"   'INI File
IF Lang$ = "S" THEN OutFile$ = OutFile$ + "SYS": Comment$ = "REM" 'SYS File

'Check to be sure input and output files are not the same
IF arg$(2) = OutFile$ THEN
    PRINT "*** ERROR ***"
    PRINT "Switch used was: "; arg$(1)
    PRINT "Input File to operate on is: "; arg$(2)
    PRINT "File conversion was to be output to: "; OutFile$
    PRINT "Cannot write to input file!": PRINT
    Help
END IF

'All set, now open files
OPEN arg$(2) FOR INPUT AS #1: OPEN OutFile$ FOR OUTPUT AS #2

    ' Parse sources and comment accordingly
    I = 0: y = CSRLIN
    WHILE NOT EOF(1)
        LINE INPUT #1, a$
        'Show line # being worked on:
        LOCATE y, 1: PRINT STRING$(79, 32);
        LOCATE y, 1: PRINT "Processing Line #"; I; : I = I + 1
        ' Neater source listing, parses out blank lines/comments
        IF LEN(a$) > 1 THEN
            IF Lang$ = "C" THEN
                'If its to be a header file, then no commenting is needed.
                IF Source$ = "H" THEN PRINT #2, a$ ELSE PRINT #2, "/* "+ a$ + " */"
            ELSE PRINT #2, Comment$ + " " + a$
            END IF
        ELSE PRINT #2, ""
        END IF
    WEND
CLOSE
LOCATE y, 1: PRINT STRING$(79, 32): LOCATE y, 1: PRINT "Done."

'***********************************************************************
'* FUNCTION Exist%
'*
'* PURPOSE
'*    Uses DOS ISR 21H, Function 4EH (Find First Matching Directory
'*    Entry) to determine the existence of FileName$.
'***********************************************************************
FUNCTION Exist% (FileName$) STATIC
     DIM IRegsX AS RegTypeX, ORegsX AS RegTypeX

     IRegsX.ax = &H4E00
     IRegsX.cx = &H3F                          'search for all files
     FileName$ = FileName$ + CHR$(0)           'must end with null byte

     IRegsX.ds = VARSEG(FileName$)             'load DS:DX with
     IRegsX.dx = SADD(FileName$)               '  address of FileName$

     INTERRUPTX &H21, IRegsX, ORegsX
     Exist% = ORegsX.ax = 0                    'if ax contains a value,
                                               '  remove the null byte
     FileName$ = LEFT$(FileName$, LEN(FileName$) - 1)
END FUNCTION

SUB Help
PRINT "USAGE: recom /switch infile.ext"
PRINT
PRINT "These switches determine the output file and filename:"
PRINT "/qx  QBasic/QuickBasic 4.5"
PRINT "/cx  ANSI C"
PRINT "/px  C++"
PRINT "/ax  Assembly Language"
PRINT "/g   GWBASIC"
PRINT "/b   Batch File (.BAT)"
PRINT "/i   .INI File"
PRINT "/s   .SYS File"
PRINT
PRINT "NOTE: x must be either an 's' (for source) or 'h' (for header)"
PRINT
END
END SUB
