1$!
2$! OS_VMS_FIX.COM
3$! Copyright (C) 2000, Stephen P. Wall
4$!
5$! Filter files for "#if" line continuations using a '\' and convert
6$! them to use comments for the continuation.  Necessary for VAXC - it
7$! doesn't understand the '\'.
8$!
9$! Yes, this is honkin' ugly code, but I deliberately avoided
10$!     if ...
11$!     then
12$!	   ....
13$!     endif
14$! and call/subroutine/endsubroutine constructs, because I can still
15$! remember when DCL didn't have them, and I wanted this to be as
16$! portable as possible, so...  If you want to structure it nicer for
17$! your own use, please feel free to do so.  However, please only
18$! distribute it in it's original form.
19$!
20$! I wrote it in DCL for portability and ease of use - a C version
21$! would definitely run faster, but then I'd have to deal with compiler
22$! differences, and users would have to deal with configuring and
23$! building it.  With DCL, it runs out-of-the-box.
24$!
25$! Note that if you use this from a VMS system to modify files on a
26$! mounted network drive, f$search() may return only the first matching
27$! file when it tries to resolve wildcards.  I have been unable to find
28$! a way around this.  Either copy the files to a local disk, or specify
29$! each file individually (Keep in mind if you do this that VMS limits
30$! you to eight parameters, so you'll only be able to filter eight files
31$! at a time).
32$!
33$! Ideas...
34$! - Use 'search filespec "#","if","\"/mat=and' to quickly eliminate
35$!   files that definitely don't need filtering.  This should speed
36$!   things up considerable.  Reading and writing every line from every
37$!   file takes quite a bit of time...
38$! - Error handling isn't great.  Come up with something better....
39$!
40$! E-mail addresses:
41$! Steve Wall		hitched97@velnet.com
42$! Zoltan Arpadffy      arpadffy@polarhome.com
43$! John W. Hamill       jhamill3@ford.com
44$!
45$! Modification History:
46$! 13Jul00 SWall	Initial Version
47$! 14Jul00 ZArpadffy    Display usage
48$! 06Mar01 JHamill      Ctrl-M problem fix
49$!
50$! If no parameters, or "-h" for a parameter, print usage and exit
51$
52$ all = "''p1'''p2'''p3'''p4'''p5'''p6'''p7'''p8'"
53$ if (all .nes. "") .and. (p1 .nes. "-h") .and. (p1 .nes. "-H") then goto startup
54$
55$ write sys$output "OS_VMS_FIX - DECC->VAXC pre-processor directive convert script"
56$ write sys$output "Usage: @OS_VMS_FIX <filename_1> <filename_2> <...>"
57$ write sys$output "       @OS_VMS_FIX <filename with wildcard> <...>"
58$ write sys$output ""
59$ write sys$output "Example: @OS_VMS_FIX *.c *.h [.proto]*.pro"
60$ write sys$output "Please note, you can define up to 8 parameters."
61$ write sys$output ""
62$ exit
63$
64$! Create an FDL file to convert VFC format files to Stream_LF.
65$! VMS OPEN/WRITE command creates VFC files.  When VFC files are read
66$! out under unix, they appear to have binary data embedded in them.
67$! To be friendly, we'll convert them to Stream_LF, which reads just
68$! file on unix.
69$
70$startup:
71$ on control_y then goto stopfdl
72$ open/write fdl []convert.fdl
73$ write fdl "SYSTEM"
74$ write fdl " SOURCE VAX/VMS"
75$ write fdl "FILE"
76$ write fdl " ORGANIZATION SEQUENTIAL"
77$ write fdl "RECORD"
78$ write fdl " BLOCK_SPAN YES"
79$ write fdl " CARRIAGE_CONTROL CARRIAGE_RETURN"
80$ write fdl " FORMAT STREAM"
81$ write fdl " SIZE 0"
82$ close fdl
83$ on control_y then goto endparamloop
84$
85$! Some symbols for use later on...
86$
87$ spc = ""
88$ spc[0,8] = 32
89$ tab = ""
90$ tab[0,8] = 9
91$
92$! Scan all positional arguments, do wildcard expansion, and call the
93$! filter routine on each resulting filename.
94$
95$ cnt = 0
96$paramloop:
97$ cnt = cnt + 1
98$
99$! VMS only allows command line parameters P1 - P8, so stop after
100$! processing 8 arguments.
101$
102$ if cnt .eq. 9 then goto endparamloop
103$
104$! Skip any empty parameter.
105$
106$ if P'cnt' .eqs. "" then goto paramloop
107$
108$! Got a parameter - do wildcard expansion.
109$
110$ arg = f$parse(P'cnt')
111$ write sys$output "Parsing ''arg'..."
112$ last = ""
113$fileloop:
114$ file = f$search(arg, 1)
115$
116$! f$search() returns "" after the last of multiple matches.
117$
118$ if file .eqs. "" then goto endfileloop
119$
120$! Strip the version number.
121$
122$ file = f$parse(file,,,"DEVICE") + f$parse(file,,,"DIRECTORY") + -
123         f$parse(file,,,"NAME") + f$parse(file,,,"TYPE")
124$
125$! f$search() returns the same filename over and over if there are no
126$! wildcards in it.
127$
128$ if file .eqs. last then goto endfileloop
129$ last = file
130$
131$! Got a valid file - filter it.
132$
133$ gosub filter
134$
135$! Reset our error handling.
136$
137$ on control_y then goto endparamloop
138$
139$! See if there's another matching filename.
140$
141$ goto fileloop
142$endfileloop:
143$
144$! Check for another parameter.
145$
146$ goto paramloop
147$endparamloop:
148$
149$! Finished - delete the FDL file.
150$
151$ delete []convert.fdl;
152$
153$! So long, and thanks for all the fish...
154$
155$ exit
156$
157$
158$! User aborted with Control-Y during creation of FDL file.
159$! Close the file, delete it, and exit with an error status.
160$
161$stopfdl:
162$ close fdl
163$ delete []convert.fdl;
164$ exit %X10000000
165$
166$
167$! Filter a file.
168$
169$filter:
170$ write sys$output "Filtering ''file'..."
171$
172$! Get a temporary filename from the subroutine parameter.
173$
174$ tmp = f$parse(file,,,"DEVICE") + f$parse(file,,,"DIRECTORY") + -
175        "tmp_" + f$parse(file,,,"NAME") + f$parse(file,,,"TYPE")
176$ on control_y then goto aborted
177$ open /read input 'file'
178$ open /write output 'tmp'
179$ changed = 0
180$readloop:
181$ read/end_of_file=endreadloop/error=readlooperror input line
182$
183$! Get the first 3 non-blank character on the line.
184$
185$ start = f$extract(0,3,f$edit(line,"COLLAPSE,LOWERCASE"))
186$
187$! If the line doesn't start with some form of "#if", just write it to
188$! the temp file.
189$
190$ if start .nes. "#if" then goto writeit
191$chkbkslsh:
192$
193$! See if the line ends in a backslash.  If not, write it to the temp file.
194$
195$ if f$extract(f$length(line)-1,1,line) .nes. "\" then goto writeit
196$
197$! Ok, got a line that needs to be modified.  Mark this file as changed,
198$! then replace the backslash at the end with the beginning of a comment
199$! (/*), and write it to the temp file.
200$
201$ changed = 1
202$ line = f$extract(0,f$length(line)-1,line) + "/*"
203$ write/symbol output line
204$
205$! Get another line from the input.
206$
207$ read/end_of_file=endreadloop/error=readlooperror input line
208$
209$! Grab all the blank space from the beginning of the line.
210$
211$ spaces = ""
212$spaceloop:
213$ if (f$extract(0,1,line) .nes. spc) .and. (f$extract(0,1,line) .nes. tab) -
214        then goto endspaceloop
215$ spaces = spaces + f$extract(0,1,line)
216$ line = f$extract(1,f$length(line)-1,line)
217$ goto spaceloop
218$endspaceloop:
219$
220$! Stick an end-comment (*/) after the leading blanks, then go back and
221$! check for a trailing backslash again, to catch code that continues
222$! across multiple lines.
223$
224$ line = spaces + "*/ " + line
225$ goto chkbkslsh
226$
227$! Write the current line, (will either be an untouched line, or the
228$! last line of a continuation) to the temp file, and go back to look
229$! for more input.
230$!
231$writeit:
232$ write/symbol output line
233$ goto readloop
234$
235$! Hit EOF.  Close the input & output, and if the file was marked as
236$! changed, convert it from VMS VFC format, to the more common Stream_LF
237$! format, so it doesn't show up full of garbage if someone tries to
238$! edit it on another OS.
239$!
240$endreadloop:
241$ close input
242$ close output
243$ if changed .eq. 0 then goto nocopy
244$ convert 'tmp' 'file' /fdl=[]convert.fdl
245$nocopy:
246$ delete 'tmp';
247$
248$! Exit this subroutine.
249$
250$ goto endfunc
251$
252$! Got a read error.  Say so, and trash the temp file.
253$
254$readlooperror:
255$ write sys$error "Error processing file ''file'"
256$ goto errorend
257$
258$! Got an interrupt.  Say so, and trash the temp file.
259$
260$aborted:
261$ write sys$error "Aborted while processing file ''file'"
262$
263$! Common code for read errors and interrupts.
264$
265$errorend:
266$ close input
267$ close output
268$ delete 'tmp';
269$ return %X10000000
270$
271$! End of filter subroutine.
272$
273$endfunc:
274$ return
275$
276$! EOF
277