Listing 9 gettok.c - scanning function that must recognize mixed numbers in various forms

/* gettok.c */
/* Copyright 1992 by P.J. LaBrocca */

#include <stdio.h>
#include <ctype.h>
#include "mixed.h"
#include "mixcalc.h"

#define LookAhead(x) while( (x = getchar()) == '' || x == '\t')

jmp_buf startup;

mixed_t *M;
enum token_value CurrentToken;

enum token_value gettok( void ) {
    int c;
    Integer tmp1, tmp2, tmp3;

    LookAhead( c );
    if( c == EOF )
       return CurrentToken = ENDFILE;
    if( isdigit(c) ) { 
       ungetc( c, stdin );
       scanf("%ld", &tmp1);
       LookAhead(c);
       if( isdigit(c) ) {
          ungetc( c, stdin );
          scanf("%ld", &tmp2);
          LookAhead(c);
                    if(c != '|') {
                           fprintf( stderr, "Expected '|'\n");
             fflush( stdin );
             longjmp( startup, 1 );
          }
          LookAhead(c);
          if( !isdigit(c) ) {
                           fprintf( stderr, "Expected a digit\n");
             fflush( stdin );
             longjmp( startup, 1 );
          }
          ungetc( c, stdin );
          scanf("%ld", &tmp3 );
                    if( tmp3 == 0 ) {
                           fprintf( stderr, "Denominator cannot be zero\n");
             fflush( stdin );
             longjmp( startup, 1 );
          }
                    mix_init( M, tmp1, tmp2, tmp3 );
          return CurrentToken = NUMBER;
    }
             if( c == '|'){
          LookAhead(c);
          if( !isdigit(c) ) {
                           fprintf( stderr, "Expected a digit\n");
             fflush( stdin );
             longjmp( startup, 1 );
          }
          ungetc( c, stdin );
          scanf("%ld", &tmp2 );
                    if( tmp2 == 0 ) {
                           fprintf( stderr, "Denominator cannot be zero\n");
             fflush( stdin );
             longjmp( startup, 1 );
          }
                    mix_init( M, 0, tmp1, tmp2 );
          return CurrentToken = NUMBER;
       }
       ungetc( c, stdin );
             mix_init( M, tmp1, 0, 1, );

          return CurrentToken = NUMBER;
       }
       if( c == '\n' || c == ';')
          return CurrentToken = PRINT;
       switch ( c ) {
          case '*':
          case '+':
          case '-':
          case '/':
          case '(':
          case ')':
             return CurrentToken = c;
          default:
                       fprintf( stderr, "Unknown token: %c\n", c);
             fflush( stdin);
             longjmp( startup, 1 );
    }
}

/* End of File */