home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
APPS
/
lout2.lzh
/
LOUT2
/
z38.c
< prev
next >
Wrap
Text File
|
1994-01-23
|
9KB
|
186 lines
/*@z38.c:Encoding Vectors:Declarations@***************************************/
/* */
/* LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05) */
/* COPYRIGHT (C) 1993 Jeffrey H. Kingston */
/* */
/* Jeffrey H. Kingston (jeff@cs.su.oz.au) */
/* Basser Department of Computer Science */
/* The University of Sydney 2006 */
/* AUSTRALIA */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 1, or (at your option) */
/* any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* */
/* FILE: z38.c */
/* MODULE: Encoding Vectors */
/* EXTERNS: EvLoad(), EvRetrieve(), EvName(), EvPrintAll() */
/* */
/*****************************************************************************/
#include "externs"
#define MAX_EV 20 /* max number of encoding vectors */
#define MAX_CHAR 256 /* max chars represented in one char */
#define MAX_HASH 353 /* size of hash table */
typedef struct evec {
OBJECT file_name; /* name of file containing the vec */
FILE_NUM fnum; /* the file number of this file */
BOOLEAN must_print; /* TRUE if this vec must be printed */
OBJECT name; /* PostScript name of encoding vec */
OBJECT vector[MAX_CHAR]; /* character names */
FULL_CHAR hash_table[MAX_HASH]; /* character hash table for inverse */
} *EVEC;
static EVEC ev_table[MAX_EV]; /* the encoding vectors */
static int evtop = 0; /* first free slot in ev_table[] */
#define hash(str, pos) \
{ FULL_CHAR *p = str; \
for( pos = 2 * *p++; *p; pos += *p++); \
pos = pos % MAX_HASH; \
}
/*@::EvLoad()@****************************************************************/
/* */
/* ENCODING EvLoad(file_name, must_print) */
/* */
/* Declare file_name to be an encoding vector file. A file may be so */
/* declared more than once. If must_print is true on any declaration, */
/* the encoding vector must be down-loaded to the PostScript interpreter. */
/* */
/*****************************************************************************/
ENCODING EvLoad(file_name, must_print)
OBJECT file_name; BOOLEAN must_print;
{ int i; FILE *fp; EVEC ev; char *malloc();
FULL_CHAR buff[30], enc; unsigned int code, pos;
debug2(DEV, D, "EvLoad(%s, %s)", EchoObject(file_name), bool(must_print));
enc = 0;
while( enc < evtop &&
!StringEqual(string(ev_table[enc]->file_name), string(file_name)) )
enc++;
if( enc < evtop )
{
/* encoding vector already loaded, so only need to record must_print */
ev_table[enc]->must_print = ev_table[enc]->must_print || must_print;
Dispose(file_name);
}
else
{
/* initialize new slot in ev_table[] for a new encoding vector */
if( evtop++ == MAX_EV )
Error(FATAL, &fpos(file_name), "too many encoding vectors");
ev_table[enc] = ev = (EVEC) malloc( sizeof(struct evec) );
if( ev == (EVEC) NULL ) Error(FATAL, &fpos(file_name),
"run out of memory when loading encoding vector");
ev->must_print = must_print;
ev->file_name = file_name;
for( i = 0; i < MAX_CHAR; i++ ) ev->vector[i] = nil;
for( i = 0; i < MAX_HASH; i++ ) ev->hash_table[i] = 0;
/* define and open the file */
ev->fnum = DefineFile(string(file_name), STR_EMPTY, &fpos(file_name),
ENCODING_FILE, ENCODING_PATH);
fp = OpenFile(ev->fnum, FALSE, FALSE);
if( fp == NULL ) Error(FATAL, PosOfFile(ev->fnum),
"cannot open encoding vector file %s", FileName(ev->fnum));
/* invent a PostScript name for the encoding vector */
StringCopy(buff, AsciiToFull("vec"));
StringCat(buff, StringInt(evtop));
ev->name = MakeWord(WORD, buff, no_fpos);
/* read character names and insert (name, position) pairs into hash table */
for( code = 0; fscanf(fp, "%s", buff) == 1; code++ )
{ if( code >= MAX_CHAR ) Error(FATAL, PosOfFile(ev->fnum),
"too many character names in encoding vector file %s",
FileName(ev->fnum));
hash(buff, pos);
while( (i = ev->hash_table[pos]) != 0 )
{ if( StringEqual(string(ev->vector[i]), buff) )
{ ev->vector[code] = ev->vector[i];
break;
}
pos = (pos + 1) % MAX_HASH;
}
if( i == 0 )
{ ev->vector[code] = MakeWord(WORD, buff, no_fpos);
ev->hash_table[pos] = (FULL_CHAR) code;
}
}
if( code != MAX_CHAR ) Error(FATAL, PosOfFile(ev->fnum),
"too few character names in encoding vector file %s",
FileName(ev->fnum));
}
debug1(DEV, D, "EvLoad returning %d", enc);
return enc;
} /* end EvLoad */
/*@::EvRetrieve(), EvName(), EvPrintAll()@************************************/
/* */
/* FULL_CHAR EvRetrieve(str, enc) */
/* */
/* Returns the character code corresponding to character name str in */
/* ENCODING enc, or 0 if not found. */
/* */
/*****************************************************************************/
FULL_CHAR EvRetrieve(str, enc)
FULL_CHAR *str; ENCODING enc;
{ unsigned int pos; FULL_CHAR code; EVEC ev;
ev = ev_table[enc];
hash(str, pos);
while( (code = ev->hash_table[pos]) != 0 )
{ if( StringEqual(string(ev->vector[code]), str) ) return code;
pos = (pos + 1) % MAX_HASH;
}
return '\0';
} /* end EvRetrieve */
/*****************************************************************************/
/* */
/* FULL_CHAR *EvName(enc) */
/* */
/* Returns the PostScript name of ENCODING enc */
/* */
/*****************************************************************************/
FULL_CHAR *EvName(enc)
ENCODING enc;
{ assert( enc < evtop, "EvName: enc out of range!" );
return string(ev_table[enc]->name);
} /* end EvName */
/*****************************************************************************/
/* */
/* EvPrintAll(fp) */
/* */
/* Print all encoding vectors in PostScript form on file fp. */
/* */
/*****************************************************************************/
EvPrintAll(fp)
FILE *fp;
{ ENCODING enc; EVEC ev; int i;
for( enc = 0; enc < evtop; enc++ ) if( ev_table[enc]->must_print )
{ ev = ev_table[enc];
fprintf(fp, "/%s [\n", string(ev->name));
for( i = 0; i < MAX_CHAR; i++ )
fprintf(fp, "/%s%c", string(ev->vector[i]), (i+1) % 8 != 0 ? ' ' : '\n');
fprintf(fp, "] def\n\n");
}
} /* end EvPrintAll */