ftp.nice.ch/pub/next/tools/printer/lj2ps.s.tar.gz#/lj2ps/scan.c

This is scan.c in view mode; [Download] [Up]

/* Project:		lj2ps
** File:		scan.c
**
** Author:		Christopher Lishka
** Organization:	Wisconsin State Laboratory of Hygiene
**			Data Processing Dept.
**
** Copyright (C) 1990 by Christopher Lishka.
**
** 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.
*/

static char * ModuleID = "Module scan: v1.0.1.2, production";

  /* Include files
  */
#include <stdio.h>

#if defined (NeXT)
	#include	<stdlib.h>
#endif

#include <ctype.h>
#include "scan.h"
#include "lj.h"
#include "lj2ps.h"

  /* External definitions
  */

  /* Global variables
  */
int    scan_state;		/* Controls which scanner is being used */
char  *text;			/* Text read in for text tokens */
char  *command;			/* Command read in */
char   variable[MAX_BUFFER];	/* Command parameter */
char   number[MAX_BUFFER];	/* Command numeric argument */
int    pos_code;		/* Command numeric position code */
token  curr_token;		/* Where to hold the scanned token */

  /* Global function list
  */
extern int  scan();		/* The entry into the scanners */
extern void scan_init();	/* Reset the input for the scanner */

  /* Local constants
  */
  /* Scanner state constants */
  /* These two constants allow access to the START and END states.  I do not
  ** recommend changing the actual values for them, because they need to be
  ** defined to the same value for *all* scanners in here.
  */
#define START     1
#define END       0
  /* Text scanner states */
#define ST____    END		/* End...must be zero! */
#define ST_STT    START		/* Start */
#define ST_CMD    2		/* Command */
#define ST_CMA    3		/* Command & */
#define ST_CMS    4		/* Command * */
#define ST_TLP    5		/* END: Text ( */
#define ST_TRP    6		/* END: Text ) */
#define ST_TBS    7		/* END: Text \ */
#define ST_TNL    8		/* END: Text \n */
#define ST_TFF    9		/* END: Text \f */
#define ST_UNK   10		/* END: Error: unknown command */
#define ST_CEQ   11		/* END: Command = */
#define ST_C9    12		/* END: Command 9 */
#define ST_CZ    13		/* END: Command Z */
#define ST_CY    14		/* END: Command Y */
#define ST_CE    15		/* END: Command E */
#define ST_CAa   16		/* END: Command &a */
#define ST_CAd   17		/* END: Command &d */
#define ST_CAf   18		/* END: Command &f */
#define ST_CAk   19		/* END: Command &k */
#define ST_CAl   20		/* END: Command &l */
#define ST_CAp   21		/* END: Command &p */
#define ST_CAs   22		/* END: Command &s */
#define ST_CSt   23		/* END: Command *t */
#define ST_CSr   24		/* END: Command *r */
#define ST_CSp   25		/* END: Command *p */
#define ST_CSc   26		/* END: Command *c */
#define ST_CSb   27		/* END: Command *b */
#define ST_CLs   28		/* END: Command (s */
#define ST_CRs   29		/* END: Command )s */
#define ST_CLP   30		/* END: Command ( */
#define ST_CRP   31		/* END: Command ) */
#define ST_TXT   32		/* END: Text */
#define ST_NUL   33		/* END: Null */
#define ST_TTB   34		/* END: Tab */
#define ST_TSI   35		/* END: Shift in */
#define ST_TSO   36		/* END: Shift out */
#define ST_MAX   37		/* End of these states */
  /* Parameter scanner states */
#define SP____    END		/* End state */
#define SP_PRM    START		/* Parameter */
#define SP_INT    2		/* Integer */
#define SP_FLP    3		/* Floating point */
#define SP_PEO    4		/* END: Parameter end -- other (no argument) */
#define SP_PE     5		/* END: Parameter end -- normal */
#define SP_PC     6		/* END: Parameter continue */
#define SP_UNK    7		/* END: Unknown command */
#define SP_MAX    8		/* End of these states */
  /* Text scanner character classes */
#define CST___    0		/* All other characters */
#define CST_LP    1		/* ( */
#define CST_RP    2		/* ) */
#define CST_BS    3		/* \ */
#define CST_NL    4		/* \n */
#define CST_FF    5		/* \f */
#define CST_NU    6		/* \0 */
#define CST_ES    7		/* ^[ */
#define CST_EQ    8		/* = */
#define CST_AM    9		/* & */
#define CST_AS   10		/* * */
#define CST_9    11		/* 9 */
#define CST_E    12		/* E */
#define CST_Y    13		/* Y */
#define CST_Z    14		/* Z */
#define CST_a    15		/* a */
#define CST_b    16		/* b */
#define CST_c    17		/* c */
#define CST_d    18		/* d */
#define CST_f    19		/* f */
#define CST_k    20		/* k */
#define CST_l    21		/* l */
#define CST_p    22		/* p */
#define CST_r    23		/* r */
#define CST_s    24		/* s */
#define CST_t    25		/* t */
#define CST_EF   26		/* EOF */
#define CST_TB   27		/* Tab */
#define CST_SI   28		/* Shift in */
#define CST_SO   29		/* Shift out */
#define CST_MAX  30		/* End of these classes */
  /* Parameter scanner character classes */
#define CSP___    0		/* All other characters */
#define CSP_SI    1		/* + - */
#define CSP_DI    2		/* 0 1 2 3 4 5 6 7 8 9 */
#define CSP_PE    3		/* . */
#define CSP_LW    4		/* a-z */
#define CSP_US    5		/* A-Z ! " # $ % & ' ( ) * , / :   */
				/* ; < = > ? @ [ \ ] ^ _ ` { | } ~ */
#define CSP_EF    6		/* EOF */
#define CSP_MAX   7		/* End of these classes */

  /* Local structures and types
  */
  /* The text buffer */
typedef struct {		/* Input buffer */
  int   length;			/* Number of characters put back */
  char  storage[MAX_BUFFER];	/* Storage for characters in the buffer */
} buffer;

  /* Local variables
  */
static FILE  *in_file;		/* Input file */
static char   curr_char;	/* The current character */
static int    end_of_file;	/* True if at the end_of_file */
static buffer input;		/* Buffer to hold put-back characters */

  /* The text scanner state/input table */
static int st_states[ST_MAX][CST_MAX] = {
/* Legend:
**{ CST___, CST_LP, CST_RP, CST_BS,   CST_NL, CST_FF, CST_NU, CST_ES,
**  CST_EQ, CST_AM, CST_AS, CST_9 ,   CST_E , CST_Y , CST_Z , CST_a ,
**  CST_b , CST_c , CST_d , CST_f ,   CST_k , CST_l , CST_p , CST_r ,
**  CST_s , CST_t , CST_EF, CST_TB,   CST_SI, CST_SO },
*/
    /* ST____: END*/
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_STT: Start */
  { ST_TXT, ST_TLP, ST_TRP, ST_TBS,   ST_TNL, ST_TFF, ST_NUL, ST_CMD,
    ST_TXT, ST_TXT, ST_TXT, ST_TXT,   ST_TXT, ST_TXT, ST_TXT, ST_TXT,
    ST_TXT, ST_TXT, ST_TXT, ST_TXT,   ST_TXT, ST_TXT, ST_TXT, ST_TXT,
    ST_TXT, ST_TXT, ST____, ST_TTB,   ST_TSI, ST_TSO },
    /* ST_CMD: Command */
  { ST_UNK, ST_CLP, ST_CRP, ST_UNK,   ST_UNK, ST_UNK, ST_UNK, ST_UNK,
    ST_CEQ, ST_CMA, ST_CMS, ST_C9 ,   ST_CE , ST_CY , ST_CZ , ST_UNK,
    ST_UNK, ST_UNK, ST_UNK, ST_UNK,   ST_UNK, ST_UNK, ST_UNK, ST_UNK,
    ST_UNK, ST_UNK, ST_UNK, ST_UNK,   ST_UNK, ST_UNK },
    /* ST_CMA: Command & */
  { ST_UNK, ST_UNK, ST_UNK, ST_UNK,   ST_UNK, ST_UNK, ST_UNK, ST_UNK,
    ST_UNK, ST_UNK, ST_UNK, ST_UNK,   ST_UNK, ST_UNK, ST_UNK, ST_CAa,
    ST_UNK, ST_UNK, ST_CAd, ST_CAf,   ST_CAk, ST_CAl, ST_CAp, ST_UNK,
    ST_CAs, ST_UNK, ST_UNK, ST_UNK,   ST_UNK, ST_UNK },
    /* ST_CMS: Command * */
  { ST_UNK, ST_UNK, ST_UNK, ST_UNK,   ST_UNK, ST_UNK, ST_UNK, ST_UNK,
    ST_UNK, ST_UNK, ST_UNK, ST_UNK,   ST_UNK, ST_UNK, ST_UNK, ST_UNK,
    ST_CSb, ST_CSc, ST_UNK, ST_UNK,   ST_UNK, ST_UNK, ST_CSp, ST_CSr,
    ST_UNK, ST_CSt, ST_UNK, ST_UNK,   ST_UNK, ST_UNK },
    /* ST_TLP: END: Text ( */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_TRP: END: Text ) */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_TBS: END: Text \ */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_TNL: END: Text \n */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_TFF: END: Text \f */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_UNK: END: Error: unknown command */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CEQ: END: Command = */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_C9:* END: Command 9 */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CZ:* END: Command Z */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CY:* END: Command Y */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CE:* END: Command E */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CAa: END: Command &a */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CAd: END: Command &d */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CAf: END: Command &f */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CAk: END: Command &k */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CAl: END: Command &l */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CAp: END: Command &p */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CAs: END: Command &s */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CSt: END: Command *t */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CSr: END: Command *r */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CSp: END: Command *p */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CSc: END: Command *c */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CSb: END: Command *b */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CLs: END: Command (s */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CRs: END: Command )s */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CLP: END: Command ( */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST_CLs, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_CRP: END: Command ) */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST_CRs, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_TXT: END: Text */
  { ST_TXT, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST_TXT, ST_TXT, ST_TXT, ST_TXT,   ST_TXT, ST_TXT, ST_TXT, ST_TXT,
    ST_TXT, ST_TXT, ST_TXT, ST_TXT,   ST_TXT, ST_TXT, ST_TXT, ST_TXT,
    ST_TXT, ST_TXT, ST____, ST____,   ST____, ST____ },
    /* ST_NUL: END: Null */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_TTB: END: Tab */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_TSI: END: Shift in */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ },
    /* ST_TSO: END: Shift out */
  { ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____, ST____, ST____,
    ST____, ST____, ST____, ST____,   ST____, ST____ }
};

static int sp_states[SP_MAX][CSP_MAX] = {
/* Legend:
**{ CSP___, CSP_SI, CSP_DI, CSP_PE,   CSP_LW, CSP_US, CSP_EF }
*/
    /* SP____: Error */
  { SP____, SP____, SP____, SP____,   SP____, SP____, SP____ },
    /* SP_PRM: Parameter */
  { SP_PEO, SP_INT, SP_INT, SP_PEO,   SP_PC , SP_PE , SP_UNK },
    /* SP_INT: Integer */
  { SP_UNK, SP_PE , SP_INT, SP_FLP,   SP_PC , SP_PE , SP_UNK },
    /* SP_FLP: Floating point */
  { SP_UNK, SP_PE , SP_FLP, SP_PE ,   SP_PC , SP_PE , SP_UNK },
    /* SP_PEO: END: Parameter end -- other (no argument) */
  { SP____, SP____, SP____, SP____,   SP____, SP____, SP____ },
    /* SP_PE:  END: Parameter end -- normal */
  { SP____, SP____, SP____, SP____,   SP____, SP____, SP____ },
    /* SP_PC:  END: Parameter continue */
  { SP____, SP____, SP____, SP____,   SP____, SP____, SP____ },
    /* SP_UNK: END: Unknown command */
  { SP____, SP____, SP____, SP____,   SP____, SP____, SP____ }
};

static int st_classes[256] = {
  /* 00 */ CST_NU, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* 08 */ CST___, CST_TB, CST_NL, CST___,   CST_FF, CST___, CST_SO, CST_SI,
  /* 10 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* 18 */ CST___, CST___, CST___, CST_ES,   CST___, CST___, CST___, CST___,
  /* 20 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST_AM, CST___,
  /* 28 */ CST_LP, CST_RP, CST_AS, CST___,   CST___, CST___, CST___, CST___,
  /* 30 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* 38 */ CST___, CST_9 , CST___, CST___,   CST___, CST_EQ, CST___, CST___,
  /* 40 */ CST___, CST___, CST___, CST___,   CST___, CST_E , CST___, CST___,
  /* 48 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* 50 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* 58 */ CST___, CST_Y , CST_Z , CST___,   CST_BS, CST___, CST___, CST___,
  /* 60 */ CST___, CST_a , CST_b , CST_c ,   CST_d , CST___, CST_f , CST___,
  /* 68 */ CST___, CST___, CST___, CST_k ,   CST_l , CST___, CST___, CST___,
  /* 70 */ CST_p , CST___, CST_r , CST_s ,   CST_t , CST___, CST___, CST___,
  /* 78 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,

  /* 80 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* 88 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* 90 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* 98 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* a0 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* a8 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* b0 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* b8 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* c0 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* c8 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* d0 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* d8 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* e0 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* e8 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* f0 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___,
  /* f8 */ CST___, CST___, CST___, CST___,   CST___, CST___, CST___, CST___
};

static int sp_classes[256] = {
  /* 00 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* 08 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* 10 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* 18 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* 20 */ CSP___, CSP_US, CSP_US, CSP_US,   CSP_US, CSP_US, CSP_US, CSP_US,
  /* 28 */ CSP_US, CSP_US, CSP_US, CSP_SI,   CSP_US, CSP_SI, CSP_PE, CSP_US,
  /* 30 */ CSP_DI, CSP_DI, CSP_DI, CSP_DI,   CSP_DI, CSP_DI, CSP_DI, CSP_DI,
  /* 38 */ CSP_DI, CSP_DI, CSP_US, CSP_US,   CSP_US, CSP_US, CSP_US, CSP_US,
  /* 40 */ CSP_US, CSP_US, CSP_US, CSP_US,   CSP_US, CSP_US, CSP_US, CSP_US,
  /* 48 */ CSP_US, CSP_US, CSP_US, CSP_US,   CSP_US, CSP_US, CSP_US, CSP_US,
  /* 50 */ CSP_US, CSP_US, CSP_US, CSP_US,   CSP_US, CSP_US, CSP_US, CSP_US,
  /* 58 */ CSP_US, CSP_US, CSP_US, CSP_US,   CSP_US, CSP_US, CSP_US, CSP_US,
  /* 60 */ CSP_LW, CSP_LW, CSP_LW, CSP_LW,   CSP_LW, CSP_LW, CSP_LW, CSP_LW,
  /* 68 */ CSP_LW, CSP_LW, CSP_LW, CSP_LW,   CSP_LW, CSP_LW, CSP_LW, CSP_LW,
  /* 70 */ CSP_LW, CSP_LW, CSP_LW, CSP_LW,   CSP_LW, CSP_LW, CSP_LW, CSP_LW,
  /* 78 */ CSP_LW, CSP_LW, CSP_LW, CSP_US,   CSP_US, CSP_US, CSP_US, CSP___,

  /* 80 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* 88 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* 90 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* 98 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* a0 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* a8 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* b0 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* b8 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* c0 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* c8 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* d0 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* d8 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* e0 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* e8 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* f0 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___,
  /* f8 */ CSP___, CSP___, CSP___, CSP___,   CSP___, CSP___, CSP___, CSP___
};


  /* Local macro definitions
  */

  /* Local function list
  */
static void  parse_argument();

  /* Function bodies
  */

  /* scan() is the front_end to the scanner.  It runs the proper scanner,
  ** based on the value of scan_state.  It returns a token number if the
  ** scan was successful, or zero if the end-of-file was reached.
  */
int
scan()
{
  register int prev_state;	/* The previous state */
  register int curr_state;	/* The current state */

 rescan:

  curr_token.storage[0] = '\0';  curr_token.length = 0;
  curr_state = START;
  
  do{				/* Main scanning loop */
    
    prev_state = curr_state;

      /* Get the next character */
    if( input.length > 0 ){
      curr_char = input.storage[--input.length];
    }
    else{
      if( (curr_char = getc(in_file)) == EOF)
	end_of_file = 1;
      else
	end_of_file = 0;
    }

#ifdef DEBUG
    if( debug == 2 ) fputc(curr_char, stderr);
#endif

    if( !end_of_file ){

#ifdef DEBUG
    if( debug == 3 ){
      switch( scan_state ){
      case SS_TEXT:
	fprintf(stderr,
		"TEXT  curr % 3.3d (prev % 3.3d)  char %c (0x%2.2x)  class % 3.3d -> % 3.3d\n",
		curr_state, prev_state,
		curr_char, (int) curr_char, st_classes[curr_char],
		st_states[curr_state][st_classes[curr_char]]
		);
	break;
      case SS_PARAM:
	fprintf(stderr,
		"TEXT  curr % 3.3d (prev % 3.3d)  char %c (0x%2.2x)  class % 3.3d -> % 3.3d\n",
		curr_state, prev_state,
		curr_char, (int) curr_char, sp_classes[curr_char],
		sp_states[curr_state][sp_classes[curr_char]]
		);
	break;
      default:
	internal_error("illegal scan state in scan()", "");
      } /* switch( ... ) */
    } /* if( debug ... ) */
#endif

      switch( scan_state ){
      case SS_TEXT:
	if( (curr_state = st_states[curr_state][st_classes[curr_char]])
	   == END ){

	    /* Put back character */
	  if( input.length == MAX_BUFFER ){
	    internal_error("you blew the put-back buffer!", "");
	  }
	  else{
	    input.storage[input.length] = curr_char;
	    input.length++;
	  }

	}
	else{

	    /* Accept character */
	  if( curr_token.length == MAX_BUFFER ){
	    internal_error("current token is too large", "");
	  }
	  else{
	    curr_token.storage[curr_token.length] = curr_char;
	    curr_token.length++;
	  }

	}
	break;
      case SS_PARAM:
	if( (curr_state = sp_states[curr_state][sp_classes[curr_char]])
	   == END ){

	    /* Put back character */
	  if( input.length == MAX_BUFFER ){
	    internal_error("you blew the put-back buffer!", "");
	  }
	  else{
	    input.storage[input.length] = curr_char;
	    input.length++;
	  }

	}
	else{

	    /* Accept character */
	  if( curr_token.length == MAX_BUFFER ){
	    internal_error("current token is too large", "");
	  }
	  else{
	    curr_token.storage[curr_token.length] = curr_char;
	    curr_token.length++;
	  }

	}
	break;
      default:
	internal_error("illegal scan state in scan()", "");
      } /* switch(...) */

    } /* if( !eof ) */
    else{

      switch( scan_state ){
      case SS_TEXT:
	if( (curr_state = st_states[curr_state][CST_EF])
	   != END ){

	  fatal_error("end-of-file found in a command", "");

	}
	break;
      case SS_PARAM:
	if( (curr_state = sp_states[curr_state][CSP_EF])
	   != END ){

	  fatal_error("end-of-file found in a command", "");

	}
	break;
      default:
	internal_error("illegal scan state in scan()", "");
      } /* switch(...) */

    } /* else( !eof ) */

  } while( curr_state != END );

    /* If this point is reached, then an entire token has been scanned.
    ** The token must be properly saved, and then the appropriate token
    ** action must be performed.  The switch() and embedded switch()'s
    ** perform the necessary token actions for each state.
    */
  curr_token.storage[curr_token.length] = '\0';
  switch( scan_state ){
  case SS_TEXT:
    switch( prev_state ){
    case ST_TLP:  scan_state = SS_TEXT;  curr_token.code = TEXT_lp;	 break;
    case ST_TRP:  scan_state = SS_TEXT;  curr_token.code = TEXT_rp;      break;
    case ST_TBS:  scan_state = SS_TEXT;  curr_token.code = TEXT_bslash;	 break;
    case ST_TNL:  scan_state = SS_TEXT;  curr_token.code = TEXT_NEWLINE; break;
    case ST_TFF:  scan_state = SS_TEXT;  curr_token.code = TEXT_FORMFEED;break;
    case ST_UNK:
      warning("LaserJet command not supported", curr_token.storage);
      scan_state = SS_TEXT;  goto rescan;
    case ST_CEQ:  scan_state = SS_TEXT;  curr_token.code = CMD_eq;  	 break;
    case ST_C9 :  scan_state = SS_TEXT;  curr_token.code = CMD_9;	 break;
    case ST_CZ :  scan_state = SS_TEXT;  curr_token.code = CMD_Z;	 break;
    case ST_CY :  scan_state = SS_TEXT;  curr_token.code = CMD_Y;	 break;
    case ST_CE :  scan_state = SS_TEXT;  curr_token.code = CMD_E;	 break;
    case ST_CAa:  scan_state = SS_PARAM; curr_token.code = CMD_amp_a;	 break;
    case ST_CAd:  scan_state = SS_PARAM; curr_token.code = CMD_amp_d;	 break;
    case ST_CAf:  scan_state = SS_PARAM; curr_token.code = CMD_amp_f;	 break;
    case ST_CAk:  scan_state = SS_PARAM; curr_token.code = CMD_amp_k;	 break;
    case ST_CAl:  scan_state = SS_PARAM; curr_token.code = CMD_amp_l;	 break;
    case ST_CAp:  scan_state = SS_PARAM; curr_token.code = CMD_amp_p;	 break;
    case ST_CAs:  scan_state = SS_PARAM; curr_token.code = CMD_amp_s;	 break;
    case ST_CSt:  scan_state = SS_PARAM; curr_token.code = CMD_star_t;	 break;
    case ST_CSr:  scan_state = SS_PARAM; curr_token.code = CMD_star_r;	 break;
    case ST_CSp:  scan_state = SS_PARAM; curr_token.code = CMD_star_p;	 break;
    case ST_CSc:  scan_state = SS_PARAM; curr_token.code = CMD_star_c;	 break;
    case ST_CSb:  scan_state = SS_PARAM; curr_token.code = CMD_star_b;	 break;
    case ST_CLs:  scan_state = SS_PARAM; curr_token.code = CMD_lp_s;	 break;
    case ST_CRs:  scan_state = SS_PARAM; curr_token.code = CMD_rp_s;	 break;
    case ST_CLP:  scan_state = SS_PARAM; curr_token.code = CMD_lp;	 break;
    case ST_CRP:  scan_state = SS_PARAM; curr_token.code = CMD_rp;	 break;
    case ST_TXT:  scan_state = SS_TEXT;  curr_token.code = TEXT_CHAR;	 break;
    case ST_NUL:  scan_state = SS_TEXT;  curr_token.code = TEXT_NULL;	 break;
    case ST_TTB:  scan_state = SS_TEXT;  curr_token.code = TEXT_TAB;     break;
    case ST_TSI:  scan_state = SS_TEXT;  curr_token.code = TEXT_SH_IN;   break;
    case ST_TSO:  scan_state = SS_TEXT;  curr_token.code = TEXT_SH_OUT;  break;
    case ST____:
    case ST_STT:
    case ST_CMD:
    case ST_CMA:
    case ST_CMS:
    default:
      if( !end_of_file ){
	internal_error("illegal state in text scanner token actions", "");
      }
    } /* switch( text scanner ) */
    break;
  case SS_PARAM:
    switch( prev_state ){
    case SP_PE :
      scan_state = SS_TEXT;
      curr_token.code = PARAM_END;
      parse_argument();
      break;
    case SP_PC :
      scan_state = SS_PARAM;
      curr_token.code = PARAM_CONTINUE;
      parse_argument();
      break;
    case SP_PEO:
      scan_state = SS_TEXT;
      curr_token.code = PARAM_END;
      parse_argument();
      break;
    case SP_UNK:
      warning("illegal character in command parameter", curr_token.storage);
      scan_state = SS_TEXT; goto rescan;
    case SP____:
    case SP_PRM:
    case SP_INT:
    case SP_FLP:
    default:
      internal_error("illegal state in parameter scanner token actions", "");
    } /* switch( parameter scanner ) */
    break;
  default:
    internal_error("illegal scan state in token actions", "");
  } /* switch( scan_state ) */

  return( !end_of_file );
} /* scan() */



  /* scan_init() initializes the scanner to a new input stream.  This is
  ** accomplished by reseting the scan_state, clearing the put-back buffer,
  ** and various other minor tasks.
  */
void
scan_init(file)
     FILE *file;
{

    /* Initialize the scan state */
  scan_state = SS_TEXT;

    /* Save the handle to the file */
  in_file = file;
  end_of_file = 0;

    /* Reset the buffer */
  input.length = 0;

    /* Miscellaneous */
  text = curr_token.storage;
  command = curr_token.storage;

} /* scan_init() */




static void
parse_argument()
{

    /* Determine whether or not the command has a numeric argument */
  if( curr_token.length == 1 ){	/* No numeric argument */
    number[0] = '0';		/* Set number = "0" */
    number[1] = '\0';
    pos_code = POS_ABSOLUTE;	/* Set to a constant value */
  }
  else{				/* Numeric argument present */
      /* Check if it is a relative offset */
    if( !isdigit(curr_token.storage[0]) ){
      if( curr_token.storage[0] == '+' )       pos_code = POS_REL_POSITIVE;
      else if( curr_token.storage[0] == '-' )  pos_code = POS_REL_NEGATIVE;
      else internal_error("illegal relative offset", curr_token.storage);
    }
    else{
      pos_code = POS_ABSOLUTE;
    }
      /* Record the scalar value */
    if( pos_code == POS_ABSOLUTE ){
      (void) strncpy(number, curr_token.storage, curr_token.length - 1);
      number[curr_token.length - 1] = '\0';
    }
    else{
      (void) strncpy(number, &(curr_token.storage)[1], curr_token.length - 2);
      number[curr_token.length - 2] = '\0';
    }
  }

    /* Finally, record the command as an *upper-case* single digit string */
  variable[0] = curr_token.storage[curr_token.length - 1];
  variable[1] = '\0';
  if( islower(variable[0]) )  variable[0] = toupper(variable[0]);

} /* parse_argument() */

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.