This example shows how print formatters can interact with the documented printer formatter subroutines. The procedure for writing a print formatter involves four steps:
Use an ASCII editor to create a formatter source file named sample.c. The file should contain the following lines:
#include <stdio.h> #include <piostruct.h> /* STRING CONSTANTS */ /* Initialize Printer, Restore Printer, Form Feed */ #define INIT_CMD "ci" #define REST_CMD "cr" #define FF_CMD "af"
/* INTEGER and STRING VARIABLES */ /* page length, page width, top margin, bottom margin */ #define Pglen (*(_Pglen + piomode)) #define Pgwidth (*(_Pgwidth + piomode)) #define Tmarg (*(_Tmarg + piomode)) #define Bmarg (*(_Bmarg + piomode))
/* indentation, begin page, form feed?, pass-through? */ #define Indent (*(_Indent + piomode)) #define Beginpg (*(_Beginpg + piomode)) #define Do_formfeed (*(_Do_formfeed + piomode)) #define Passthru (*(_Passthru + piomode))
/* initialize printer?, restore printer? */ #define Init_printer (*(_Init_printer + piomode)) #define Restoreprinter (*(_Restoreprinter + piomode))
/* Command names: form feed, vertical increment and decrement */ #define Ff_cmd (*(_Ff_cmd + piomode)) #define Vincr_cmd (*(_Vincr_cmd + piomode)) #define Vdecr_cmd (*(_Vdecr_cmd + piomode))
/* Work variables for vertical increment and decrement */ #define Vincr (*(_Vincr + piomode)) #define Vdecr (*(_Vdecr + piomode))
/* Variables referenced by above #defines */ int *_Pglen, *_Pgwidth, *_Tmarg, *_Bmarg, *_Indent, *_Beginpg, *_Do_ formfeed, *_Passthru, *_Init_printer, *_Restoreprinter, *_Vincr, *_V decr; struct str_info *_Ff_cmd, *_Vincr_cmd, *_Vdecr_cmd;
/* TABLE OF ATTRIBUTE VALUES */ struct attrparms attrtable[] = { /* name data type lookup address of pointer */ "_b", VAR_INT, NULL, (union dtypes *) &_Bmarg, "_g", VAR_INT, NULL, (union dtypes *) &_Beginpg, "_i", VAR_INT, NULL, (union dtypes *) &_Indent, "_j", VAR_INT, NULL, (union dtypes *) &_Init_printer, "_l", VAR_INT, NULL, (union dtypes *) &_Pglen, "_t", VAR_INT, NULL, (union dtypes *) &_Tmarg, "_w", VAR_INT, NULL, (union dtypes *) &_Pgwidth, "_J", VAR_INT, NULL, (union dtypes *) &_Restoreprinter, "_Z", VAR_INT, NULL, (union dtypes *) &_Do_formfeed, "wp", VAR_INT, NULL, (union dtypes *) &_Passthru, "wf", VAR_STR, NULL, (union dtypes *) &_Ff_cmd, "wi", VAR_STR, NULL, (union dtypes *) &_Vincr_cmd, "wy", VAR_STR, NULL, (union dtypes *) &_Vdecr_cmd, "wV", VAR_INT, NULL, (union dtypes *) &_Vincr, "wD", VAR_INT, NULL, (union dtypes *) &_Vdecr, NULL, 0 , NULL, NULL }; int pglen, tmarg, bmarg, vpos, vtab_base; struct shar_vars sharevars;
struct shar_vars * /*** Setup Processing ***/ setup(argc, argv, passthru) unsigned argc; char *argv[]; int passthru: {
/* Initialize variables and command line values */ (void) piogetvals(attrtable, NULL); (void) piogetopt(argc, argv, NULL, NULL); /* (need to verify values entered by user) */
/* Initialize work variables */ pglen = Pglen * Vincr; tmarg = Tmarg * Vincr; bmarg = Bmarg * Vincr; piopgskip = Beginpg - 1;
/* Check for pass-through option */ if (Passthru = passthru) return(NULL);
/* Initialize pointers to vertical spacing */ /* variables shared with formatter driver */ /* (Refer to /usr/include/piostruct.h) */ sharevars._pl = &pglen; sharevars._tmarg = &tmarg; sharevars._bmarg = &bmarg; sharevars._vpos = &vpos; sharevars._vtab_base = &vtab_base; sharevars._vincr = &Vincr; sharevars._vincr_cmd = (&Vincr_cmd)->ptr; sharevars._vdecr = &Vdecr; sharevars._vdecr_cmd = (&Vdecr_cmd)->ptr; sharevars._ff_cmd = (&Ff_cmd)->ptr; sharevars._ff_at_eof = &Do_formfeed; return(&sharevars); }
initialize() /*** Initialize the Printer ***/ { if (Init_printer) (void) piocmdout(INIT_CMD, NULL, 0, NULL); return(0); }
lineout(fileptr) /*** Format a Line ***/ FILE *fileptr; { int ch, charcount = 0; for (ch = 0; ch < Indent; ch++) pioputchar(' '); while ((ch=piogetc(fileptr)) != '\n' && ch != EOF && charcount < Pgwidth) { charcount++; pioputchar(c); } vpos += Vincr; return(charcount); }
passthru() /*** Pass-through Option ***/ { int ch; while ((ch = piogetc(stdin)) != EOF) pioputchar(ch); if (piodatasent && Do_formfeed) (void) piocmdout(FF_CMD, NULL, 0, NULL); return(0); }
restore() /*** Restore the Printer ***/ { if (Restoreprinter) (void) piocmdout(REST_CMD, NULL, 0, NULL); return(0); }
Use an editor to create an imports file named sample.imp. The file should contain the following:
#! main piogetvals piogetopt piomsgout pioexit piomode piodatasent piopgskip statusfile piocmdout piogetstr
Use an editor to create an exports file named sample.exp. The file should contain the following:
#! setup initialize passthru restore lineout
Enter the following to compile and link the formatter:
cc -o sample -bI:sample.imp -bE:sample.exp sample.c