home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
443.lha
/
pcl2english_v2.0
/
utils.c
< prev
Wrap
C/C++ Source or Header
|
1990-12-02
|
10KB
|
431 lines
/* $RCSfile: utils.c,v $ $Revision: 2.0 $ */
#include <stdio.h>
#include "gdefs.h"
#include "externals.h"
#include "protos.h"
extern FILE *ifile,*ofile;
static int begin_or_end = FALSE; /* Variable used between
print_char and print_chars */
void err_exit(int x)
{
printf(err_msg[x]);
exit(x);
}
void print_hex(int i)
{
if ((i>=0) && (i<=9)) {
fputc(i+'0',ofile);
}
else if ((i>=10) && (i<=15)) {
fputc(i+'A'-10,ofile);
}
else printf("\nERROR: i= %d\n",i);
}
void output_byte(int c)
{
int i,j,k;
i=c;
j=i / 16;
k=i % 16;
print_hex(j);
print_hex(k);
}
void indent(int x)
{
int i;
/* Default is to indent 4 spaces */
if (x != 0) {
for (i=0; i<x; i++) {
/* Insert favorite tabbing style */
fprintf(ofile," ");
}
}
}
/* ROUTINE: print_esc_string
*
* This routine prints the entire escape sequence string. If the
* hex option is used, a hex printout of the string is also given.
*/
void print_esc_string(void)
{
fprintf(ofile,"\n<Esc>%s\n", &esc_string[1]);
if (opt_x) {
int i,j;
/* Print the characters in hex */
for (i=0; i <= esc_count; i++) {
j = 0xff & esc_string[i];
output_byte(j);
fprintf(ofile," ");
}
fprintf(ofile,"\n");
}
}
/* ROUTINE: print_sub_string
*
* This routine prints part of the escape sequence string.
* This consists of the "header" which is the first header characters
* after the escape. Then the string between start and stop is printed.
*/
void print_sub_string(int header, int start, int stop)
{
int i;
char s[255];
char *ptr_c;
ptr_c = s;
for (i=1; i<=header; i++) {
*ptr_c++ = esc_string[i];
}
for (i=start; i<=stop; i++) {
*ptr_c++ = esc_string[i];
}
*ptr_c = 0;
indent(1);
fprintf(ofile,"<Esc>%-6s ", s);
}
/* ROUTINE: get_num
*
* Convert an alpha number sequence to an actual int.
*
* Variables used:
* stop_pos -- *stop_pos contains the starting point on
* entry and is updated to the new "stop point"
* before exiting.
* num -- global variable used to return the integer value.
* fraction -- global string used to return fractional part (if exists)
* is_float -- global flag to say that fractional part exists.
* plus -- global flag to say number started with a '+' sign.
* minus -- global flag to say number started with a '-' sign.
*
* NOTES:
* Pcl assumes a zero if no number is given. Thus, this routine returns
* a zero if '0' is encountered or if no digits are encountered.
*
* If the fractional part of a floating point number is zero, the
* number will be treated like an int.
*/
void get_num(int *stop_pos, int sum)
{
char c;
int done;
int i,j;
i = *stop_pos;
c = esc_string[i];
plus = minus = is_float = FALSE;
if (c == '-') {
minus = TRUE;
i++;
}
else if (c == '+') {
i++;
plus = TRUE;
}
done = FALSE;
while (done == FALSE) {
c = esc_string[i];
if ((c >= '0') && (c <= '9')) {
sum *= 10;
sum += c - '0';
i++;
}
else done = TRUE;
}
if (c == '.') {
i++;
done = FALSE;
j = 0;
while (done == FALSE) {
c = esc_string[i];
if ((c >= '0') && (c <= '9')) {
fraction[j] = c;
i++;
j++;
}
else done = TRUE;
}
/* Remove trailing 0's and see if anything's left */
if (j > 0) {
done = FALSE;
while (done == FALSE) {
fraction[j] = 0;
if ((j == 0) || (fraction[j-1] != '0')) {
done = TRUE;
}
else {
j--;
}
}
if (j != 0) {
is_float = TRUE;
}
}
}
*stop_pos = i;
if (minus) {
sum = -sum;
}
num = sum;
}
/*
* ROUTINE: decode_esc_string
*
* This routine provides the first level of decoding for an escape
* string. If it is a simple 2 character escape sequence, it is
* handled here. Otherwise, the appropriate lower level routine
* is called.
*/
void decode_esc_string(void)
{
char c;
c = esc_string[1];
if (esc_count == 1) {
indent(1);
fprintf(ofile,"<Esc>%-6s ", &esc_string[1]);
switch (c) {
case '9':
fprintf(ofile,
"Reset Left and Right Margins to default settings.\n");
break;
case '=':
fprintf(ofile,"Half Line Feed. Move down one-half line.\n");
break;
case 'E':
fprintf(ofile,"Reset to user defaults.\n");
indent(4);
fprintf(ofile,
"Print buffered page. Delete temporary fonts and macros.\n");
break;
case 'Y':
fprintf(ofile,"Display Functions ON.\n");
break;
case 'Z':
fprintf(ofile,"Display Functions OFF.\n");
break;
case 'z':
fprintf(ofile,"Print Self Test.\n");
break;
default:
fprintf(ofile,"%s",bad_esc);
break;
}
}
else {
switch (c) {
case '(':
case ')':
decode_paren();
break;
case '&':
decode_ampersand();
break;
case '*':
decode_asterisk();
break;
default:
fprintf(ofile,"%s",bad_esc);
break;
}
}
}
/* ROUTINE: add_char
*
* This routine places a character into a buffer when we are in
* character mode. The idea is to store the first (typically 10)
* characters and last (again typically 10) characters. Thus, if
* we encounter a big text section, we don't have to print the whole
* thing. The first characters are placed in the char_start
* array. The last characters are placed in the char_end array which
* is a circular buffer.
*/
void add_char(int c)
{
if (opt_e == FALSE) {
if (char_count <= CHAR_START_LEN + CHAR_END_LEN - 1) {
char_start[char_count] = c;
}
if (char_count >= CHAR_START_LEN) {
char_end[(char_count - CHAR_START_LEN) % CHAR_END_LEN] = c;
}
char_count++;
}
}
/* ROUTINE: print_extra_rasters
*
* Raster images are printed a line at a time. Rather than print
* each raster escape sequence, the first is simply printed, and
* all others that follow of the same size are counted, and the
* additional count is printed with this routine.
*/
void print_extra_rasters(void)
{
if ((raster_mode != NO_RASTER) && (raster_count > 0)) {
indent(1);
fprintf(ofile,"%d same size raster commands follow.\n",raster_count);
}
raster_mode = NO_RASTER;
raster_count = 0;
}
/* ROUTINE: print_char
*
* This routine prints a character that was encountered in character
* mode. Some special characters are expressed mnemonically between
* brackets. Other (typically) non-printing characters are represented
* by their hex character codes in brackets. The space character gets
* some extra special treatment. In cases at the beginning or end of
* strings, where it might not be visually obvious, a <SP> is printed
* instead. The begin_or_end variable is used between this routine
* and print_chars to convey this information and is always cleared
* on exit from this routine.
*/
void print_char(char c)
{
char s[2];
switch (c) {
case CARRIAGE_RETURN:
fprintf(ofile,"<CR>");
break;
case LINE_FEED:
fprintf(ofile,"<LF>");
break;
case BACK_SPACE:
fprintf(ofile,"<BS>");
break;
case TAB:
fprintf(ofile,"<TAB>");
break;
case ' ':
if (begin_or_end) {
fprintf(ofile,"<SP>");
}
else {
fprintf(ofile," ");
}
break;
default:
if (((c >= 32) && (c <= 127)) || ((c >= 161) && (c <= 254))) {
s[0]=c;
s[1]=0;
fprintf(ofile,"%s",s);
}
else {
/* Non-printing characters in Roman-8 character set */
/* Hopefully one won't see much of these */
fprintf(ofile,"<0x%x>",0xff & c);
}
break;
}
begin_or_end = FALSE;
}
/*
* ROUTINE: print_chars
* Prints the first (10) characters and last (10) characters of text
*
* NOTES:
* Uses the following forms:
* <=20 chars "123456789ab"
* >20 chars "123456789a ... 123456789a"
* Will also print additional line info when lines have been skipped.
* Special characters will come out between <>'s. If you are unsure
* if <>'s were in your text, count the number of characters printed.
* Spaces on "ends" of text will come out as <SP>.
* The actual number of characters printed depends on CHAR_START_LEN
* and CHAR_END_LEN.
* Will print the hex equivalents if -x option used.
*/
void print_chars(void)
{
int i,j,k;
print_extra_rasters();
if (opt_e == FALSE) {
if (char_count > 0) {
fprintf(ofile,"\n");
if (char_count <= CHAR_START_LEN + CHAR_END_LEN) {
/* Only print (some of the) start characters */
begin_or_end = TRUE;
for (i=0; i<char_count; i++) {
if (i == char_count-1) {
begin_or_end = TRUE;
}
print_char(char_start[i]);
}
if (opt_x) {
fprintf(ofile,"\n");
for (i=0; i<char_count; i++) {
j = 0xff & char_start[i];
output_byte(j);
fprintf(ofile," ");
}
}
}
else {
/* "End" array did "wrap around" */
/* Move the "end" characters to end of "start" array */
j = k = (char_count - CHAR_START_LEN) % CHAR_END_LEN;
for (i=CHAR_START_LEN; k<CHAR_END_LEN; i++, k++) {
char_start[i] = char_end[k];
}
for (k=0; k<j; i++, k++) {
char_start[i] = char_end[k];
}
begin_or_end = TRUE;
/* Print the first set */
for (i=0; i<CHAR_START_LEN; i++) {
if (i == CHAR_START_LEN-1) {
begin_or_end = TRUE;
}
print_char(char_start[i]);
}
fprintf(ofile," ... ");
begin_or_end = TRUE;
/* Print the second set */
for (i=CHAR_START_LEN; i<CHAR_START_LEN+CHAR_END_LEN; i++) {
if (i == CHAR_START_LEN+CHAR_END_LEN-1) {
begin_or_end = TRUE;
}
print_char(char_start[i]);
}
if (opt_x) {
fprintf(ofile,"\n");
for (i=0; i<CHAR_START_LEN; i++) {
j = 0xff & char_start[i];
output_byte(j);
fprintf(ofile," ");
}
fprintf(ofile," ... ");
for (i=CHAR_START_LEN; i<CHAR_START_LEN+CHAR_END_LEN; i++) {
j = 0xff & char_start[i];
output_byte(j);
fprintf(ofile," ");
}
}
}
fprintf(ofile,"\n");
if (num_lines > 0) {
indent(1);
fprintf(ofile,"Added %d more lines.\n", num_lines);
}
}
}
num_lines = char_count = 0;
}