home *** CD-ROM | disk | FTP | other *** search
- ~ Struct Indenter
- ~ Version 1.0 by Roland Acton - August 1993
- ~ Internet address: xracton@ccvax.fullerton.edu
-
- ~ Version 1.1 by Roland Acton - January 1994
- ~ Changes: The program now uses register variables, and makes proper
- ~ procedure and library calls.
-
- ~ This is an indenting program for the Struct language. It serves as
- ~ a useful programming aid and also as an example of how to write a
- ~ simple program in Struct.
- ~ This program is public domain. You may use any part of it you wish
- ~ in a program of your own, provided that you credit me and send me
- ~ a copy of the program.
-
- define procedure Kahm
- define procedure word=ParseCommandLine
- set startup Kahm
-
- open library exec
- open library dos
-
- constant indentamount=2,maxkeywords=15
-
- global srcfilehandle:long,destfilehandle:long
-
-
-
- procedure Kahm
- local indent:word,bufferstart:long,bufferpos:word,buffercount:word
- local fileline:long,linepos:word,spacebuffer:long,z:byte
- local counter:long,indentskip:long,keywordcount:word
- local keywordpointer:long,foundkeyword:word,x:byte,linepointer:long
- local pclsuccess:word
-
- string (info1) "Indenter for the Struct language",10
- string (info2) "Version 1.1 by Roland Acton - January 1994",10,10
- print info1
- print info2
- proc call pclsuccess=ParseCommandLine
- if pclsuccess=1
- libcall bufferstart=allocmem(256,0)
- libcall fileline=allocmem(256,0)
- libcall spacebuffer=allocmem(256,0)
-
- ~ Strictly speaking, I should check to see if the memory allocation
- ~ fails, but if the system is that low on memory it's going to fail
- ~ for other reasons in short order.
-
- for counter=spacebuffer;spacebuffer+252;4
- longpoke counter,32*256+32*256+32*256+32
- next
- libcall buffercount=read(srcfilehandle,bufferstart,256)
- bufferpos=0
- indent=0
-
- ~ The section of code below is an internal buffering system. It
- ~ pulls in 256 bytes at a time from the source file and extracts
- ~ lines of source code from them.
-
- mainloop:
- data register bufferpos,z,linepos,buffercount,fileline
- address register bufferstart,fileline,indentskip
- regload
- linepos=0
- repeat
- bytepeek z=bufferstart+bufferpos
- bytepoke fileline+linepos,z
- bufferpos=bufferpos+1
- linepos=linepos+1
- if bufferpos=buffercount
- libcall buffercount=read(srcfilehandle,bufferstart,256)
- bufferpos=0
- end if
- until z=10 | buffercount=0 | linepos=256
-
- ~ It's assumed that no line will be larger than 256 bytes. The extra
- ~ condition above is just to stop the program from crashing if it's
- ~ accidentally run on a binary file.
-
- for indentskip=fileline;fileline+linepos-1
- bytepeek z=indentskip
- if z<>32
- exit
- end if
- next
- linepos=fileline+linepos-indentskip
-
- ~ The section of code above is designed to skip any indentation that
- ~ already exists.
-
- ~ Now we have to determine which keyword, if any, the line begins
- ~ with. We skip over spaces and convert alphabetic characters to
- ~ uppercase.
-
- bytedata (keywords) "IF",0,"FOR",0,"WHILE",0,"REPEAT",0,"LOOP",0
- bytedata "ZEROLOOP",0,"ASM",0
- bytedata "ELSE",0
- bytedata "ENDIF",0,"NEXT",0,"WEND",0,"UNTIL",0,"ENDLOOP",0
- bytedata "ZEND",0,"ENDASM",0
-
- data register z,x,keywordcount,foundkeyword,indent
- address register keywordpointer,linepointer,indentskip
- regload
- keywordcount=1
- load address keywordpointer=keywords
- repeat
- linepointer=indentskip
- foundkeyword=1
- loop ;x<>0;
- bytepeek z=linepointer
- if z=32
- linepointer=linepointer+1
- bytepeek z=linepointer
- back if
- end if
- if z=>97 & z=<122
- z=z-32
- end if
- bytepeek x=keywordpointer
- if z<>x & x<>0
- foundkeyword=0
- end if
- linepointer=linepointer+1
- keywordpointer=keywordpointer+1
- end loop
- if foundkeyword=1
- exit
- end if
- keywordcount=keywordcount+1
- until keywordcount>maxkeywords
-
- ~ If the line started with a valid keyword, its number is in
- ~ keywordcount.
-
- ~ Check for one of the pre-output indent changers.
-
- if keywordcount=>8 & keywordcount=<15
- indent=indent-indentamount
- if indent<0
- indent=0
- end if
- end if
-
- ~ Output the line.
-
- bytepeek z=indentskip
-
- ~ If this is a comment line, or is blank, we do not indent it at
- ~ all.
-
- if linepos>1 & z<>126
- libcall write(destfilehandle,spacebuffer,indent)
- end if
- libcall write(destfilehandle,indentskip,linepos)
-
- ~ Check for one of the post-output indent changers.
-
- if keywordcount=<8
- indent=indent+indentamount
- end if
-
- ~ If there's still something left in the input buffer, we go back to
- ~ get the next line.
-
- if buffercount>0
- goto mainloop
- end if
- libcall freemem(bufferstart,256)
- libcall freemem(fileline,256)
- libcall freemem(spacebuffer,256)
- libcall close(srcfilehandle)
- libcall close(destfilehandle)
- end if
- end procedure
-
-
-
- procedure word=ParseCommandLine
- local step:word,z:byte,srcfilename:long,destfilename:long
- local addresskludge:long
-
- ~ If the command line appears valid, it is altered (by changing the
- ~ space and linefeed characters to nulls) so that it can be used to
- ~ open the source and destination files.
- ~ Note that this routine is deficient in that it cannot properly
- ~ handle parameters enclosed in quotes.
-
- load address addresskludge=error1
- srcfilename=commandpointer
- commandlength=commandlength-1
- parsecommandline=0
- if commandlength>0
- for step=0;commandlength-1
- bytepeek z=commandpointer+step
- if z=32
- exit
- end if
- next
- if step<commandlength
- bytepoke commandpointer+step,0
- step=step+1
- destfilename=commandpointer+step
- loop ;step<commandlength;step=step+1
- bytepeek z=commandpointer+step
- if z=32
- exit
- end if
- end loop
- if step=commandlength
- bytepoke commandpointer+commandlength,0
- parsecommandline=1
- end if
- end if
- end if
- string (error1) "Couldn't open file ",0,10
- if parsecommandline=1
- libcall srcfilehandle=open(srcfilename,1005)
- if srcfilehandle>0
- libcall destfilehandle=open(destfilename,1006)
- if destfilehandle>0
- parsecommandline=1
- else
- libcall close(srcfilehandle)
- print addresskludge
- print destfilename
- addresskludge=addresskludge+20
- print addresskludge
- parsecommandline=0
- end if
- else
- print addresskludge
- print srcfilename
- addresskludge=addresskludge+20
- print addresskludge
- parsecommandline=0
- end if
- else
- string (error2) "Error in command line",10
- string (error3) "Syntax: IndentStr <source-file> <destination-file>",10
- print error2
- print error3
- parsecommandline=0
- end if
- end procedure
-