]> git.sesse.net Git - rdpsrv/blobdiff - Xserver/lib/font/Type1/token.c
Removed Xserver/ directory, it does nothing useful ATM.
[rdpsrv] / Xserver / lib / font / Type1 / token.c
diff --git a/Xserver/lib/font/Type1/token.c b/Xserver/lib/font/Type1/token.c
deleted file mode 100644 (file)
index da1c291..0000000
+++ /dev/null
@@ -1,1211 +0,0 @@
-/* $XConsortium: token.c,v 1.3 94/02/04 17:07:17 gildea Exp $ */
-/* Copyright International Business Machines,Corp. 1991
- * All Rights Reserved
- *
- * License to use, copy, modify, and distribute this software
- * and its documentation for any purpose and without fee is
- * hereby granted, provided that the above copyright notice
- * appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation,
- * and that the name of IBM not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission.
- *
- * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
- * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
- * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
- * THIRD PARTY RIGHTS.  THE ENTIRE RISK AS TO THE QUALITY AND
- * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
- * OR MAINTAIN, BELONGS TO THE LICENSEE.  SHOULD ANY PORTION OF
- * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
- * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION.  IN
- * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-/* Authors: Sig Nin & Carol Thompson IBM Almaden Research Laboratory */
-#include "t1stdio.h"
-#include "util.h"
-#include "digit.h"
-#include "token.h"
-#include "tokst.h"
-#include "hdigit.h"
-/*
- * -------------------------------------------------------------------
- * Globals
- * -------------------------------------------------------------------
- */
-/* These variables are set by the caller */
-char           *tokenStartP;   /* Pointer to token buffer in VM */
-char           *tokenMaxP;     /* Pointer to last byte in buffer + 1 */
-/* These variables are set by TOKEN */
-int             tokenLength;   /* Characters in token */
-boolean         tokenTooLong;  /* Token too long for buffer */
-int             tokenType;     /* Type of token identified */
-psvalue         tokenValue;    /* Token value */
-/*
- * -------------------------------------------------------------------
- * Private variables
- * -------------------------------------------------------------------
- */
-static FILE    *inputFileP;    /* Current input file */
-/* Token */
-static char    *tokenCharP;    /* Pointer to next character in token */
-/*
- * -------------------------------------------------------------------
- * Private routines for manipulating numbers
- * -------------------------------------------------------------------
- */
-#define Exp10(e) \
-((e) == 0\
- ? (double)(1.0)\
- : (-64 <= (e) && (e) <= 63\
-    ? Exp10T[(e)+64]\
-    : P10(e)\
-   )\
-)
-static double Exp10T[128] = {
-  1e-64, 1e-63, 1e-62, 1e-61, 1e-60, 1e-59, 1e-58, 1e-57,
-  1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49,
-  1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41,
-  1e-40, 1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33,
-  1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25,
-  1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 1e-19, 1e-18, 1e-17,
-  1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9,
-  1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
-  1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7,
-  1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
-  1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 1e23,
-  1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30, 1e31,
-  1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
-  1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47,
-  1e48, 1e49, 1e50, 1e51, 1e52, 1e53, 1e54, 1e55,
-  1e56, 1e57, 1e58, 1e59, 1e60, 1e61, 1e62, 1e63
-};
-static double P10(exponent)
-  long exponent;
-{
-  double value, power;
-  if (exponent < 0) {
-    power = 0.1;
-    value = (exponent & 1 ? power : 1.0);
-    exponent = -(++exponent >> 1); /* portable C for -(exponent/2) */
-  }
-  else {
-    power = 10.0;
-    value = (exponent & 1 ? power : 1.0);
-    exponent = exponent >> 1;
-  }
-  while(exponent > 0) {
-    power *= power;
-    if (exponent & 1)
-      value *= power;
-    exponent >>= 1;
-  }
-  return(value);
-}
-/*
- * -------------------------------------------------------------------
- * Private routines and macros for manipulating the input
- * -------------------------------------------------------------------
- */
-/* Get next character from the input --
- *
- */
-#define next_ch()    (getc(inputFileP))
-/* Push a character back into the input --
- *
- * Ungetc of EOF will fail, but that's ok: the next getc will
- * return EOF.
- *
- * NOTE:  These macros are presently written to return the character
- * pushed, or EOF if none was pushed.  However, they are not
- * required to return anything in particular, and callers should
- * not rely on the returned value.
- */
-#define back_ch(ch)   (ungetc(ch, inputFileP))
-/* Push a character back into the input if it was not white space.
- * If it is a carriage return (\r) then check next char for
- * linefeed and consume them both, otherwise put next char back.
- *
- */
-#define back_ch_not_white(ch) \
-(\
-isWHITE_SPACE(ch)\
- ? ((ch == '\r')\
-   ? (((ch = next_ch()) == '\n')\
-     ? EOF\
-     : back_ch(ch)\
-     )\
-   : EOF\
-   )\
- : back_ch(ch)\
-)
-/*
- * -------------------------------------------------------------------
- * Private routines and macros for manipulating the token buffer
- * -------------------------------------------------------------------
- */
-/* Add a character to the token
- * ---- use ONLY when you KNOW that this character will
- *      be stored within the token buffer.
- */
-#define save_unsafe_ch(ch) (*tokenCharP++ = ch)
-/* Add a character to the token, if not too long to fit */
-#define save_ch(ch) \
-((tokenCharP < tokenMaxP)\
- ? save_unsafe_ch(ch)\
- : (tokenTooLong = TRUE)\
-)
-
-#define save_ch_no_inc(ch) \
-((tokenCharP < tokenMaxP) && (*tokenCharP = ch))
-/*
- * -------------------------------------------------------------------
- * Action Routines
- *
- *  These routines all
- *    -- take int ch as a parameter
- *    -- return int ch if no token was recognized, DONE otherwise
- *    -- leave the next character in the input, if returning DONE
- * -------------------------------------------------------------------
- */
-#define DONE  (256)
-/* Get the next input character */
-static int next_char(ch)
-  int ch;
-{
-  return(next_ch());
-}
-/* Add character to token */
-static int add_char(ch)
-  int ch;
-{
-  save_ch(ch);
-  return(next_ch());
-}
-/* -------------------------------------------------------------------
- * Skip white space and comments
- */
-/* Skip white space */
-static int skip_space(ch)
-  int ch;
-{
-  do {
-    ch = next_ch();
-  } while(isWHITE_SPACE(ch));
-  return(ch);
-}
-/* Skip comments */
-static int skip_comment(ch)
-  int ch;
-{
-  do {
-    ch = next_ch();
-  } while(isCOMMENT(ch));
-  return(ch);
-}
-/* -------------------------------------------------------------------
- * Collect value elements for a number
- */
-/* decimal integer or real number mantissa */
-static int m_sign;
-static long m_value;
-static long m_scale;
-/* real number exponent */
-static int e_sign;
-static long e_value;
-static long e_scale;
-/* radix number */
-static long r_base;
-static long r_value;
-static long r_scale;
-static int add_sign(ch)
-  int ch;
-{
-  m_sign = ch;
-  save_unsafe_ch(ch);
-  return(next_ch());
-}
-static int add_1st_digits(ch)
-  int ch;
-{
-  m_sign = '+';
-  return(add_digits(ch));
-}
-static int add_digits(ch)
-  int ch;
-{
-  long value, p_value, scale;
-  int digit;
-  /* On entry, expect m_sign to be set to '+' or '-';
-   *  ch is a decimal digit.
-   * Expect at most one character saved at this point,
-   *  a sign.  This routine will save up to 10 more
-   *  characters without checking the buffer boundary.
-   */
-  value = ch - '0';
-  save_unsafe_ch(ch);
-  ch = next_ch();
-  while(isDECIMAL_DIGIT(ch) && value < (MAX_INTEGER/10)) {
-    value = (value << 3) + (value << 1) + (ch - '0');
-    save_unsafe_ch(ch);
-    ch = next_ch();
-  }
-  /* Quick exit for small integers --
-   *    |x| <= 10*((MAX_INTEGER/10)-1)+9
-   *    |x| <= 2,147,483,639 for 32 bit integers
-   */
-  if (isNUMBER_ENDER(ch)) {
-    back_ch_not_white(ch);
-    tokenValue.integer = (m_sign == '-' ? -value : value);
-    tokenType = TOKEN_INTEGER;
-    return(DONE);
-  }
-  /* Handle additional digits.  Beyond the boundary case,
-   *   10*(MAX_INTEGER/10) <= |number| <= MAX_INTEGER
-   * just count the digits: the number is too large to
-   * represent as an integer and will be returned as a real.
-   * The mantissa of a real holds fewer bits than an integer.
-   */
-  p_value = value;
-  value = (m_sign == '-' ? -value : value);
-  scale = 0;
-  if (isDECIMAL_DIGIT(ch)) {
-    /* Handle the boundary case */
-    if (p_value == (MAX_INTEGER/10)) {
-      digit = ch - '0';
-      /* Must handle positive and negative values separately  */
-      /* for 2's complement arithmetic */
-      if (value > 0) {
-        if (digit <= MAX_INTEGER%10)
-          value = (value << 3) + (value << 1) + digit;
-        else
-          ++scale;  /* Too big, just count it */
-      }
-      else {
-        /* Use positive % operands for portability */
-        if (digit <= -(MIN_INTEGER+10)%10)
-          value = (value << 3) + (value << 1) - digit;
-        else
-          ++scale;  /* Too big, just count it */
-      }
-    }
-    else
-      ++scale;  /* Not boundary case, just count digit */
-    save_unsafe_ch(ch);
-    ch = next_ch();
-    /* Continue scanning digits, but can't store them */
-    while(isDECIMAL_DIGIT(ch)) {
-      ++scale;
-      save_ch(ch);
-      ch = next_ch();
-    }
-  }
-  /* Continue from here scanning radix integer or real */
-  m_value = value;
-  m_scale = scale;
-  /* Initialize for possible real */
-  e_sign = '+';
-  e_value = 0;
-  e_scale = 0;
-  return(ch);
-}
-static int add_1st_decpt(ch)
-  int ch;
-{
-  m_sign = '+';
-  return(add_decpt(ch));
-}
-static int add_decpt(ch)
-  int ch;
-{
-  /* On entry, expect m_sign to be set to '+' or '-' */
-  m_value = 0;
-  m_scale = 0;
-  save_unsafe_ch(ch);
-  return(next_ch());
-}
-static int add_fraction(ch)
-  int ch;
-{
-  long value, scale;
-  int digit;
-  /* On entry, expect m_value and m_scale to be initialized,
-   * and m_sign to be set to '+' or '-'.  Expect m_value and m_sign
-   * to be consistent (this is not checked).
-   */
-  value = m_value;
-  scale = m_scale;
-  /* Scan leading zeroes */
-  if (value == 0) {
-    while(ch == '0') {
-      --scale;
-      save_ch(ch);
-      ch = next_ch();
-    }
-    /* Scan first significant digit */
-    if (isDECIMAL_DIGIT(ch)) {
-      --scale;
-      value = ch - '0';
-      value = (m_sign == '-' ? -value : value);
-      save_ch(ch);
-      ch = next_ch();
-    }
-    else
-      /* no significant digits -- number is zero */
-      scale = 0;
-  }
-  /* value != 0 || value == 0 && !isDECIMAL_DIGIT(ch) */
-  /* Scan additional significant digits */
-  if (isDECIMAL_DIGIT(ch)) {
-    if (value > 0) {
-      while(isDECIMAL_DIGIT(ch) && value < (MAX_INTEGER/10)) {
-        --scale;
-        value = (value << 3) + (value << 1) + (ch - '0');
-        save_ch(ch);
-        ch = next_ch();
-      }
-      /* Check boundary case */
-      if (isDECIMAL_DIGIT(ch) && value == (MAX_INTEGER/10)) {
-        digit = ch - '0';
-        if (digit <= MAX_INTEGER%10) {
-          --scale;
-          value = (value << 3) + (value << 1) + digit;
-          save_ch(ch);
-          ch = next_ch();
-        }
-      }
-    }
-    else {
-      /* value < 0 */
-      while(isDECIMAL_DIGIT(ch) && value > -(-(MIN_INTEGER+10)/10+1)) {
-        /* Use positive / operands for portability */
-        --scale;
-        value = (value << 3) + (value << 1) - (ch - '0');
-        save_ch(ch);
-        ch = next_ch();
-      }
-      /* Check boundary case */
-      if (isDECIMAL_DIGIT(ch)
-          && value == -(-(MIN_INTEGER+10)/10+1)) {
-        digit = ch - '0';
-        if (digit <= -(MIN_INTEGER+10)%10) {
-        /* Use positive % operands for portability */
-          --scale;
-          value = (value << 3) + (value << 1) - digit;
-          save_ch(ch);
-          ch = next_ch();
-        }
-      }
-    }
-    /* Additional digits can be discarded */
-    while(isDECIMAL_DIGIT(ch)) {
-      save_ch(ch);
-      ch = next_ch();
-    }
-  }
-  /* Store results */
-  m_value = value;
-  m_scale = scale;
-  /* Initialize for possible real */
-  e_sign = '+';
-  e_value = 0;
-  e_scale = 0;
-  return(ch);
-}
-static int add_e_sign(ch)
-  int ch;
-{
-  e_sign = ch;
-  save_ch(ch);
-  return(next_ch());
-}
-static int add_exponent(ch)
-  int ch;
-{
-  long value, p_value;
-  long scale = 0;
-  int digit;
-  /* On entry, expect e_sign to be set to '+' or '-' */
-  value = ch - '0';
-  save_ch(ch);
-  ch = next_ch();
-  while(isDECIMAL_DIGIT(ch) && value < (MAX_INTEGER/10)) {
-    value = (value << 3) + (value << 1) + (ch - '0');
-    save_ch(ch);
-    ch = next_ch();
-  }
-  p_value = value;
-  value = (e_sign == '-' ? -value : value);
-  /* Handle additional digits.  Beyond the boundary case,
-   *   10*(MAX_INTEGER/10) <= |number| <= MAX_INTEGER
-   * just count the digits: the number is too large to
-   * represent as an integer.
-   */
-  if (isDECIMAL_DIGIT(ch)) {
-    /* Examine boundary case */
-    if (p_value == (MAX_INTEGER/10)) {
-      digit = ch - '0';
-      /* Must handle positive and negative values separately */
-      /*  for 2's complement arithmetic */
-      if (value > 0) {
-        if (digit <= MAX_INTEGER%10)
-          value = (value << 3) + (value << 1) + digit;
-        else
-          ++scale; /* Too big, just count it */
-      }
-      else {
-        /* Use positive % operands for portability */
-        if (digit <= -(MIN_INTEGER+10)%10)
-          value = (value << 3) + (value << 1) - digit;
-        else
-          ++scale; /* Too big, just count it */
-      }
-    }
-    else
-      ++scale;  /* Not boundary case, just count digit */
-    save_ch(ch);
-    ch = next_ch();
-    /* Continue scanning digits, but can't store any more */
-    while(isDECIMAL_DIGIT(ch)) {
-      ++scale;
-      save_ch(ch);
-      ch = next_ch();
-    }
-  }
-  /* Store results */
-  e_value = value;
-  e_scale = scale;
-  return(ch);
-}
-static int add_radix(ch)
-  int ch;
-{
-  if (2 <= m_value && m_value <= 36 && m_scale == 0) {
-    r_base = m_value;
-    save_ch(ch);
-    return(next_ch());
-  }
-  else {
-    /* Radix invalid, complete a name token */
-    return(AAH_NAME(ch));
-  }
-}
-static int add_r_digits(ch)
-  int ch;
-{
-  unsigned long value;
-  long radix, scale;
-  int digit;
-  /* NOTE:  The syntax of a radix number allows only for
-   * values of zero or more.  The value will be stored as
-   * a 32 bit integer, which PostScript then interprets
-   * as signed.  This means, for example, that the numbers:
-   *
-   *     8#37777777777
-   *    10#4294967295
-   *    16#FFFFFFFF
-   *    36#1Z141Z3
-   *
-   * are all interpreted as -1.  This routine implements this
-   * idea explicitly:  it accumulates the number's value
-   * as unsigned, then casts it to signed when done.
-   */
-  /* Expect r_base to be initialized */
-  radix = r_base;
-  value = 0;
-  scale = 0;
-  /* Scan leading zeroes */
-  while(ch == '0') {
-    save_ch(ch);
-    ch = next_ch();
-  }
-  /* Handle first non-zero digit */
-  if ((digit=digit_value[ch]) < radix) {
-    value = digit;
-    save_ch(ch);
-    ch = next_ch();
-    /* Add digits until boundary case reached */
-    while((digit=digit_value[ch]) < radix
-            && value < (MAX_ULONG / radix)) {
-      value = value * radix + digit;
-      save_ch(ch);
-      ch = next_ch();
-    };
-    /* Scan remaining digits */
-    if ((digit=digit_value[ch]) < radix) {
-      /* Examine boundary case ---
-       *   radix*(MAX_ULONG/radix) <= number <= MAX_ULONG
-       */
-      if (value == (MAX_ULONG/radix) && digit <= MAX_ULONG%radix)
-        value = value * radix + digit;
-      else
-        ++scale;
-      /* Continue scanning digits, but can't store them */
-      save_ch(ch);
-      ch = next_ch();
-      while(digit_value[ch] < radix) {
-        ++scale;
-        save_ch(ch);
-        ch = next_ch();
-      }
-    }
-  }
-  /* Store result */
-  r_value = (long) value; /* result is signed */
-  r_scale = scale;
-  return(ch);
-}
-/* -------------------------------------------------------------------
- * Complete a number; set token type and done flag.
- * Put current input character back, if it is not white space.
- */
-/* Done: Radix Number */
-static int RADIX_NUMBER(ch)
-  int ch;
-{
-  back_ch_not_white(ch);
-  if (r_scale == 0) {
-    tokenValue.integer = r_value;
-    tokenType = TOKEN_INTEGER;
-  }
-  else {
-    tokenType = TOKEN_NAME;
-  }
-  return(DONE);
-}
-/* Done: Integer */
-static int INTEGER(ch)
-  int ch;
-{
-  back_ch_not_white(ch);
-  if (m_scale == 0) {
-    tokenValue.integer = m_value;
-    tokenType = TOKEN_INTEGER;
-  }
-  else {
-    tokenValue.real = (double)(m_value) * Exp10(m_scale);
-    tokenType = TOKEN_REAL;
-  }
-  return(DONE);
-}
-/* Done: Real */
-static int REAL(ch)
-  int ch;
-{
-  double temp;
-  back_ch_not_white(ch);
-  /* NOTE: ignore e_scale, since e_value alone will cause
-   *   exponent overflow if e_scale > 0.
-   */
-  /* HAZARD: exponent overflow of intermediate result
-   * (e.g., in 370 floating point); this should not be a problem
-   * with IEEE floating point.  Reduce exponent overflow hazard by
-   * combining m_scale and e_value first, if they have different signs,
-   * or multiplying m_value and one of the other factors, if both
-   * m_scale and e_value are negative.
-   */
-  if ((m_scale >= 0 && e_value <= 0)
-      || (m_scale <= 0 && e_value >= 0)) {
-    tokenValue.real = (double)(m_value) * Exp10(m_scale + e_value);
-  }
-  else {
-    temp = (double)(m_value) * Exp10(m_scale);
-    tokenValue.real = temp * Exp10(e_value);
-  }
-  tokenType = TOKEN_REAL;
-  return(DONE);
-}
-/* -------------------------------------------------------------------
- * Assemble a hex string; set token type and done flag.
- */
-/* Done: Hex String */
-static int HEX_STRING(ch)
-  int ch;
-{
-  int value;
-  while(TRUE) {
-    /* Process odd digit */
-    ch = next_ch();
-    if (!isHEX_DIGIT(ch)) {
-      /* Skip white space */
-      while(isWHITE_SPACE(ch))
-        ch = next_ch();
-      /* Check for terminator */
-      if (!isHEX_DIGIT(ch)) {
-        break;
-      }
-    }
-    value = digit_value[ch] << 4;
-    /* Process even digit */
-    ch = next_ch();
-    if (!isHEX_DIGIT(ch)) {
-      /* Skip white space */
-      while(isWHITE_SPACE(ch))
-        ch = next_ch();
-      /* Check for terminator */
-      if (!isHEX_DIGIT(ch)) {
-        save_ch(value);
-        break;
-      }
-    }
-    save_ch(value + digit_value[ch]);
-  }
-  /* Classify result, based on why loop ended */
-  if (ch == '>')
-    tokenType = TOKEN_HEX_STRING;
-  else {
-    /* save the invalid character for error reporting */
-    save_ch(ch);
-    tokenType = TOKEN_INVALID;
-  }
-  return(DONE);
-}
-/* -------------------------------------------------------------------
- * Assemble a string; set token type and done flag
- */
-/* Save a backslash-coded character in a string --
- *
- *   Store the proper character for special cases
- *   "\b", "\f", "\n", "\r", and "\t".
- *
- *   Decode and store octal-coded character, up to
- *   three octal digits, "\o", "\oo", and "\ooo".
- *
- *   The sequence "\<newline>" is a line continuation,
- *   so consume both without storing anything.
- *
- *   The sequence "\<EOF>" is an error; exit without
- *   storing anything and let the caller handle it.
- *
- *   For other characters, including the sequences
- *   "\\", "\(", and "\)", simply store the second
- *   character.
- */
-static void save_digraph(ch)
-  int ch;
-{
-  int value;
-  switch (ch) {
-    case 'b':   /* backspace */
-      ch = '\b';
-      break;
-    case 'f':   /* formfeed */
-      ch = '\f';
-      break;
-    case 'n':   /* newline */
-      ch = '\n';
-      break;
-    case 'r':   /* carriage return */
-      ch = '\r';
-      break;
-    case 't':   /* horizontal tab */
-      ch = '\t';
-      break;
-    case '\n':  /* line continuation -- consume it */
-      return;
-    case '\r':  /* carriage return   -- consume it */
-      ch = next_ch();   /* look at next character, is it \n?  */
-      if (ch == '\n')  return;
-      back_ch(ch);      /* if not a line feed, then return it */
-      return;
-    case EOF:   /* end of file -- forget it */
-      return;
-  default:
-    /* scan up to three octal digits to get value */
-    if (isOCTAL_DIGIT(ch)) {
-      value = digit_value[ch];
-      ch = next_ch();
-      if (isOCTAL_DIGIT(ch)) {
-        value = (value << 3) + digit_value[ch];
-        ch = next_ch();
-        if (isOCTAL_DIGIT(ch))
-          value = (value << 3) + digit_value[ch];
-        else
-          back_ch(ch);
-      }
-      else
-        back_ch(ch);
-      ch = value;
-    }
-  }
-  /* Found a character to save */
-  save_ch(ch);
-}
-/* Done: String */
-static int STRING(ch)
-  int ch;
-{
-  int nest_level = 1;
-  tokenType = TOKEN_STRING;
-  do {
-    ch = next_ch();
-    while(!isSTRING_SPECIAL(ch)) {
-      save_ch(ch);
-      ch = next_ch();
-    };
-    switch (ch) {
-     case '(':
-       ++nest_level;
-       save_ch(ch);
-       break;
-     case ')':
-       if (--nest_level > 0)
-         save_ch(ch);
-       break;
-     case '\\':
-          save_digraph(next_ch());
-        break;
-     case '\r':
-        /* All carriage returns (\r) are turned into linefeeds (\n)*/
-          ch = next_ch();       /* get the next one, is it \n? */
-          if (ch != '\n') {     /* if not, then put it back.   */
-            back_ch(ch);
-          }
-          save_ch('\n');        /* in either case, save a linefeed */
-        break;
-     case EOF:
-       tokenType = TOKEN_INVALID;  /* Unterminated string */
-       nest_level = 0;
-       break;
-    }
-  } while(nest_level > 0);
-  /* If there's room, add a 0-byte termination without increasing string
-     length.  This fixes certain dependencies on 0-terminated strings */
-  save_ch_no_inc(0);
-
-  return(DONE);
-}
-/* -------------------------------------------------------------------
- * Assemble a name; set token type and done flag.
- * Put current input character back, if it is not white space.
- */
-/* Done: Name
- *  (Safe version used to complete name tokens that
- *   start out looking like something else).
- */
-static int AAH_NAME(ch)
-  int ch;
-{
-  do {
-    save_ch(ch);
-    ch = next_ch();
-  } while(isNAME(ch));
-  back_ch_not_white(ch);
-  tokenType = TOKEN_NAME;
-  return(DONE);
-}
-/* Done: Name */
-static int NAME(ch)
-  int ch;
-{
-  save_unsafe_ch(ch);
-  ch = next_ch();
-  if (isNAME(ch)) {
-    save_unsafe_ch(ch);
-    ch = next_ch();
-    if (isNAME(ch)) {
-      save_unsafe_ch(ch);
-      ch = next_ch();
-      if (isNAME(ch)) {
-        save_unsafe_ch(ch);
-        ch = next_ch();
-        if (isNAME(ch)) {
-          save_unsafe_ch(ch);
-          ch = next_ch();
-          if (isNAME(ch)) {
-            save_unsafe_ch(ch);
-            ch = next_ch();
-            if (isNAME(ch)) {
-              save_unsafe_ch(ch);
-              ch = next_ch();
-              while(isNAME(ch)) {
-                save_ch(ch);
-                ch = next_ch();
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-  back_ch_not_white(ch);
-  tokenType = TOKEN_NAME;
-  return(DONE);
-}
-/* Done: Literal Name */
-static int LITERAL_NAME(ch)
-  int ch;
-{
-  if (isNAME(ch)) {
-    save_unsafe_ch(ch);
-    ch = next_ch();
-    if (isNAME(ch)) {
-      save_unsafe_ch(ch);
-      ch = next_ch();
-      if (isNAME(ch)) {
-        save_unsafe_ch(ch);
-        ch = next_ch();
-        if (isNAME(ch)) {
-          save_unsafe_ch(ch);
-          ch = next_ch();
-          if (isNAME(ch)) {
-            save_unsafe_ch(ch);
-            ch = next_ch();
-            if (isNAME(ch)) {
-              save_unsafe_ch(ch);
-              ch = next_ch();
-              while(isNAME(ch)) {
-                save_ch(ch);
-                ch = next_ch();
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-  back_ch_not_white(ch);
-  tokenType = TOKEN_LITERAL_NAME;
-  return(DONE);
-}
-/* Done: immediate Name */
-static int IMMED_NAME(ch)
-  int ch;
-{
-  ch = next_ch();
-  if (isNAME(ch)) {
-    save_unsafe_ch(ch);
-    ch = next_ch();
-    if (isNAME(ch)) {
-      save_unsafe_ch(ch);
-      ch = next_ch();
-      if (isNAME(ch)) {
-        save_unsafe_ch(ch);
-        ch = next_ch();
-        if (isNAME(ch)) {
-          save_unsafe_ch(ch);
-          ch = next_ch();
-          if (isNAME(ch)) {
-            save_unsafe_ch(ch);
-            ch = next_ch();
-            if (isNAME(ch)) {
-              save_unsafe_ch(ch);
-              ch = next_ch();
-              while(isNAME(ch)) {
-                save_ch(ch);
-                ch = next_ch();
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-  back_ch_not_white(ch);
-  tokenType = TOKEN_IMMED_NAME;
-  return(DONE);
-}
-/* Done: Name found while looking for something else */
-static int OOPS_NAME(ch)
-  int ch;
-{
-  back_ch_not_white(ch);
-  tokenType = TOKEN_NAME;
-  return(DONE);
-}
-/* -------------------------------------------------------------------
- * Complete a miscellaneous token; set token type and done flag.
- */
-/* Done: Unmatched Right Angle-Bracket */
-static int RIGHT_ANGLE(ch)
-  int ch;
-{
-  tokenType = TOKEN_RIGHT_ANGLE;
-  return(DONE);
-}
-/* Done: Unmatched Right Parenthesis */
-static int RIGHT_PAREN(ch)
-  int ch;
-{
-  tokenType = TOKEN_RIGHT_PAREN;
-  return(DONE);
-}
-/* Done: Left Brace */
-static int LEFT_BRACE(ch)
-  int ch;
-{
-  tokenType = TOKEN_LEFT_BRACE;
-  return(DONE);
-}
-/* Done: Right Brace */
-static int RIGHT_BRACE(ch)
-  int ch;
-{
-  tokenType = TOKEN_RIGHT_BRACE;
-  return(DONE);
-}
-/* Done: Left Bracket */
-static int LEFT_BRACKET(ch)
-  int ch;
-{
-  save_unsafe_ch(ch);
-  tokenType = TOKEN_LEFT_BRACKET;
-  return(DONE);
-}
-/* Done: Right Bracket */
-static int RIGHT_BRACKET(ch)
-  int ch;
-{
-  save_unsafe_ch(ch);
-  tokenType = TOKEN_RIGHT_BRACKET;
-  return(DONE);
-}
-/* Done: Break */
-static int BREAK_SIGNAL(ch)
-  int ch;
-{
-  tokenType = TOKEN_BREAK;
-  return(DONE);
-}
-/* Done: No Token Found */
-static int NO_TOKEN(ch)
-  int ch;
-{
-  tokenType = TOKEN_EOF;
-  return(DONE);
-}
-/*
- * -------------------------------------------------------------------
- *  scan_token -- scan one token from the input.  It uses a simple
- *    finite state machine to recognize token classes.
- *
- *  The input is from a file.
- *
- *  On entry --
- *
- *    inputP -> input PostScript object, a file.
- *    tokenStartP -> buffer in VM for accumulating the token.
- *    tokenMaxP -> last character in the token buffer
- *
- *  On exit --
- *
- *    tokenLength = number of characters in the token
- *    tokenTooLong = TRUE if the token did not fit in the buffer
- *    tokenType = code for the type of token parsed.
- *    tokenValue = converted value of a numeric token.
- *
- *
- * -------------------------------------------------------------------
- */
-void scan_token(inputP)
-  psobj *inputP;
-{
-  int ch;
-  unsigned char *stateP = s0;
-  unsigned char entry;
-  int (*actionP)();
-  /* Define input source */
-  inputFileP = inputP->data.fileP;
-  if (inputFileP == NULL)  {
-    tokenType = TOKEN_EOF;
-    return;
-  }
-  /* Ensure enough space for most cases
-   * (so we don't have to keep checking)
-   * The length needs to cover the maximum number
-   * of save_unsafe_ch() calls that might be executed.
-   * That number is 11 (a sign and 10 decimal digits, e.g.,
-   * when scanning -2147483648), but use MAX_NAME_LEN
-   * in case someone changes that without checking.
-   */
-  tokenStartP = vm_next_byte();
-  tokenMaxP = tokenStartP + MIN(vm_free_bytes(), MAX_STRING_LEN);
-  if ((tokenMaxP-tokenStartP) < (MAX_NAME_LEN)) {
-    tokenLength = 0;
-    tokenTooLong = TRUE;
-    tokenType = TOKEN_NONE;
-    tokenValue.integer = 0;
-    return;
-  }
-  /* Reset token */
-  tokenCharP = tokenStartP;
-  tokenTooLong = FALSE;
-  /* Scan one token */
-  ch = next_ch();
-  do {
-    entry = stateP[ch];
-    stateP = classActionTable[entry].nextStateP;
-    actionP = classActionTable[entry].actionRoutineP;
-    ch = (*actionP)(ch);
-  } while(ch != DONE);
-  /* Return results */
-  tokenLength = tokenCharP - tokenStartP;
-}