aboutsummaryrefslogtreecommitdiff
path: root/sys/fio/ungetci.x
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /sys/fio/ungetci.x
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'sys/fio/ungetci.x')
-rw-r--r--sys/fio/ungetci.x69
1 files changed, 69 insertions, 0 deletions
diff --git a/sys/fio/ungetci.x b/sys/fio/ungetci.x
new file mode 100644
index 00000000..9a8283a3
--- /dev/null
+++ b/sys/fio/ungetci.x
@@ -0,0 +1,69 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <config.h>
+include <syserr.h>
+include <fio.h>
+
+# UNGETCI -- Push a character back into the input stream. Pushback is last
+# in first out, i.e., the last character pushed will be the first character
+# returned in the next getc, getline, or read. Multiple characters and
+# strings may be pushed back into the input until the push back buffer
+# overflows. Overflow is often an indication of recursion in whatever
+# routine is doing the pushback.
+#
+# Single character pushback is fairly expensive, but the i/o system is
+# very efficient for even character at a time input and is optimized with
+# that in mind. The overhead for pushing back an entire string is about
+# the same as for a single character, so recursive macro expansion may be
+# implemented quite efficiently with this pushback technique.
+
+procedure ungetci (fd, ch)
+
+int fd # file
+int ch # char to be pushed back
+pointer pb_sp, pb_iop
+int or()
+include <fio.com>
+
+begin
+ fp = fiodes[fd]
+ if (fd <= 0 || fp == NULL)
+ call syserr (SYS_FILENOTOPEN)
+
+ if (FPBBUF(fp) == NULL)
+ call fmkpbbuf (fd)
+
+ # Push the old pb_iop, iop, itop and bufptr on the stack. Note bufptr
+ # must be set to a value less than or equal to iop to avoid a buffer
+ # fault.
+
+ pb_iop = FPBIOP(fp)
+ pb_sp = FPBSP(fp) - 1
+
+ Memi[pb_sp] = pb_iop
+ pb_sp = pb_sp - 1
+ Memi[pb_sp] = bufptr[fd]
+ pb_sp = pb_sp - 1
+ Memi[pb_sp] = itop[fd]
+ pb_sp = pb_sp - 1
+ Memi[pb_sp] = iop[fd]
+
+ # Deposit the char in the pbbuf and set up i/o pointers. When iop
+ # reaches itop filbuf will pop the old input pointers off the pbstack.
+ # Note: pushed back data grows upward, while the pb stack grows
+ # downward.
+
+ Memc[pb_iop] = ch
+ bufptr[fd] = pb_iop
+ iop[fd] = pb_iop
+ pb_iop = pb_iop + 1
+ itop[fd] = pb_iop
+
+ # Check for overflow.
+ if (pb_iop >= (pb_sp - 1) * SZ_INT + 1)
+ call syserrs (SYS_FPBOVFL, FNAME(fp))
+
+ FPBSP(fp) = pb_sp
+ FPBIOP(fp) = pb_iop
+ fflags[fd] = or (fflags[fd], FF_PUSHBACK)
+end