/* * DVIasm -- Construct test DVI files from an assembly-language-like * input file. * * This program was written for as part of the efforts of the * TeX Users' Group DVI Driver Standards Committee. The program * is in the public domain and may be freely used, copied, and * ported to other systems. * * * Author: Thomas J. Reid * Texas A&M University * Computing Services Center * College Station, Texas * 77843-3142 USA * Telephone: (409) 845-8459 * BITNET: X066TR@TAMVM1 * Internet: X066TR@TAMVM1.TAMU.EDU * * * Change History: * * Initials: TJR = Thomas J. Reid, Texas A&M University * * TJR: Version 1.0 * 08/11/89 Ported program into existence. * -- The original code included conditional code for UNIX, * 08/11/89 VAX/VMS, VM/CMS using Waterloo C and SAS/C, MVS using * Waterloo C and SAS/C, and AOS/VS. The only system * tested in this version is UNIX. * * TJR: Version 1.0 UNIX + CMS(WatC) * 08/18/89 Ported program to VM/CMS using Waterloo C. * Although the program has not been tested under MVS * using Waterloo C, it is expected that it will work. * Corrected a bug in the output for the FNT_DEF opcodes. * * TJR: Version 1.0 UNIX + CMS(WatC+SAS/C) + MVS(SAS/C) * 08/27/89 Ported program to VM/CMS and MVS using SAS/C. * Modified code for VM/CMS to build and issue a FILEDEF * command. Also changed BLOCKSIZE for MVS to 2048 bytes. * TAMU CSC does not run Waterloo C under MVS, so the MVS * port using it cannot be tested. * * TJR: Version 1.0 UNIX + CMS(Watc+SAS/C) + MVS(SAS/C) + VAX/VMS * 08/28/89 Ported program to VAX/VMS using VAXC. * * * Source and Test Files: * * dviasm.c Source file for all versions of DVIasm. * dviasm.h Declarations for DVIasm. Included by dviasm.c. * daconfig.h Machine/System/Compiler-dependent declarations. * Included by dviasm.c. * test.dviasm Test input file which exercises all of the DVIasm * commands. * story.dviasm Sample input file to construct the same DVI file * which TeX creates when processing story.tex. * * * Compiling, Linking, and Running Instructions: * * UNIX: cc -o dviasm dviasm.c * dviasm test * or dviasm test.dviasm * * VAX/VMS: CC DVIASM.C/LIS * LINK DVIASM/MAP=DVIASM.MAP/EXECUTABLE=DVIASM.EXE * DVIASM := $device:[directory]DVIASM.EXE * DVIASM TEST * or DVIASM TEST.DVIASM * * VM/CMS: Using Waterloo C Version 3.0 * Note: "WATC" and "CMS" in next line must be entered in caps. * cw dviasm ( align nowng prm WATC 1 prm CMS 1 opt * global txtlib clib * load dviasm ( nodup * genmod dviasm ( from main * dviasm test * or dviasm test dviasm * or dviasm test dviasm a1 * * VM/CMS: Using SAS/C Version 4.00C * Note: "LC370" compiler option must be entered in caps. * global maclib lc370 * lc370 dviasm ( define LC370=1 noprint * global txtlib lc370 * clink dviasm ( genmod dviasm * dviasm test * or dviasm test dviasm * or dviasm test dviasm a1 * * * MVS: Using SAS/C Version 4.00C * //name JOB acct * //STEP1 EXEC LC370CLG * //C.H DD DSN=header-data-set-name,DISP=SHR * //C.SYSIN DD DSN=dviasm.c-data-set-name,DISP=SHR * //GO.DVI DD DSN=output-dvi-data-set-name,DISP=OLD * //GO.SYSIN DD DSN=test.dviasm-data-set-name,DISP=SHR * // * * * Input Language: * * The input for this program consists of DVI opcodes with operands. * Comments may also be included. Opcodes with necessary operands are * entered on separate lines. Comments may be included on the same * line by placing them after a percent sign (%). Comments extend to * the end of the line. (This is the same format that TeX uses.) * Entirely blank lines as well as comment only lines are permitted. * * Labels (in the format of an identifier of letters and/or digits and * terminated with a colon) may appear on any line. Labels may be * entered as a prefix to an opcode, or may be on a separate line. If * they are entered on the same line as an opcode, the value assigned * to the label will be the address of the DVI opcode. * * The valid DVI opcodes and forms of operands is mostly the same as * that shown in Section 585ff of "TeX: The Program." The opcodes are * entered as SET_CHAR_0, PUT_RULE, RIGHT4, FNT_DEF3, etc. and can be * given in mixed case if desired. The commands must be entered with * the underscores. Alternate forms of codes exist for the opcodes * which occur in groups of four (such as RIGHT1, RIGHT2, RIGHT3, and * RIGHT4). This alternate form consists of simply the opcode name * without the trailing number. DVIasm determines the shortest form * of the opcode which will work and uses it. * * The operands following the opcodes must appear as shown in Section * 585ff with the exception of string operands and their length: The * length of the string is not given; instead, DVIasm supplies the * length of the actual string the is given. String arguments are * entered in double quotes. Thus, an XXX1 command is given as: * * XXX1 "This is a special string." * * DVIasm will output the code for an XXX1 opcode, a one-byte string * length containing the value 25, and the 25 bytes of the string. * * Numeric operands for the opcodes can be given as decimal integers * with an optional leading minus sign, or may be given in hexadecimal * form in C notation (ie, the characters "0x" or "0X" followed by * one to eight hexadecimal codes). Numeric operands in one form or * the other must be entered where numeric operands are expected and * string arguments must be entered where strings are expected. * * A label name may also be given where a numeric operand is expected. * The entry should consist of the name of the label without the colon. * DVIasm will substitute the last value assigned to that label. This * option is used to place pointers to previous DVI locations in some * of the opcodes (such as BOP, POST, and POST_POST). * * Two alternate forms for DVI opcodes are allowed. These consist of * entering a string enclosed in double quotes where an opcode is * expected, and entering a numeric constant for the opcode. Use of * a string is a shorthand form for entering the individual SET_CHAR_n * codes for each character of the string. Use of numeric operands * allows any code to be placed in the DVI file. The number of bytes * written for a string equals the length of the string while the number * of bytes written for a numeric operand is the minimum number of bytes * needed to represent the value when it is treated as an unsigned * integer. * * * Sample input file: -------------------------------------------------------------------------- % This DVIasm file represents the DVI file normally produced when % running the published story.tex file though TeX. Some of the % comments reflect the influences of Plain TeX. % % Comments explain the origins of the dimensions which are found in % the DVI file. The units of the dimensions are appropriate for the % source of the dimension. Some of these are given as "1/2u#" which % represent METAFONT dimensions. The actual value of u# depends upon % the current font. For the examples here, u# is 20/36pt for both % cmr10 and cmsl10 and 23/36pt for cmbx10. % % The comments beginning with "% >>>" show the input line from % story.tex which resulted in the generated output. % % For reference, here is a copy of the Plain TeX output routine: % % \output{\plainoutput} % \def\plainoutput{\shipout\vbox{\makeheadline\pagebody\makefootline}% % \advancepageno % \ifnum\outputpenalty>-\@MM \else\dosupereject\fi} % \def\pagebody{\vbox to\vsize{\boxmaxdepth\maxdepth \pagecontents}} % \def\makeheadline{\vbox to\z@{\vskip-22.5\p@ % \line{\vbox to8.5\p@{}\the\headline}\vss}\nointerlineskip} % \def\makefootline{\baselineskip24\p@\line{\the\footline}} % \def\dosupereject{\ifnum\insertpenalties>\z@ % something is being held over % \line{}\kern-\topskip\nobreak\vfill\supereject\fi} % % \def\pagecontents{\ifvoid\topins\else\unvbox\topins\fi % \dimen@=\dp\@cclv \unvbox\@cclv % open up \box255 % \ifvoid\footins\else % footnote info is present % \vskip\skip\footins % \footnoterule % \unvbox\footins\fi % \ifr@ggedbottom \kern-\dimen@ \vfil \fi} % \def\footnoterule{\kern-3\p@ % \hrule width 2truein \kern 2.6\p@} % the \hrule is .4pt high % \newtoks\headline \headline={\hfil} % headline is normally blank % \newtoks\footline \footline={\hss\tenrm\folio\hss} % ------------------------------------------------------------------------ % First, the preamble (short and simple): PRE 2 25400000 473628672 1000 " DVIasm output 1989.08.18 1055" % 2 = DVI format code % 25400000 = (numerator of scale) 254cm/100in * 100000du/cm % 473628672 = (denomiator of scale) 7227pt/100in * 65536sp/pt % scale = (254cm/100in * 100000du/cm) / (7227pt/100in * 65536sp/pt) % = 254 / (7227 * 65536) du/sp % Since scaled DVI units (du) are in $10^{-7}m$ units, % arguments in this file are in scaled points (sp). % 1000 = (overall scaling of DVI units) 1000/1000 x normal size % ------------------------------------------------------------------------ % Now, the body of the DVI file: % Start new page and record current file position in "page1" Page1: BOP 1 0 0 0 0 0 0 0 0 0 -1 % A non-zero \voffset will cause a DOWNn command to appear hear. % A non-zero \hoffset will cause a RIGHTn command to appear hear. % \def\makeheadline{\vbox to 0pt{...}} PUSH % \vskip -22.5pt DOWN3 -917504 % -22.5pt (\vskip) + 8.5pt (\vbox to 8.5pt) % ...\line{\vbox to 8.5pt{}\the\headline}\vss}\nointerlineskip} % \headline={\hfil} % Note the optimization that TeX does: since all boxes are empty, % TeX does not output the contents of any of them. POP % \def\pagebody{\vbox to\vsize{\boxmaxdepth\maxdepth \pagecontents}} DOWN4 42152922 % 8.9in (height of \vbox to \vsize) PUSH DOWN4 -41497562 % -8.9in (\vsize) + 10pt (\topskip glue) % >>> \hrule PUT_RULE 26214 30785863 % 0.4pt (default height) by 6.5in (from \hsize) % >>> \vskip 1in DOWN3 5185936 % 1in (\vskip) + 6.8611pt (cap height of cmbx10) % >>> \centerline{\bf A SHORT STORY} PUSH RIGHT4 12265425 % left glue for \centerline{\bf A SHORT STORY} FNT_DEF1 23 0x1af22256 655360 655360 "" "cmbx10" FNT_NUM_23 "A" W3 251220 % 6u# (from cmbx10) space between words "SHOR" X3 -62805 % -3/2u# (from cmbx10) kern between "R" and "T" "T" W0 % 6u# (from cmbx10) space between words "STOR" X0 % -3/2u# (from cmbx10) kern between "R" and "Y" "Y" POP % >>> \vskip 6pt DOWN3 1179648 % 6pt (\vskip) + 12pt (\baselineskip) % >>> \centerline{\sl by A. U. Thor} PUSH RIGHT4 13334915 % left glue for \centerline{\sl by A. U. Thor} FNT_DEF1 33 0x70ae304a 655360 655360 "" "cmsl10" FNT_NUM_33 "b" RIGHT2 -18205 % 1/2u# (from cmsl10) kern between "b" and "y" "y" W3 218453 % 6u# (from cmsl10) space between words "A." W0 % 6u# (from cmsl10) space between words "U." W0 % 6u# (from cmsl10) space between words "Thor" POP % >>> \vskip .5cm DOWN3 1718771 % 0.5cm (\vskip) + 12pt (\baselineskip) % >>> Once upon a time, in a distant % >>> galaxy called \"\O\"o\c c, % >>> there lived a computer % >>> named R.~J. Drofnats. % >>> \par % (really a blank line) PUSH RIGHT3 1310720 % 20pt (\parindent) FNT_DEF1 0 0x4bf16079 655360 655360 "" "cmr10" FNT_NUM_0 "Once" W3 218453 % 6u# (from cmr10) space between words "up" RIGHT2 18205 % 1/2u# (from cmr10) kern between "p" and "o" "on" W0 % 6u# (from cmr10) space between words "a" W0 % 6u# (from cmr10) space between words "time," W0 % 6u# (from cmr10) space between words "in" W0 % 6u# (from cmr10) space between words "a" W0 % 6u# (from cmr10) space between words "distan" X2 -18205 % -1/2u# (from cmr10) kern between "n" and "t" "t" W0 % 6u# (from cmr10) space between words "galaxy" W0 % 6u# (from cmr10) space between words "called" PUSH % accents over uppercase letters require box % all u# dimensions here are from cmr10 RIGHT3 309476% 6u# (space) + (14u#-9u#)/2 (center umlaut on "O") DOWN3 -165660% (246-155)/36pt (x-height - cap-height of cmr10) SET_CHAR_127 % the umlaut accent POP W0 % 6u# (from cmr10) space between words "O" SET_CHAR_127 % umlaut accent RIGHT3 -327681 % -9u# (from cmr10) back up over umlaut accent "o" SET_CHAR_24 % cedilla accent RIGHT3 -291271 % -8u# (from cmr10) back up over cedilla accent "c," W0 % 6u# (from cmr10) space between words "there" W0 % 6u# (from cmr10) space between words "liv" X0 % -1/2u# (from cmr10) kern between "v" and "e" "ed" W0 % 6u# (from cmr10) space between words "a" W0 % 6u# (from cmr10) space between words "computer" W0 % 6u# (from cmr10) space between words "named" W0 % 6u# (from cmr10) space between words "R." W0 % 6u# (from cmr10) space between words "J." W0 % 6u# (from cmr10) space between words "Drofnats." POP % >>> Mr.~Drofnats---or ``R. J.'' as % >>> he preferred to be called---%error has been fixed! % >>> was happiest when he was at work % >>> typesetting beautiful documents. Y3 786432 % 12pt (\baselineskip) + 0pt (\parskip) PUSH RIGHT3 1310720 % 20pt (\parindent) "Mr." W3 220375 % 6u# (cmr10) + 1922sp (stretch) space between words "Drofnats" SET_CHAR_124 % em-dash (---) ligature "or" W0 % 6u# (cmr10) + 1922sp (stretch) space between words SET_CHAR_92 % left double quote (``) ligature "R." W0 % 6u# (cmr10) + 1922sp (stretch) space between words "J.," SET_CHAR_34 % right double quote ('') ligature RIGHT3 220855 % 6u# + 1922sp + 480sp (extra stretch for comma) "as" W0 % 6u# (cmr10) + 1922sp (stretch) space between words "he" W0 % 6u# (cmr10) + 1922sp (stretch) space between words "preferred" W0 % 6u# (cmr10) + 1922sp (stretch) space between words "to" W0 % 6u# (cmr10) + 1922sp (stretch) space between words "b" RIGHT2 18205 % 1/2u# (from cmr10) kern between "b" and "e" "e" W0 % 6u# (cmr10) + 1922sp (stretch) space between words "called" SET_CHAR_124 % em-dash (---) ligature "w" X2 -18205 % -1/2u# (from cmr10) kern between "w" and "a" "as" W0 % 6u# (cmr10) + 1922sp (stretch) space between words "happiest" W0 % 6u# (cmr10) + 1922sp (stretch) space between words "when" W0 % 6u# (cmr10) + 1922sp (stretch) space between words "he" W0 % 6u# (cmr10) + 1922sp (stretch) space between words "w" X0 % -1/2u# (from cmr10) kern between "w" and "a" "as" W0 % 6u# (cmr10) + 1922sp (stretch) space between words "at" W0 % 6u# (cmr10) + 1922sp (stretch) space between words "w" X0 % -1/2u# (from cmr10) kern between "w" and "o" "ork" W0 % 6u# (cmr10) + 1922sp (stretch) space between words "t" X0 % -1/2u# (from cmr10) kern between "t" and "y" "yp" RIGHT2 18205 % 1/2u# (from cmr10) kern between "p" and "e" "esetting" POP Y0 % 12pt (\baselineskip) PUSH "b" W2 18205 % 1/2u# (from cmr10) kern between "b" and "e" % Note the use of W for kerning instead of word spacing. "eautiful" RIGHT3 218453 % 6u# (from cmr10) space between words "do" W0 % 1/2u# (from cmr10) kern between "c" and "c" "cumen" RIGHT2 -18205 % -1/2u# (from cmr10) kern between "n" and "t" "ts." POP % >>> \vskip 1in DOWN3 4762500 % 1in + 0.4pt (height of \hrule) % >>> \hrule PUT_RULE 26214 30785863 % 0.4pt (default height) by 6.5in (from \hsize) % >>> \vfill\eject POP % \def\makefootline{\baselineskip 24pt ... % ...\line{\the\footline}} % \footline={\hss\tenrm\folio\hss} % \def\folio{\ifnum\pageno<0 \romannumeral-\pageno \else\number\pageno \fi} % \countdef\pageno=0 \pageno=1 % first page is number 1 DOWN3 1572864 % 24pt (modified \baselineskip) PUSH RIGHT4 15229091 % left glue for centering page number "1" POP EOP % End of page [1.0.0.0.0.0.0.0.0.0] % ------------------------------------------------------------------------ % Finally, the postamble: PostStart: % record position of start of postamble POST Page1 25400000 473628672 1000 43725786 30785863 3 1 % 25400000 = (numerator of scale) 254cm/100in * 100000du/cm % 473628672 = (denomiator of scale) 7227pt/100in * 65536sp/pt % scale = (254cm/100in * 100000du/cm) / (7227pt/100in * 65536sp/pt) % = 254 / (7227 * 65536) du/sp % Since scaled DVI units (du) are in $10^{-7}m$ units, % arguments in this file are in scaled points (sp). % 1000 = (overall scaling of DVI units) 1000/1000 x normal size % 43725786 = (page depth) 8.9in (\vsize) + 24pt (modified \baselineskip) % 30785863 = (page width) 6.5in (\hsize) % 3 = maximum stack depth % 1 = number of pages % \font\tenrm=cmr10 % \font\... definitions for fonts 1 through 21 % \font\tenbx=cmbx10 % \font\... definitions for fonts 24 through 32 % \font\tensl=cmsl10 % \font\... definitions for remaining fonts % Note that TeX only issues FNT_DEFn opcodes for fonts that have been used. FNT_DEF1 33 0x70ae304a 655360 655360 "" "cmsl10" FNT_DEF1 23 0x1af22256 655360 655360 "" "cmbx10" FNT_DEF1 0 0x4bf16079 655360 655360 "" "cmr10" % 655360 = 10pt (design size and "at" size for all fonts) POST_POST PostStart 2 % End postamble and point to start of postamble % 2 = DVI format code 0xdfdfdfdf % Write out four DF bytes FILL 0xdf % Fill out to "blocksize" with DFs. The "blocksize" is % system-dependent. The following values are used: % UNIX ------- 4 % VAX/VMS -- 512 % VM/CMS -- 1024 % MVS ----- 2048 % AOS/VS -- 1024 (?) -------------------------------------------------------------------------- ********************************************************************** */ #include "daconfig.h" #include "dviasm.h" int main (argc, argv) int argc; char *argv[]; { char line[MAXLINE+2]; void open_DVIasm(); void open_DVI(); int parse_input(); (void) printf ("DVIasm Version 1.0 (08/28/89)\n\n"); global.error = 0; global.first_label = NULL; global.current_DVI_position = 0; open_DVIasm (argc, argv); open_DVI (); while (fgets (line, MAXLINE+2, global.in_file) != NULL) { if (parse_input (line)) { global.error = 1; } } (void) fclose (global.in_file); (void) fclose (global.out_file); if (global.error) { (void) printf ("\n>>>>> Errors found in input. <<<<<\n"); (void) printf ("\nDVIasm terminating with errors.\n"); } else (void) printf ("\nDVIasm terminating normally.\n"); #if UTS | AOS if (global.error) return 1; else return 0; #endif #if VMS /* Don't return a value to VMS; it prints a stupid message */ #endif #if CMS | MVS if (global.error) return 8; else return 0; #endif } /* Open_DVIasm Function *********************************************** */ /* * Get the name of the input file and open it. Also, set determine * output file name. * */ void open_DVIasm (argc, argv) int argc; char *argv[]; { #if UTS | VMS | AOS char *name_ptr; char *type_ptr; #endif #if MVS == 0 void usage(); #if WATC == 0 void exit(); #endif #endif #if UTS if (argc != 2) usage (); if (strrchr (argv[1], '/') != NULL) { name_ptr = strrchr (argv[1], '/') + 1; } else name_ptr = argv[1]; if (strchr (name_ptr, '.') != NULL) { type_ptr = strchr (name_ptr, '.') + 1; } else type_ptr = NULL; (void) strcpy (global.in_file_name, argv[1]); if (type_ptr == NULL) { (void) strcat (global.in_file_name, ".dviasm"); (void) strcpy (global.out_file_name, name_ptr); (void) strcat (global.out_file_name, ".dvi"); } else { (void) strncpy (global.out_file_name, name_ptr, strcspn (name_ptr, ".")); *(global.out_file_name + strcspn (name_ptr, ".")) = '\0'; (void) strcat (global.out_file_name, ".dvi"); } global.in_file = fopen (global.in_file_name, "r"); if (global.in_file == NULL) { (void) printf ("Cannot open file \"%s\".\n", global.in_file_name); exit (1); } #endif /* UTS */ #if VMS int i; if (argc != 2) usage (); for (i = 0; i < strlen (argv[1]); i++) argv[1][i] = MAKEUPPER (argv[1][i]); if (strrchr (argv[1], ']') != NULL) { name_ptr = strrchr (argv[1], ']') + 1; } else name_ptr = argv[1]; if (strchr (name_ptr, '.') != NULL) { type_ptr = strchr (name_ptr, '.') + 1; } else type_ptr = NULL; (void) strcpy (global.in_file_name, argv[1]); if (type_ptr == NULL) { (void) strcat (global.in_file_name, ".DVIASM"); (void) strcpy (global.out_file_name, name_ptr); (void) strcat (global.out_file_name, ".DVI"); } else { (void) strncpy (global.out_file_name, name_ptr, strcspn (name_ptr, ".")); *(global.out_file_name + strcspn (name_ptr, ".")) = '\0'; (void) strcat (global.out_file_name, ".DVI"); } global.in_file = fopen (global.in_file_name, "r"); if (global.in_file == NULL) { (void) printf ("Cannot open file \"%s\".\n", global.in_file_name); exit (1); } #endif /* VMS */ #if CMS switch (argc) { case 1: usage (); break; case 2: (void) sprintf (global.in_file_name, "%s DVIASM *", argv[1]); break; case 3: (void) sprintf (global.in_file_name, "%s %s *", argv[1], argv[2]); break; default: (void) sprintf (global.in_file_name, "%s %s %s", argv[1], argv[2], argv[3]); break; } global.in_file = fopen (global.in_file_name, "r"); (void) sprintf (global.out_file_name, "%s DVI A1", argv[1]); if (global.in_file == NULL) { (void) printf ("Cannot open file \"%s\".\n", global.in_file_name); exit (16); } #endif /* CMS */ #if MVS global.in_file = stdin; /* Read input from //SYSIN DD ... */ (void) strcpy (global.out_file_name, "DVI"); #endif /* MVS */ #if AOS int i; for (i = 0; i < strlen (argv[1]); i++) argv[1][i] = MAKEUPPER (argv[1][i]); if (strrchr (argv[1], ':') != NULL) { name_ptr = strrchr (argv[1], ':') + 1; } else name_ptr = argv[1]; if (strchr (name_ptr, '.') != NULL) { type_ptr = strchr (name_ptr, '.') + 1; } else type_ptr = NULL; (void) strcpy (global.in_file_name, argv[1]); if (type_ptr == NULL) { (void) strcat (global.in_file_name, ".DVIASM"); (void) strcpy (global.out_file_name, name_ptr); (void) strcat (global.out_file_name, ".DVI"); } else { (void) strncpy (global.out_file_name, name_ptr, strcspn (name_ptr, ".")); *(global.out_file_name + strcspn (name_ptr, ".")) = '\0'; (void) strcat (global.out_file_name, ".DVI"); } global.in_file = fopen (global.in_file_name, "r"); if (global.in_file == NULL) { (void) printf ("Cannot open file \"%s\".\n", global.in_file_name); exit (1); } #endif /* AOS */ } /* Open_DVI Function ************************************************** */ /* * Open the DVI output file. * */ void open_DVI () { #if UTS void exit(); global.out_file = fopen (global.out_file_name, "w"); if (global.out_file == NULL) { (void) printf ("Cannot open \"%s\" for output.\n", global.out_file_name); exit (1); } #endif #if VMS void exit(); global.out_file = fopen (global.out_file_name, "w", "rfm=fix", "mrs=512", "bls=512"); if (global.out_file == NULL) { (void) printf ("Cannot open \"%s\" for output.\n", global.out_file_name); exit (1); } #endif #if LC370 /* CMS and MVS */ #if CMS char cmd[100]; int i; int system(); #endif void exit(); #if CMS (void) sprintf (cmd, "FILEDEF DVI DISK %s ( RECFM F LRECL 1024", global.out_file_name); for (i = 0; i < strlen (cmd); i++) { cmd[i] = MAKEUPPER (cmd[i]); } if (system (cmd) != 0) { (void) printf ("Cannot issue \"%s\" command.\n", cmd); exit (1); } #endif global.out_file = fopen ("DDN:DVI", "wb"); if (global.out_file == NULL) { (void) printf ("Cannot open \"%s\" for output.\n", global.out_file_name); exit (1); } #endif #if WATC /* CMS and WATC */ char file_name[300]; (void) sprintf (file_name, "%s ( RECFM F LRECL %d BIN", global.out_file_name, BLOCKSIZE); global.out_file = fopen (file_name, "w"); if (global.out_file == NULL) { (void) printf ("Cannot open \"%s\" for output.\n", global.out_file_name); exit (1); } #endif #if AOS void exit(); global.out_file = fopen (global.out_file_name, "w"); if (global.out_file == NULL) { (void) printf ("Cannot open \"%s\" for output.\n", global.out_file_name); exit (1); } #endif } /* Parse_Input Function *********************************************** */ /* * Parse an input line and call appropriate processing function. * */ int parse_input (line) char *line; { char *c; int token_return; int DVIcmds_index; char copy_of_line[MAXLINE]; int extract_token(); void write_DVI_u1(); void write_DVI_u2(); void write_DVI_u3(); void write_DVI_u4(); void write_DVI(); c = line + strlen (line) - 1; *c-- = '\0'; /* truncate \n from line */ while ((c >= line) && (*c == ' ')) /* remove trailing blanks */ *c-- = '\0'; (void) strcpy (copy_of_line, line); /* save line in case of error */ if (c < line) return 0; /* ignore null line */ if (strchr (line, '%') != NULL) /* chop off comments */ { c = strchr (line, '%'); if (c == line) return 0; *c-- = '\0'; while ((c >= line) && (*c == ' ')) *c-- = '\0'; /* remove blanks before % */ } if (c < line) return 0; /* ignore, blank line */ c = line; while (*c == ' ') /* remove leading blanks */ c++; global.num_tokens = 0; for (;;) { token_return = extract_token (&c); if (token_return == NO_MORE_TOKENS) break; if (token_return == INVALID_TOKEN) { (void) printf (">>> %s\n\n", copy_of_line); return 1; } } if (global.num_tokens == 0) return 0; switch (cmdargs[0].token_type) { case DVI_OPCODE_TOKEN: DVIcmds_index = cmdargs[0].token.DVIcmds_index; cmdargs[0].token.DVI_code = DVIcmds[DVIcmds_index].code; token_return = (*DVIcmds[DVIcmds_index].processing_function) (); if (token_return) { (void) printf (">>> %s\n\n", copy_of_line); } return token_return; case NUMBER_TOKEN: if ((unsigned) cmdargs[0].token.number < 256) write_DVI_u1 ((unsigned) cmdargs[0].token.number); else if ((unsigned) cmdargs[0].token.number < 65536) write_DVI_u2 ((unsigned) cmdargs[0].token.number); else if ((unsigned) cmdargs[0].token.number < 16777216) write_DVI_u3 ((unsigned) cmdargs[0].token.number); else write_DVI_u4 ((unsigned) cmdargs[0].token.number); return 0; case STRING_TOKEN: write_DVI ((unsigned char *) cmdargs[0].token.string, strlen (cmdargs[0].token.string)); return 0; default: (void) printf (">>> Invalid command.\n"); (void) printf (">>> %s\n\n", copy_of_line); return 1; } /* NOTREACHED */ } /* Extract_Token Function ********************************************* */ /* * Extract the next token from a line. * */ int extract_token (ptr_string) char **ptr_string; { char *string; char token_value[MAXLINE]; char *token_char; char *end; int end_string_flag; int token_type; int numeric_value; #if EBCDIC_MACHINE static char ascii[256] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0x00 -- 0x07 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0x08 -- 0x0f */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0x10 -- 0x17 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0x18 -- 0x1f */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0x20 -- 0x27 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0x28 -- 0x2f */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0x30 -- 0x37 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0x38 -- 0x3f */ 0x20, 0x5b, 0x5d, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0x40 -- 0x47 */ 0x20, 0x20, 0x20, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* 0x48 -- 0x4f */ 0x26, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0x50 -- 0x57 */ 0x20, 0x20, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* 0x58 -- 0x5f */ 0x2d, 0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0x60 -- 0x67 */ 0x20, 0x20, 0x7c, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* 0x68 -- 0x6f */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0x70 -- 0x77 */ 0x20, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* 0x78 -- 0x7f */ 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x80 -- 0x87 */ 0x68, 0x69, 0x20, 0x7b, 0x20, 0x20, 0x20, 0x20, /* 0x88 -- 0x8f */ 0x20, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 0x90 -- 0x97 */ 0x71, 0x72, 0x20, 0x7d, 0x20, 0x20, 0x20, 0x20, /* 0x98 -- 0x9f */ 0x20, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* 0xa0 -- 0xa7 */ 0x79, 0x7a, 0x20, 0x20, 0x20, 0x5b, 0x20, 0x20, /* 0xa8 -- 0xaf */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0xb0 -- 0xb7 */ 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x20, 0x20, /* 0xb8 -- 0xbf */ 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0xc0 -- 0xc7 */ 0x48, 0x49, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0xc8 -- 0xcf */ 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* 0xd0 -- 0xd7 */ 0x51, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0xd8 -- 0xdf */ 0x5c, 0x20, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* 0xe0 -- 0xe7 */ 0x59, 0x5a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 0xe8 -- 0xef */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0xf0 -- 0xf7 */ 0x38, 0x39, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x20};/* 0xf8 -- 0xff */ #endif int classify_token(); string = *ptr_string; if (*string == '\0') return NO_MORE_TOKENS; (void) strcpy (token_value, string); if (*token_value == '"') { token_char = token_value; end = string + 1; end_string_flag = 0; while (*end) { switch (*end) { case '"': *token_char = '\0'; end++; end_string_flag = 1; break; default: #if ASCII_MACHINE *token_char++ = *end; /* copy if already ASCII */ #else *token_char++ = ascii[*end]; /* else translate */ #endif break; } end++; if (end_string_flag) break; } string = end; if ( ! end_string_flag) { (void) printf (">>> Non-terminating string.\n"); return INVALID_TOKEN; } if (strlen (token_value) > MAX_STR_LEN) { (void) printf (">>> String is too long.\n"); return INVALID_TOKEN; } token_type = STRING_TOKEN; } else { if ((end = strchr (token_value, ' ')) != NULL) *end = '\0'; string = string + strlen (token_value); token_type = classify_token (token_value, &numeric_value); } while (*string == ' ') /* remove leading blanks on next token */ string++; *ptr_string = string; /* return update pointer to caller */ switch (token_type) { case LABEL_ASSIGNMENT_TOKEN: break; case LABEL_VALUE_TOKEN: cmdargs[global.num_tokens].token_type = token_type; cmdargs[global.num_tokens].token.label = numeric_value; global.num_tokens++; break; case NUMBER_TOKEN: cmdargs[global.num_tokens].token_type = token_type; cmdargs[global.num_tokens].token.number = numeric_value; global.num_tokens++; break; case STRING_TOKEN: cmdargs[global.num_tokens].token_type = token_type; (void) strcpy (cmdargs[global.num_tokens].token.string, token_value); global.num_tokens++; break; case DVI_OPCODE_TOKEN: cmdargs[global.num_tokens].token_type = token_type; cmdargs[global.num_tokens].token.DVIcmds_index = numeric_value; global.num_tokens++; break; default: break; } if (global.num_tokens > MAX_NUM_TOKENS) { (void) printf (">>> Too many tokens (>%d) on line.\n", MAX_NUM_TOKENS); return INVALID_TOKEN; } return FOUND_TOKEN; } /* Classify_Token Function ******************************************** */ /* * Classify the type of the token. * */ int classify_token (token_value, ptr_value) char *token_value; int *ptr_value; { int i; LABEL *label_ptr; #if WATC == 0 void exit(); #endif if ((strlen (token_value) > 1) && (token_value[strlen(token_value)-1] == ':')) { token_value[strlen(token_value)-1] = '\0'; /* drop the colon */ if (strlen (token_value) > MAX_STR_LEN) { (void) printf (">>> Label too long.\n"); return INVALID_TOKEN; } label_ptr = global.first_label; while (label_ptr != NULL) { if (match (token_value, label_ptr->label)) break; label_ptr = label_ptr->next_label; } if (label_ptr == NULL) { label_ptr = (LABEL *) malloc (sizeof (LABEL)); if (label_ptr == NULL) { (void) printf (">>> %s %s.\n", "Cannot allocate memory for label", token_value); exit (1); } label_ptr->next_label = global.first_label; global.first_label = label_ptr; } (void) strcpy (label_ptr->label, token_value); label_ptr->value = global.current_DVI_position; *ptr_value = label_ptr->value; return LABEL_ASSIGNMENT_TOKEN; } if ((strncmp (token_value, "0x", 2) == 0) || (strncmp (token_value, "0X", 2) == 0)) { if ((strlen (token_value) > 2) && (strlen (token_value) < 11) && (strspn (token_value+2, "0123456789abcdefABCDEF") == strlen (token_value+2))) { (void) sscanf (token_value+2, "%x", ptr_value); return NUMBER_TOKEN; } (void) printf (">>> Invalid hexadecimal constant: %s.\n", token_value); return INVALID_TOKEN; } if (strspn (token_value, "0123456789") == strlen (token_value)) { (void) sscanf (token_value, "%d", ptr_value); return NUMBER_TOKEN; } if ((*token_value == '-') && (strspn (token_value+1, "0123456789") == strlen (token_value+1))) { (void) sscanf (token_value, "%d", ptr_value); return NUMBER_TOKEN; } for (i = 0; i < NUM_DVI_CMDS; i++) { if (match (token_value, DVIcmds[i].command)) { *ptr_value = i; return DVI_OPCODE_TOKEN; } } label_ptr = global.first_label; while (label_ptr != NULL) { if (match (token_value, label_ptr->label)) { *ptr_value = label_ptr->value; return LABEL_VALUE_TOKEN; } label_ptr = label_ptr->next_label; } return INVALID_TOKEN; } /* Match Function ***************************************************** */ /* * Test two strings for equality ignoring case. * */ int match (given, test) char *given; char *test; { int len; char given_char, test_char; len = strlen (given); if (len != strlen (test)) return 0; /* given arg is too long */ while (len--) { given_char = MAKELOWER (*given); test_char = MAKELOWER (*test); if (given_char != test_char) return 0; /* unmatch chars found */ given++; test++; } return 1; } /* Cmd_No_Ops Function ************************************************ */ /* * Process a DVI command that has no operands * */ int cmd_no_ops () { void write_DVI_u1(); if (global.num_tokens != 1) { (void) printf (">>> Improper number of tokens; should be 1.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); return 0; } /* Cmd_1ByteS Function ************************************************ */ /* * Process a DVI command with a 1-byte signed operand. * */ int cmd_1bytes () { void write_DVI_u1(); void write_DVI_s1(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_s1 (cmdargs[1].token.number); return 0; } /* Cmd_2ByteS Function ************************************************ */ /* * Process a DVI command with a 2-byte signed operand. * */ int cmd_2bytes () { void write_DVI_u1(); void write_DVI_s2(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_s2 (cmdargs[1].token.number); return 0; } /* Cmd_3ByteS Function ************************************************ */ /* * Process a DVI command with a 3-byte signed operand. * */ int cmd_3bytes () { void write_DVI_u1(); void write_DVI_s3(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_s3 (cmdargs[1].token.number); return 0; } /* Cmd_4ByteS Function ************************************************ */ /* * Process a DVI command with a 4-byte signed operand. * */ int cmd_4bytes () { void write_DVI_u1(); void write_DVI_s4(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_s4 (cmdargs[1].token.number); return 0; } /* Cmd_VByteS Function ************************************************ */ /* * Process a DVI command with a variable-length signed operand. * */ int cmd_vbytes () { void write_DVI_u1(); void write_DVI_s1(); void write_DVI_s2(); void write_DVI_s3(); void write_DVI_s4(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } if ((cmdargs[1].token.number < -8388608) || (cmdargs[1].token.number >= 8388608)) { write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code - 997); write_DVI_s4 (cmdargs[1].token.number); } else if ((cmdargs[1].token.number < -32768) || (cmdargs[1].token.number >= 32768)) { write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code - 998); write_DVI_s3 (cmdargs[1].token.number); } else if ((cmdargs[1].token.number < -128) || (cmdargs[1].token.number >= 128)) { write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code - 999); write_DVI_s2 (cmdargs[1].token.number); } else { write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code - 1000); write_DVI_s1 (cmdargs[1].token.number); } return 0; } /* Cmd_1ByteU Function ************************************************ */ /* * Process a DVI command with a 1-byte unsigned operand. * */ int cmd_1byteu () { void write_DVI_u1(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_u1 ((unsigned) cmdargs[1].token.number); return 0; } /* Cmd_2ByteU Function ************************************************ */ /* * Process a DVI command with a 2-byte unsigned operand. * */ int cmd_2byteu () { void write_DVI_u1(); void write_DVI_u2(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_u2 ((unsigned) cmdargs[1].token.number); return 0; } /* Cmd_3ByteU Function ************************************************ */ /* * Process a DVI command with a 3-byte unsigned operand. * */ int cmd_3byteu () { void write_DVI_u1(); void write_DVI_u3(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_u3 ((unsigned) cmdargs[1].token.number); return 0; } /* Cmd_VByteU Function ************************************************ */ /* * Process a DVI command with a variable-length unsigned operand. * */ int cmd_vbyteu () { void write_DVI_u1(); void write_DVI_u2(); void write_DVI_u3(); void write_DVI_s4(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } if ((cmdargs[1].token.number >= 16777216) || (cmdargs[1].token.number < 0)) { write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code - 997); write_DVI_s4 ((unsigned) cmdargs[1].token.number); } else if (cmdargs[1].token.number >= 65536) { write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code - 998); write_DVI_u3 ((unsigned) cmdargs[1].token.number); } else if (cmdargs[1].token.number >= 256) { write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code - 999); write_DVI_u2 ((unsigned) cmdargs[1].token.number); } else { write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code - 1000); write_DVI_u1 ((unsigned) cmdargs[1].token.number); } return 0; } /* Cmd_Rule Function ************************************************** */ /* * Process a DVI SET_RULE or PUT_RULE opcode. * */ int cmd_rule () { void write_DVI_u1(); void write_DVI_s4(); if (global.num_tokens != 3) { (void) printf (">>> Improper number of tokens; should be 3.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_s4 (cmdargs[1].token.number); write_DVI_s4 (cmdargs[2].token.number); return 0; } /* Cmd_BOP Function *************************************************** */ /* * Process a DVI BOP opcode. * */ int cmd_bop () { int i; void write_DVI_u1(); void write_DVI_s4(); if (global.num_tokens != 12) { (void) printf (">>> Improper number of tokens; should be 12.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); for (i = 1; i < 12; i++) { write_DVI_s4 (cmdargs[i].token.number); } return 0; } /* Cmd_1XXX Function ************************************************** */ /* * Process a DVI special with a 1-byte length. * */ int cmd_1xxx () { int len; void write_DVI_u1(); void write_DVI(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } len = strlen (cmdargs[1].token.string); if (len > 255) { (void) printf (">>> Special is too long.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_u1 ((unsigned) len); write_DVI ((unsigned char *) cmdargs[1].token.string, len); return 0; } /* Cmd_2XXX Function ************************************************** */ /* * Process a DVI special with a 2-byte length. * */ int cmd_2xxx () { int len; void write_DVI_u1(); void write_DVI_u2(); void write_DVI(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } len = strlen (cmdargs[1].token.string); if (len > 65535) { (void) printf (">>> Special is too long.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_u2 ((unsigned) len); write_DVI ((unsigned char *) cmdargs[1].token.string, len); return 0; } /* Cmd_3XXX Function ************************************************** */ /* * Process a DVI special with a 3-byte length. * */ int cmd_3xxx () { int len; void write_DVI_u1(); void write_DVI_u3(); void write_DVI(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } len = strlen (cmdargs[1].token.string); if (len > 16777215) { (void) printf (">>> Special is too long.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_u3 ((unsigned) len); write_DVI ((unsigned char *) cmdargs[1].token.string, len); return 0; } /* Cmd_4XXX Function ************************************************** */ /* * Process a DVI special with a 4-byte length. * */ int cmd_4xxx () { int len; void write_DVI_u1(); void write_DVI_u4(); void write_DVI(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } len = strlen (cmdargs[1].token.string); write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_u4 ((unsigned) len); write_DVI ((unsigned char *) cmdargs[1].token.string, len); return 0; } /* Cmd_VXXX Function ************************************************** */ /* * Process a DVI special with a variable-length length. * */ int cmd_vxxx () { int len; int cmd_1xxx(); int cmd_2xxx(); int cmd_3xxx(); int cmd_4xxx(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } len = strlen (cmdargs[1].token.string); if (len >= 16777216) { cmdargs[0].token.DVI_code -= 997; return cmd_4xxx (); } if (len >= 65536) { cmdargs[0].token.DVI_code -= 998; return cmd_3xxx (); } if (len >= 256) { cmdargs[0].token.DVI_code -= 999; return cmd_2xxx (); } cmdargs[0].token.DVI_code -= 1000; return cmd_1xxx (); } /* Cmd_1FNT_DEF Function ********************************************** */ /* * Process a DVI FNT_DEF with a 1-byte font number. * */ int cmd_1fnt_def () { int area_len, font_len; void write_DVI_u1(); void write_DVI_s4(); void write_DVI(); if (global.num_tokens != 7) { (void) printf (">>> Improper number of tokens; should be 7.\n"); return 1; } area_len = strlen (cmdargs[5].token.string); if (area_len > 255) { (void) printf (">>> Area name is too long.\n"); return 1; } font_len = strlen (cmdargs[6].token.string); if (font_len > 255) { (void) printf (">>> Font name is too long.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_u1 ((unsigned) cmdargs[1].token.number); write_DVI_s4 (cmdargs[2].token.number); write_DVI_s4 (cmdargs[3].token.number); write_DVI_s4 (cmdargs[4].token.number); write_DVI_u1 ((unsigned) area_len); write_DVI_u1 ((unsigned) font_len); write_DVI ((unsigned char *) cmdargs[5].token.string, area_len); write_DVI ((unsigned char *) cmdargs[6].token.string, font_len); return 0; } /* Cmd_2FNT_DEF Function ********************************************** */ /* * Process a DVI FNT_DEF with a 2-byte font number. * */ int cmd_2fnt_def () { int area_len, font_len; void write_DVI_u1(); void write_DVI_u2(); void write_DVI_s4(); void write_DVI(); if (global.num_tokens != 7) { (void) printf (">>> Improper number of tokens; should be 7.\n"); return 1; } area_len = strlen (cmdargs[5].token.string); if (area_len > 255) { (void) printf (">>> Area name is too long.\n"); return 1; } font_len = strlen (cmdargs[6].token.string); if (font_len > 255) { (void) printf (">>> Font name is too long.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_u2 ((unsigned) cmdargs[1].token.number); write_DVI_s4 (cmdargs[2].token.number); write_DVI_s4 (cmdargs[3].token.number); write_DVI_s4 (cmdargs[4].token.number); write_DVI_u1 ((unsigned) area_len); write_DVI_u1 ((unsigned) font_len); write_DVI ((unsigned char *) cmdargs[5].token.string, area_len); write_DVI ((unsigned char *) cmdargs[6].token.string, font_len); return 0; } /* Cmd_3FNT_DEF Function ********************************************** */ /* * Process a DVI FNT_DEF with a 3-byte font number. * */ int cmd_3fnt_def () { int area_len, font_len; void write_DVI_u1(); void write_DVI_u3(); void write_DVI_s4(); void write_DVI(); if (global.num_tokens != 7) { (void) printf (">>> Improper number of tokens; should be 7.\n"); return 1; } area_len = strlen (cmdargs[5].token.string); if (area_len > 255) { (void) printf (">>> Area name is too long.\n"); return 1; } font_len = strlen (cmdargs[6].token.string); if (font_len > 255) { (void) printf (">>> Font name is too long.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_u3 ((unsigned) cmdargs[1].token.number); write_DVI_s4 (cmdargs[2].token.number); write_DVI_s4 (cmdargs[3].token.number); write_DVI_s4 (cmdargs[4].token.number); write_DVI_u1 ((unsigned) area_len); write_DVI_u1 ((unsigned) font_len); write_DVI ((unsigned char *) cmdargs[5].token.string, area_len); write_DVI ((unsigned char *) cmdargs[6].token.string, font_len); return 0; } /* Cmd_4FNT_DEF Function ********************************************** */ /* * Process a DVI FNT_DEF with a 4-byte font number. * */ int cmd_4fnt_def () { int area_len, font_len; void write_DVI_u1(); void write_DVI_s4(); void write_DVI(); if (global.num_tokens != 7) { (void) printf (">>> Improper number of tokens; should be 7.\n"); return 1; } area_len = strlen (cmdargs[5].token.string); if (area_len > 255) { (void) printf (">>> Area name is too long.\n"); return 1; } font_len = strlen (cmdargs[6].token.string); if (font_len > 255) { (void) printf (">>> Font name is too long.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_s4 (cmdargs[1].token.number); write_DVI_s4 (cmdargs[2].token.number); write_DVI_s4 (cmdargs[3].token.number); write_DVI_s4 (cmdargs[4].token.number); write_DVI_u1 ((unsigned) area_len); write_DVI_u1 ((unsigned) font_len); write_DVI ((unsigned char *) cmdargs[5].token.string, area_len); write_DVI ((unsigned char *) cmdargs[6].token.string, font_len); return 0; } /* Cmd_VFNT_DEF Function ********************************************** */ /* * Process a DVI FNT_DEF with a variable-length font number. * */ int cmd_vfnt_def () { int font; int cmd_1fnt_def(); int cmd_2fnt_def(); int cmd_3fnt_def(); int cmd_4fnt_def(); if (global.num_tokens != 7) { (void) printf (">>> Improper number of tokens; should be 7.\n"); return 1; } font = cmdargs[1].token.number; if ((font >= 16777216) || (font < 0)) { cmdargs[0].token.DVI_code -= 997; return cmd_4fnt_def (); } if (font >= 65536) { cmdargs[0].token.DVI_code -= 998; return cmd_3fnt_def (); } if (font >= 256) { cmdargs[0].token.DVI_code -= 999; return cmd_2fnt_def (); } cmdargs[0].token.DVI_code -= 1000; return cmd_1fnt_def (); } /* Cmd_PRE Function *************************************************** */ /* * Process a DVI PRE opcode. * */ int cmd_pre () { int len; void write_DVI_u1(); void write_DVI_s4(); void write_DVI(); if (global.num_tokens != 6) { (void) printf (">>> Improper number of tokens; should be 6.\n"); return 1; } len = strlen (cmdargs[5].token.string); if (len > 255) { (void) printf (">>> Comment is too long.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_u1 ((unsigned) cmdargs[1].token.number); write_DVI_s4 (cmdargs[2].token.number); write_DVI_s4 (cmdargs[3].token.number); write_DVI_s4 (cmdargs[4].token.number); write_DVI_u1 ((unsigned) len); write_DVI ((unsigned char *) cmdargs[5].token.string, len); return 0; } /* Cmd_POST Function ************************************************** */ /* * Process a DVI POST opcode. * */ int cmd_post () { void write_DVI_u1(); void write_DVI_s4(); void write_DVI_s2(); if (global.num_tokens != 9) { (void) printf (">>> Improper number of tokens; should be 9.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_s4 (cmdargs[1].token.number); write_DVI_s4 (cmdargs[2].token.number); write_DVI_s4 (cmdargs[3].token.number); write_DVI_s4 (cmdargs[4].token.number); write_DVI_s4 (cmdargs[5].token.number); write_DVI_s4 (cmdargs[6].token.number); write_DVI_s2 (cmdargs[7].token.number); write_DVI_s2 (cmdargs[8].token.number); return 0; } /* Cmd_POST_POST Function ********************************************* */ /* * Process a DVI POST_POST opcode. * */ int cmd_post_post () { void write_DVI_s4(); void write_DVI_u1(); if (global.num_tokens != 3) { (void) printf (">>> Improper number of tokens; should be 3.\n"); return 1; } write_DVI_u1 ((unsigned) cmdargs[0].token.DVI_code); write_DVI_s4 (cmdargs[1].token.number); write_DVI_u1 ((unsigned) cmdargs[2].token.number); return 0; } /* Cmd_FILL Function ************************************************** */ /* * Process a DVI FILL command. * */ int cmd_fill () { int count; void write_DVI_u1(); if (global.num_tokens != 2) { (void) printf (">>> Improper number of tokens; should be 2.\n"); return 1; } if (cmdargs[1].token.number <= 0) { (void) printf (">>> Byte boundary must be positive.\n"); return 1; } count = global.current_DVI_position % BLOCKSIZE; if (count == 0) return 0; count = BLOCKSIZE - count; while (count--) { write_DVI_u1 ((unsigned) cmdargs[1].token.DVI_code); } return 0; } /* Write_DVI_S1 Function ********************************************** */ /* * Write a signed 1-byte argument to the DVI file. * */ void write_DVI_s1 (arg) int arg; { unsigned char buffer[1]; void write_DVI(); #if TWOS_COMPLEMENT_MACHINE == 0 unsigned int uarg; unsigned int twos_complement(); #endif #if TWOS_COMPLEMENT_MACHINE buffer[0] = (arg & 0x000000ff); #else if (cmdargs[1].token.number > 0) uarg = arg; else uarg = twos_complement (arg); buffer[0] = (uarg & 0x000000ff); #endif write_DVI (buffer, 1); } /* Write_DVI_S2 Function ********************************************** */ /* * Write a signed 2-byte argument to the DVI file. * */ void write_DVI_s2 (arg) int arg; { unsigned char buffer[2]; void write_DVI(); #if TWOS_COMPLEMENT_MACHINE == 0 unsigned int uarg; unsigned int twos_complement(); #endif #if TWOS_COMPLEMENT_MACHINE buffer[0] = (arg & 0x0000ff00) >> 8; buffer[1] = (arg & 0x000000ff); #else if (cmdargs[1].token.number > 0) uarg = arg; else uarg = twos_complement (arg); buffer[0] = (uarg & 0x0000ff00) >> 8; buffer[1] = (uarg & 0x000000ff); #endif write_DVI (buffer, 2); } /* Write_DVI_S3 Function ********************************************** */ /* * Write a signed 3-byte argument to the DVI file. * */ void write_DVI_s3 (arg) int arg; { unsigned char buffer[3]; void write_DVI(); #if TWOS_COMPLEMENT_MACHINE == 0 unsigned int uarg; unsigned int twos_complement(); #endif #if TWOS_COMPLEMENT_MACHINE buffer[0] = (arg & 0x00ff0000) >> 16; buffer[1] = (arg & 0x0000ff00) >> 8; buffer[2] = (arg & 0x000000ff); #else if (cmdargs[1].token.number > 0) uarg = arg; else uarg = twos_complement (arg); buffer[0] = (uarg & 0x00ff0000) >> 16; buffer[1] = (uarg & 0x0000ff00) >> 8; buffer[2] = (uarg & 0x000000ff); #endif write_DVI (buffer, 3); } /* Write_DVI_S4 Function ********************************************** */ /* * Write a signed 4-byte argument to the DVI file. * */ void write_DVI_s4 (arg) int arg; { unsigned char buffer[4]; void write_DVI(); #if TWOS_COMPLEMENT_MACHINE == 0 unsigned int uarg; unsigned int twos_complement(); #endif #if TWOS_COMPLEMENT_MACHINE buffer[0] = (arg & 0xff000000) >> 24; buffer[1] = (arg & 0x00ff0000) >> 16; buffer[2] = (arg & 0x0000ff00) >> 8; buffer[3] = (arg & 0x000000ff); #else if (cmdargs[1].token.number > 0) uarg = arg; else uarg = twos_complement (arg); buffer[0] = (uarg & 0xff000000) >> 24; buffer[1] = (uarg & 0x00ff0000) >> 16; buffer[2] = (uarg & 0x0000ff00) >> 8; buffer[3] = (uarg & 0x000000ff); #endif write_DVI (buffer, 4); } /* Write_DVI_U1 Function ********************************************** */ /* * Write an unsigned 1-byte argument to the DVI file. * */ void write_DVI_u1 (arg) unsigned int arg; { unsigned char buffer[1]; void write_DVI(); buffer[0] = (arg & 0x000000ff); write_DVI (buffer, 1); } /* Write_DVI_U2 Function ********************************************** */ /* * Write an unsigned 2-byte argument to the DVI file. * */ void write_DVI_u2 (arg) unsigned int arg; { unsigned char buffer[2]; void write_DVI(); buffer[0] = (arg & 0x0000ff00) >> 8; buffer[1] = (arg & 0x000000ff); write_DVI (buffer, 2); } /* Write_DVI_U3 Function ********************************************** */ /* * Write an unsigned 3-byte argument to the DVI file. * */ void write_DVI_u3 (arg) unsigned int arg; { unsigned char buffer[3]; void write_DVI(); buffer[0] = (arg & 0x00ff0000) >> 16; buffer[1] = (arg & 0x0000ff00) >> 8; buffer[2] = (arg & 0x000000ff); write_DVI (buffer, 3); } /* Write_DVI_U4 Function ********************************************** */ /* * Write an unsigned 4-byte argument to the DVI file. * */ void write_DVI_u4 (arg) unsigned int arg; { unsigned char buffer[4]; void write_DVI(); buffer[0] = (arg & 0xff000000) >> 24; buffer[1] = (arg & 0x00ff0000) >> 16; buffer[2] = (arg & 0x0000ff00) >> 8; buffer[3] = (arg & 0x000000ff); write_DVI (buffer, 4); } /* Write_DVI Function ************************************************* */ /* * Output codes to the DVI file. * */ void write_DVI (buffer, length) unsigned char *buffer; int length; { #if WATC == 0 void exit(); #endif #if UTS | CMS | MVS | AOS if (fwrite ((char *)buffer, 1, length, global.out_file) != length) { (void) printf (">>> I/O error writing DVI file.\n"); exit (1); } global.current_DVI_position += length; #endif #if VMS global.current_DVI_position += length; while (length--) { (void) fputc (*buffer++, global.out_file); } #endif } #if MVS == 0 /* Usage Function ***************************************************** */ /* * Print out usage message and exit. * */ void usage () { #if WATC == 0 void exit(); #endif #if CMS (void) printf ("Usage: DVIASM filename [filetype [fm]]\n"); #else (void) printf ("Usage: dviasm input-file-name\n"); #endif exit (1); } #endif /* non-MVS systems */