| @@ -0,0 +1,340 @@ |
| | 1 | This is the change file for CWEB's COMMON under QSOD/SMSQ |
| | 2 | (Contributed by Robert H. Klein, September 1994) |
| | 3 | |
| | 4 | This change file is intended for use with C68 v4.13 (or later). |
| | 5 | compile with |
| | 6 | ex <dev_>cc;'-v -h -c -=500000 -DCWEBINPUTS=flp2_ common_c' |
| | 7 | |
| | 8 | |
| | 9 | |
| | 10 | @x |
| | 11 | \def\v{\char'174} % vertical (|) in typewriter font |
| | 12 | |
| | 13 | \def\title{Common code for CTANGLE and CWEAVE (Version 3.3)} |
| | 14 | \def\topofcontents{\null\vfill |
| | 15 | \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and |
| | 16 | {\ttitlefont CWEAVE}} |
| | 17 | \vskip 15pt |
| | 18 | \centerline{(Version 3.3)} |
| | 19 | \vfill} |
| | 20 | \def\botofcontents{\vfill |
| | 21 | \noindent |
| | 22 | @y |
| | 23 | \def\v{\char'174} % vertical (|) in typewriter font |
| | 24 | |
| | 25 | \def\title{Common code for CTANGLE and CWEAVE (QL Version 3.4)} |
| | 26 | \def\topofcontents{\null\vfill |
| | 27 | \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and |
| | 28 | {\ttitlefont CWEAVE}} |
| | 29 | \vskip 15pt |
| | 30 | \centerline{(Version 3.4)} |
| | 31 | \vfill} |
| | 32 | \def\botofcontents{\vfill |
| | 33 | \noindent |
| | 34 | @z |
| | 35 | |
| | 36 | @x |
| | 37 | The line number of each open file is also kept for error reporting and |
| | 38 | for the benefit of \.{CTANGLE}. |
| | 39 | |
| | 40 | @f line x /* make |line| an unreserved word */ |
| | 41 | @d max_include_depth 10 /* maximum number of source files open |
| | 42 | simultaneously, not counting the change file */ |
| | 43 | @d max_file_name_length 60 |
| | 44 | @d cur_file file[include_depth] /* current file */ |
| | 45 | @d cur_file_name file_name[include_depth] /* current file name */ |
| | 46 | @d cur_line line[include_depth] /* number of current line in current file */ |
| | 47 | @d web_file file[0] /* main source file */ |
| | 48 | @d web_file_name file_name[0] /* main source file name */ |
| | 49 | @y |
| | 50 | The line number of each open file is also kept for error reporting and |
| | 51 | for the benefit of \.{CTANGLE}. |
| | 52 | |
| | 53 | For use on QDOS/SMSQ systems the variable |max_file_name_length| is shortened |
| | 54 | to 42 characters, i.e. 5 characters for the device name, 36 characters |
| | 55 | for the file name plus one character as string terminator. (Note that |
| | 56 | (current) QDOS/SMSQ file systems have a limitation of 36 characters as |
| | 57 | maximum length for a file name. |
| | 58 | |
| | 59 | @f line x /* make |line| an unreserved word */ |
| | 60 | @d max_include_depth 10 /* maximum number of source files open |
| | 61 | simultaneously, not counting the change file */ |
| | 62 | @d max_file_name_length 42 |
| | 63 | @d cur_file file[include_depth] /* current file */ |
| | 64 | @d cur_file_name file_name[include_depth] /* current file name */ |
| | 65 | @d cur_line line[include_depth] /* number of current line in current file */ |
| | 66 | @d web_file file[0] /* main source file */ |
| | 67 | @d web_file_name file_name[0] /* main source file name */ |
| | 68 | @z |
| | 69 | |
| | 70 | |
| | 71 | @x |
| | 72 | cur_file_name[l]='/'; /* \UNIX/ pathname separator */ |
| | 73 | @y |
| | 74 | cur_file_name[l]='_'; /* QDOS/SMSQ pathname separator */ |
| | 75 | @z |
| | 76 | |
| | 77 | |
| | 78 | @x |
| | 79 | @ We now must look at the command line arguments and set the file names |
| | 80 | accordingly. At least one file name must be present: the \.{CWEB} |
| | 81 | file. It may have an extension, or it may omit the extension to get |".w"| or |
| | 82 | |".web"| added. The \TEX/ output file name is formed by replacing the \.{CWEB} |
| | 83 | file name extension by |".tex"|, and the \CEE/ file name by replacing |
| | 84 | the extension by |".c"|, after removing the directory name (if any). |
| | 85 | |
| | 86 | If there is a second file name present among the arguments, it is the |
| | 87 | change file, again either with an extension or without one to get |".ch"|. |
| | 88 | An omitted change file argument means that |"/dev/null"| should be used, |
| | 89 | when no changes are desired. |
| | 90 | @^system dependencies@> |
| | 91 | |
| | 92 | If there's a third file name, it will be the output file. |
| | 93 | |
| | 94 | @<Pred...@>= |
| | 95 | void scan_args(); |
| | 96 | |
| | 97 | @ @c |
| | 98 | void |
| | 99 | scan_args() |
| | 100 | { |
| | 101 | char *dot_pos; /* position of |'.'| in the argument */ |
| | 102 | char *name_pos; /* file name beginning, sans directory */ |
| | 103 | register char *s; /* register for scanning strings */ |
| | 104 | boolean found_web=0,found_change=0,found_out=0; |
| | 105 | /* have these names have been seen? */ |
| | 106 | boolean flag_change; |
| | 107 | |
| | 108 | while (--argc > 0) { |
| | 109 | if ((**(++argv)=='-'||**argv=='+')&&*(*argv+1)) @<Handle flag argument@>@; |
| | 110 | else { |
| | 111 | s=name_pos=*argv;@+dot_pos=NULL; |
| | 112 | while (*s) { |
| | 113 | if (*s=='.') dot_pos=s++; |
| | 114 | else if (*s=='/') dot_pos=NULL,name_pos=++s; |
| | 115 | else s++; |
| | 116 | } |
| | 117 | if (!found_web) @<Make |
| | 118 | |web_file_name|, |tex_file_name| and |C_file_name|@>@; |
| | 119 | else if (!found_change) @<Make |change_file_name| from |fname|@>@; |
| | 120 | else if (!found_out) @<Override |tex_file_name| and |C_file_name|@>@; |
| | 121 | else @<Print usage error message and quit@>; |
| | 122 | } |
| | 123 | } |
| | 124 | if (!found_web) @<Print usage error message and quit@>; |
| | 125 | if (found_change<=0) strcpy(change_file_name,"/dev/null"); |
| | 126 | } |
| | 127 | |
| | 128 | @ We use all of |*argv| for the |web_file_name| if there is a |'.'| in it, |
| | 129 | otherwise we add |".w"|. If this file can't be opened, we prepare an |
| | 130 | |alt_web_file_name| by adding |"web"| after the dot. |
| | 131 | The other file names come from adding other things |
| | 132 | after the dot. We must check that there is enough room in |
| | 133 | |web_file_name| and the other arrays for the argument. |
| | 134 | |
| | 135 | @<Make |web_file_name|...@>= |
| | 136 | { |
| | 137 | if (s-*argv > max_file_name_length-5) |
| | 138 | @<Complain about argument length@>; |
| | 139 | if (dot_pos==NULL) |
| | 140 | sprintf(web_file_name,"%s.w",*argv); |
| | 141 | else { |
| | 142 | strcpy(web_file_name,*argv); |
| | 143 | *dot_pos=0; /* string now ends where the dot was */ |
| | 144 | } |
| | 145 | sprintf(alt_web_file_name,"%s.web",*argv); |
| | 146 | sprintf(tex_file_name,"%s.tex",name_pos); /* strip off directory name */ |
| | 147 | sprintf(idx_file_name,"%s.idx",name_pos); |
| | 148 | sprintf(scn_file_name,"%s.scn",name_pos); |
| | 149 | sprintf(C_file_name,"%s.c",name_pos); |
| | 150 | found_web=1; |
| | 151 | } |
| | 152 | |
| | 153 | @ @<Make |change_file_name|...@>= |
| | 154 | { |
| | 155 | if (strcmp(*argv,"-")==0) found_change=-1; |
| | 156 | else { |
| | 157 | if (s-*argv > max_file_name_length-4) |
| | 158 | @<Complain about argument length@>; |
| | 159 | if (dot_pos==NULL) |
| | 160 | sprintf(change_file_name,"%s.ch",*argv); |
| | 161 | else strcpy(change_file_name,*argv); |
| | 162 | found_change=1; |
| | 163 | } |
| | 164 | } |
| | 165 | |
| | 166 | @ @<Override...@>= |
| | 167 | { |
| | 168 | if (s-*argv > max_file_name_length-5) |
| | 169 | @<Complain about argument length@>; |
| | 170 | if (dot_pos==NULL) { |
| | 171 | sprintf(tex_file_name,"%s.tex",*argv); |
| | 172 | sprintf(idx_file_name,"%s.idx",*argv); |
| | 173 | sprintf(scn_file_name,"%s.scn",*argv); |
| | 174 | sprintf(C_file_name,"%s.c",*argv); |
| | 175 | } else { |
| | 176 | strcpy(tex_file_name,*argv); |
| | 177 | if (flags['x']) { /* indexes will be generated */ |
| | 178 | if (program==cweave && strcmp(*argv+strlen(*argv)-4,".tex")!=0) |
| | 179 | fatal("! Output file name should end with .tex\n",*argv); |
| | 180 | @.Output file name...tex@> |
| | 181 | strcpy(idx_file_name,*argv); |
| | 182 | strcpy(idx_file_name+strlen(*argv)-4,".idx"); |
| | 183 | strcpy(scn_file_name,*argv); |
| | 184 | strcpy(scn_file_name+strlen(*argv)-4,".scn"); |
| | 185 | } |
| | 186 | strcpy(C_file_name,*argv); |
| | 187 | } |
| | 188 | found_out=1; |
| | 189 | } |
| | 190 | @y |
| | 191 | @ We now must look at the command line arguments and set the file names |
| | 192 | accordingly. At least one file name must be present: the \.{CWEB} |
| | 193 | file. It may have an extension, or it may omit the extension to get |"_w"| or |
| | 194 | |"_web"| added. The \TEX/ output file name is formed by replacing the \.{CWEB} |
| | 195 | file name extension by |"_tex"|, and the \CEE/ file name by replacing |
| | 196 | the extension by |"_c"|, after removing the directory name (if any). |
| | 197 | |
| | 198 | If there is a second file name present among the arguments, it is the |
| | 199 | change file, again either with an extension or without one to get |"_ch"|. |
| | 200 | An omitted change file argument means that |"NUL"| should be used, |
| | 201 | when no changes are desired. |
| | 202 | @^system dependencies@> |
| | 203 | |
| | 204 | If there's a third file name, it will be the output file. |
| | 205 | |
| | 206 | Because |"_"| is a directory {\em and} extension separator, \.{CWEB} will |
| | 207 | always use the {\em full} name (i.e. with full path). Fortunately the |
| | 208 | routine has been written to search for the last ``dot'', so the altered |
| | 209 | version will search for the last |"_"| (including directory separators), |
| | 210 | so we have what we want. |
| | 211 | |
| | 212 | @<Pred...@>= |
| | 213 | void scan_args(); |
| | 214 | |
| | 215 | @ @c |
| | 216 | void |
| | 217 | scan_args() |
| | 218 | { |
| | 219 | char *dot_pos; /* position of |'_'| in the argument */ |
| | 220 | char *name_pos; /* file name beginning, sans directory */ |
| | 221 | register char *s; /* register for scanning strings */ |
| | 222 | boolean found_web=0,found_change=0,found_out=0; |
| | 223 | /* have these names have been seen? */ |
| | 224 | boolean flag_change; |
| | 225 | |
| | 226 | while (--argc > 0) { |
| | 227 | if ((**(++argv)=='-'||**argv=='+')&&*(*argv+1)) @<Handle flag argument@>@; |
| | 228 | else { |
| | 229 | s=name_pos=*argv;@+dot_pos=NULL; |
| | 230 | while (*s) { |
| | 231 | if (*s=='_') dot_pos=s++; |
| | 232 | else if (*s=='_') dot_pos=NULL,name_pos=++s; |
| | 233 | else s++; |
| | 234 | } |
| | 235 | if (!found_web) @<Make |
| | 236 | |web_file_name|, |tex_file_name| and |C_file_name|@>@; |
| | 237 | else if (!found_change) @<Make |change_file_name| from |fname|@>@; |
| | 238 | else if (!found_out) @<Override |tex_file_name| and |C_file_name|@>@; |
| | 239 | else @<Print usage error message and quit@>; |
| | 240 | } |
| | 241 | } |
| | 242 | if (!found_web) @<Print usage error message and quit@>; |
| | 243 | if (found_change<=0) strcpy(change_file_name,"NUL"); |
| | 244 | } |
| | 245 | |
| | 246 | @ We use all of |*argv| for the |web_file_name| if there is a |'_'| in it, |
| | 247 | otherwise we add |"_w"|. If this file can't be opened, we prepare an |
| | 248 | |alt_web_file_name| by adding |"web"| after the dot. |
| | 249 | The other file names come from adding other things |
| | 250 | after the dot. We must check that there is enough room in |
| | 251 | |web_file_name| and the other arrays for the argument. |
| | 252 | |
| | 253 | If you've read the section before carefully you'll have noticed, that |
| | 254 | QDOS/SMSQ file names contain almost a |"_"|, so this routine will not work, |
| | 255 | i.e. you'll {\em have} to add the |"_w"| always. Nevertheless I adapted |
| | 256 | the routine as if it would work. |
| | 257 | |
| | 258 | @<Make |web_file_name|...@>= |
| | 259 | { |
| | 260 | if (s-*argv > max_file_name_length-5) |
| | 261 | @<Complain about argument length@>; |
| | 262 | if (dot_pos==NULL) |
| | 263 | sprintf(web_file_name,"%s_w",*argv); |
| | 264 | else { |
| | 265 | strcpy(web_file_name,*argv); |
| | 266 | *dot_pos=0; /* string now ends where the dot was */ |
| | 267 | } |
| | 268 | sprintf(alt_web_file_name,"%s_web",*argv); |
| | 269 | sprintf(tex_file_name,"%s_tex",name_pos); /* strip off directory name */ |
| | 270 | sprintf(idx_file_name,"%s_idx",name_pos); |
| | 271 | sprintf(scn_file_name,"%s_scn",name_pos); |
| | 272 | sprintf(C_file_name,"%s_c",name_pos); |
| | 273 | found_web=1; |
| | 274 | } |
| | 275 | |
| | 276 | @ @<Make |change_file_name|...@>= |
| | 277 | { |
| | 278 | if (strcmp(*argv,"-")==0) found_change=-1; |
| | 279 | else { |
| | 280 | if (s-*argv > max_file_name_length-4) |
| | 281 | @<Complain about argument length@>; |
| | 282 | if (dot_pos==NULL) |
| | 283 | sprintf(change_file_name,"%s_ch",*argv); |
| | 284 | else strcpy(change_file_name,*argv); |
| | 285 | found_change=1; |
| | 286 | } |
| | 287 | } |
| | 288 | |
| | 289 | @ @<Override...@>= |
| | 290 | { |
| | 291 | if (s-*argv > max_file_name_length-5) |
| | 292 | @<Complain about argument length@>; |
| | 293 | if (dot_pos==NULL) { |
| | 294 | sprintf(tex_file_name,"%s_tex",*argv); |
| | 295 | sprintf(idx_file_name,"%s_idx",*argv); |
| | 296 | sprintf(scn_file_name,"%s_scn",*argv); |
| | 297 | sprintf(C_file_name,"%s_c",*argv); |
| | 298 | } else { |
| | 299 | strcpy(tex_file_name,*argv); |
| | 300 | if (flags['x']) { /* indexes will be generated */ |
| | 301 | if (program==cweave && strcmp(*argv+strlen(*argv)-4,"_tex")!=0) |
| | 302 | fatal("! Output file name should end with _tex\n",*argv); |
| | 303 | @.Output file name...tex@> |
| | 304 | strcpy(idx_file_name,*argv); |
| | 305 | strcpy(idx_file_name+strlen(*argv)-4,"_idx"); |
| | 306 | strcpy(scn_file_name,*argv); |
| | 307 | strcpy(scn_file_name+strlen(*argv)-4,"_scn"); |
| | 308 | } |
| | 309 | strcpy(C_file_name,*argv); |
| | 310 | } |
| | 311 | found_out=1; |
| | 312 | } |
| | 313 | @z |
| | 314 | |
| | 315 | |
| | 316 | @x |
| | 317 | @ @<Print usage error message and quit@>= |
| | 318 | { |
| | 319 | if (program==ctangle) |
| | 320 | fatal( |
| | 321 | "! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n" |
| | 322 | ,""); |
| | 323 | @.Usage:@> |
| | 324 | else fatal( |
| | 325 | "! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n" |
| | 326 | ,""); |
| | 327 | } |
| | 328 | @y |
| | 329 | @ @<Print usage error message and quit@>= |
| | 330 | { |
| | 331 | if (program==ctangle) |
| | 332 | fatal( |
| | 333 | "! Usage: ctangle [options] webfile[_w] [{changefile[_ch]|-} [outfile[_c]]]\n" |
| | 334 | ,""); |
| | 335 | @.Usage:@> |
| | 336 | else fatal( |
| | 337 | "! Usage: cweave [options] webfile[_w] [{changefile[_ch]|-} [outfile[_tex]]]\n" |
| | 338 | ,""); |
| | 339 | } |
| | 340 | @z |