/ bcpl.c
bcpl.c
  1  // Helper functions for bcpl.h
  2  
  3  #include "bcpl.h"
  4  #include "emas.h"	// for TERMINATOR
  5  
  6  #include <ctype.h>	// for isdigit()
  7  #include <string.h>	// for strcmp()
  8  
  9  // Which file descriptors should BCPL's input and output use?
 10  // We use (FILE *)0 as a synonym for stdin / stdout since
 11  // we can't initialise statically because stdin and stdout
 12  //  are not constants on some systems.
 13  FILE *bcpl_INPUT_fp=(FILE *)0;
 14  FILE *bcpl_OUTPUT_fp=(FILE *)0;
 15  
 16  FILE *
 17  bcpl_FINDINPUT(char *file)
 18  {
 19  	IF strcmp(file, ".IN") == 0 DO file="/dev/stdin";
 20  	RESULTIS fopen(file, "r");
 21  }
 22  
 23  FILE *
 24  bcpl_FINDOUTPUT(char *file)
 25  {
 26  	IF strcmp(file, ".OUT") == 0 DO file="/dev/stdout";
 27  	IF strcmp(file, ".ERR") == 0 DO file="/dev/stderr";
 28  	RESULTIS fopen(file, "w");
 29  }
 30  
 31  // EMAS's READN() gobbles up the following character
 32  // and deposits it in a global variable TERMINATOR. So we do the same.
 33  
 34  // KRC only needs positive numbers, and an initial digit is guaranteed,
 35  WORD bcpl_READN()
 36  {  WORD D = 0;
 37     int CH = RDCH();
 38     WHILE isdigit(CH) DO {
 39        D=D*10+(CH-'0');
 40        CH=RDCH();
 41     }
 42     TERMINATOR=CH;
 43     RESULTIS D;
 44  }
 45  
 46  // The character that has been UNRDCH-ed. -1 means none are pending.
 47  static int UNREADCH=-1;
 48  
 49  // The standard function for RDCH(c)
 50  int bcpl_RDCH()
 51  {
 52     IF UNREADCH>=0 DO {
 53        int CH=UNREADCH;
 54        UNREADCH=-1;
 55        RESULTIS CH;
 56     }
 57     RESULTIS getc(bcpl_INPUT);
 58  }
 59  
 60  // A version of RDCH that echoes what it reads
 61  int echo_RDCH()
 62  {
 63     int CH;
 64     IF UNREADCH>=0 DO {
 65        CH=UNREADCH;
 66        UNREADCH=-1;
 67        RESULTIS CH;
 68     }
 69     CH=getc(bcpl_INPUT);
 70     WRCH(CH);
 71     RESULTIS CH;
 72  }
 73  
 74  int bcpl_UNRDCH(int c)
 75  {
 76          return(UNREADCH=c & 0xff);
 77  }
 78  
 79  // The standard function for WRCH(c)
 80  void bcpl_WRCH(WORD C)
 81  {
 82  	putc(C, bcpl_OUTPUT);
 83  }
 84  
 85  // _RDCH and _WRCH are the function pointers used to perform
 86  // RDCH() and WRCH() and may be modified to attain special effects.
 87  // Normally in BCPL you would say "WRCH=WHATEVER"
 88  // but in C, WRCH and WRCH() would conflict so
 89  // say _WRCH=WHATEVER to change it,
 90  
 91  int (*_RDCH)() = bcpl_RDCH;
 92  int (*_UNRDCH)(int) = bcpl_UNRDCH;
 93  void (*_WRCH)(WORD C) = bcpl_WRCH;
 94  
 95  // Other output functions must go through WRCH so that
 96  // callers may redirect it to some other function.
 97  void
 98  bcpl_WRITES(char *s) { while (*s) WRCH(*s++); }
 99  
100  // Helper function writes positive integers
101  static void
102  bcpl_WRITEP(WORD n) {
103        if (n/10) bcpl_WRITEP(n/10);
104        WRCH(n%10 + '0');
105  }
106  
107  void
108  bcpl_WRITEN(WORD n) {
109     if (n<0) { WRCH('-'); n=-n; }
110     bcpl_WRITEP(n);
111  }