home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
517a.lha
/
FontManipulatorForDtp_v2
/
source
/
mkatc
/
mkatc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-09
|
19KB
|
702 lines
/* CGFont .atc file builder for PPage etc. File "mkatc.c".
* (C) Adrian Aylward 1991
*
* You may freely copy, use, and modify this file.
*
* This program prints builds a CGFont encoding (.atc) file in the format
* used by Professional Page from a PostScript style encoding table.
*
* The program was tested using Lattice C V5.05. It has various Lattice
* dependencies.
*
* This is version 1.0.
*/
# include <dos.h>
# include <exec/exec.h>
# include <proto/dos.h>
# include <proto/exec.h>
# include <string.h>
# include <setjmp.h>
# include <stdio.h>
/* Atc file format */
struct atcfile
{ int af_uid;
unsigned short af_code[256];
};
/* External data (initialised to zero) */
char *argatcfile;
char *argencodingfile, *argcharcodefile;
int optread, optverify, optuid;
int uid;
int lochar, hichar;
BPTR newfh;
int retcode;
# define memsize 10000
char *membeg[100], *memptr;
int memsegs, memfree;
struct atcmem
{ struct atcfile file;
int dummy;
};
struct atcmem atcmem;
struct charentry
{ short code;
char *str;
};
# define charcodesize 2000
struct charentry charcode[charcodesize];
int charcodelen;
char *currentfile;
FILE *currentfptr;
# define NOURCH (EOF - 1)
int lineno, urch;
int scanmode;
int retcode;
jmp_buf errjmp;
# define typeeof 0
# define typeeol 1
# define typesemi 2
# define typepercent 3
# define typename 4
# define typeint 5
int tokentype, tokenival;
char namebuf[256];
/* Encoding vector, initially Adobe StandardEncoding */
char *encoding[256] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
"space", "exclam", "quotedbl", "numbersign", /* 20 */
"dollar", "percent", "ampersand", "quoteright",
"parenleft", "parenright", "asterisk", "plus",
"comma", "hyphen", "period", "slash",
"zero", "one", "two", "three", /* 30 */
"four", "five", "six", "seven",
"eight", "nine", "colon", "semicolon",
"less", "equal", "greater", "question",
"at", "A", "B", "C", /* 40 */
"D", "E", "F", "G",
"H", "I", "J", "K",
"L", "M", "N", "O",
"P", "Q", "R", "S", /* 50 */
"T", "U", "V", "W",
"X", "Y", "Z", "bracketleft",
"backslash", "bracketright", "asciicircum", "underscore",
"quoteleft", "a", "b", "c", /* 60 */
"d", "e", "f", "g",
"h", "i", "j", "k",
"l", "m", "n", "o",
"p", "q", "r", "s", /* 70 */
"t", "u", "v", "w",
"x", "y", "z", "braceleft",
"bar", "braceright", "asciitilde", 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, "exclamdown", "cent", "sterling", /* A0 */
"fraction", "yen", "florin", "section",
"currency", "quotesingle", "quotedblleft", "guillemotleft",
"guilsinglleft", "guilsinglright","fi", "fl",
0, "endash", "dagger", "daggerdbl", /* B0 */
"periodcentered",0, "paragraph", "bullet",
"quotesinglbase","quotedblbase", "quotedblright", "guillemotright",
"ellipsis", "perthousand", 0, "questiondown",
0, "grave", "acute", "circumflex", /* C0 */
"tilde", "macron", "breve", "dotaccent",
"dieresis", 0, "ring", "cedilla",
0, "hungarumlaut", "ogonek", "caron",
"emdash", 0, 0, 0, /* D0 */
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, "AE", 0, "ordfeminine",/* E0 */
0, 0, 0, 0,
"Lslash", "Oslash", "OE", "ordmasculine",
0, 0, 0, 0,
0, "ae", 0, 0, /* F0 */
0, "dotlessi", 0, 0,
"lslash", "oslash", "oe", "germandbls",
0, 0, 0, 0
};
/* Routines */
extern int strtoint(char **sp, int *ip);
extern void readencoding(void);
extern void readcharcode(void);
extern void rdtoken(void);
extern void skipeol(void);
extern void skipspace(void);
extern int rdch(void);
extern void unrdch(int ch);
extern void errsyntax(char *f);
extern void errmemory(void);
extern char *makestring(char *str);
extern void *allocmem(int size);
extern void freeall(void);
extern void stub(void);
extern void chkabort(void);
/* Main program */
void main(int argc, char **argv)
{ char *s;
int *ip, i, j, ch;
/* Parse arguments. No workbench startup */
lochar = 32;
hichar = 255;
if (argc == 0) goto tidyexit;
argv++;
argc--;
if (argc == 0 || (argc == 1 && strcmp(*argv, "?") == 0)) goto query;
while (argc)
{ s = *argv;
if (*s != '-') break;
argv++;
argc--;
if (strcmp(s, "--") == 0) break;
s++;
for (;;)
{ ch = *s++;
if (ch == 0) break;
switch (ch)
{ case 'E': case 'e':
if (argc == 0) goto badargs;
argencodingfile = *argv++;
argc--;
continue;
case 'C': case 'c':
if (argc == 0) goto badargs;
argcharcodefile = *argv++;
argc--;
continue;
case 'U': case 'u':
optuid = 1;
ip = &uid;
break;
case 'R': case 'r':
optread = 1;
continue;
case 'v':
optverify = 1;
continue;
case 'V':
optverify = 2;
continue;
case 'L': case 'l':
ip = &lochar;
break;
case 'H': case 'h':
ip = &hichar;
break;
default:
fprintf(stderr, "mkatc: unknown option \"-%c\"", ch);
goto badusage;
}
if (!strtoint(&s, ip)) goto badargs;
}
if (*s == '-' && *(s + 1) == 0) break;
}
if (lochar > hichar || hichar > 255)
{ fprintf(stderr, "mkatc: LoChar/HiChar out of range "
"(0 <= Lo <= Hi <= 255)\n");
goto errorexit;
}
if (argc != 1) goto badargs;
argatcfile = argv[0];
if (argencodingfile == NULL) argencodingfile = "PSFonts:encoding.ps";
if (argcharcodefile == NULL) argcharcodefile = "CGFonts:cgcharcodes";
/* Read the encoding file */
if (optread) goto skipenc;
currentfile = argencodingfile;
currentfptr = fopen(currentfile, "r");
if (currentfptr == NULL)
{ fprintf(stderr, "mkatc: can't open encoding file %s\n", currentfile);
goto errorexit;
}
readencoding();
if (retcode != 0) goto errorexit;
fclose(currentfptr);
currentfptr = NULL;
/* Read the charcode file */
skipenc:
currentfile = argcharcodefile;
currentfptr = fopen(currentfile, "r");
if (currentfptr == NULL)
{ fprintf(stderr, "mkatc: can't open charcode file %s\n", currentfile);
goto errorexit;
}
readcharcode();
if (retcode != 0) goto errorexit;
fclose(currentfptr);
currentfptr = NULL;
/* Read the old .atc file */
if (optread || !optuid)
{ newfh = Open(argatcfile, MODE_OLDFILE);
if (newfh == NULL)
{ fprintf(stderr, "mkatc: can't open atc file %s\n",
argatcfile);
goto errorexit;
}
i = Read(newfh, (UBYTE *) &atcmem, sizeof (atcmem));
Close(newfh);
if (i == -1)
{ fprintf(stderr, "mkatc: error reading atc file %s\n",
argatcfile);
goto errorexit;
}
if (i != sizeof (struct atcfile))
{ fprintf(stderr, "mkatc: atc file %s format error\n",
argatcfile);
goto errorexit;
}
}
/* Update the uid */
if (optuid) atcmem.file.af_uid = uid;
if (optverify)
fprintf(stdout, "% file \"%s\" uid = %d\n",
argatcfile, atcmem.file.af_uid);
/* If reading, we look up the codes in the charcodes */
if (optread)
{ for (i = 0; i < 256; i++)
{ ch = atcmem.file.af_code[i];
if (ch != 0)
{ for (j = 0; j < charcodelen; j++)
if (charcode[j].code == ch)
{ s = charcode[j].str;
goto gotit1;
}
fprintf(stderr, "mkatc: character %4d "
"not in charcodes, name unknown\n", ch);
retcode = 5;
s = "NULL";
gotit1: if (optverify == 1)
fprintf(stdout, "%3d /%-20s %% %4d\n", i, s, ch);
if (optverify == 2)
fprintf(stdout, " %-20s %3d %4d\n", s, i, ch);
}
}
}
/* If writing, we look up the names in the charcodes */
else
{ for (i = 0; i < 256; i++)
{ ch = 0;
if (i >= lochar && i <= hichar)
{ s = encoding[i];
if (s != NULL)
{ for (j = 0; j < charcodelen; j++)
if (strcmp(charcode[j].str, s) == 0)
{ ch = charcode[j].code;
if (ch == 0) goto skipv2;
goto gotit2;
}
fprintf(stderr, "mkatc: character \"%s\" "
"not in charcodes, omitted\n", s);
retcode = 5;
gotit2: if (optverify == 1)
fprintf(stdout, "%3d /%-20s %% %4d\n", i, s, ch);
if (optverify == 2)
fprintf(stdout, " %-20s %3d %4d\n", s, i, ch);
}
}
skipv2: atcmem.file.af_code[i] = ch;
}
}
/* Write out the new .atc file */
if (!optread)
{ newfh = Open(argatcfile, MODE_NEWFILE);
if (newfh == NULL)
{ fprintf(stderr, "mkatc: can't open atc file %s\n",
argatcfile);
goto errorexit;
}
i = Write(newfh, (UBYTE *) &atcmem, sizeof (struct atcfile));
Close(newfh);
if (i != sizeof (struct atcfile))
{ fprintf(stderr, "mkatc: error writing atc file %s\n",
argatcfile);
goto errorexit;
}
}
goto tidyexit;
/* Argument errors and usage query */
query:
fprintf(stderr, "Atc file builder. MkAtc version 1.0\n"
"Makes CGFont .atc files from the encoding file\n"
"\n"
" Usage:\n"
"\n"
" mkatc -options atcfile\n"
"\n"
" -e encodingfile Encoding file name\n"
" -c charcodesfile Character codes file name\n"
" -lnnn LoChar\n"
" -hnnn Hichar\n"
" -unnn Unique id\n"
" -r Read .atc file, do not update\n"
" -v Verify encoding table\n"
" -V Verify encoding, "
"alternative format\n"
"\n"
" For example:\n"
"\n"
" mkatc cgfonts:Times.atc\n");
goto tidyexit;
badargs:
fprintf(stderr, "mkatc: arguments bad, or value missing");
badusage:
retcode = 20;
fprintf(stderr, ". Usage:\n"
" mkatc -options atcfile\n");
goto tidyexit;
/* Tidy up and exit */
broken:
fprintf(stderr, "mkatc: *** Break\n");
retcode = 10;
goto tidyexit;
errorexit:
retcode = 20;
tidyexit:
if (currentfptr) fclose(currentfptr);
currentfptr = NULL;
freeall();
exit(retcode);
}
/* String to integer conversion; digits only, with error check */
int strtoint(char **sp, int *ip)
{ char *s = *sp;
int i = 0;
int ch;
for (;;)
{ ch = *s;
if (ch < '0' || ch > '9') break;
i = i * 10 + (ch - '0');
s++;
}
if (s == *sp)
return 0;
else
{ *sp = s;
*ip = i;
return 1;
}
}
/* Read the encoding file */
void readencoding(void)
{ char *str;
int ch;
lineno = 1;
urch = NOURCH;
retcode = setjmp(errjmp);
if (retcode != 0) return;
for (;;)
{ rdtoken();
if (tokentype == typeeof) break;
if (tokentype == typeeol) continue;
if (tokentype != typeint) errsyntax("integer expected");
ch = tokenival;
rdtoken();
if (tokentype != typename) errsyntax("name expected");
if (namebuf[0] == '/')
str = makestring(&namebuf[1]);
else
str = makestring(&namebuf[0]);
rdtoken();
if (tokentype != typeeol) errsyntax("end of line expected");
if (ch < 0 || ch > 255)
errsyntax("character code out of range");
if (strcmp(str, ".notdef") != 0) encoding[ch] = str;
}
}
/* Read the charcode file */
void readcharcode(void)
{ char *str;
int ch;
lineno = 1;
urch = NOURCH;
retcode = setjmp(errjmp);
if (retcode != 0) return;
for (;;)
{ rdtoken();
if (tokentype == typeeof) break;
if (tokentype == typeeol) continue;
if (tokentype != typeint) errsyntax("integer expected");
ch = tokenival;
rdtoken();
if (tokentype != typename) errsyntax("name expected");
if (namebuf[0] == '/')
str = makestring(&namebuf[1]);
else
str = makestring(&namebuf[0]);
rdtoken();
if (tokentype != typeeol) errsyntax("end of line expected");
if (ch < 0 || ch > 65535)
errsyntax("character code out of range");
if (charcodelen >= charcodesize)
errsyntax("too many characters");
charcode[charcodelen].code = ch;
charcode[charcodelen].str = str;
charcodelen++;
}
}
/* Read the next token */
void rdtoken(void)
{ int val, i, j, ch;
skipspace();
i = 0;
for (;;)
{ ch = rdch();
if (ch == EOF)
{ if (i == 0)
{ tokentype = typeeof;
return;
}
else
break;
}
if (ch == '%')
{ if (i == 0)
{ skipeol();
tokentype = typeeol;
return;
}
else
break;
}
if (ch == '\n')
{ if (i == 0)
{ tokentype = typeeol;
return;
}
else
break;
}
if (ch == ' ' || ch == '\t') break;
if (i >= 255) errsyntax("token too long");
namebuf[i++] = ch;
}
namebuf[i] = 0;
unrdch(ch);
tokentype = typename;
{ j = 0;
if (namebuf[0] == '-')
{ j++;
if (i <= j) return;
}
val = 0;
while (j < i)
{ ch = namebuf[j];
if (ch < '0' || ch > '9') return;
val = val * 10 + (ch - '0');
j++;
}
if (namebuf[0] == '-') val = -val;
tokentype = typeint;
tokenival = val;
}
}
/* Skip to end of line */
void skipeol(void)
{ int ch;
for (;;)
{ ch = rdch();
if (ch == EOF)
{ unrdch(EOF);
break;
}
if (ch == '\n') break;
}
}
/* Skip white space */
void skipspace(void)
{ int ch;
for (;;)
{ ch = rdch();
if (ch != ' ' && ch != '\t') break;
}
unrdch(ch);
}
/* Read next character */
int rdch(void)
{ int ch;
if (urch == NOURCH)
{ ch = getc(currentfptr);
if (ch == EOF)
{ if (ferror(currentfptr)) errsyntax("file read error");
return EOF;
}
if (ch == '\n')
{ ch = getc(currentfptr);
if (ch != '\r' && ch != EOF) ungetc(ch, currentfptr);
ch = '\n';
lineno++;
}
else if (ch == '\r')
{ ch = '\n';
lineno++;
}
}
else
{ ch = urch;
urch = NOURCH;
}
return ch;
}
/* Unread last character */
void unrdch(int ch)
{ urch = ch;
}
/* Syntax error */
void errsyntax(char *str)
{ fprintf(stderr, "mkatc: syntax error in \"%s\", line %d - %s\n",
currentfile, lineno, str);
longjmp(errjmp, 20);
}
/* Memory allocation error */
void errmemory(void)
{ fprintf(stderr, "mkatc: memory exhausted\n");
longjmp(errjmp, 20);
}
/* Make a string */
char *makestring(char *str)
{ char *s;
s = allocmem(strlen(str) + 1);
if (s == NULL) errmemory();
strcpy(s, str);
return s;
}
/* Allocate memory */
void *allocmem(int size)
{ char *ptr;
int msize;
msize = (size + 3) & ~3;
if (msize > memfree)
{ if (msize > memsize) return NULL;
if (memsegs == 100) return NULL;
ptr = AllocMem(memsize, MEMF_CLEAR);
if (ptr == NULL) return NULL;
membeg[memsegs++] = ptr;
memptr = ptr;
memfree = memsize;
}
ptr = memptr;
memfree -= msize;
memptr += msize;
return (void *) ptr;
}
/* Free all memory */
void freeall(void)
{ while (memsegs)
{ memsegs--;
FreeMem(membeg[memsegs], memsize);
}
}
/* Dummy stub routine */
void stub(void)
{ return;
}
/* Dummy check abort routine */
void chkabort(void)
{ return;
}
/* End of file "mkatc.c" */