4.4BSD/usr/src/contrib/dipress/src/bin/ipmetrics/ipmetrics.c
/*
*
* Copyright (c) 1984, 1985, 1986 Xerox Corp.
*
* Owner: Lee Moore
*
* Description:
* This program reads an Interpress file, executes it and produces a
* set of Troff printer description files.
*
* The metrics file will be read from the file "name.ip",
* where name is read from the command line. The ".ip"
* extension will not be added if it is already present in the
* name.
*
* HISTORY
* 18-Aug-86 Lee Moore (lee) at Xerox Webster Research Center
* Moved typesetter specific routine calls to the file "conf.c".
*
* 15-Apr-86 Lee Moore (lee) at Xerox Webster Research Center
* Added table of contents mode (toc).
*
* 04-Feb-86 lee at Xerox, WRC
* Added the ability to execute several masters instead of just one.
*
* 06-Jan-86 Lee Moore(lee) at Xerox, WRC
* Converted for use with ipmetrics.
*/
#include <stdio.h>
#include <strings.h>
#include "stack.h"
#include "token.h"
#include "config.h"
#include "ipmetrics.h"
#include "conf.h"
#define TRUE 1
#define FALSE 0
#define SAME 0
extern struct CompositionSwitch CompositionSwitch[];
extern char *getstring();
extern char *malloc();
extern unsigned char **getvector();
struct FontConfig *ReadConfigFile();
char *LibraryDirectory = "../lib",
LibraryDirStorage[1024];
#define err0 "ipmetrics: No input ip file name!\n"
#define err1 "ipmetrics: ip file could not be found, %s!\n"
FILE *fpin;
int fdout;
char DeviceName1[MAXTOKENSIZE];
char *DeviceName = DeviceName1;
main(argc, argv)
int argc;
char *argv[];
{
int system;
struct FontConfig *configChain;
unsigned char *fontVec;
struct CompositionSwitch *csp;
DebugLevel = 0;
system = getargs(argc, argv);
csp = &CompositionSwitch[system];
if( csp->cs_readConfigFile )
configChain = ReadConfigFile();
fprintf(stderr, "output initialization...\n");
(* csp->cs_initializationProc)(configChain);
/* call the metrics vector processing routine for each font vector */
while (!stackempty()) {
fontVec = pop(0, 0);
(* csp->cs_fontProc)(configChain, fontVec);
free((char *) fontVec); } /* should do a recursive free? */
fprintf(stderr, "cleaning-up...\n");
(* csp->cs_cleanUpProc)(configChain);
fprintf(stderr, "done.\n");
exit(0);
}
/*
* process the command line arguments
*/
getargs(argc, argv)
int argc;
char *argv[];
{
char *filename;
extern int optind;
extern char *optarg;
int system,
c;
char systemName[30];
struct CompositionSwitch *csp;
(void) strcpy(systemName, "troff");
while ((c = getopt(argc, argv, "c:d:")) != EOF)
switch (c) {
case 'd':
(void) strncpy(LibraryDirStorage, optarg, sizeof(LibraryDirStorage));
LibraryDirectory = LibraryDirStorage;
break;
case 'c':
(void) strncpy(systemName, optarg, sizeof(systemName));
break;
default:
printf("ipmetrics: option '%c' not allowed\n");
}
/* look-up system name */
for(csp = CompositionSwitch, system = 0; csp->cs_systemName != NULL; csp++, system++)
if( strncmp(csp->cs_systemName, systemName, sizeof(systemName)) == SAME)
break;
if( csp->cs_systemName == NULL) {
printf("unknown system: %s\n", systemName);
exit(1); }
if (argc == optind) { /* at least one argument */
error(err0);
exit(1);
}
printf("executing...\n");
for( ; optind < argc ; optind++ ) {
/* Open input IP file. */
fdout = 1;
filename = (char *) malloc((unsigned) strlen(argv[optind])+1+strlen(".ip"));
(void) strcpy(filename, argv[optind]);
if (strcmp(".ip", rindex(filename, '.')) != 0)
(void) strcat(filename, ".ip");
fpin = fopen(filename, "r");
if (fpin == NULL) {
fprintf(stderr, err1, filename);
exit(2);
}
printf("\t%s\n", filename); (void) fflush(stdout);
parse(fpin);
}
return system;
}
/*
* read the font configuration file
*/
struct FontConfig *
ReadConfigFile() {
char token[MAXTOKENSIZE];
struct TokenState *ts;
struct FontConfig **last,
*p,
*configChain;
printf("reading configuration file\n");
last = &configChain;
ts = InitTokenStream(stdin);
GetToken(ts, token, MAXTOKENSIZE);
if( strcmp(token, "device") != 0 ) {
fprintf(stderr, "first token is %s, not 'device'\n", token);
exit(1); }
GetToken(ts, DeviceName, MAXTOKENSIZE);
printf("\tdevice is %s\n", DeviceName);
while( !EndOfFile(ts) ) {
p = (struct FontConfig *)
malloc((unsigned) sizeof(struct FontConfig));
GetToken(ts, p->FontPt1, MAXTOKENSIZE);
if( EndOfLine(ts) ) {
fprintf(stderr,
"lines ends prematurely; last token was `%s'\n",
p->FontPt1);
exit(2);}
GetToken(ts, p->FontPt2, MAXTOKENSIZE);
if( EndOfLine(ts) ) {
fprintf(stderr,
"lines ends prematurely; last token was `%s'\n",
p->FontPt2);
exit(2);}
GetToken(ts, p->FontPt3, MAXTOKENSIZE);
if( EndOfLine(ts) ) {
fprintf(stderr,
"lines ends prematurely; last token was `%s'\n",
p->FontPt3);
exit(2);}
GetToken(ts, p->TargetName, MAXTOKENSIZE);
if( !EndOfLine(ts) )
GetToken(ts, p->MapFile, MAXTOKENSIZE);
else
p->MapFile[0] = '\0';
p->Next = NULL;
*last = p;
last = &p->Next;
}
return configChain;
}
/*
* get the font name from a font vector
*/
GetFontNameProperty(fontDescVec, CName)
unsigned char *fontDescVec;
char *CName[3]; {
unsigned char *nameProperty,
**nameVec;
int i;
if( (nameProperty = GetStringProp("name", fontDescVec)) == NULL ) {
printf("ipmetrics: can't find 'name' property\n");
return FALSE;
}
nameVec = getvector(nameProperty);
/* loop for each part of the three part name */
for( i = 0; i < 3; i++ ) {
if( gettype(nameVec[i]) != type_string ) {
printf("name vector not of type string\n");
free((char *) nameVec);
return FALSE;
}
if( getsubtype(nameVec[i]) != subtype_identifier ) {
printf("name subtype not an identifier\n");
free((char *) nameVec);
return FALSE;
}
CName[i] = getstring(nameVec[i], subtype_identifier);
}
free((char *) nameVec);
return TRUE;
}
/*
* get a property off the property-vector whose type is "string"
*/
unsigned char *
GetStringProp(propName, list)
char *propName;
unsigned char *list; {
int i,
vecLength;
char *candidate;
unsigned char **listArray,
*result;
if( gettype(list) != type_vector ) {
printf("ipmetric: non-vector found in stack!\n");
return NULL;}
if( getsubtype(list) != subtype_general ) {
printf("ipmetric: vector sub-type is not 'general'\n");
return NULL; }
if( (vecLength = getdepth(list)) & 01 ) {
printf("ipmetrics: property vector is of odd length\n");
return NULL;}
listArray = getvector(list);
/* cdr down the list */
for( i = 0; i < vecLength; i += 2 ) {
if( ! checktype(listArray[i], type_string, subtype_identifier) ) {
printf("ipmetrics: property of incorrect type\n");
free((char *) listArray);
return NULL;}
candidate = getstring(listArray[i], subtype_identifier);
if( strcmp(propName, candidate) == 0 ) {
result = listArray[i+1];
free((char *) listArray);
return result;
}
}
free((char *) listArray);
return NULL;
}
/*
* get a property from the property-vector that is type "integer"
*/
unsigned char *
GetIntegerProp(property, list)
int property;
unsigned char *list; {
int i,
vecLength;
int candidate;
unsigned char **listArray,
*result;
if( gettype(list) != type_vector ) {
printf("ipmetric: non-vector found in stack!\n");
return NULL;}
if( getsubtype(list) != subtype_general ) {
printf("ipmetric: vector sub-type is not 'general'\n");
return NULL; }
if( (vecLength = getdepth(list)) & 01 ) {
printf("ipmetrics: property vector is of odd length\n");
return NULL;}
listArray = getvector(list);
for( i = 0; i < vecLength; i += 2 ) {
if( ! checktype(listArray[i], type_number, subtype_integer) ) {
printf("ipmetrics: property of incorrect type\n");
free((char *) listArray);
return NULL;}
candidate = getint(listArray[i]);
if( property == candidate ) {
result = listArray[i+1];
free((char *) listArray);
return result;
}
}
free((char *) listArray);
return NULL;
}