From 40e5a5811c6ffce9b0974e93cdd927cbcf60c157 Mon Sep 17 00:00:00 2001 From: Joe Hunkeler Date: Tue, 11 Aug 2015 16:51:37 -0400 Subject: Repatch (from linux) of OSX IRAF --- sys/libc/Libc.hlp | 559 ++++++++++++++++++++++++++++++++++++++++++++++++++ sys/libc/README | 208 +++++++++++++++++++ sys/libc/atof.c | 24 +++ sys/libc/atoi.c | 48 +++++ sys/libc/atol.c | 49 +++++ sys/libc/caccess.c | 22 ++ sys/libc/calloc.c | 27 +++ sys/libc/callocate.c | 80 ++++++++ sys/libc/cclktime.c | 35 ++++ sys/libc/cclose.c | 23 +++ sys/libc/ccnvdate.c | 25 +++ sys/libc/ccnvtime.c | 25 +++ sys/libc/cdelete.c | 20 ++ sys/libc/cenvget.c | 143 +++++++++++++ sys/libc/cenvlist.c | 32 +++ sys/libc/cenvmark.c | 54 +++++ sys/libc/cenvscan.c | 32 +++ sys/libc/cerract.c | 21 ++ sys/libc/cerrcode.c | 15 ++ sys/libc/cerrget.c | 27 +++ sys/libc/cerror.c | 20 ++ sys/libc/cfchdir.c | 19 ++ sys/libc/cfilbuf.c | 36 ++++ sys/libc/cfinfo.c | 30 +++ sys/libc/cflsbuf.c | 43 ++++ sys/libc/cflush.c | 20 ++ sys/libc/cfmapfn.c | 36 ++++ sys/libc/cfmkdir.c | 20 ++ sys/libc/cfnextn.c | 26 +++ sys/libc/cfnldir.c | 26 +++ sys/libc/cfnroot.c | 25 +++ sys/libc/cfpath.c | 34 +++ sys/libc/cfredir.c | 46 +++++ sys/libc/cfseti.c | 22 ++ sys/libc/cfstati.c | 21 ++ sys/libc/cgetpid.c | 15 ++ sys/libc/cgetuid.c | 24 +++ sys/libc/cgflush.c | 20 ++ sys/libc/cimaccess.c | 28 +++ sys/libc/cimdrcur.c | 39 ++++ sys/libc/ckimapc.c | 28 +++ sys/libc/clexnum.c | 54 +++++ sys/libc/cmktemp.c | 27 +++ sys/libc/cndopen.c | 25 +++ sys/libc/cnote.c | 29 +++ sys/libc/copen.c | 26 +++ sys/libc/coscmd.c | 33 +++ sys/libc/cpoll.c | 150 ++++++++++++++ sys/libc/cprcon.c | 198 ++++++++++++++++++ sys/libc/cprdet.c | 109 ++++++++++ sys/libc/cprintf.c | 53 +++++ sys/libc/crcursor.c | 28 +++ sys/libc/crdukey.c | 28 +++ sys/libc/cread.c | 70 +++++++ sys/libc/crename.c | 26 +++ sys/libc/creopen.c | 27 +++ sys/libc/csalloc.c | 80 ++++++++ sys/libc/cseek.c | 42 ++++ sys/libc/csppstr.c | 31 +++ sys/libc/cstropen.c | 26 +++ sys/libc/cstrpak.c | 35 ++++ sys/libc/cstrupk.c | 41 ++++ sys/libc/ctsleep.c | 18 ++ sys/libc/cttset.c | 88 ++++++++ sys/libc/cttycdes.c | 19 ++ sys/libc/cttyclear.c | 21 ++ sys/libc/cttyclln.c | 22 ++ sys/libc/cttyctrl.c | 27 +++ sys/libc/cttygetb.c | 24 +++ sys/libc/cttygeti.c | 23 +++ sys/libc/cttygetr.c | 22 ++ sys/libc/cttygets.c | 34 +++ sys/libc/cttygoto.c | 23 +++ sys/libc/cttyinit.c | 22 ++ sys/libc/cttyodes.c | 89 ++++++++ sys/libc/cttyputl.c | 28 +++ sys/libc/cttyputs.c | 29 +++ sys/libc/cttyseti.c | 22 ++ sys/libc/cttyso.c | 23 +++ sys/libc/cttystati.c | 21 ++ sys/libc/ctype.c | 31 +++ sys/libc/cungetc.c | 28 +++ sys/libc/cungetl.c | 31 +++ sys/libc/cvfnbrk.c | 30 +++ sys/libc/cwmsec.c | 20 ++ sys/libc/cwrite.c | 51 +++++ sys/libc/cxgmes.c | 29 +++ sys/libc/cxonerr.c | 19 ++ sys/libc/cxttysize.c | 25 +++ sys/libc/cxwhen.c | 63 ++++++ sys/libc/eprintf.c | 25 +++ sys/libc/fclose.c | 23 +++ sys/libc/fdopen.c | 76 +++++++ sys/libc/fflush.c | 24 +++ sys/libc/fgetc.c | 19 ++ sys/libc/fgets.c | 43 ++++ sys/libc/fopen.c | 61 ++++++ sys/libc/fputc.c | 20 ++ sys/libc/fputs.c | 22 ++ sys/libc/fread.c | 55 +++++ sys/libc/freadline.c | 34 +++ sys/libc/free.c | 22 ++ sys/libc/freopen.c | 56 +++++ sys/libc/fseek.c | 93 +++++++++ sys/libc/ftell.c | 21 ++ sys/libc/fwrite.c | 36 ++++ sys/libc/gets.c | 34 +++ sys/libc/getw.c | 28 +++ sys/libc/index.c | 26 +++ sys/libc/isatty.c | 20 ++ sys/libc/libc_proto.h | 326 +++++++++++++++++++++++++++++ sys/libc/malloc.c | 24 +++ sys/libc/mathf.f | 75 +++++++ sys/libc/mkpkg | 168 +++++++++++++++ sys/libc/mktemp.c | 24 +++ sys/libc/perror.c | 36 ++++ sys/libc/printf.c | 245 ++++++++++++++++++++++ sys/libc/puts.c | 25 +++ sys/libc/putw.c | 27 +++ sys/libc/qsort.c | 221 ++++++++++++++++++++ sys/libc/realloc.c | 28 +++ sys/libc/rewind.c | 19 ++ sys/libc/rindex.c | 27 +++ sys/libc/scanf.c | 558 +++++++++++++++++++++++++++++++++++++++++++++++++ sys/libc/setbuf.c | 68 ++++++ sys/libc/spf.c | 65 ++++++ sys/libc/sprintf.c | 58 ++++++ sys/libc/stgio.c | 60 ++++++ sys/libc/strcat.c | 24 +++ sys/libc/strcmp.c | 22 ++ sys/libc/strcpy.c | 21 ++ sys/libc/strdup.c | 22 ++ sys/libc/strlen.c | 21 ++ sys/libc/strncat.c | 26 +++ sys/libc/strncmp.c | 22 ++ sys/libc/strncpy.c | 27 +++ sys/libc/system.c | 26 +++ sys/libc/ungetc.c | 29 +++ sys/libc/zzdebug.x | 7 + sys/libc/zztest.c | 98 +++++++++ 140 files changed, 7204 insertions(+) create mode 100644 sys/libc/Libc.hlp create mode 100644 sys/libc/README create mode 100644 sys/libc/atof.c create mode 100644 sys/libc/atoi.c create mode 100644 sys/libc/atol.c create mode 100644 sys/libc/caccess.c create mode 100644 sys/libc/calloc.c create mode 100644 sys/libc/callocate.c create mode 100644 sys/libc/cclktime.c create mode 100644 sys/libc/cclose.c create mode 100644 sys/libc/ccnvdate.c create mode 100644 sys/libc/ccnvtime.c create mode 100644 sys/libc/cdelete.c create mode 100644 sys/libc/cenvget.c create mode 100644 sys/libc/cenvlist.c create mode 100644 sys/libc/cenvmark.c create mode 100644 sys/libc/cenvscan.c create mode 100644 sys/libc/cerract.c create mode 100644 sys/libc/cerrcode.c create mode 100644 sys/libc/cerrget.c create mode 100644 sys/libc/cerror.c create mode 100644 sys/libc/cfchdir.c create mode 100644 sys/libc/cfilbuf.c create mode 100644 sys/libc/cfinfo.c create mode 100644 sys/libc/cflsbuf.c create mode 100644 sys/libc/cflush.c create mode 100644 sys/libc/cfmapfn.c create mode 100644 sys/libc/cfmkdir.c create mode 100644 sys/libc/cfnextn.c create mode 100644 sys/libc/cfnldir.c create mode 100644 sys/libc/cfnroot.c create mode 100644 sys/libc/cfpath.c create mode 100644 sys/libc/cfredir.c create mode 100644 sys/libc/cfseti.c create mode 100644 sys/libc/cfstati.c create mode 100644 sys/libc/cgetpid.c create mode 100644 sys/libc/cgetuid.c create mode 100644 sys/libc/cgflush.c create mode 100644 sys/libc/cimaccess.c create mode 100644 sys/libc/cimdrcur.c create mode 100644 sys/libc/ckimapc.c create mode 100644 sys/libc/clexnum.c create mode 100644 sys/libc/cmktemp.c create mode 100644 sys/libc/cndopen.c create mode 100644 sys/libc/cnote.c create mode 100644 sys/libc/copen.c create mode 100644 sys/libc/coscmd.c create mode 100644 sys/libc/cpoll.c create mode 100644 sys/libc/cprcon.c create mode 100644 sys/libc/cprdet.c create mode 100644 sys/libc/cprintf.c create mode 100644 sys/libc/crcursor.c create mode 100644 sys/libc/crdukey.c create mode 100644 sys/libc/cread.c create mode 100644 sys/libc/crename.c create mode 100644 sys/libc/creopen.c create mode 100644 sys/libc/csalloc.c create mode 100644 sys/libc/cseek.c create mode 100644 sys/libc/csppstr.c create mode 100644 sys/libc/cstropen.c create mode 100644 sys/libc/cstrpak.c create mode 100644 sys/libc/cstrupk.c create mode 100644 sys/libc/ctsleep.c create mode 100644 sys/libc/cttset.c create mode 100644 sys/libc/cttycdes.c create mode 100644 sys/libc/cttyclear.c create mode 100644 sys/libc/cttyclln.c create mode 100644 sys/libc/cttyctrl.c create mode 100644 sys/libc/cttygetb.c create mode 100644 sys/libc/cttygeti.c create mode 100644 sys/libc/cttygetr.c create mode 100644 sys/libc/cttygets.c create mode 100644 sys/libc/cttygoto.c create mode 100644 sys/libc/cttyinit.c create mode 100644 sys/libc/cttyodes.c create mode 100644 sys/libc/cttyputl.c create mode 100644 sys/libc/cttyputs.c create mode 100644 sys/libc/cttyseti.c create mode 100644 sys/libc/cttyso.c create mode 100644 sys/libc/cttystati.c create mode 100644 sys/libc/ctype.c create mode 100644 sys/libc/cungetc.c create mode 100644 sys/libc/cungetl.c create mode 100644 sys/libc/cvfnbrk.c create mode 100644 sys/libc/cwmsec.c create mode 100644 sys/libc/cwrite.c create mode 100644 sys/libc/cxgmes.c create mode 100644 sys/libc/cxonerr.c create mode 100644 sys/libc/cxttysize.c create mode 100644 sys/libc/cxwhen.c create mode 100644 sys/libc/eprintf.c create mode 100644 sys/libc/fclose.c create mode 100644 sys/libc/fdopen.c create mode 100644 sys/libc/fflush.c create mode 100644 sys/libc/fgetc.c create mode 100644 sys/libc/fgets.c create mode 100644 sys/libc/fopen.c create mode 100644 sys/libc/fputc.c create mode 100644 sys/libc/fputs.c create mode 100644 sys/libc/fread.c create mode 100644 sys/libc/freadline.c create mode 100644 sys/libc/free.c create mode 100644 sys/libc/freopen.c create mode 100644 sys/libc/fseek.c create mode 100644 sys/libc/ftell.c create mode 100644 sys/libc/fwrite.c create mode 100644 sys/libc/gets.c create mode 100644 sys/libc/getw.c create mode 100644 sys/libc/index.c create mode 100644 sys/libc/isatty.c create mode 100644 sys/libc/libc_proto.h create mode 100644 sys/libc/malloc.c create mode 100644 sys/libc/mathf.f create mode 100644 sys/libc/mkpkg create mode 100644 sys/libc/mktemp.c create mode 100644 sys/libc/perror.c create mode 100644 sys/libc/printf.c create mode 100644 sys/libc/puts.c create mode 100644 sys/libc/putw.c create mode 100644 sys/libc/qsort.c create mode 100644 sys/libc/realloc.c create mode 100644 sys/libc/rewind.c create mode 100644 sys/libc/rindex.c create mode 100644 sys/libc/scanf.c create mode 100644 sys/libc/setbuf.c create mode 100644 sys/libc/spf.c create mode 100644 sys/libc/sprintf.c create mode 100644 sys/libc/stgio.c create mode 100644 sys/libc/strcat.c create mode 100644 sys/libc/strcmp.c create mode 100644 sys/libc/strcpy.c create mode 100644 sys/libc/strdup.c create mode 100644 sys/libc/strlen.c create mode 100644 sys/libc/strncat.c create mode 100644 sys/libc/strncmp.c create mode 100644 sys/libc/strncpy.c create mode 100644 sys/libc/system.c create mode 100644 sys/libc/ungetc.c create mode 100644 sys/libc/zzdebug.x create mode 100644 sys/libc/zztest.c (limited to 'sys/libc') diff --git a/sys/libc/Libc.hlp b/sys/libc/Libc.hlp new file mode 100644 index 00000000..e13faeea --- /dev/null +++ b/sys/libc/Libc.hlp @@ -0,0 +1,559 @@ +.help LIBC Sep84 "C Runtime Library" +.sp 2 +.ce +\fBIRAF Runtime Library for the C Language\fR +.ce +CL Interface to IRAF +.sp 3 +.nh +Introduction + + The IRAF runtime library for the C language was developed to port the +IRAF command language (CL) from UNIX to IRAF. The C runtime library (LIBC) +consists of two parts: an emulation of the standard i/o library provided +for the C language on an UNIX host, and a library of "system calls", i.e., +the C interface to the IRAF virtual operating system. + +.nh +Naming Conventions + + Providing familiar and predictable procedure names in C is complicated +by the possibility of name collisions with external names in the program +interface libraries. To solve this problem while maintaining compatibility +with UNIX the external names of all UNIX emulation procedures are assigned +in C \fIdefine\fR statements. The external name is simply the UNIX name +preceded by the prefix "u_", e.g., + + fopen() + +compiles as + + u_fopen() + +The names of the "system calls" are not compatible with those of the UNIX +system calls. Each system call maps directly to an IRAF program interface +procedure. The name of the C version is the IRAF name preceded by the +prefix "c_", e.g., + + open() + +is called in C as + + c_open() + +The "c_" names are not redefined except where necessary to produce an +external identifier unique in the first seven characters. When an external +name is redefined to make it unique in the first seven characters this +is done by application of the 4+1 rule, leaving the "c_" prefix as is. +The calling sequences of the C system calls have been kept as compatible +with the "crib sheet" versions as possible, even when a more convenient +syntax could have been used for C. + +.nh +Include Files + + C style global include files pose a problem in a portable system since +machine dependent filenames cannot be used. This problem is sidestepped +for LIBC by using the C language preprocessor to indirectly reference the +global include files via a single master include file installed in the +C system include file directory. The master include file is referenced +as . The actual include files reside in the IRAF directory system +(as does a copy of ) and hence are automatically ported with the +system. The pathname to the LIBC global include files is arbitrary, but +currently these files are stored in lib$libc. + +The technique used to access LIBC global include files in perhaps best +explained by use of a simple example from the CL: + + +.ks +.nf + #define import_spp global includes + #define import_libc + #define import_stdio + #include + + #include "config.h" local includes + #include "operand.h" + #include "param.h" + #include "task.h" +.fi +.ke + + +The include file contains preprocessor control lines which load +the include files referenced by "#define import_packagename" statements. +In addition to being portable, this technique has the benefits of ensuring +that the include files are loaded in the correct order and are not loaded +more than once. + +The include file referenced by \fIimport_libc\fR should be included in +every C source file which uses LIBC. In addition to loading the referenced +include files, also includes definitions for the IRAF root +directory IRAFDIR, the default image storage directory IMAGEDIR, and the +name of the host operating system (e.g. "UNIX" or "VMS"). + +.nh +UNIX Emulation + + All procedures in the UNIX standard i/o (stdio) package are emulated +in libc. A listing of the calling sequences of all currently implemented +procedures is given as an appendix. The syntax and semantics of these +procedures have been kept as close to those of the V7 UNIX procedures as +possible. + +.nh +IRAF Program Interface Routines + + All i/o in the CL is implemented ultimately by calls to procedures in +the IRAF program interface libraries. The UNIX emulation procedures +discussed in the previous sections, for example, are reasonably portable +C language packages which call C versions of the IRAF program interface +routines. With few exceptions the C version of each procedure maps trivially +to the corresponding program interface procedure. The main complication +arises from the need to pack and unpack character strings when calling an +SPP (Fortran) procedure from C. Read only arguments are passed by value +for the convenience of the C language progammer. + +The full program interface contains on the order of a thousand procedures +(including generics) and it would be prohibitively difficult to make them +all available in C. We have therefore included only the packages actually +used by the CL in the interface, and then only the most commonly used +procedures in each package. All files which directly reference program +interface procedures should include a reference to the C language include +file \fBirafio.h\fR. + +.nh 2 +File I/O (FIO) + + The fundamental unit of storage in both C and SPP is the \fBchar\fR, +but unfortunately a char is not necessarily the same size in both languages. +In the C version of FIO data is referenced in units of C chars (bytes), +subject to the restriction that only an \fIintegral\fR number of SPP chars +can be read and written at a time, and seeks must be aligned on a char +boundary. If a nonintegral number of SPP chars are read or written, +the interface will silently move the extra bytes necessary to fill out +an SPP char, possibly writing beyond the end of the input buffer on a read. +These problems are less serious than it might seem, however, since CL level +i/o is predominantly text only (binary file i/o is not currently used in +the CL). + +In keeping with the C language tradition, all FIO offsets are \fIzero\fR +indexed, and all integer valued procedures return ERR as the function value +in the event of an error. Pointer valued functions return NULL in the +event of an error. Although only "significant" function values are shown in the +calling sequences below, all procedures return a function value. + + +.ks +.nf +High Level FIO: + + fd = c_open (vfn, mode, type) + c_close (fd) + c_flush (fd) + + c_fseti (fd, param, value) + int = c_fstati (fd, param) + + stat = c_finfo (vfn, &fi) + y/n = c_access (vfn, mode, type) + c_delete (vfn) + c_rename (old_vfn, new_vfn) + c_mktemp (root, &fname, maxch) +.fi +.ke + + +The "low level" FIO procedures perform binary file i/o and fill and flush +the internal FIO file buffer. These procedures are called by the STDIO +package and are not intended to be called directly by general CL code. +Seeking is not implemented in STDIO due to the difficulty of implementing +\fBfseek\fR in a portable system, but is not currently required anywhere +in the CL. STDIO directly accesses the internal FIO buffer pointers +via a data structure defined in \fBirafio.h\fR. + + +.ks +.nf +Low Level FIO: + + nchars = c_read (fd, &buf, maxch) + c_write (fd, &buf, nchars) + c_seek (fd, loffset) + loffset = c_note (fd) + + ch = c_filbuf (fd) + ch = c_flsbuf (fd, ch) + FILE = c_fioptr (fd) +.fi +.ke + + +The file access modes and types are specified as in SPP, i.e., via predefined +integer constants defined in \fIirafio.h\fR (READ_ONLY, NEW_FILE, etc.). +Only a few \fBfset\fR options are implemented; these are likewise defined +in \fIirafio.h\fR. The integer constants STDIN, STDOUT, etc. refer to +FIO file descriptors, and should not be confused with \fBstdin\fR, +\fBstdout\fR, etc., which reference STDIO file pointers. + +.nh 2 +Environment Facilities + + The environment list is managed entirely by the program interface via +the ENV package. The CL calls ENV procedures to create, modify, and access +the environment list. The \fBc_propen\fR procedure in the program interface +passes the environment list on to a connected child process at process +creation time. + + +.ks +.nf + nchars = c_envgets (name, &value, maxch) + redef = c_envputs (name, &value) + c_envmark (&sp) + nredefs = c_envfree (sp) + + bool = c_envgetb (name) + int = c_envgeti (name) + c_envlist (out_fd, prefix, show_redefs) + nscan = c_envscan (input_source) +.fi +.ke + +The following (non program interface) procedure is defined and used internally +by the CL to lookup names in the environment list: + + strp = envget (name) + +.nh 3 +Implementation Notes + + The environment list is maintained as a multi-threaded linked list. This +provides the searching efficiency of a hash table plus stack like semantics +for redefinitions and for freeing blocks of variables. There are two primary +data structures internally, an array of pointers to the heads of the threads, +and a buffer containing the list elements. These data structures are +dynamically allocated and will be automatically reallocated at runtime if +overflow occurs. The number of threads determines the hashing efficiency and +is a compile time parameter. + +The \fBenvmark\fR and \fBenvfree\fR procedures +mark and free storage on the environment list stack. +All environment variables defined or redefined after a call to \fBenvmark\fR +will be deleted and storage freed by a call to \fBenvfree\fR. If a redef +is freed the next most recent definition becomes current. \fBEnvfree\fR returns +as its function value the number of redefined variables uncovered by the free +operation. The calling program must mark and free in the correct order or the +environment list may be trashed. + +The \fBenvlist\fR procedure prints the environment list on a file. +Redefined values will be printed only if so indicated. +The environment list is printed as a list of +\fBset\fR statements in most recent first order, i.e., + + +.ks +.nf + set nameN=valueN + set nameM=valueM + ... + set name1=value1 +.fi +.ke + + +The \fBenvlist\fR function is used both to inspect the environment list +and to pass the list on to a child process. +Redefined variables are omitted when passing +the list on to a child process, hence the order of definition does not matter. +The output format is "prefix name=value", where the prefix string is supplied +by the user. + +The \fBenvscan\fR function parses one or more \fBset\fR statements, +calling \fBenvputs\fR to enter the SET declarations into the environment list. +The argument is either a \fBset\fR declaration or a string of the form +"set @filename", where "filename" is the name of a file containing \fBset\fR +declarations. + +.nh 2 +Process Control + + Separate facilities are provided for \fBconnected\fR and \fBdetached\fR +processes. Virtually all process control is concerned with connected +subprocesses, i.e., subprocesses running synchronously with the CL and +communicating with the CL via bidirectional IPC channels. The only detached +process in the system is the CL itself, when spawned as a background job +by another (usually interactive) CL process. + +.nh 3 +Connected Subprocesses + + A connected subprocess is connected with \fBpropen\fR and disconnected +with \fBprclose\fR. The \fBpropen\fR procedure spawns the named process, +connects the IPC channels to FIO file descriptors, then sends commands to +the child process to initialize the environment and current working directory. +Once connected the \fIin\fR and \fIout\fR file descriptors may be reopened +with \fBfdopen\fR for UNIX style i/o to the subprocess. The \fBprclose\fR +procedure sends the "bye" (shutdown) command to the child, waits for the +child to terminate, and then returns the process termination status as the +function value. Normal exit status is OK, otherwise a positive integer +error code is returned. + + +.ks +.nf + pid = c_propen (process, in, out) + stat = c_prclose (pid) + c_prsignal (pid, signal) + c_prredir (pid, stream, new_fd) + c_prupdate (message) +.fi +.ke + + +To execute a task in a connected child process the CL writes a command to +the \fIout\fR channel with a conventional \fBfputs\fR or other STDIO call. +After starting the task the CL redirects its command input to the \fIin\fR +channel of the task; conventional \fBfgets\fR or \fBgetc\fR calls are made +to read commands from the task, until "bye" is received, signaling task +termination. + +New \fBset\fR or \fBchdir\fR statements may be broadcast to all connected +subprocesses at any time (except while actually executing a task resident +in a connected subprocess) by a call to \fBprupdate\fR. While there is no +way the CL can free space on the environment stack in a child process, it is +possible to broadcast new redefinitions to all child processes if redefinitions +should be uncovered by an \fBenvfree\fR call in the CL. + +The \fBprsignal\fR procedure is used to raise the interrupt exception X_INT +in a connected child process. When the user types interrupt (e.g. ctrl/c) +at the CL level, the CL interrupt exception handler signals the child +process containing the external task currently in execution (if any), +and then resumes processing of commands from the child. If a special exception +handler is not posted in the child it will go through error restart, +eventually sending the \fBerror\fR statement to the CL indicating abnormal +termination of the task. Note that it is permissible for a child process +to ignore the interrupt exception, or take special recovery actions if +interrupt occurs. + +.nh 4 +I/O Redirection + + Pseudofile i/o (\fBxmit\fR and \fBxfer\fR directives for the task's STDIN, +STDOUT, etc.) is handled by the program interface transparently to the CL. +By default the standard i/o streams of the child are connected to the +identical streams of the parent (the CL). If redirection of a stream +is desired the stream may be redirected in either of two ways: +.ls +.ls [1] +A stdio stream may be redirected directly at the task level in the child +process by including redirection information on the command line sent to +the child to execute the task. This is the most efficient technique, and +it should be used when appropriate, e.g., for pipes or whenever an output +stream of an external task is explicitly redirected on the CL command line. +The syntax of the task statement recognized by the IRAF Main is documented +in the \fISystem Interface Reference Manual\fR. For example, to run a task +with the standard output redirected to a pipe file: + +.ks +.nf + fprintf (out_fp, "%s %d > %s\n", + taskname, STDOUT, pipefilename); +.fi +.ke + +Pipe files, by the way, are implemented as binary files for maximum flexibility +and efficiency. This is acceptable since they are read and written only by +the system. Very high i/o bandwidths are possible using direct i/o to a binary +file. +.le + +.ls [2] +A stdio stream may be redirected at the CL level to any previously opened +FIO file, e.g., to one of the CL's standard streams, to a text or binary +file opened explicitly by the CL, or to another child process (e.g. redirection +of the standard graphics output of the child to a graphics subprocess). +This type of redirection requires the following steps by the CL: +.ls +.ls o +Open local stream to which child's stream is to be redirected. +.le +.ls o +Call \fBprredir\fR to map the child's stream to the local stream. +.le +.ls o +When the task is run, include an argument of the form "N >" on the task +command line, indicating that stream N has been redirected by the parent +process (the file name is omitted). +.le +.ls o +When the task terminates, or when the next task is run in the same process, +restore the original i/o connection with another call to \fBprredir\fR. +The default connection is established by the system only at \fBpropen\fR time. +.le +.le +.le +.le + + +The I/O redirection mechanism permits messages to be shuffled from a child +process deep in the process tree to a device owned by the CL, or from a child +process in one branch of the process tree to a process in another branch of +the tree. If raw mode is set on the STDIN stream in the child it will +automatically be passed on to the process which physically reads the raw mode +device. Asynchronous execution is possible so long as messages pass only +one way. Synchronization occurs whenever a process waits on a read. The most +complex example of the IPC i/o redirection mechanism in the current system +occurs when a science or utility task sends graphics commands via the CL to a +separate graphics task. Ignoring GKS inquires, this process is fully +asynchronous and should be acceptably efficient provided the IPC buffer size +is reasonable (1-4 Kb) and large amounts of bulk data do not have to be passed. + +.nh 3 +Detached Processes + + The CL executes commands in the background, i.e., asynchronously, by +dumping the entire run time context of the CL into a binary background +file, then spawning a detached CL process to execute the already compiled +command in the context of the parent. The run time context consists of +the dictionary and stack areas, the environment list, and various other +internal state parameters which are copied into the header area of the +bkgfile. This is a potential problem area if dynamic memory is used, +since it may not be possible to duplicate the virtual addresses of the +parent's data area in the child. + + +.ks +.nf + job = c_propdpr (process, bkgfile) + stat = c_prcldpr (job) + y/n = c_prdone (job) + c_prkill (job) + + exit = c_onentry (prytpe, bkgfile) + c_onexit (epa) +.fi +.ke + + +The CL process uses the same IRAF Main as a normal IRAF process, except that +a special \fBonentry\fR procedure is linked which serves as the CL main. +The \fBonentry\fR procedure is called by the IRAF Main during +process startup with the arguments shown; the function value returned by +\fBonentry\fR determines whether or not the interpreter in the IRAF Main +is entered. Since we do not want IRAF Main prompts from the CL process +the CL version of \fBonentry\fR always returns CL_EXIT, causing process +shutdown following execution of any procedures posted with \fBonexit\fR +during execution of \fBonentry\fR. + +A detached process opened with \fBpropdpr\fR should always be closed with +\fBprcldpr\fR if it terminates while the parent is still executing. +The \fBprdone\fR procedure may be called to determine if a background job +has terminated. A background job may be aborted with \fBprkill\fR. + +.nh 2 +Terminal Control + + The TTY interface is provided at the CL level to support screen editing. +TTY is the IRAF interface to the \fBtermcap\fR terminal capability database, +originally developed at Berkeley for UNIX by Bill Joy. + + +.ks +.nf + tty = c_ttyodes (ttyname) + c_ttycdes (tty) + c_ttyseti (tty, parameter, value) + int = c_ttystati (tty, parameter) + + bool = c_ttygetb (tty, cap) + int = c_ttygeti (tty, cap) + float = c_ttygetr (tty, cap) + nchars = c_ttygets (tty, cap, &outstr, maxch) + c_ttyctrl (fd, tty, cap, afflncnt) + c_ttyputs (fd, tty, ctrlstr, afflncnt) + + c_ttyclear (fd, tty) + c_ttyclearln (fd, tty) + c_ttygoto (fd, tty, col, line) + c_ttyinit (fd, tty) + c_ttyputline (fd, tty, text, map_cc) + c_ttyso (fd, tty, onflag) +.fi +.ke + + +Complete descriptions of TTY and \fBtermcap\fR are given elsewhere. +Briefly, the device descriptor for a particular terminal is opened +with \fBttyodes\fR, which returns a IRAF pointer (C integer) to the +binary TTY descriptor. +The terminal name may be given as "terminal", in which case \fBttyodes\fR +will look up the name of the default terminal in the environment and search +the termcap database for the entry for the named device. + +The \fBttyget\fR functions are used to read the capabilities. +Capabilities are specified by two character mnemonics (character strings), +shown as the \fIcap\fR arguments in the calling sequences above. +Control sequences may be output with \fBttyctrl\fR or with \fBttyputs\fR, +depending on whether you are willing to do a binary search for a +particular capability at run time. +The remaining high level functions make it easy to perform the more common +control functions. + +Raw mode output to a terminal device is provided by the system interface +(the newline and tab characters are exceptions). Raw mode input is +provided as an \fBfseti\fR option in FIO. To set raw mode on STDIN: + + c_fseti (STDIN, F_RAW, YES); + +While raw mode is in effect input characters are read as they are typed, +few or no control characters are recognized, and no echoing is performed. + +.nh 2 +Memory Management + + Both heap and stack storage facilities are available in the program +interface, and we have made both types of facilities available in the CL. +Note, however, that the CL does not currently use dynamic memory allocation +directly due to the difficulties such use would cause when passing the +context of the CL to a background CL (used to execute commands in the +background). The CL currently makes heavy use of pointers in the dictionary +data structures, and since the dictionary is passed to the background CL +as a binary array, it must be restored to the same base memory address or +the pointers will be meaningless. This led to the implementation of the +dictionary and stack areas as fixed size, statically allocated arrays. + +The use of a fixed size dictionary is restrictive and wasteful of storage; +a future implementation based on \fBsalloc\fR (the stack facilities) is +desirable provided the context passing problem can be solved. Note that +the environment facilities do use dynamic storage and that it is nonetheless +possible to pass the environment to a background CL, despite the internal +use of pointers in the environment management package. + + +.ks +.nf +Heap Storage (UNIX compatible): + + buf = malloc (nchars) u_malloc + buf = calloc (nchars) u_calloc + mfree (buf) u_mfree + + +Stack Storage: + + c_smark (&sp) + buf = c_salloc (nchars) + c_sfree (sp) +.fi +.ke + + +Note that the C callable versions of \fBmalloc\fR, \fBcalloc\fR, and +\fBmfree\fR emulate the comparable UNIX procedures. The storage units +are C chars, i.e., bytes. Promotion to an integral number of SPP chars +is automatic. The \fIbuf\fR argument is a C pointer. The \fIsp\fR +argument, used to mark the position of the stack pointer, is an integer. +The stack is implemented in segments allocated on the heap, hence there +is no builtin limit on the size of the stack. diff --git a/sys/libc/README b/sys/libc/README new file mode 100644 index 00000000..4801a369 --- /dev/null +++ b/sys/libc/README @@ -0,0 +1,208 @@ +LIBC -- C language binding for a portion of the IRAF VOS + UNIX emulator + +This directory contains + + [1] A subset of the routines from the UNIX stdio library. These routines + emulate the equivalent UNIX routines but are interfaced to the IRAF + program interface. + + [2] C-callable versions of a subset of the routines from the IRAF program + interface. Included are portions of the following packages: + + file i/o + formatted i/o + environment + process control + terminal control + memory management + exception handling + +The header files "irafio.h" and "names.h" should be included in all C files +which reference the C library. The include files "stdio.h" and "ctype.h" +should be used wherever they would be used in a UNIX/C system. + + +IMPORTANT NOTE: + + Routines marked VARARGS are machine dependent in that they assume a +certain ordering (left to right) for the argument list. On some machines +the ordering may be the opposite. + +TODO: Rewrite these procedures to use the UNIX macros. + + +1. LIBC Emulation of UNIX C-Library Procedures + + syntax err eof + + double = asin (x) + double = acos (x) + double = atan (x) + double = atan2 (x, y) + double = atof (str) 0. + int = atoi (str) 0 + long = atol (str) 0 + charp = calloc (nelems, elsize) NULL + clearerr (fp) + double = cos (x) + double = exp (x) + fclose (fp) EOF + FILE = fdopen (fd, modestr) NULL + bool = feof (fp) + bool = ferror (fp) + fflush (fp) EOF + ch = fgetc (fp) EOF + charp = fgets (buf, maxch, fp) NULL + fd = fileno (fp) + FILE = fopen (fname, modestr) NULL + fputc (ch, fp) EOF + fputs (str, fp) + nelem = fread (bp, szelem, nelem, fp) 0 0 + free (buf) + FILE = freopen (fname, modestr, fp) NULL + fseek (fp, offset, origin) EOF + long = ftell (fp) + nelem = fwrite (bp, szelem, nelem, fp) 0 0 + ch = getc (fp) EOF EOF + ch = getchar () EOF EOF + charp = getenv (envvar) NULL + charp = gets (buf) NULL NULL + word = getw (fp) EOF EOF + charp = index (str, ch) NULL + double = log (x) + double = log10 (x) + int = nint (x) + charp = malloc (nbytes) NULL + charp = mktemp (template) NULL + perror (prefix) + double = pow (x, y) + printf (format, argp) + fprintf (fp, format, argp) + sprintf (str, format, argp) + eprintf (format, argp) + ch = putc (ch, fp) EOF + ch = putchar (ch) EOF + puts (str) + word = putw (word, fp) EOF + qsort (array, len, isize, compar) + charp = realloc (buf, newsize) NULL + rewind (fp) EOF + charp = rindex (str, ch) + nscan = scanf (format, argp) EOF EOF + nscan = fscanf (fp, format, argp) EOF EOF + nscan = sscanf (str, format, argp) EOF EOF + setbuf (fp, buf) + setbuffer (fp, buf, size) + setlinebuf (fp) + double = sin (x) + double = sqrt (x) + charp = strcat (s1, s2) + charp = strcmp (s1, s2) + charp = strcpy (s1, s2) + int = strlen (str) + charp = strncat (s1, s2, n) + charp = strncmp (s1, s2, n) + charp = strncpy (s1, s2, n) + stat = system (cmd) + ch = ungetc (ch, fp) EOF + + + +2. System Calls + +All output parameters are shown as "&name" regardless of whether the actual +parameter is a pointer. If no ERR or EOF type is shown it is inapplicable to +the procedure. The error type "*" denotes an error action which will lead to +error recovery if not caught by calling the procedure inside an "iferr". In +general, error actions are permitted only where errors are not expected and +where we suspect that the programmer would ignore an error return code if one +were used. Fatal errors cannot be caught but "cannot happen". + + + syntax err eof + + bool = c_access (fname, mode, type) * + longsec = c_clktime (reftime) + c_close (fd) * + charp = c_cnvdate (clktime, &outstr, maxch) + charp = c_cnvtime (clktime, &outstr, maxch) + longmsec = c_cputime (reftime) + c_delete (fname) ERR + nchars = c_envfind (var, &outstr, maxch) 0 + nchars = c_envgets (var, &outstr, maxch) 0 + bool = c_envgetb (var) no=0 + ival = c_envgeti (var) * + c_envputs (var, value) * + c_envlist (fd, prefix, show_redefs) * + c_envmark (&envp) + nredefs = c_envfree (envp) + nscan = c_envscan (input_source) * + c_error (errcode, errmsg) * + c_erract (action) * + errcode = c_errget (&outstr, maxch) + c_fchdir (newdir) ERR + ch = c_filbuf (fp) EOF EOF + c_finfo (fname, fi) ERR + ch = c_flsbuf (ch, fp) EOF + c_flush (fd) * + nchars = c_fmapfn (vfn, &osfn, maxch) 0 + stat = c_fmkdir (newdir) ERR + nchars = c_fnldir (vfn, &ldir, maxch) + nchars = c_fnroot (vfn, &root, maxch) + nchars = c_fnextn (vfn, &extn, maxch) + nchars = c_fpath (vfn, &osfn, maxch) 0 + fd = c_fredir (fd, fname, mode, type) ERR + c_fseti (fd, param, value) * + ival = c_fstati (fd, param) * + int = c_getpid () + c_getuid (&outstr, maxch) * + os_chan = c_kimapchan (ki_chan, nodename, maxch) + token = c_lexnum (str, &toklen) + nchars = c_mktemp (root, &temp_filename, maxch) 0 + long = c_note (fd) * + fd = c_open (fname, mode, type) ERR + exit_stat = c_oscmd (cmd, infile, outfile, errfile) * + c_prchdir (pid, newdir) ERR + exit_stat = c_prcldpr (job) * + c_prclose (pid) * + bool = c_prdone (job) * + c_prenvset (pid, envvar, valuestr) ERR + c_prkill (job) ERR + pid = c_propdpr (process, bkgfile) NULL + pid = c_propen (process, &in, &out) NULL + c_prredir (pid, stream, new_fd) ERR + c_prsignal (pid, signal) ERR + nbytes = c_read (fd, &buf, maxbytes) * EOF + c_rename (old_fname, new_fname) ERR + charp = c_salloc (nbytes) fatal + c_smark (&sp) fatal + c_sfree (sp) fatal + bool = c_stkcmp (p1, p2) * + c_seek (fd, offset) ERR + xcharp = c_sppstr (xstr) + cstr = c_strpak (sppstr, &cstr, maxch) + xcharp = c_strupk (str, &xoutstr, maxch) + c_tsleep (nseconds) + tty(int) = c_ttyodes (ttyname) ERR + c_ttycdes (tty) * + c_ttyseti (tty, param, value) * + ival = c_ttystati (tty, param) * + bool = c_ttygetb (tty, cap) no=0 + ival = c_ttygeti (tty, cap) 0 + fval = c_ttygetr (tty, cap) 0. + nchars = c_ttygets (tty, cap, &outstr, maxch) 0 + c_ttyputs (fd, tty, cap, afflncnt) ERR + c_ttyctrl (fd, tty, cap, afflncnt) ERR + c_ttyclear (fd, tty) * + c_ttyclearln (fd, tty) * + c_ttygoto (fd, tty, col, line) * + c_ttyinit (fd, tty) * + c_ttyputline (fd, tty, line, map_cc) * + c_ttyso (fd, tty, onoff) * + c_ungetc (fd, ch) ERR + c_ungetline (fd, str) ERR + c_vfnbrk (vfn, root, extn) + nbytes = c_write (fd, buf, nbytes) * + c_xwhen (vex, new_handler, old_handler) * + c_xgmes (oscode, oserrmsg, maxch) diff --git a/sys/libc/atof.c b/sys/libc/atof.c new file mode 100644 index 00000000..df0ec7d9 --- /dev/null +++ b/sys/libc/atof.c @@ -0,0 +1,24 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_ctype +#include + + +/* ATOF -- Ascii to double floating. Convert any legal floating point number +** into a binary double precision floating value. +*/ +double +atof (char *str) +{ + XINT ip = 1; + XDOUBLE dval; + + if (CTOD (c_sppstr(str), &ip, &dval) == 0) + return ( (double) 0); + else + return ( (double) dval); +} diff --git a/sys/libc/atoi.c b/sys/libc/atoi.c new file mode 100644 index 00000000..6df13153 --- /dev/null +++ b/sys/libc/atoi.c @@ -0,0 +1,48 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_ctype +#include + + +/* ATOI -- Ascii to integer. Convert a simple integer in decimal radix to +** a binary integer value. +*/ +int +atoi (char *str) +{ + register char *ip = str; + register int ch, ival; + int neg; + + + if (*str == EOS) + return (0); + + /* Skip leading whitespace. */ + while (isspace (*ip)) + ip++; + + /* Check for indefinite. */ + if ((ch = *ip) == 'I') + if (strncmp (ip, "INDEF", 5) == 0) + if (! (isalnum (ch = *(ip+5)) || ch == '_')) + return (INDEFI); + + /* Check for leading + or - sign. */ + neg = 0; + if (ch == '-') { + neg++; + ip++; + } else if (ch == '+') + ip++; + + /* Accumulate sequence of digits. */ + ival = 0; + while (isdigit (ch = *ip++)) + ival = ival * 10 + tointeg(ch); + + return (neg ? -ival : ival); +} diff --git a/sys/libc/atol.c b/sys/libc/atol.c new file mode 100644 index 00000000..f5780583 --- /dev/null +++ b/sys/libc/atol.c @@ -0,0 +1,49 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_ctype +#include + + +/* ATOL -- Ascii to long integer. Convert a simple integer in decimal radix to +** a binary long integer value. +*/ +long +atol (char *str) +{ + register char *ip = str; + register int ch; + register long lval; + int neg; + + + if (*str == EOS) + return (0); + + /* Skip leading whitespace. */ + while (isspace (*ip)) + ip++; + + /* Check for indefinite. */ + if ((ch = *--ip) == 'I') + if (strncmp (ip, "INDEF", 5) == 0) + if (! (isalnum (ch = *(ip+5)) || ch == '_')) + return (INDEFL); + + /* Check for leading + or - sign. */ + neg = 0; + if (ch == '-') { + neg++; + ip++; + } else if (ch == '+') + ip++; + + /* Accumulate sequence of digits. */ + lval = 0; + while (isdigit (ch = *ip++)) + lval = lval * 10 + tointeg(ch); + + return (neg ? -lval : lval); +} diff --git a/sys/libc/caccess.c b/sys/libc/caccess.c new file mode 100644 index 00000000..13b6f52e --- /dev/null +++ b/sys/libc/caccess.c @@ -0,0 +1,22 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_ACCESS -- FIO file access. +*/ +int +c_access ( + char *fname, /* name of file to be accessed */ + int mode, /* access mode */ + int type /* file type */ +) +{ + XINT x_mode = mode, x_type = type; + + return (ACCESS (c_sppstr(fname), &x_mode, &x_type)); +} diff --git a/sys/libc/calloc.c b/sys/libc/calloc.c new file mode 100644 index 00000000..f9a4f044 --- /dev/null +++ b/sys/libc/calloc.c @@ -0,0 +1,27 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* CALLOC -- Allocate memory for NELEM elements of size ELSIZE bytes per +** element. The space is initialized to all zeros. +*/ +char * +calloc ( + unsigned int nelems, + unsigned int elsize +) +{ + XINT nchars = (nelems*elsize + sizeof(XCHAR)-1) / sizeof(XCHAR); + XINT ptr, dtype = TY_CHAR; + + + iferr (CALLOC (&ptr, &nchars, &dtype)) + return (NULL); + else + return ((char *)&Memc[ptr]); +} diff --git a/sys/libc/callocate.c b/sys/libc/callocate.c new file mode 100644 index 00000000..303896c3 --- /dev/null +++ b/sys/libc/callocate.c @@ -0,0 +1,80 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_ALLOCATE -- Allocate a device (and mount it, if necessary). +*/ +int +c_allocate ( + char *device /* device to be allocated */ +) +{ + int status; + + iferr (status = XALLOCATE (c_sppstr(device))) + return (ERR); + else + return (status); +} + + +/* C_DEALLOCATE -- Deallocate a device. +*/ +int +c_deallocate ( + char *device, /* device to be allocated */ + int rewind /* rewind flag, if magtape */ +) +{ + int status; + XINT x_rewind = rewind; + + iferr (status = (int) XDEALLOCATE (c_sppstr(device), &x_rewind)) + return (ERR); + else + return (status); +} + + +/* C_DEVSTATUS -- Print the current status of the named device. +*/ +void +c_devstatus ( + char *device, /* device name */ + int out /* output file */ +) +{ + XINT x_out = out; + + XDEVSTATUS (c_sppstr(device), &x_out); +} + + +/* C_DEVOWNER -- Determine if a device is allocated, and if so return +** the name of the owner. +*/ +int +c_devowner ( + char *device, /* device to be allocated */ + char *owner, /* receives owner name string */ + int maxch +) +{ + PKCHAR x_owner[SZ_FNAME+1]; + XINT x_maxch = SZ_FNAME; + int status; + + + iferr (status = (int) XDEVOWNER(c_sppstr(device), x_owner, &x_maxch)) { + owner[0] = EOS; + return (ERR); + } else { + c_strpak (x_owner, owner, maxch); + return (status); + } +} diff --git a/sys/libc/cclktime.c b/sys/libc/cclktime.c new file mode 100644 index 00000000..ca26e56e --- /dev/null +++ b/sys/libc/cclktime.c @@ -0,0 +1,35 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_CLKTIME -- Return the clock time in long integer seconds since Jan. 1, +** 1980, minus the reference argument (0 for absolute time). +*/ +long +c_clktime ( + long reftime /* reference time */ +) +{ + XLONG x_reftime = reftime; + + return (CLKTIME (&x_reftime)); +} + + +/* C_CPUTIME -- Return the cpu time consumed by the current process and all +** subprocesses, in long integer milliseconds, minus the reference time. +*/ +long +c_cputime ( + long reftime /* reference time */ +) +{ + XLONG x_reftime = reftime; + + return (CPUTIME (&x_reftime)); +} diff --git a/sys/libc/cclose.c b/sys/libc/cclose.c new file mode 100644 index 00000000..630f097d --- /dev/null +++ b/sys/libc/cclose.c @@ -0,0 +1,23 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_CLOSE -- FIO file close. +*/ +int +c_close ( + XINT fd /* FIO file descriptor */ +) +{ + XINT x_fd = fd; + + iferr (CLOSE (&x_fd)) + return (ERR); + else + return (OK); +} diff --git a/sys/libc/ccnvdate.c b/sys/libc/ccnvdate.c new file mode 100644 index 00000000..ee97169f --- /dev/null +++ b/sys/libc/ccnvdate.c @@ -0,0 +1,25 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_CNVDATE -- Convert long integer time as returned by CLKTIME into a short +** format date string. +*/ +char * +c_cnvdate ( + long clktime, /* seconds since jan.1,1980 */ + char *outstr, /* encoded time string */ + int maxch +) +{ + XCHAR buf[SZ_LINE]; + XINT x_maxch = SZ_LINE; + + CNVDATE (&clktime, buf, &x_maxch); + return (c_strpak (buf, outstr, maxch)); +} diff --git a/sys/libc/ccnvtime.c b/sys/libc/ccnvtime.c new file mode 100644 index 00000000..4923907c --- /dev/null +++ b/sys/libc/ccnvtime.c @@ -0,0 +1,25 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_CNVTIME -- Convert long integer time as returned by CLKTIME into a long +** format date string. +*/ +char * +c_cnvtime ( + long clktime, /* seconds since jan.1,1980 */ + char *outstr, /* encoded time string */ + int maxch +) +{ + XCHAR buf[SZ_LINE]; + XINT x_maxch = SZ_LINE; + + CNVTIME (&clktime, buf, &x_maxch); + return (c_strpak (buf, outstr, maxch)); +} diff --git a/sys/libc/cdelete.c b/sys/libc/cdelete.c new file mode 100644 index 00000000..14d97926 --- /dev/null +++ b/sys/libc/cdelete.c @@ -0,0 +1,20 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + +/* C_DELETE -- FIO delete file. +*/ +int +c_delete ( + char *fname /* name of file to be opened */ +) +{ + iferr (DELETE (c_sppstr(fname))) + return (ERR); + else + return (OK); +} diff --git a/sys/libc/cenvget.c b/sys/libc/cenvget.c new file mode 100644 index 00000000..2c812226 --- /dev/null +++ b/sys/libc/cenvget.c @@ -0,0 +1,143 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* +** ENVGET[SBI] -- Assorted routines for fetching the values of environment +** variables. +** ENVPUTS -- Set or redefine the value of an environment variable. +** ENVRESET -- Reset (overwrite) the value of an environment variable. +*/ + +#define SZ_VALUESTR SZ_COMMAND + +static XCHAR valuestr[SZ_VALUESTR+1]; +static XINT len_valuestr = SZ_VALUESTR; + + +/* ENVGET -- (Near) emulation of the UNIX getenv procedure. This is a handy +** routine for looking up environment variables in C programs. The value is +** fetched into an internal static array and a pointer to this array is returned +** as the function value, else NULL if the environment variable is not found. +** The caller is responsible for using the value string before it is overwritten +** by the next call. +*/ +char * +envget ( + char *var /* environment variable name */ +) +{ + if (ENVFIND (c_sppstr(var), valuestr, &len_valuestr) < 0) + return (NULL); + else + return (c_strpak (valuestr, (char *)valuestr, len_valuestr+1)); +} + + +/* C_ENVGETS -- Fetch the string value of an environment variable into the +** output string. Return the strlen length of the output string as the +** function value. If the variable is not found and the process is being +** used interactively a query is generated. If no value is given in response +** to the query or the process is noninteractive and the variable is not +** found, zero is returned. +*/ +int +c_envgets ( + char *var, /* name of variable to be fetched */ + char *outstr, /* output string */ + int maxch /* length including EOS */ +) +{ + register int nchars; + + if ((nchars = ENVGETS (c_sppstr(var), valuestr, &len_valuestr)) < 0) + return (nchars); + else { + c_strpak (valuestr, outstr, maxch); + return (nchars > maxch ? maxch : nchars); + } +} + + +/* C_ENVFIND -- Just like ENVGETS, except that a query will not be generated +** even if working interactively. +*/ +int +c_envfind ( + char *var, /* name of variable to be fetched */ + char *outstr, /* output string */ + int maxch /* length including EOS */ +) +{ + register int nchars; + + if ((nchars = ENVFIND (c_sppstr(var), valuestr, &len_valuestr)) < 0) + return (nchars); + else { + c_strpak (valuestr, outstr, maxch); + return (nchars > maxch ? maxch : nchars); + } +} + + +/* C_ENVGETB -- Return the boolean value of an environment variable. An error +** action is taken if the variable is not found or the value string cannot +** be interpreted as a boolean value. +*/ +int +c_envgetb ( + char *var /* name of variable to be fetched */ +) +{ + return ((int) BTOI ((XINT) ENVGETB (c_sppstr(var)))); +} + + +/* C_ENVGETI -- Return the integer value of an environment variable. An error +** action is taken if the variable is not found or the value string cannot +** be interpreted as an integer value. +*/ +int +c_envgeti ( + char *var /* name of variable to be fetched */ +) +{ + return ((int) ENVGETI (c_sppstr(var))); +} + + +/* C_ENVPUTS -- Set or redefine the value of an environment variable. If the +** variable is not defined a new entry is created. If the variable is already +** defined but has a different value it is redefined, with the new definition +** having precedence over the former (redefinitions can be undone; see envmark +** and envfree). If the variable is already defined and the new definition +** has the same value, it is ignored. +** +** Arguments: set var = value +*/ +void +c_envputs ( + char *var, /* name of variable to be set */ + char *value /* value string */ +) +{ + ENVPUTS (c_sppstr(var), c_strupk (value, valuestr, SZ_VALUESTR)); +} + + +/* C_ENVRESET -- Reset (overwrite) the value of an environment variable. +** If the variable is not defined a new entry is created. +*/ +void +c_envreset ( + char *var, /* name of variable to be set */ + char *value /* value string */ +) +{ + ENVRESET (c_sppstr(var), c_strupk (value, valuestr, SZ_VALUESTR)); +} diff --git a/sys/libc/cenvlist.c b/sys/libc/cenvlist.c new file mode 100644 index 00000000..1616a4d5 --- /dev/null +++ b/sys/libc/cenvlist.c @@ -0,0 +1,32 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_ENVLIST -- List the names and values of all environment variables on the +** output file. Variables are listed in the reverse of the order in which +** they were defined. If a variable is redefined all definitions or only the +** most recent definition may be listed. Each definition appears on a separate +** line in the following format: +** +** prefix var="value" +** +** where "prefix" is the prefix string supplied as an argument, "var" is the +** name of the variable, and "value" is the value string. +*/ +void +c_envlist ( + XINT fd, /* output file */ + char *prefix, /* prefix string, e.g. "set " */ + int show_redefs /* 0=hide redefs, 1=show redefs */ +) +{ + XINT x_fd = fd, + x_show_redefs = show_redefs; + + ENVLIST (&x_fd, c_sppstr(prefix), &x_show_redefs); +} diff --git a/sys/libc/cenvmark.c b/sys/libc/cenvmark.c new file mode 100644 index 00000000..14963844 --- /dev/null +++ b/sys/libc/cenvmark.c @@ -0,0 +1,54 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* ENVMARK -- Mark the position of the "stack pointer" of the environment +** list. A subsequent call to ENVFREE will unset all set environment +** operations since the corresponding mark. +*/ +void +c_envmark ( + XINT *envp /* storage for saved stack pointer */ +) +{ + ENVMARK (envp); +} + + +/* ENVFREE -- Free or unset all environment variables set since the matching +** call to ENVMARK. The number of redefined variables uncovered by the free +** operation is returned as the function value. +*/ +int +c_envfree ( + int envp, /* marker returned by envmark */ + int userfcn /* epa of user function for redefs */ +) +{ + XINT x_envp = envp; + + return (ENVFREE (&x_envp, (XINT *)&userfcn)); +} + + +/* PRENVFREE -- Free or unset all environment variables set since the matching +** call to ENVMARK. The number of redefined variables uncovered by the free +** operation is returned as the function value. This call is equivalent to +** envfree except that it also updates the values of any uncovered redefinitions +** in the specified connected subprocesses. +*/ +int +c_prenvfree ( + int pid, /* process pid, or 0 for all subprocs */ + int envp /* marker returned by envmark */ +) +{ + XINT x_pid = pid, x_envp = envp; + + return (PRENVFREE (&x_pid, &x_envp)); +} diff --git a/sys/libc/cenvscan.c b/sys/libc/cenvscan.c new file mode 100644 index 00000000..5fef48e7 --- /dev/null +++ b/sys/libc/cenvscan.c @@ -0,0 +1,32 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + */ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_ENVSCAN -- High level command to parse and enter a SET declaration into +** the environment list, or to parse and enter a list of SET declarations from +** a text file. The single input string argument should be either a SET +** declaration, i.e., +** +** set var="value" (quotes optional) +** +** or an indirect reference to a text file containing SET declarations, e.g., +** +** @filename +** +** If a file is specified, only lines beginning with the keyword "set" will +** be decoded; all other lines are ignored. The number of SET declarations +** processed is returned as the function value. There is no fixed limit on +** the number of SET declarations for a process. +*/ +int +c_envscan ( + char *input_source +) +{ + return (ENVSCAN (c_sppstr(input_source))); +} diff --git a/sys/libc/cerract.c b/sys/libc/cerract.c new file mode 100644 index 00000000..a9c9cb2d --- /dev/null +++ b/sys/libc/cerract.c @@ -0,0 +1,21 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_ERRACT -- Take an error action. Typically called in an IFERR error +** handler to print a warning message or initiate error recovery after +** application specific cleanup actions have been taken. The actions are +** defined in import_error +*/ +void +c_erract (int action) +{ + XINT x_action = action; + + ERRACT (&x_action); +} diff --git a/sys/libc/cerrcode.c b/sys/libc/cerrcode.c new file mode 100644 index 00000000..305ab39d --- /dev/null +++ b/sys/libc/cerrcode.c @@ -0,0 +1,15 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + +/* C_ERRCODE -- Get the error code of the most recent error. +*/ +int +c_errcode ( void ) +{ + return (ERRCODE()); +} diff --git a/sys/libc/cerrget.c b/sys/libc/cerrget.c new file mode 100644 index 00000000..a62a2f67 --- /dev/null +++ b/sys/libc/cerrget.c @@ -0,0 +1,27 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_ERRGET -- Get the error code and error message string of the most +** recent error. +*/ +int +c_errget ( + char *outstr, /* error message string */ + int maxch /* max chars out, incl EOS */ +) +{ + XCHAR buf[SZ_LINE+1]; + XINT szbuf = SZ_LINE; + int errcode; + + errcode = (int) ERRGET (buf, &szbuf); + c_strpak (buf, outstr, maxch); + + return (errcode); +} diff --git a/sys/libc/cerror.c b/sys/libc/cerror.c new file mode 100644 index 00000000..214d54a8 --- /dev/null +++ b/sys/libc/cerror.c @@ -0,0 +1,20 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_ERROR -- Post an error. +*/ +void +c_error ( + int errcode, /* error code */ + char *errmsg /* error message */ +) +{ + XINT x_errcode = errcode; + ERROR (&x_errcode, c_sppstr(errmsg)); +} diff --git a/sys/libc/cfchdir.c b/sys/libc/cfchdir.c new file mode 100644 index 00000000..2dc708da --- /dev/null +++ b/sys/libc/cfchdir.c @@ -0,0 +1,19 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_FCHDIR -- Change directory. +*/ +int +c_fchdir (char *newdir) +{ + iferr (FCHDIR (c_sppstr (newdir))) + return (ERR); + else + return (OK); +} diff --git a/sys/libc/cfilbuf.c b/sys/libc/cfilbuf.c new file mode 100644 index 00000000..e37aec75 --- /dev/null +++ b/sys/libc/cfilbuf.c @@ -0,0 +1,36 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_stdio +#include + + +/* C_FILBUF -- Fill the FIO file buffer. Called by the GETC macro to fill +** the file buffer when the end of the buffer is reached. The function +** value is either the first char in the refilled buffer or EOF. If the +** file is connected to a child process the filter PRFILBUF is called to +** handle the XMIT and XFER requests. +*/ +int +c_filbuf (FILE *fp) +{ + register int nchars; + XINT x_fd = fileno(fp); + XINT (*fillbuffer)(); + XINT PRFILBUF(), FILBUF(); + + + fillbuffer = ((fp->_fflags & _FIPC) ? PRFILBUF : FILBUF); + + iferr (nchars = (int) (*fillbuffer)(&x_fd)) { + fp->_fflags |= _FERR; + return (EOF); + } else if (nchars == XEOF) { + fp->_fflags |= _FEOF; + return (EOF); + } else + return (Memc[fp->_iop++] & 0377); +} diff --git a/sys/libc/cfinfo.c b/sys/libc/cfinfo.c new file mode 100644 index 00000000..7e69e5e0 --- /dev/null +++ b/sys/libc/cfinfo.c @@ -0,0 +1,30 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_xnames +#define import_finfo +#define import_libc +#include + + +/* C_FINFO -- FIO get directory info for named file. +*/ +int +c_finfo ( + char *fname, /* name of file to be opened */ + struct _finfo *fi /* finfo structure (output) */ +) +{ + register int status; + + iferr (status = (int) FINFO (c_sppstr(fname), (XLONG *)fi)) { + status = ERR; + } else if (status != XERR) { + c_strpak ((XCHAR *)fi->fi_owner, fi->fi_owner, SZ_OWNERSTR); + status = OK; + } else + status = ERR; + + return (status); +} diff --git a/sys/libc/cflsbuf.c b/sys/libc/cflsbuf.c new file mode 100644 index 00000000..9547b0c2 --- /dev/null +++ b/sys/libc/cflsbuf.c @@ -0,0 +1,43 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_stdio +#include + + +/* C_FLSBUF -- Flush the FIO file buffer. Called by the PUTC macro to flush +** the file buffer when it fills. The function value returned is either the +** first char written to the buffer (passed as an argument) or EOF in the +** event of an error. +*/ +int +c_flsbuf ( + unsigned int ch, /* char which caused the fault */ + FILE *fp /* output file */ +) +{ + register int buf_not_full; + XINT fd = fileno(fp); + XINT nreserve = 1; + + + /* If we were called due to flush on newline and there is space in + * the buffer, put the ch in the buffer before flushing. + */ + buf_not_full = (fp->_iop < fp->_otop); + if (buf_not_full) + Memc[fp->_iop++] = (unsigned)ch; + + iferr (FLSBUF (&fd, &nreserve)) { + fp->_fflags |= _FERR; + return (EOF); + } + + if (!buf_not_full) + Memc[fp->_iop++] = (unsigned)ch; + + return (ch); +} diff --git a/sys/libc/cflush.c b/sys/libc/cflush.c new file mode 100644 index 00000000..7a7a029a --- /dev/null +++ b/sys/libc/cflush.c @@ -0,0 +1,20 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_FLUSH -- FIO file flush. +*/ +void +c_flush ( + XINT fd /* FIO file descriptor */ +) +{ + XINT x_fd = fd; + + FLUSH (&x_fd); +} diff --git a/sys/libc/cfmapfn.c b/sys/libc/cfmapfn.c new file mode 100644 index 00000000..0d4181a0 --- /dev/null +++ b/sys/libc/cfmapfn.c @@ -0,0 +1,36 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_FMAPFN -- Map a VFN (virtual filename) into an OSFN (host system filename). +*/ +int +c_fmapfn ( + char *vfn, /* virtual filename */ + char *osfn, /* OS filename */ + int maxch +) +{ + XCHAR x_osfn[SZ_PATHNAME+1]; + XINT sz_path = SZ_PATHNAME; + + + /* The OSFN is returned as a packed string in the XCHAR array x_osfn. + * An intermediate buffer is used to avoid char->xchar alignment + * problems of upward pointer coercion on some machines. + */ + if (maxch) + iferr (FMAPFN (c_sppstr(vfn), x_osfn, &sz_path)) + osfn[0] = EOS; + else { + (void) strncpy (osfn, (char *)x_osfn, maxch); + osfn[maxch-1] = EOS; + } + + return (strlen (osfn)); +} diff --git a/sys/libc/cfmkdir.c b/sys/libc/cfmkdir.c new file mode 100644 index 00000000..9888461d --- /dev/null +++ b/sys/libc/cfmkdir.c @@ -0,0 +1,20 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_FMKDIR -- FIO procedure to create a new directory. +*/ +int +c_fmkdir (newdir) +char *newdir; /* name of the new directory */ +{ + iferr (FMKDIR (c_sppstr(newdir))) + return (ERR); + else + return (OK); +} diff --git a/sys/libc/cfnextn.c b/sys/libc/cfnextn.c new file mode 100644 index 00000000..9917b89f --- /dev/null +++ b/sys/libc/cfnextn.c @@ -0,0 +1,26 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_FNEXTN -- Extract the filename extension substring from a filename. +*/ +int +c_fnextn ( + char *vfn, /* filename */ + char *extn, /* filename extension (output) */ + int maxch /* max chars out */ +) +{ + XCHAR spp_extn[SZ_FNAME+1]; + XINT x_maxch = SZ_FNAME, nchars; + + nchars = (int) FNEXTN (c_sppstr(vfn), spp_extn, &x_maxch); + c_strpak (spp_extn, extn, maxch); + + return (nchars); +} diff --git a/sys/libc/cfnldir.c b/sys/libc/cfnldir.c new file mode 100644 index 00000000..9b8b469c --- /dev/null +++ b/sys/libc/cfnldir.c @@ -0,0 +1,26 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_FNLDIR -- Extract the directory prefix substring from a filename. +*/ +int +c_fnldir ( + char *vfn, /* filename */ + char *ldir, /* directory prefix (output) */ + int maxch /* max chars out */ +) +{ + XCHAR spp_ldir[SZ_FNAME+1]; + XINT x_maxch = SZ_FNAME, nchars; + + nchars = FNLDIR (c_sppstr(vfn), spp_ldir, &x_maxch); + c_strpak (spp_ldir, ldir, maxch); + + return (nchars); +} diff --git a/sys/libc/cfnroot.c b/sys/libc/cfnroot.c new file mode 100644 index 00000000..78ac72bb --- /dev/null +++ b/sys/libc/cfnroot.c @@ -0,0 +1,25 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + +/* C_FNROOT -- Extract the root filename substring from a filename. +*/ +int +c_fnroot ( + char *vfn, /* filename */ + char *root, /* root filename (output) */ + int maxch /* max chars out */ +) +{ + XCHAR spp_root[SZ_FNAME+1]; + XINT x_maxch = SZ_FNAME, nchars; + + nchars = FNROOT (c_sppstr(vfn), spp_root, &x_maxch); + c_strpak (spp_root, root, maxch); + + return (nchars); +} diff --git a/sys/libc/cfpath.c b/sys/libc/cfpath.c new file mode 100644 index 00000000..b7820012 --- /dev/null +++ b/sys/libc/cfpath.c @@ -0,0 +1,34 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_FPATHNAME -- Map a VFN (virtual filename) into a pathname (filename +** specification which is independent of the current directory). +*/ +int +c_fpathname ( + char *vfn, /* virtual filename */ + char *osfn, /* OS filename */ + int maxch +) +{ + XCHAR x_osfn[SZ_PATHNAME+1]; + XINT x_maxch = SZ_PATHNAME; + + + /* The OSFN is returned as a packed string in the XCHAR array x_osfn. + * An intermediate buffer is used to avoid char->xchar alignment + * problems of upward pointer coercion on some machines. + */ + iferr (FPATHNAME (c_sppstr(vfn), x_osfn, &x_maxch)) + osfn[0] = EOS; + else + c_strpak (x_osfn, osfn, maxch); + + return (strlen (osfn)); +} diff --git a/sys/libc/cfredir.c b/sys/libc/cfredir.c new file mode 100644 index 00000000..2a4ae5b1 --- /dev/null +++ b/sys/libc/cfredir.c @@ -0,0 +1,46 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_stdio +#include + + +/* C_FREDIR -- FIO redirect an open i/o stream to a named file. Most commonly +** used to redirect one of the standard i/o streams to a file. The named file +** need not be of the same type as the old stream. +*/ +int +c_fredir ( + XINT fd, /* stream to be redirected */ + char *fname, /* name of file to be opened */ + int mode, /* access mode */ + int type /* file type */ +) +{ + XINT x_fd = fd, x_type = type, x_mode = mode; + + iferr (FREDIR (&x_fd, c_sppstr(fname), &x_mode, &x_type)) + return (ERR); + else + return (fd); +} + + +/* C_FREDIRO -- FIO redirect an open i/o stream to another open stream. +*/ +int +c_frediro ( + XINT fd, /* stream to be redirected */ + XINT newfd /* where it is to be redirected */ +) +{ + XINT x_fd = fd, x_newfd = newfd; + + iferr (FREDIRO (&x_fd, &x_newfd)) + return (ERR); + else + return (fd); +} diff --git a/sys/libc/cfseti.c b/sys/libc/cfseti.c new file mode 100644 index 00000000..7d496c33 --- /dev/null +++ b/sys/libc/cfseti.c @@ -0,0 +1,22 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_FSETI -- FIO set integer file parameter. +*/ +void +c_fseti ( + XINT fd, /* FIO file descriptor */ + int param, /* param to be set */ + int value /* new value */ +) +{ + XINT x_fd = fd, x_param = param, x_value = value; + + FSETI (&x_fd, &x_param, &x_value); +} diff --git a/sys/libc/cfstati.c b/sys/libc/cfstati.c new file mode 100644 index 00000000..aacf670a --- /dev/null +++ b/sys/libc/cfstati.c @@ -0,0 +1,21 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_FSTATI -- FIO get integer file parameter. +*/ +int +c_fstati ( + XINT fd, /* FIO file descriptor */ + int param /* param to be queried */ +) +{ + XINT x_fd = fd, x_param = param; + + return (FSTATI (&x_fd, &x_param)); +} diff --git a/sys/libc/cgetpid.c b/sys/libc/cgetpid.c new file mode 100644 index 00000000..69ad6133 --- /dev/null +++ b/sys/libc/cgetpid.c @@ -0,0 +1,15 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#define import_xnames +#include + + +/* C_GETPID -- Get the process id. +*/ +int +c_getpid ( void ) +{ + return ((int) GETPID()); +} diff --git a/sys/libc/cgetuid.c b/sys/libc/cgetuid.c new file mode 100644 index 00000000..cb86f4a3 --- /dev/null +++ b/sys/libc/cgetuid.c @@ -0,0 +1,24 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_GETUID -- Get the user identification string (user name). +*/ +char * +c_getuid ( + char *outstr, /* user name, C string */ + int maxch /* max chars out, incl EOS */ +) +{ + XCHAR spp_uid[SZ_FNAME+1]; + XINT x_maxch = SZ_FNAME; + + + GETUID (spp_uid, &x_maxch); + return (c_strpak (spp_uid, outstr, maxch)); +} diff --git a/sys/libc/cgflush.c b/sys/libc/cgflush.c new file mode 100644 index 00000000..8d5fe072 --- /dev/null +++ b/sys/libc/cgflush.c @@ -0,0 +1,20 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_GFLUSH -- Flush any buffered graphics output. +*/ +void +c_gflush ( + int stream /* graphics stream */ +) +{ + XINT x_stream = stream; + + GTR_GFLUSH (&x_stream); +} diff --git a/sys/libc/cimaccess.c b/sys/libc/cimaccess.c new file mode 100644 index 00000000..17d2e874 --- /dev/null +++ b/sys/libc/cimaccess.c @@ -0,0 +1,28 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_IMACCESS -- IMIO test if image can be accessed (exists). 1 is returned +** if the image exists and is unique, 0 if the image does not exist, and ERR +** if the image name ambiguous and multiple images exist matching that name. +*/ +int +c_imaccess ( + char *imname, /* name of image to be accessed */ + int mode /* access mode */ +) +{ + int status; + XINT x_mode = mode; + + + iferr (status = (int) IMACCESS (c_sppstr(imname), &x_mode)) + return (ERR); + else + return (status); +} diff --git a/sys/libc/cimdrcur.c b/sys/libc/cimdrcur.c new file mode 100644 index 00000000..1ac9f85b --- /dev/null +++ b/sys/libc/cimdrcur.c @@ -0,0 +1,39 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_IMDRCUR -- Read the logical image cursor (temporary routine, will be +** phased out in a later release). +*/ +int +c_imdrcur ( + char *device, /* logical device name or "stdimage" */ + float *x, /* cursor X coordinate (out) */ + float *y, /* cursor Y coordinate (out) */ + int *wcs, /* wcs of coords (out, = frame*100+d_wcs) */ + int *key, /* keystroke which triggered read (out) */ + char *strval, /* string value, if key=':' */ + int maxch, /* max chars out */ + int d_wcs, /* 0 for frame coords, 1 for image coords */ + int pause /* true to pause for key to terminate read */ +) +{ + PKCHAR x_strval[SZ_LINE+1]; + XINT x_maxch = maxch, x_d_wcs = d_wcs, x_pause = pause; + XINT x_wcs, x_key; + + + if (IMDRCUR (c_sppstr(device), x, y, &x_wcs, &x_key, x_strval, &x_maxch, + &x_d_wcs, &x_pause) >= 0) + c_strpak (x_strval, strval, maxch); + + *wcs = x_wcs; + *key = x_key; + + return (*key = (*key == XEOF) ? EOF : *key); +} diff --git a/sys/libc/ckimapc.c b/sys/libc/ckimapc.c new file mode 100644 index 00000000..6653dd29 --- /dev/null +++ b/sys/libc/ckimapc.c @@ -0,0 +1,28 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_KIMAPCHAN -- Map a KI channel number into the corresponding OS channel +** number or pid and node name. +*/ +int +c_kimapchan ( + int chan, /* KI channel number */ + char *nodename, /* receives server node name */ + int maxch /* maxch chars out */ +) +{ + XCHAR x_nodename[SZ_FNAME+1]; + XINT ki_chan = chan, x_maxch = SZ_FNAME; + int os_chan; + + os_chan = (int) KI_MAPCHAN (&ki_chan, x_nodename, &x_maxch); + c_strpak (x_nodename, nodename, SZ_FNAME); + + return (os_chan); +} diff --git a/sys/libc/clexnum.c b/sys/libc/clexnum.c new file mode 100644 index 00000000..6e5091bc --- /dev/null +++ b/sys/libc/clexnum.c @@ -0,0 +1,54 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_ctype +#define import_lexnum +#define import_xnames +#include + + +/* LEXNUM -- Lexically analyze a string to determine if it is a legal IRAF +** style number. Returns one of the following tokens (lexnum.h): +** +** LEX_OCTAL octal number (e.g. B suffix) +** LEX_HEX hex number (e.g. X suffix) +** LEX_DECIMAL decimal number +** LEX_REAL real number (incl sexagesimal) +** LEX_NONNUM nonnumeric +** +** A numeric token is returned if any (prefix) portion of the field is +** numeric. The total number of numeric characters is also returned so +** that the application may verify that the entire field was numeric, +** if desired. +*/ +int +c_lexnum ( + char *str, /* input string */ + int *toklen /* nchars in token */ +) +{ + register char *ip; + register XCHAR *op, ch, ndigits; + PKCHAR numbuf[SZ_FNAME]; + XINT ip_start = 1, x_toklen = *toklen; + int status; + + + /* Convert number to XCHAR for lexnum. In the process check to see + * if we have a simple decimal integer constant to save a scan. + */ + for (ip=str, op=numbuf, ndigits=0; (*op++ = ch = *ip++); ) + if (isdigit (ch)) + ndigits++; + + if (ndigits == (ip - str - 1)) { + *toklen = ndigits; + return (LEX_DECIMAL); + } else { + status = LEXNUM (numbuf, &ip_start, &x_toklen); + *toklen = (int) x_toklen; + return (status); + } +} diff --git a/sys/libc/cmktemp.c b/sys/libc/cmktemp.c new file mode 100644 index 00000000..cdc9e5a7 --- /dev/null +++ b/sys/libc/cmktemp.c @@ -0,0 +1,27 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_MKTEMP -- FIO make temporary (unique) filename. +*/ +int +c_mktemp ( + char *root, /* root filename */ + char *temp_filename, /* generated filename */ + int maxch /* max chars in output filename */ +) +{ + XCHAR temp[SZ_FNAME+1]; + XINT sz_temp = SZ_FNAME; + + + iferr (MKTEMP (c_sppstr(root), temp, &sz_temp)) + return (0); + else + return (strlen (c_strpak (temp, temp_filename, maxch))); +} diff --git a/sys/libc/cndopen.c b/sys/libc/cndopen.c new file mode 100644 index 00000000..1a6920be --- /dev/null +++ b/sys/libc/cndopen.c @@ -0,0 +1,25 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_NDOPEN -- Network driver FIO file open. +*/ +int +c_ndopen ( + char *fname, /* name of file to be opened */ + int mode /* access mode */ +) +{ + int fd; + XINT x_mode = mode; + + iferr (fd = NDOPEN (c_sppstr(fname), &x_mode)) + return (ERR); + else + return (fd); +} diff --git a/sys/libc/cnote.c b/sys/libc/cnote.c new file mode 100644 index 00000000..c62a0b02 --- /dev/null +++ b/sys/libc/cnote.c @@ -0,0 +1,29 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_fset +#include + + +/* C_NOTE -- FIO note file offset. If the actual file is a text file the +** seek offset is a magic number and is returned unchanged. If the actual +** file is a binary file the seek offset is returned as a zero-indexed byte +** offset. +*/ +long +c_note ( + XINT fd /* FIO file descriptor */ +) +{ + long xchar_offset; + XINT x_fd = fd; + + xchar_offset = (long) NOTE (&x_fd); + if (c_fstati (fd, F_TYPE) == BINARY_FILE) + return ((xchar_offset - 1) * sizeof(XCHAR)); + else + return (xchar_offset); +} diff --git a/sys/libc/copen.c b/sys/libc/copen.c new file mode 100644 index 00000000..144dc5d4 --- /dev/null +++ b/sys/libc/copen.c @@ -0,0 +1,26 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_OPEN -- FIO file open. +*/ +int +c_open ( + char *fname, /* name of file to be opened */ + int mode, /* access mode */ + int type /* file type */ +) +{ + int fd; + XINT x_mode = mode, x_type = type; + + iferr (fd = (int) OPEN (c_sppstr(fname), &x_mode, &x_type)) + return (ERR); + else + return (fd); +} diff --git a/sys/libc/coscmd.c b/sys/libc/coscmd.c new file mode 100644 index 00000000..d6185bfe --- /dev/null +++ b/sys/libc/coscmd.c @@ -0,0 +1,33 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_OSCMD -- Send a command to the host system. If the filename strings +** are nonnull the kernel will attempt to redirect the standard i/o streams +** to the indicated streams during execution of the command. OK is returned +** if execution is completes successfully, otherwise a positive integer error +** code is returned. +*/ +int +c_oscmd ( + char *cmd, /* command to be executed */ + char *infile, /* stdin file */ + char *outfile, /* stdout file */ + char *errfile /* stderr file */ +) +{ + XCHAR spp_infile[SZ_FNAME+1]; + XCHAR spp_outfile[SZ_FNAME+1]; + XCHAR spp_errfile[SZ_FNAME+1]; + + c_strupk (infile, spp_infile, SZ_FNAME); + c_strupk (outfile, spp_outfile, SZ_FNAME); + c_strupk (errfile, spp_errfile, SZ_FNAME); + + return (OSCMD (c_sppstr(cmd), spp_infile, spp_outfile, spp_errfile)); +} diff --git a/sys/libc/cpoll.c b/sys/libc/cpoll.c new file mode 100644 index 00000000..65f05274 --- /dev/null +++ b/sys/libc/cpoll.c @@ -0,0 +1,150 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_fpoll +#define import_xnames +#include + + +/* C_POLL -- LIBC binding to the FIO polling interface. +** +** fds = c_poll_open () # open a poll descriptor set +** npolls = c_poll (fds, nfds, timeout) # poll the set +** c_poll_close (fds) # free the poll descriptor set +** +** c_poll_zero (fds) # zero the poll array +** c_poll_set (fds, fd, type) # set fd to poll for type +** c_poll_clear (fds, fd, type) # unset type on fd poll +** y/n = c_poll_test (fds, fd, type) # test fd for type event +** c_poll_print (fds) # print the poll array +** N = c_poll_get_nfds (fds) # get size of descriptor set +*/ + + +/* C_POLL_OPEN -- Open a poll descriptor set. +*/ +XINT +c_poll_open ( void ) +{ + XINT fds; + + iferr ((fds = (XINT) POLL_OPEN ())) + return (NULL); + else + return (fds); +} + + +/* C_POLL -- Poll the descriptor set. +*/ +int +c_poll ( + XINT fds, /* descriptor set ptr */ + int nfds, /* no. descriptors */ + int timeout /* poll timeout */ +) +{ + XINT x_fds = fds, x_nfds = nfds, x_timeout = timeout; + + return ((int) POLL (&x_fds, &x_nfds, &x_timeout)); +} + + +/* C_POLL_CLOSE -- Close and free a poll descriptor set. +*/ +void +c_poll_close ( + XINT fds /* descriptor set ptr */ +) +{ + XINT x_fds = fds; + + POLL_CLOSE (&x_fds); +} + + +/* C_POLL_ZERO -- Zero the descriptor set. +*/ +void +c_poll_zero ( + XINT fds /* descriptor set ptr */ +) +{ + XINT x_fds = fds; + + POLL_ZERO (&x_fds); +} + + +/* C_POLL_SET -- Add a descriptor to the set, and/or modify the event type. +** The type may be a bitwise or of testable events. +*/ +void +c_poll_set ( + XINT fds, /* descriptor set ptr */ + XINT fd, /* no. descriptors */ + int type /* event type */ +) +{ + XINT x_fds = fds, x_fd = fd, x_type = type; + + POLL_SET (&x_fds, &x_fd, &x_type); +} + + +/* C_POLL_CLEAR -- Remove a descriptor or event type from the set. The type +** may be a bitwise or of testable events. If the event mask becomes NULL the +** descriptor is removed entirely from the set. +*/ +void +c_poll_clear ( + XINT fds, /* descriptor set ptr */ + XINT fd, /* no. descriptors */ + int type /* event type */ +) +{ + XINT x_fds = fds, x_fd = fd, x_type = type; + + POLL_CLEAR (&x_fds, &x_fd, &x_type); +} + + +/* C_POLL_TEST -- Test the descriptor for the given event type. +*/ +int +c_poll_test ( + XINT fds, /* descriptor set ptr */ + XINT fd, /* no. descriptors */ + int type /* event type */ +) +{ + XINT x_fds = fds, x_fd = fd, x_type = type; + + return ((int) POLL_TEST (&x_fds, &x_fd, &x_type)); +} + + +/* C_POLL_GET_NFDS -- Return the size of the descriptor set. +*/ +int +c_poll_get_nfds ( + XINT fds /* descriptor set ptr */ +) +{ + XINT x_fds = fds; + + return (POLL_GET_NFDS (&x_fds)); +} + + +/* C_POLL_PRINT -- Debug print utility. +*/ +void +c_poll_print (XINT fds) +{ + XINT x_fds = fds; + + POLL_PRINT (&x_fds); +} diff --git a/sys/libc/cprcon.c b/sys/libc/cprcon.c new file mode 100644 index 00000000..c0534a60 --- /dev/null +++ b/sys/libc/cprcon.c @@ -0,0 +1,198 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_stdio +#define import_prstat +#include + + +/* CPRCON -- Connected subprocesses. A connected subprocess is an active filter +** which communicates with the parent process via an input stream and an output +** stream. A connected subprocess is logically equivalent to the user terminal. +** The set of useful operations thus far identified for connected subprocesses +** are open and close, read and write, and signal (interrupt). The read and +** write operations are provided by interfacing the IPC channels from the +** subprocess to FIO. The remaining operations are peculiar to connected +** subprocesses and are summarized below. +** +** pid = c_propen (process, in, out) +** stat = c_prclose (pid) +** stat = c_prstati (pid, param) +** c_prsignal (pid, signal) +** c_prredir (pid, stream, new_fd) +** c_prchdir (pid, newdir) +** c_prenvset (pid, envvar, valuestr) +** +** A connected subprocess must be opened either with c_propen or with the low +** level procedure PROPCPR (the latter does not require that the subprocess +** recognize the standard IPC protocol). An idle subprocess may be closed +** with c_prclose, which not only closes the process but releases important +** system resources. The c_prsignal procedure raises the X_INT (interrupt) +** exception in a subprocess, generally following receipt of a user interrupt +** by the parent process. Redirection of the child's standard i/o streams +** is provided by c_prredir. Finally, c_prchdir and c_prenvsets are used +** to update the current directory and environment in child processes. +*/ + + +/* C_PROPEN -- Open a connected subprocess, i.e., spawn the subprocess and +** connect the two IPC channels connecting the child and parent to FIO. +** The FIO streams may subsequently be opened for C style STDIO by calling +** FDOPEN, if desired. The C_PROPEN procedure sends the current environment +** and working directory to the child as part of process startup. The process +** id (PID) of the child process is returned as the function value. This +** magic integer value uniquely identifies the process to the system. +** +** N.B.: opening a child process leaves the child in the IRAF Main interpreter +** loop, with the child waiting for a command from the parent. A child process +** is capabable of performing an arbitrary number of "tasks". To get the child +** to run a task, the parent must write the name of the task to the OUT stream, +** then read from the IN stream, responding to all queries from the child until +** "bye" or "error" is received. +*/ +unsigned int +c_propen ( + char *process, /* filename of executable process */ + int *in, /* FD for reading from child */ + int *out /* FD for writing to child */ +) +{ + register unsigned int pid; + XINT x_in = *in, x_out = *out; + + iferr (pid = (unsigned int) PROPEN (c_sppstr(process), &x_in, &x_out)) + return (NULL); + else { + *in = (int) x_in; + *out = (int) x_out; + FDTOFP(*in)->_fflags |= _FIPC; + return (pid); + } +} + + +/* C_PRCLOSE -- Close a connected subprocess. The "bye" command is sent to +** the child, commanding it to shut down, and when the task terminates the +** exit status is returned as the function value. The C_PRCLOSE procedure +** must be called at process termination to free system resources. C_PRCLOSE +** is automatically called by the system if error recovery takes place in +** the parent process. Calling C_PRCLOSE is equivalent to individually +** closing the IN and OUT streams to the subprocess (which is what happens +** if system error recovery takes place). +*/ +int +c_prclose ( + unsigned int pid /* process id returned by C_PROPEN */ +) +{ + XINT x_pid = pid; + + return (PRCLOSE (&x_pid)); +} + + +/* C_PRSTATI -- Get status on a connected subprocess. See +** for a list of parameters. +*/ +int +c_prstati ( + int pid, /* process id of process */ + int param /* parameter for which value is ret */ +) +{ + XINT x_pid = pid, x_param = param; + + return (PRSTATI (&x_pid, &x_param)); +} + + +/* C_PRSIGNAL -- Send a signal, i.e., asynchronous interrupt, to a connected +** child process. Currently only the X_INT signal is implemented, and the +** second argument is not used. The value X_INT should nontheless be passed. +*/ +int +c_prsignal ( + unsigned pid, /* process id of process */ + int signal /* not used at present */ +) +{ + XINT x_pid = pid, x_signal = signal; + + iferr (PRSIGNAL (&x_pid, &x_signal)) + return (ERR); + else + return (OK); +} + + +/* C_PRREDIR -- Redirect one of the standard i/o streams of the child process. +** By default the child inherits the standard i/o streams of the parent at +** C_PROPEN time, i.e., the STDOUT of the child is connected to the STDOUT of +** the parent. If the parent's STDOUT is subsequently redirected, e.g., with +** C_FREDIR, the child's output will be redirected as well. More commonly +** one or more of the child's streams will be explicitly redirected with +** C_PRREDIR. Such redirection remains in effect for the life of the +** process, i.e., until process termination via C_PRCLOSE or until another +** call to C_PRREDIR. Note that often this is not what is desired, rather, +** one wishes to redirect a stream for the duration of a task running within +** the process. For this reason it is recommended that C_PRREDIR be called +** for each standard stream (it costs almost nothing) immediately prior to +** task execution. +** +** Example: +** fp = fopen ("tmp$spoolfile", "w"); +** if (c_prredir (pid, STDOUT, fileno(fp)) == ERR) +** ... +*/ +int +c_prredir ( + unsigned pid, /* process id of child */ + int stream, /* child's stream to be redirected */ + int new_fd /* FD of opened file in parent */ +) +{ + XINT x_pid = pid, x_stream = stream, x_new_fd = new_fd; + + iferr (PRREDIR (&x_pid, &x_stream, &x_new_fd)) + return (ERR); + else + return (OK); +} + + +/* C_PRCHDIR -- Change the current working directory of a child process. +** If pid=NULL all currently connected processes are updated. May only +** be called when the child process is idle. +*/ +int +c_prchdir ( + int pid, + char *newdir +) +{ + XINT x_pid = pid; + + return (PRCHDIR (&x_pid, c_sppstr (newdir))); +} + + +/* C_PRENVSET -- Transmit a set environment directive to the child process. +** If pid=NULL all currently connected processes are updated. May only +** be called when the child process is idle. +*/ +int +c_prenvset ( + int pid, + char *envvar, + char *value +) +{ + XCHAR spp_value[SZ_LINE]; + XINT x_pid = pid; + + c_strupk (value, spp_value, SZ_LINE); + return (PRENVSET (&x_pid, c_sppstr (envvar), spp_value)); +} diff --git a/sys/libc/cprdet.c b/sys/libc/cprdet.c new file mode 100644 index 00000000..92829723 --- /dev/null +++ b/sys/libc/cprdet.c @@ -0,0 +1,109 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* +** CPRDET -- Detached processes. A detached process is a process which runs +** asynchronously with and independently of the parent, generally without +** interprocess communication during execution. The primary example of a +** detached process in IRAF is the CL process spawned by an interactive CL +** to execute a command in the background. +** +** The parent communicates with the child by means of the "bkgfile", the name +** of which is passed by the system to the child during process startup. +** While the format and contents of the bkgfile are in general application +** dependent, the system default action is to open the bkgfile as a text file +** and read commands from it. The CL process does not make use of this +** default, but rather uses its own special format binary file to communicate +** the full runtime context of the parent to the child, partially emulating +** the UNIX fork. The system automatically deletes the bkgfile when the +** child process terminates. +** +** N.B.: The environment and cwd are not automatically passed to the child, +** as they are for a connected subprocess. The application must see to it +** that this information is passed in the bkgfile if needed by the child. +*/ + +/* C_PROPDPR -- Open a detached process. The named process is either spawned +** or queued for delayed execution (depending on the system and other factors). +** When the process eventually runs it reads the bkgfile passed by the parent +** to determine what to do. When the process terminates, either normally or +** abnormally, the system deletes the bkgfile. Deletion of the bkgfile signals +** process termination. +*/ +unsigned int +c_propdpr ( + char *process, /* filename of executable file */ + char *bkgfile, /* filename of bkgfile */ + char *bkgmsg /* control string for kernel */ +) +{ + unsigned job; + XCHAR spp_bkgfile[SZ_PATHNAME]; + XCHAR spp_bkgmsg[SZ_LINE]; + + + c_strupk (bkgfile, spp_bkgfile, SZ_PATHNAME); + c_strupk (bkgmsg, spp_bkgmsg, SZ_LINE); + iferr (job = PROPDPR (c_sppstr(process), spp_bkgfile, spp_bkgmsg)) + return (NULL); + else + return (job); +} + + +/* C_PRCLDPR -- Close a detached process. Wait (indefinitely) for process +** termination, then free all system resources allocated to the process. +** Should be called if a detached process terminated while the parent is +** still executing. The exit status of the child is returned as the function +** value; the value OK (0) indicates normal termination. A positive value +** is the error code of the error which caused abnormal process termination. +*/ +int +c_prcldpr ( + unsigned job /* job code from C_PROPDPR */ +) +{ + XINT x_job = job; + + return (PRCLDPR (&x_job)); +} + + +/* C_PRDONE -- Determine if a bkg job is still executing (function return NO) +** or has terminated (function return YES). +*/ +int +c_prdone ( + unsigned job /* job code from C_PROPDPR */ +) +{ + XINT x_job = job; + + return (PRDONE (&x_job)); +} + + +/* C_PRKILL -- Kill a bkg job. If the bkg job has begun execution it is +** killed without error recovery. If the bkg job is still sitting in a queue +** it is dequeued. C_PRKILL returns ERR for an illegal jobcode or if sufficient +** permission is not available to kill the job. C_PRCLDPR should subsequently +** be called to wait for process termination and free system resources. +*/ +int +c_prkill ( + unsigned job /* job code from C_PROPDPR */ +) +{ + XINT x_job = job; + + iferr (PRKILL (&x_job)) + return (ERR); + else + return (OK); +} diff --git a/sys/libc/cprintf.c b/sys/libc/cprintf.c new file mode 100644 index 00000000..dd317f69 --- /dev/null +++ b/sys/libc/cprintf.c @@ -0,0 +1,53 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_PRINTF -- Formatted print to STDOUT. +*/ +int +c_printf ( + char *format /* format string */ +) +{ + iferr (PRINTF (c_sppstr(format))) + return (ERR); + else + return (OK); +} + + +/* C_FPRINTF -- Formatted print to given file. +*/ +int +c_fprintf ( + XINT fd, /* output file */ + char *format /* format string */ +) +{ + XINT x_fd = fd; + + iferr (FPRINTF (&x_fd, c_sppstr(format))) + return (ERR); + else + return (OK); +} + + +void c_pargb (int ival) { XINT x_ival = ival; PARGI (&x_ival); } +void c_pargc (int ival) { XINT x_ival = ival; PARGI (&x_ival); } +void c_pargs (short sval) { XSHORT x_sval = sval; PARGS (&x_sval); } +void c_pargi (int ival) { XINT x_ival = ival; PARGI (&x_ival); } +void c_pargl (long lval) { XLONG x_lval = lval; PARGL (&x_lval); } +void c_pargr (float rval) { XREAL x_rval = rval; PARGR (&x_rval); } +void c_pargd (double dval) { XDOUBLE x_dval = dval; PARGD (&x_dval); } + + +void c_pargstr (char *strval) +{ + PARGSTR (c_sppstr(strval)); +} diff --git a/sys/libc/crcursor.c b/sys/libc/crcursor.c new file mode 100644 index 00000000..695c9668 --- /dev/null +++ b/sys/libc/crcursor.c @@ -0,0 +1,28 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_RCURSOR -- Read a cursor. +*/ +int +c_rcursor ( + int fd, /* FIO file descriptor */ + char *outstr, /* output string */ + int maxch +) +{ + XCHAR buf[SZ_LINE]; + XINT x_fd = fd, x_maxch = maxch; + int key; + + + key = (int) RCURSOR (&x_fd, buf, &x_maxch); + c_strpak (buf, outstr, maxch); + + return (key == XEOF ? EOF : key); +} diff --git a/sys/libc/crdukey.c b/sys/libc/crdukey.c new file mode 100644 index 00000000..a0b7042c --- /dev/null +++ b/sys/libc/crdukey.c @@ -0,0 +1,28 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_RDUKEY -- Read a user keystroke object from the terminal in raw mode. +*/ +int +c_rdukey ( + char *obuf, /* output buffer */ + int maxch /* maxc chars out */ +) +{ + XCHAR buf[SZ_LINE+1]; + XINT x_maxch = SZ_LINE; + int status; + + + obuf[0] = EOS; + if ((status = (int) RDUKEY (buf, &x_maxch)) > 0) + c_strpak (buf, obuf, maxch); + + return (status); +} diff --git a/sys/libc/cread.c b/sys/libc/cread.c new file mode 100644 index 00000000..8cc727a5 --- /dev/null +++ b/sys/libc/cread.c @@ -0,0 +1,70 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_stdio +#define import_error +#define import_fset +#include + + +/* C_READ -- FIO read from a file. Read up to maxbytes bytes from the stream +** fd into the buffer buf. If the device associated with file fd is a record +** structured device a single record is read, and the byte count will generally +** be less than the maximum. If the physical record was larger than maxbytes +** the remainder of the record is returned in successive reads. If the actual +** file is a text file FIO XCHARs are returned as C chars. If the actual file +** is a binary file no conversion is performed, and an integral number of XCHARs +** are read. +** +** For reasons of consistency with SPP usage, EOF is returned when end of file +** is reached (fread returns 0), and an error action is taken if a file read +** error occurs. We cannot return ERR when an error occurs since ERR and EOF +** have the same value in STDIO land. IFERR may be used to catch file read +** errors. +*/ +int +c_read ( + XINT fd, /* FIO file descriptor */ + char *buf, /* output buffer */ + int maxbytes /* max bytes to read */ +) +{ + XINT x_fd = fd; + int nchars_read; + + + if (c_fstati (fd, F_TYPE) == TEXT_FILE) { + register char *op = buf; + register int ch, n = maxbytes; + register FILE *fp = FDTOFP(fd); + + while (--n >= 0 && (ch = getc(fp)) >= 0) { + *op++ = ch; + if (ch == '\n') + break; + } + if (ferror (fp)) + c_erract (EA_ERROR); + if (!(nchars_read = op - buf)) + nchars_read = XEOF; + + } else { + XINT x_maxchars = maxbytes / sizeof(XCHAR); + XCHAR *bp = (XCHAR *)buf; + + /* Verify that the pointer coercion char->XCHAR->char is legal, + * i.e., that the char pointer is aligned to an XCHAR word + * boundary if required on this machine. + */ + if (buf != (char *)bp) + c_error (1, "c_read: buffer not xchar aligned"); + + if ((nchars_read = READ (&x_fd, bp, &x_maxchars)) > 0) + nchars_read *= sizeof(XCHAR); + } + + return (nchars_read == XEOF ? EOF : nchars_read); +} diff --git a/sys/libc/crename.c b/sys/libc/crename.c new file mode 100644 index 00000000..5f5b6668 --- /dev/null +++ b/sys/libc/crename.c @@ -0,0 +1,26 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_RENAME -- FIO rename file. +*/ +int +c_rename ( + char *old_fname, /* current name of file */ + char *new_fname /* new file name */ +) +{ + XCHAR spp_new_fname[SZ_FNAME]; + int maxch = SZ_FNAME; + + c_strupk (new_fname, spp_new_fname, maxch); + iferr (RENAME (c_sppstr(old_fname), spp_new_fname)) + return (ERR); + else + return (OK); +} diff --git a/sys/libc/creopen.c b/sys/libc/creopen.c new file mode 100644 index 00000000..da38703e --- /dev/null +++ b/sys/libc/creopen.c @@ -0,0 +1,27 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_REOPEN -- Reopen a binary file. +*/ +int +c_reopen ( + XINT fd, /* FIO file descriptor */ + int mode /* access mode */ +) +{ + XINT x_fd = fd, x_mode = mode; + int new_fd; + + + iferr (new_fd = (int) REOPEN (&x_fd, &x_mode)) + return (ERR); + else + return (new_fd); +} + diff --git a/sys/libc/csalloc.c b/sys/libc/csalloc.c new file mode 100644 index 00000000..823c0bca --- /dev/null +++ b/sys/libc/csalloc.c @@ -0,0 +1,80 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + +/* +** CSALLOC -- Dynamic memory allocation on the SPP stack. +** +** c_smark (&sp) +** c_sfree (sp) +** ptr = c_salloc (nbytes) +** +** A contiguous segment of dynamic storage may be allocated with C_SALLOC, +** much as is done with the UNIX emulation procedure MALLOC. All buffer +** space allocated on the stack since a call to C_SMARK to mark the position +** of the stack pointer may be freed in a single call to C_SFREE. +** +** The stack is implemented as a linked list of a few large buffers allocated +** on the heap with MALLOC, each of which normally contains many small buffers +** allocated with individual C_SALLOC calls. Stack allocation is very +** efficient for buffers small enough to fit into a stack segment. If it is +** necessary to add a new segment to accomodate a large buffer, the expense is +** about the same as for a buffer allocation with MALLOC. +*/ + + +/* C_SALLOC -- Allocate a contiguous segment of memory on the stack. The +** contents of the buffer will be uninitialized. The buffer is guaranteed to +** have at least XDOUBLE alignment with the Mem common. One extra XCHAR +** of storage is automatically allocated for the EOS delimiter in the event +** that the buffer is used to hold a character string (thus it is not necessary +** to be forever adding +1 in calls to the memory allocator). +** +** N.B.: it is a fatal error if storage cannot be allocated on the stack, +** hence error checking is not necessary. +*/ +char * +c_salloc ( + unsigned nbytes /* nbytes of storage to be allocated */ +) +{ + XINT buf; + XINT x_nchars = nbytes, x_dtype = TY_CHAR; + + + x_nchars = (nbytes + sizeof(XCHAR)-1) / sizeof(XCHAR); + SALLOC (&buf, &x_nchars, &x_dtype); + return ((char *)&Memc[buf]); +} + + +/* C_SMARK -- Mark the position of the stack pointer. +*/ +void +c_smark ( + int *sp /* stack pointer is saved here */ +) +{ + XINT x_sp = *sp; + + SMARK (&x_sp); + *sp = x_sp; +} + + +/* C_SFREE -- Free all stack storage allocated since the stack pointer passed as +** the sole argument was marked by C_SMARK. +*/ +void +c_sfree ( + int sp /* saved stack pointer */ +) +{ + XINT x_sp = sp; + + SFREE (&x_sp); +} diff --git a/sys/libc/cseek.c b/sys/libc/cseek.c new file mode 100644 index 00000000..58cedcc3 --- /dev/null +++ b/sys/libc/cseek.c @@ -0,0 +1,42 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_fset +#include + + +/* C_SEEK -- FIO seek on a file. If the actual file is a text file the +** seek offset is assumed to have been obtained by a prior call to FTELL +** and is passed on unchanged. If the actual file is a binary file the +** seek offset is a zero-indexed byte offset. This offset is converted +** to a one-indexed XCHAR offset; it is an error if the offset is not +** aligned to an XCHAR word boundary. +*/ +int +c_seek ( + XINT fd, /* FIO file descriptor */ + long offset /* file offset */ +) +{ + XLONG x_char_offset = offset; + XINT x_fd = fd; + int bypass; + + + bypass = (offset == BOFL || offset == EOFL + || c_fstati (fd, F_TYPE) == TEXT_FILE); + + if (!bypass) { + x_char_offset /= sizeof(XCHAR); + if ((x_char_offset++ * sizeof(XCHAR)) != offset) + return ((long) ERR); + } + + iferr (SEEK (&x_fd, &x_char_offset)) + return (ERR); + else + return (OK); +} diff --git a/sys/libc/csppstr.c b/sys/libc/csppstr.c new file mode 100644 index 00000000..ce7c9461 --- /dev/null +++ b/sys/libc/csppstr.c @@ -0,0 +1,31 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#include + +#define SZ_UPKSTR SZ_COMMAND +static XCHAR u_upkstr[SZ_UPKSTR+1]; + +/* C_SPPSTR -- Unpack a C string into an SPP string. This routine is offered +** as a convenient alternative to C_STRUPK for cases when the length of the +** string is known to be short and the value will be used before we are again +** called. The unpacked string is left in a static internal buffer and a +** pointer to XCHAR is returned as the function value. +*/ +XCHAR * +c_sppstr ( + char *str +) +{ + register char *ip = str; + register XCHAR *op = u_upkstr; + register int n = SZ_UPKSTR; + + while (--n >= 0 && (*op++ = *ip++) != XEOS) + ; + u_upkstr[SZ_UPKSTR] = XEOS; + + return (u_upkstr); +} diff --git a/sys/libc/cstropen.c b/sys/libc/cstropen.c new file mode 100644 index 00000000..ac7d01a8 --- /dev/null +++ b/sys/libc/cstropen.c @@ -0,0 +1,26 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_STROPEN -- FIO string-file open. +*/ +int +c_stropen ( + XCHAR *obuf, /* string file-buffer */ + int maxch, /* max chars in string */ + int mode /* file access mode */ +) +{ + XINT x_maxch = maxch, x_mode = mode; + int fd; + + iferr (fd = (int) STROPEN (obuf, &x_maxch, &x_mode)) + return (ERR); + else + return (fd); +} diff --git a/sys/libc/cstrpak.c b/sys/libc/cstrpak.c new file mode 100644 index 00000000..6236aa0d --- /dev/null +++ b/sys/libc/cstrpak.c @@ -0,0 +1,35 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#include + + +/* C_STRPAK -- Pack an SPP string (type XCHAR) into a C string in a user +** supplied buffer. Return a pointer to the output buffer. +** +** N.B.: This routine should be used in preference to STRPAK in C code +** since the output string is of type char*, rather than XCHAR*. +*/ +char * +c_strpak ( + XCHAR *sppstr, /* SPP string */ + char *cstr, /* C string */ + int maxch /* max chars out, incl EOS */ +) +{ + register XCHAR *ip = sppstr; + register char *op = cstr; + register int n = maxch-1; + + if (maxch) { + if (sizeof(XCHAR) != sizeof(char) || (char *)sppstr != cstr) { + while (--n >= 0 && (*op++ = *ip++) != EOS) + ; + cstr[maxch-1] = EOS; + } + } + + return (cstr); +} diff --git a/sys/libc/cstrupk.c b/sys/libc/cstrupk.c new file mode 100644 index 00000000..c8e26e19 --- /dev/null +++ b/sys/libc/cstrupk.c @@ -0,0 +1,41 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#define import_spp +#include + +/* C_STRUPK -- Unpack a C string into an SPP string. This procedure should +** be called from C in preference to the SPP procedure STRUPK because the +** input string is declared to be of type char, rather than as an XCHAR +** array containing packed chars as in STRUPK. The output string is however +** of type XCHAR since it is expected to be passed to an SPP procedure. A +** pointer to the output string is returned as the function value for use +** in argument lists. +*/ +XCHAR * +c_strupk ( + char *str, /* C string */ + XCHAR *outstr, /* SPP string */ + int maxch /* max chars out, incl EOS */ +) +{ + register char *ip = str; + register XCHAR *op = outstr; + register int n = maxch-1; + + + /* Is is necessary to determine the length of the string in order to + * be able to unpack the string in place, i.e., from right to left. + */ + if (maxch) + if (sizeof(char) != sizeof(XCHAR) || str != (char *)outstr) { + n = min (n, strlen(ip)); + op[n] = XEOS; + + for (n = n - 1; n >= 0; --n) + op[n] = ip[n]; + } + + return (outstr); +} diff --git a/sys/libc/ctsleep.c b/sys/libc/ctsleep.c new file mode 100644 index 00000000..9b89fe08 --- /dev/null +++ b/sys/libc/ctsleep.c @@ -0,0 +1,18 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#define import_xnames +#include + +/* C_TSLEEP -- Suspend process execution for the specified number of seconds. +*/ +void +c_tsleep ( + int nseconds +) +{ + XINT x_nsec = nseconds; + + TSLEEP (&x_nsec); +} diff --git a/sys/libc/cttset.c b/sys/libc/cttset.c new file mode 100644 index 00000000..ab252ea2 --- /dev/null +++ b/sys/libc/cttset.c @@ -0,0 +1,88 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_STTYCO -- Set terminal driver options via a command string. +*/ +void +c_sttyco ( + char *args, + XINT ttin, + XINT ttout, + XINT outfd +) +{ + XCHAR x_args[SZ_COMMAND]; + XINT x_ttin = ttin, x_ttout = ttout, x_outfd = outfd; + + c_strupk (args, x_args, SZ_COMMAND); + STTYCO (x_args, &x_ttin, &x_ttout, &x_outfd); +} + + +/* C_TTSETI -- FIO set integer terminal driver parameter. +*/ +void +c_ttseti ( + XINT fd, /* FIO file descriptor */ + int param, /* param to be set */ + int value /* new value */ +) +{ + XINT x_fd = fd, x_param = param, x_value = value; + + TTSETI (&x_fd, &x_param, &x_value); +} + + +/* C_TTSTATI -- FIO stat integer terminal driver parameter. +*/ +int +c_ttstati ( + XINT fd, /* FIO file descriptor */ + int param /* param to be set */ +) +{ + XINT x_fd = fd, x_param = param; + + return (TTSTATI (&x_fd, &x_param)); +} + +/* C_TTSETS -- FIO set string terminal driver parameter. +*/ +void +c_ttsets ( + XINT fd, /* FIO file descriptor */ + int param, /* param to be set */ + char *value /* new value */ +) +{ + XINT x_fd = fd, x_param = param; + + TTSETS (&x_fd, &x_param, c_sppstr (value)); +} + + +/* C_TTSTATS -- FIO stat string terminal driver parameter. +*/ +int +c_ttstats ( + XINT fd, /* FIO file descriptor */ + int param, /* param to be set */ + char *outstr, /* receives string value */ + int maxch +) +{ + XCHAR x_sval[SZ_LINE+1]; + XINT x_fd = fd, x_param = param, x_maxch = SZ_LINE; + int nchars; + + nchars = TTSTATS (&x_fd, &x_param, x_sval, &x_maxch); + c_strpak (x_sval, outstr, maxch); + return (maxch < nchars ? maxch : nchars); +} diff --git a/sys/libc/cttycdes.c b/sys/libc/cttycdes.c new file mode 100644 index 00000000..1d7cfc84 --- /dev/null +++ b/sys/libc/cttycdes.c @@ -0,0 +1,19 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + +/* C_TTYCDES -- Close the TTY descriptor. +*/ +void +c_ttycdes ( + XINT tty /* SPP pointer to descriptor */ +) +{ + XINT x_tty = tty; + + TTYCDES (&x_tty); +} diff --git a/sys/libc/cttyclear.c b/sys/libc/cttyclear.c new file mode 100644 index 00000000..e10c274f --- /dev/null +++ b/sys/libc/cttyclear.c @@ -0,0 +1,21 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_TTYCLEAR -- Clear the screen. +*/ +void +c_ttyclear ( + XINT fd, /* output file */ + XINT tty /* tty descriptor */ +) +{ + XINT x_fd = fd, x_tty = tty; + + TTYCLEAR (&x_fd, &x_tty); +} diff --git a/sys/libc/cttyclln.c b/sys/libc/cttyclln.c new file mode 100644 index 00000000..7a6a20ee --- /dev/null +++ b/sys/libc/cttyclln.c @@ -0,0 +1,22 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_TTYCLEARLN -- Clear the current line. The cursor is left positioned to +** the left margin. +*/ +void +c_ttyclearln ( + XINT fd, /* output file */ + XINT tty /* tty descriptor */ +) +{ + XINT x_fd = fd, x_tty = tty; + + TTYCLEARLN (&x_fd, &x_tty); +} diff --git a/sys/libc/cttyctrl.c b/sys/libc/cttyctrl.c new file mode 100644 index 00000000..8143c8e4 --- /dev/null +++ b/sys/libc/cttyctrl.c @@ -0,0 +1,27 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_TTYCTRL -- Lookup a capability in the termcap entry for a device and +** output the associated control string to the given output file. The baud +** rate (extracted from the environment at TTYODES time or set in a C_TTYSETI +** call) determines the number of pad characters output for delays. ERR is +** returned if the control sequence could not be output. +*/ +int +c_ttyctrl ( + XINT fd, /* output file */ + XINT tty, /* tty descriptor */ + char *cap, /* two char capability name */ + int afflncnt /* number of lines affected */ +) +{ + XINT x_fd = fd, x_tty = tty, x_afflncnt = afflncnt; + + return (TTYCTRL (&x_fd, &x_tty, c_sppstr(cap), &x_afflncnt)); +} diff --git a/sys/libc/cttygetb.c b/sys/libc/cttygetb.c new file mode 100644 index 00000000..cc1386bc --- /dev/null +++ b/sys/libc/cttygetb.c @@ -0,0 +1,24 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_TTYGETB -- Determine if the named capability exists for a device. +** Presence of the capability in the termcap entry for the device results +** in a return value of YES (=1), regardless of the actual datatype of +** the parameter. +*/ +int +c_ttygetb ( + XINT tty, /* tty descriptor */ + char *cap /* two char capability name */ +) +{ + XINT x_tty = tty; + + return ((int) BTOI ((XBOOL) TTYGETB (&x_tty, c_sppstr(cap)))); +} diff --git a/sys/libc/cttygeti.c b/sys/libc/cttygeti.c new file mode 100644 index 00000000..1011dac5 --- /dev/null +++ b/sys/libc/cttygeti.c @@ -0,0 +1,23 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_TTYGETI -- Get the value of a termcap capability of type integer. +** Zero is returned if the device does not have such a capability or if +** the the value string cannot be interpreted as an integer. +*/ +XINT +c_ttygeti ( + XINT tty, /* tty descriptor */ + char *cap /* two char capability name */ +) +{ + XINT x_tty = tty; + + return ((XINT) TTYGETI (&x_tty, c_sppstr(cap))); +} diff --git a/sys/libc/cttygetr.c b/sys/libc/cttygetr.c new file mode 100644 index 00000000..195d0e87 --- /dev/null +++ b/sys/libc/cttygetr.c @@ -0,0 +1,22 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + +/* C_TTYGETR -- Get the value of a termcap capability of type real. +** Zero is returned if the device does not have such a capability or if +** the the value string cannot be interpreted as a real. +*/ +float +c_ttygetr ( + XINT tty, /* tty descriptor */ + char *cap /* two char capability name */ +) +{ + XINT x_tty = tty; + + return ((float) TTYGETR (&x_tty, c_sppstr(cap))); +} diff --git a/sys/libc/cttygets.c b/sys/libc/cttygets.c new file mode 100644 index 00000000..04aea891 --- /dev/null +++ b/sys/libc/cttygets.c @@ -0,0 +1,34 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + +#define SZ_CAPSTR 128 +static XCHAR buf[SZ_CAPSTR]; +static XINT szbuf = 128; + + +/* C_TTYGETS -- Get the value of a termcap capability as a character string, +** suitable for subsequent output to the device with TTYPUTS (assuming the +** capability is a control function). The number of characters in the output +** string is returned as the function value. +*/ +int +c_ttygets ( + XINT tty, /* tty descriptor */ + char *cap, /* two char capability name */ + char *outstr, /* output string */ + int maxch /* max chars out, excl EOS */ +) +{ + XINT x_tty = tty; + int nchars; + + nchars = TTYGETS (&x_tty, c_sppstr(cap), buf, &szbuf); + c_strpak (buf, outstr, maxch); + + return (nchars); +} diff --git a/sys/libc/cttygoto.c b/sys/libc/cttygoto.c new file mode 100644 index 00000000..eb6f8922 --- /dev/null +++ b/sys/libc/cttygoto.c @@ -0,0 +1,23 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_TTYGOTO -- Move the cursor to the indicated X,Y position (one-indexed). +*/ +void +c_ttygoto ( + XINT fd, /* output file */ + XINT tty, /* tty descriptor */ + int col, /* x coordinate */ + int line /* y coordinate */ +) +{ + XINT x_fd = fd, x_tty = tty, x_col = col, x_line = line; + + TTYGOTO (&x_fd, &x_tty, &x_col, &x_line); +} diff --git a/sys/libc/cttyinit.c b/sys/libc/cttyinit.c new file mode 100644 index 00000000..da7da5ab --- /dev/null +++ b/sys/libc/cttyinit.c @@ -0,0 +1,22 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_TTYINIT -- Output the initialization sequence, if any, to the output +** file. +*/ +void +c_ttyinit ( + XINT fd, /* output file */ + XINT tty /* tty descriptor */ +) +{ + XINT x_fd = fd, x_tty = tty; + + TTYINIT (&x_fd, &x_tty); +} diff --git a/sys/libc/cttyodes.c b/sys/libc/cttyodes.c new file mode 100644 index 00000000..2d7a5cc3 --- /dev/null +++ b/sys/libc/cttyodes.c @@ -0,0 +1,89 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* +** CTTY -- Terminal control. The TTY package is an interface to the TERMCAP +** database, originally developed for Berkeley UNIX by Bill Joy. The termcap +** entry for a particular terminal presents in a condensed form the +** characteristics of the device, e.g., the number of line and columns on the +** screen, and how to clear the screen or move the cursor. The TTY routines +** are used to retrieve such capabilities from the database as well as to +** send the appropriate characters to a file (terminal) to perform such control +** functions. +** +** tty = c_ttyodes (ttyname) +** c_ttycdes (tty) +** c_ttyseti (tty, parameter, value) +** int = c_ttystati (tty, parameter) +** +** bool = c_ttygetb (tty, cap) +** int = c_ttygeti (tty, cap) +** float = c_ttygetr (tty, cap) +** nchars = c_ttygets (tty, cap, &outstr, maxch) +** c_ttyctrl (fd, tty, cap, afflncnt) +** c_ttyputs (fd, tty, ctrlstr, afflncnt) +** +** c_ttyclear (fd, tty) +** c_ttyclearln (fd, tty) +** c_ttygoto (fd, tty, col, line) +** c_ttyinit (fd, tty) +** c_ttyputline (fd, tty, text, map_cc) +** c_ttyso (fd, tty, onflag) +** +** +** Complete descriptions of TTY and termcap are given elsewhere. Briefly, the +** device descriptor for a particular terminal is opened with ttyodes, which +** returns a IRAF pointer (C integer) to the binary TTY descriptor. The +** terminal name may be given as "terminal", in which case ttyodes will look up +** the name of the default terminal in the environment and search the termcap +** database for the entry for the named device. +** +** The ttyget functions are used to read the capabilities. Capabilities are +** specified by two character mnemonics (character strings), shown as the cap +** arguments in the calling sequences above. Control sequences may be output +** with ttyctrl or with ttyputs, depending on whether you are willing to do a +** binary search for a particular capability at run time. The remaining high +** level functions make it easy to perform the more common control functions. +** +** Raw mode output to a terminal device is provided by the system interface +** (the newline and tab characters are exceptions). Raw mode input is provided +** as an fseti option in FIO. To set raw mode on STDIN: +** +** c_fseti (STDIN, F_RAW, YES); +** +** While raw mode is in effect input characters are read as they are typed, +** few or no control characters are recognized, and no echoing is performed. +** Raw mode is cleared whenever the newline character is sent to the terminal, +** but will be reset if by the next read if F_RAW remains set. +*/ + + +/* C_TTYODES -- Open the TTY descriptor for a particular terminal device. +** An SPP pointer to the TTY descriptor is returned as the function value. +** If the device name is given as "terminal" or "printer", the actual device +** name is taken to be the value of the environment variable of the same name. +** If the device name is the filename of a termcap format file, the entry +** for the first device in the file is loaded (this gives the user a simple +** means to supply special termcap entries). The name of the default +** termcap file is given by the environment variable "termcap". TTY maintains +** a cache of preloaded termcap device entries for frequently referenced +** devices. +*/ +XINT +c_ttyodes ( + char *ttyname /* termcap name of device */ +) +{ + XINT tty; + + iferr (tty = (XINT) TTYODES (c_sppstr (ttyname))) + return ((XINT) ERR); + else + return (tty); +} diff --git a/sys/libc/cttyputl.c b/sys/libc/cttyputl.c new file mode 100644 index 00000000..84fdf90a --- /dev/null +++ b/sys/libc/cttyputl.c @@ -0,0 +1,28 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_TTYPUTLINE -- Put a line of text to the output device. Any device +** independent control characters embedded in the text, e.g., tab, newline, +** formfeed, backspace, or the special control codes SO (enter standout mode) +** or SI (leave standout mode) are converted as necessary to drive the device. +** Unknown control codes are converted to printable sequences (e.g. ^C) if +** the map_cc flag is set. +*/ +void +c_ttyputline ( + XINT fd, /* output file */ + XINT tty, /* tty descriptor */ + char *line, /* line to be output */ + int map_cc /* map unknown ctrl chars */ +) +{ + XINT x_fd = fd, x_tty = tty, x_map_cc = map_cc; + + TTYPUTLINE (&x_fd, &x_tty, c_sppstr(line), &x_map_cc); +} diff --git a/sys/libc/cttyputs.c b/sys/libc/cttyputs.c new file mode 100644 index 00000000..4d428964 --- /dev/null +++ b/sys/libc/cttyputs.c @@ -0,0 +1,29 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_TTYPUTS -- Put a control sequence obtained in a prior call to C_TTYGETS +** to the output file. The baud rate (extracted from the environment at +** TTYODES time or set in a C_TTYSETI call) determines the number of pad +** characters output for delays. +*/ +int +c_ttyputs ( + XINT fd, /* output file */ + XINT tty, /* tty descriptor */ + char *cap, /* two char capability name */ + int afflncnt /* number of lines affected */ +) +{ + XINT x_fd = fd, x_tty = tty, x_afflncnt = afflncnt; + + iferr (TTYPUTS (&x_fd, &x_tty, c_sppstr(cap), &x_afflncnt)) + return (ERR); + else + return (OK); +} diff --git a/sys/libc/cttyseti.c b/sys/libc/cttyseti.c new file mode 100644 index 00000000..086dd98f --- /dev/null +++ b/sys/libc/cttyseti.c @@ -0,0 +1,22 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_TTYSETI -- Set a TTY interface parameter of type integer. +*/ +void +c_ttyseti ( + XINT tty, /* tty descriptor */ + int param, /* code of param to be set */ + int value /* value to be set */ +) +{ + XINT x_tty = tty, x_param = param, x_value = value; + + TTYSETI (&x_tty, &x_param, &x_value); +} diff --git a/sys/libc/cttyso.c b/sys/libc/cttyso.c new file mode 100644 index 00000000..3283f83f --- /dev/null +++ b/sys/libc/cttyso.c @@ -0,0 +1,23 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_TTYSO -- Turn standout mode (reverse video, underline, or upper case +** depending on the device) on or off. +*/ +void +c_ttyso ( + XINT fd, /* output file */ + XINT tty, /* tty descriptor */ + int onoff /* 1=on, 0=off */ +) +{ + XINT x_fd = fd, x_tty = tty, x_onoff = onoff; + + TTYSO (&x_fd, &x_tty, &x_onoff); +} diff --git a/sys/libc/cttystati.c b/sys/libc/cttystati.c new file mode 100644 index 00000000..9ba254c5 --- /dev/null +++ b/sys/libc/cttystati.c @@ -0,0 +1,21 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_TTYSTATI -- Return the value of a TTY integer interface parameter. +*/ +XINT +c_ttystati ( + XINT tty, /* tty descriptor */ + int param /* code of param to be set */ +) +{ + XINT x_tty = tty, x_param = param; + + return (TTYSTATI (&x_tty, &x_param)); +} diff --git a/sys/libc/ctype.c b/sys/libc/ctype.c new file mode 100644 index 00000000..4d52648c --- /dev/null +++ b/sys/libc/ctype.c @@ -0,0 +1,31 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_ctype +#include + +#ifdef vms +globaldef vms_ctype_defs; /* [MACHDEP] */ +#endif + +/* Character class associations for the ctype.h macros. +*/ +char u_ctype_[] = { + 0, + _C, _C, _C, _C, _C, _C, _C, _C, + _C, _S, _S, _S, _S, _S, _C, _C, + _C, _C, _C, _C, _C, _C, _C, _C, + _C, _C, _C, _C, _C, _C, _C, _C, + _S, _P, _P, _P, _P, _P, _P, _P, + _P, _P, _P, _P, _P, _P, _P, _P, + _N, _N, _N, _N, _N, _N, _N, _N, + _N, _N, _P, _P, _P, _P, _P, _P, + _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U, + _U, _U, _U, _U, _U, _U, _U, _U, + _U, _U, _U, _U, _U, _U, _U, _U, + _U, _U, _U, _P, _P, _P, _P, _P, + _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L, + _L, _L, _L, _L, _L, _L, _L, _L, + _L, _L, _L, _L, _L, _L, _L, _L, + _L, _L, _L, _P, _P, _P, _P, _C +}; diff --git a/sys/libc/cungetc.c b/sys/libc/cungetc.c new file mode 100644 index 00000000..d1f416ef --- /dev/null +++ b/sys/libc/cungetc.c @@ -0,0 +1,28 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_UNGETC -- Push a character back into the input stream. Pushback is last +** in first out, i.e., the last character pushed back is the first one +** read by GETC. Characters (and strings) may be pushed back until the +** FIO pushback buffer overflows. +*/ +int +c_ungetc ( + XINT fd, /* file */ + int ch /* char to be pushed */ +) +{ + XINT x_fd = fd; + XCHAR x_ch = ch; + + iferr (UNGETC (&x_fd, &x_ch)) + return (ERR); + else + return (OK); +} diff --git a/sys/libc/cungetl.c b/sys/libc/cungetl.c new file mode 100644 index 00000000..5e0fa40c --- /dev/null +++ b/sys/libc/cungetl.c @@ -0,0 +1,31 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + +#define MAX_STRLEN SZ_COMMAND + + +/* C_UNGETLINE -- Push a string back into the input stream. Pushback is last +** in first out, i.e., the last string pushed back is the first one read by +** GETC. Strings (and single characters) may be pushed back until the FIO +** pushback buffer overflows. +*/ +int +c_ungetline ( + XINT fd, /* file */ + char *str /* string to be pushed back */ +) +{ + XINT x_fd = fd; + XCHAR spp_str[MAX_STRLEN]; + + + iferr (UNGETLINE (&x_fd, c_strupk (str, spp_str, MAX_STRLEN))) + return (ERR); + else + return (OK); +} diff --git a/sys/libc/cvfnbrk.c b/sys/libc/cvfnbrk.c new file mode 100644 index 00000000..346b07fb --- /dev/null +++ b/sys/libc/cvfnbrk.c @@ -0,0 +1,30 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_knames +#include + + +/* C_VFNBRK -- Break a virtual filename (or host filename) into its component +** parts, i.e., logical directory (ldir), root, and extension. No characters +** are actually moved, rather, the offsets to the root and extn fields are +** returned as output arguments. +*/ +void +c_vfnbrk ( + char *vfn, /* virtual filename (or osfn) */ + int *root, /* offset of root field. */ + int *extn /* offset of extn field. */ +) +{ + XCHAR sppvfn[SZ_PATHNAME]; + XINT x_root = *root, x_extn = extn; + + ZFNBRK (c_strupk(vfn,sppvfn,SZ_PATHNAME), &x_root, &x_extn); + + /* Make offsets zero-indexed. */ + *root -= 1; + *extn -= 1; +} diff --git a/sys/libc/cwmsec.c b/sys/libc/cwmsec.c new file mode 100644 index 00000000..246285a1 --- /dev/null +++ b/sys/libc/cwmsec.c @@ -0,0 +1,20 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_knames +#include + + +/* C_WMSEC -- Delay for so may milliseconds. +*/ +void +c_wmsec ( + int msec /* milliseconds to delay */ +) +{ + XINT x_msec = msec; + + ZWMSEC (&x_msec); +} diff --git a/sys/libc/cwrite.c b/sys/libc/cwrite.c new file mode 100644 index 00000000..5ca7dab9 --- /dev/null +++ b/sys/libc/cwrite.c @@ -0,0 +1,51 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_fset +#define import_stdio +#define import_error +#include + + +/* C_WRITE -- FIO write to a file. Write exactly nbytes bytes from the buffer +** buf to the stream fd. If the actual file is a text file C chars are output +** as XCHARs. If the actual file is a binary file no conversion is performed, +** but an integral number of XCHARs are always written. +*/ +int +c_write ( + XINT fd, /* FIO file descriptor */ + char *buf, /* buffer containing data to be written */ + int nbytes /* nbytes to be written */ +) +{ + XINT x_fd = fd; + + if (c_fstati (fd, F_TYPE) == TEXT_FILE) { + register FILE *fp = FDTOFP(fd); + register char *ip; + register int n = nbytes; + + for (ip=buf; --n >= 0; ip++) + putc (*ip, fp); + if (ferror (fp)) + c_erract (EA_ERROR); + + } else { + XINT x_nchars = (nbytes + sizeof(XCHAR)-1) / sizeof(XCHAR); + XCHAR *bp = (XCHAR *)buf; + + /* Verify that the pointer coercion char->XCHAR->char is legal, + * i.e., that the char pointer is aligned to an XCHAR word + * boundary if required on this machine. + */ + if (buf != (char *) bp) + return (ERR); + WRITE (&x_fd, bp, &x_nchars); + } + + return (nbytes); +} diff --git a/sys/libc/cxgmes.c b/sys/libc/cxgmes.c new file mode 100644 index 00000000..f8384923 --- /dev/null +++ b/sys/libc/cxgmes.c @@ -0,0 +1,29 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_knames +#include + + +/* C_XGMES -- Fetch the machine dependent integer code and message string +** for the most recent exception. The integer code XOK is returned if +** no exception has occurred or if C_XGMES is called more than once after +** a single exception. +*/ +void +c_xgmes ( + int *oscode, /* os integer code of exception */ + char *oserrmsg, /* os error message string */ + int maxch +) +{ + PKCHAR x_oserrmsg[SZ_LINE+1]; + XINT x_oscode = *oscode, x_maxch = SZ_LINE; + + ZXGMES (&x_oscode, x_oserrmsg, &x_maxch); + (void) strncpy (oserrmsg, (char *)x_oserrmsg, maxch); + *oscode = x_oscode; +} diff --git a/sys/libc/cxonerr.c b/sys/libc/cxonerr.c new file mode 100644 index 00000000..2154851c --- /dev/null +++ b/sys/libc/cxonerr.c @@ -0,0 +1,19 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#define import_xnames +#include + + +/* C_XONERR -- Call any error handler procedures posted with ONERROR. +*/ +void +c_xonerr ( + int errcode +) +{ + XINT x_errcode = errcode; + + XONERR (&x_errcode); +} diff --git a/sys/libc/cxttysize.c b/sys/libc/cxttysize.c new file mode 100644 index 00000000..81ac4541 --- /dev/null +++ b/sys/libc/cxttysize.c @@ -0,0 +1,25 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* C_XTTYSIZE -- Get the terminal screen size, dynamically querying the +** terminal for the screen size if the terminal has this capabability (e.g., +** a workstation window). +*/ +void +c_xttysize ( + int *ncols, /* ncols (output) */ + int *nlines /* nlines (output) */ +) +{ + XINT x_ncols, x_nlines; + + XTTYSIZE (&x_ncols, &x_nlines); + *ncols = x_ncols; + *nlines = x_nlines; +} diff --git a/sys/libc/cxwhen.c b/sys/libc/cxwhen.c new file mode 100644 index 00000000..b3523dfe --- /dev/null +++ b/sys/libc/cxwhen.c @@ -0,0 +1,63 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_xnames +#define import_knames +#define import_libc +#include + + +/* CXWHEN -- Post an exception handler. The exception handler procedure +** is called when an exception occurs, unless the exception has been +** disabled. If a user exception handler has not been posted and an +** exception has not been disabled, a system default exception handler is +** called when the exception occurs. +** +** Currently only four exceptions are recognized (import_xwhen): +** +** X_INT interrupt +** X_ARITH arithmetic exception (e.g. divide by zero) +** X_ACV access violation (e.g. illegal memory reference) +** X_IPC write to IPC with no reader +** +** When an exception occurs the user supplied exception handler is called +** with the following argument list: +** +** handler (&exception, &next_handler) +** +** The first argument is the code for the virtual exception calling the user +** handler (the same handler may be posted for more than one exception). +** The second argument is set by the user handler before exiting, and +** must be either the ZLOCPR entry point address of the next exception +** handler to be called or NULL, indicating that normal execution is to +** resume. +** +** For portability reasons, only the virtual exceptions should be used to +** post exception handlers. For good diagnostic messages when an exception +** occurs it is desirable, however, to have a more precise description of +** the actual host system exception which occurred. This may be obtained +** by a call to C_XGMES. +*/ + +#define SZ_ERRMSG 64 +typedef int (*PFI)(); /* pointer to function returning int */ + + +/* C_XWHEN -- Post an exception handler for an exception, or disable the +** exception (not all exceptions can be disabled). +*/ +void +c_xwhen ( + int exception, /* code for virtual exception */ + PFI new_handler, /* new exception handler */ + PFI *old_handler /* old exception handler (output) */ +) +{ + XINT excode = exception; + XINT epa_new_handler = (XINT)new_handler; + XINT epa_old_handler; + + XWHEN (&excode, &epa_new_handler, &epa_old_handler); + *old_handler = (PFI)epa_old_handler; +} diff --git a/sys/libc/eprintf.c b/sys/libc/eprintf.c new file mode 100644 index 00000000..54cb5b8f --- /dev/null +++ b/sys/libc/eprintf.c @@ -0,0 +1,25 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#define import_stdarg +#include + + +/* EPRINTF -- Formatted print to the standard error output. +*/ +void +eprintf (char *format, ...) +{ + va_list argp; + + extern void u_doprnt(); + + + va_start (argp, format); + u_doprnt (format, &argp, stderr); + va_end (argp); + (void) fflush (stderr); +} diff --git a/sys/libc/fclose.c b/sys/libc/fclose.c new file mode 100644 index 00000000..969c5d50 --- /dev/null +++ b/sys/libc/fclose.c @@ -0,0 +1,23 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#define import_xnames +#include + +/* FCLOSE -- Close a file opened with fopen. +*/ +int +fclose ( + FILE *fp +) +{ + XINT x_fd = fileno(fp); + + iferr (CLOSE (&x_fd)) + return (EOF); + else + return (OK); +} diff --git a/sys/libc/fdopen.c b/sys/libc/fdopen.c new file mode 100644 index 00000000..c9e2bc9f --- /dev/null +++ b/sys/libc/fdopen.c @@ -0,0 +1,76 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#define import_fset +#include + + +extern int c_fstati(); + + +/* FDOPEN -- Reopen a file for i/o with the STDIO package, after the file +** as already been opened by FIO. It is an error if the access modes are +** incompatible. +*/ +FILE * +fdopen ( + XINT fd, /* FIO file descriptor */ + char *mode /* STDIO access mode */ +) +{ + register int fio_mode = c_fstati (fd, F_MODE); + register int fio_type = c_fstati (fd, F_TYPE); + + + /* Verify file access mode. No mode checking is performed for the + * special file types. + */ + if (fio_type == TEXT_FILE || fio_type == BINARY_FILE) + switch (mode[0]) { + case 'r': + if (fio_mode != READ_ONLY && fio_mode != READ_WRITE) + return (NULL); + break; + + case 'w': + switch (fio_mode) { + case NEW_FILE: + case READ_WRITE: + case WRITE_ONLY: + break; + default: + return (NULL); + } + break; + + case 'a': + if (fio_mode != APPEND && fio_mode != NEW_FILE) + return (NULL); + break; + + default: + return (NULL); + } + + /* Verify file type. No checking is performed if no type is given. + */ + switch (mode[1]) { + case EOS: + break; + case 't': + if (fio_type != TEXT_FILE) + return (NULL); + break; + case 'b': + if (fio_type != BINARY_FILE) + return (NULL); + break; + default: + return (NULL); + } + + return (FDTOFP(fd)); +} diff --git a/sys/libc/fflush.c b/sys/libc/fflush.c new file mode 100644 index 00000000..14a2356a --- /dev/null +++ b/sys/libc/fflush.c @@ -0,0 +1,24 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#define import_xnames +#include + + +/* FFLUSH -- Flush the output file. +*/ +int +fflush ( + FILE *fp +) +{ + XINT x_fd = fileno(fp); + + iferr (FLUSH (&x_fd)) + return (EOF); + else + return (OK); +} diff --git a/sys/libc/fgetc.c b/sys/libc/fgetc.c new file mode 100644 index 00000000..155a1111 --- /dev/null +++ b/sys/libc/fgetc.c @@ -0,0 +1,19 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* FGETC -- Get a character from the input file. Offered as a functionally +** equivalent alternative to the macro GETC. +*/ +int +fgetc ( + FILE *fp +) +{ + return (getc (fp)); +} diff --git a/sys/libc/fgets.c b/sys/libc/fgets.c new file mode 100644 index 00000000..45c228c6 --- /dev/null +++ b/sys/libc/fgets.c @@ -0,0 +1,43 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* FGETS -- Return a newline delimited string in the user buffer. If the +** buffer fills before newline is seen the string will not be newline +** delimited. +*/ +char * +fgets ( + char *buf, /* user supplied output buffer */ + int maxch, /* max chars out (incl EOS) */ + FILE *fp /* input file */ +) +{ + register int ch = 0, lastch = 0, n = maxch - 1; + register char *op = buf; + + while (--n >= 0 && (ch = getc (fp)) >= 0) { + lastch = ch; + if (ch == '\r') /* handle DOS-style CR-NL */ + continue; + *op++ = ch; + if (ch == '\n') + break; + } + + if (ch == EOF && op == buf) + return ((char *) NULL); + else { +#ifdef ADD_NEWLINE + if (lastch != '\n') /* handle missing NL at EOF */ + *op++ = '\n'; +#endif + *op = EOS; + return (buf); + } +} diff --git a/sys/libc/fopen.c b/sys/libc/fopen.c new file mode 100644 index 00000000..f9fe16ae --- /dev/null +++ b/sys/libc/fopen.c @@ -0,0 +1,61 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_stdio +#include + + +/* FOPEN -- Open a file with the given access mode and file type. The file type +** (text or binary) is specified with an optional, non UNIX standard character +** "t" or "b" in the modestring. The default is text file if no type is given. +*/ +FILE * +fopen ( + char *fname, /* vfn of file */ + char *modestr /* access mode [and type] */ +) +{ + XINT x_filetype, x_filemode; + int fd; + + + /* Get file type. + */ + switch (modestr[1]) { + case 't': + case EOS: + x_filetype = TEXT_FILE; + break; + case 'b': + x_filetype = BINARY_FILE; + break; + default: + return (NULL); + } + + /* Determine file access mode. + */ + switch (modestr[0]) { + case 'r': + x_filemode = READ_ONLY; + break; + case 'w': + x_filemode = NEW_FILE; + break; + case 'a': + x_filemode = APPEND; + break; + default: + return (NULL); + } + + /* Open file. + */ + iferr (fd = OPEN (c_sppstr(fname), &x_filemode, &x_filetype)) + return (NULL); + else + return (FDTOFP(fd)); +} diff --git a/sys/libc/fputc.c b/sys/libc/fputc.c new file mode 100644 index 00000000..7d815206 --- /dev/null +++ b/sys/libc/fputc.c @@ -0,0 +1,20 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* FPUTC -- Put a character to the output file. Offered as a functionally +** equivalent alternative to the macro PUTC. +*/ +int +fputc ( + char ch, + FILE *fp +) +{ + return (putc (ch, fp)); +} diff --git a/sys/libc/fputs.c b/sys/libc/fputs.c new file mode 100644 index 00000000..76dca159 --- /dev/null +++ b/sys/libc/fputs.c @@ -0,0 +1,22 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* FPUTS -- Put a null terminated string to the output file. +*/ +void +fputs ( + char *str, /* input string */ + FILE *fp /* output file */ +) +{ + register char *ip; + + for (ip=str; *ip != EOS; ip++) + putc (*ip, fp); +} diff --git a/sys/libc/fread.c b/sys/libc/fread.c new file mode 100644 index 00000000..28f1376c --- /dev/null +++ b/sys/libc/fread.c @@ -0,0 +1,55 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* FREAD -- Read a binary block of data from the input file. To be consistent +** with UNIX we must read until nelem chars have been accumulated or until +** EOF is seen. Hence, if reading from a record structured device such as a +** terminal, the read will not be terminated by end of record (newline). +** If the number of bytes (C chars) requested does not fill an integral number +** of XCHARS additional bytes will be read to fill out the last XCHAR. +*/ +int +fread ( + char *bp, /* output buffer */ + int szelem, /* nbytes per element */ + int nelem, /* nelems to read */ + FILE *fp +) +{ + register int nread, n; + int nbytes; + XINT fd = fileno (fp); + char *op = bp; + + + fd = fileno (fp); + nbytes = nelem * szelem; + nread = 0; + + if (fp == stdin) + (void) fflush (stdout); + if (szelem <= 0) + return (0); + + for (op = bp; nread < nbytes; op += n) { + iferr (n = c_read (fd, op, nbytes-nread)) { + fp->_fflags |= _FERR; + break; + } else if (n == EOF) { + fp->_fflags |= _FEOF; + break; + } else + nread += n; + } + + if (fp->_fflags & (_FEOF|_FERR)) + return (nread ? nread / szelem : 0); + else + return (nread / szelem); +} diff --git a/sys/libc/freadline.c b/sys/libc/freadline.c new file mode 100644 index 00000000..b335ee20 --- /dev/null +++ b/sys/libc/freadline.c @@ -0,0 +1,34 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* FREADLINE -- Get a line from a user with editing. This is a libc + * interface to the host readline() interface. The host readline() + * returns a buffer allocated which we free here, what's returned to + * the caller is a static buffer containing the input string. + */ +char * +freadline ( + char *prompt /* user supplied output buffer */ +) +{ + char *cmd = (char *) NULL; + static char line[SZ_LINE]; + char *readline (char *prompt); + + + memset (line, 0, SZ_LINE); + if ((cmd = readline (prompt)) == (char *) NULL) { + return ((char *) NULL); + } else { + strcpy (line, cmd); /* save to static buffer */ + zfree_ ((void *) cmd); /* free readline() buffer */ + } + + return ((char *) line); +} diff --git a/sys/libc/free.c b/sys/libc/free.c new file mode 100644 index 00000000..4edd18c0 --- /dev/null +++ b/sys/libc/free.c @@ -0,0 +1,22 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* FREE -- Free a block of storage previously allocated by malloc, calloc, +** or realloc. +*/ +void +free ( + char *buf +) +{ + XINT x_ptr, x_dtype = TY_CHAR; + + x_ptr = Memcptr (buf); + MFREE (&x_ptr, &x_dtype); +} diff --git a/sys/libc/freopen.c b/sys/libc/freopen.c new file mode 100644 index 00000000..4d4ed997 --- /dev/null +++ b/sys/libc/freopen.c @@ -0,0 +1,56 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* FREOPEN -- Close a stream and reopen it upon the named file. This is +** commonly used to redirect one of the standard streams stdin, stdout, +** or stderr to a named file. +*/ +FILE * +freopen ( + char *fname, /* vfn of file to be opened */ + char *modestr, /* access mode [and type] */ + FILE *fp /* stream to be reopened */ +) +{ + register XINT fd = fileno(fp); + register int status, filetype; + + + /* Determine the file type of the file to be opened. This is given + * by an optional second character in the mode string. Default is + * text file if absent. + */ + switch (modestr[1]) { + case 't': + case EOS: + filetype = TEXT_FILE; + break; + case 'b': + filetype = BINARY_FILE; + break; + default: + return (NULL); + } + + switch (modestr[0]) { + case 'r': + status = c_fredir (fd, fname, READ_ONLY, filetype); + break; + case 'w': + status = c_fredir (fd, fname, NEW_FILE, filetype); + break; + case 'a': + status = c_fredir (fd, fname, APPEND, filetype); + break; + default: + return (NULL); + } + + return (status == ERR ? NULL : fp); +} diff --git a/sys/libc/fseek.c b/sys/libc/fseek.c new file mode 100644 index 00000000..fa32466c --- /dev/null +++ b/sys/libc/fseek.c @@ -0,0 +1,93 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#define import_fset +#include + + +/* FSEEK -- Seek on a file opened under stdio. The seek functions do not +** completely emulate the UNIX seek functions. The following restrictions +** apply: +** +** - It is only permissible to seek to the beginning of a line if the +** actual file is a text file. The seek offset must have been +** obtained by a prior call to FTELL, which returns the seek offset +** of the next line to be read or written. Seek offsets cannot be +** manufactured, e.g., as physical char offsets in the file, as is +** the case for binary files. These restrictions apply because text +** files are record structured on many systems, rather than simple +** byte stream files as in UNIX. +** +** - It is permissible to randomly seek about on a binary file, but +** seeks must be aligned on XCHAR word boundaries in the file. This +** can be guaranteed by structuring the application so that it always +** reads and writes binary data records that are an integral number +** of integers in size. If this is done the program is portable to +** any IRAF machine as well as to UNIX. Seek offsets are specified +** in units of bytes and are zero-indexed, as in C. +*/ +int +fseek ( + FILE *fp, /* operand file */ + long offset, /* offset in file */ + int mode /* 0=absolute, 1=relative, 2=from EOF */ +) +{ + register XINT fd = fileno(fp); + int text_file, stat; + long c_note(); + + + text_file = (c_fstati (fd, F_TYPE) == TEXT_FILE); + fp->_fflags &= ~_FEOF; + + if (text_file) { + switch (mode) { + case 0: + if (offset == 0L) + stat = c_seek (fd, BOFL); + else + stat = c_seek (fd, offset); + break; + case 2: + if (offset == 0L) { + stat = c_seek (fd, EOFL); + fp->_fflags |= _FEOF; + } else + stat = ERR; + break; + default: + stat = ERR; + break; + } + + } else { + /* Random seeks on (non-streaming) binary files are permitted, + * but the seek must be to an XCHAR offset. This is checked + * by c_seek, which takes a zero-indexed byte offset as argument. + */ + switch (mode) { + case 0: + stat = c_seek (fd, offset); + break; + case 1: + stat = c_seek (fd, c_note(fd) + offset); + break; + case 2: + if ((stat = c_seek (fd, EOFL)) != ERR) { + if (offset == 0L) + fp->_fflags |= _FEOF; + else + stat = c_seek (fd, c_note(fd) - offset); + } + break; + default: + stat = ERR; + } + } + + return (stat); +} diff --git a/sys/libc/ftell.c b/sys/libc/ftell.c new file mode 100644 index 00000000..be373a6d --- /dev/null +++ b/sys/libc/ftell.c @@ -0,0 +1,21 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* FTELL -- Get the FSEEK offset of the current position in a file, i.e., +** the file offset at which the next read or write will occur. For a text +** file this is a magic number, for a binary file it is the zero-indexed +** offset in bytes from the beginning of the file. +*/ +long +ftell ( + FILE *fp /* operand file */ +) +{ + return (c_note (fileno(fp))); +} diff --git a/sys/libc/fwrite.c b/sys/libc/fwrite.c new file mode 100644 index 00000000..cb9e06e6 --- /dev/null +++ b/sys/libc/fwrite.c @@ -0,0 +1,36 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* FWRITE -- Write a binary block of data to the output file. If the number +** of bytes (C chars) specified does not fill an integral number of XCHARS +** additional bytes will be written to fill out the last XCHAR. The actual +** number of elements written is returned as the function value. +*/ +int +fwrite ( + char *bp, /* output buffer */ + int szelem, /* nbytes per element */ + int nelem, /* nelems to read */ + FILE *fp +) +{ + register int stat; + XINT fd = fileno (fp); + + + if (szelem) { + stat = c_write (fd, bp, nelem * szelem); + if (stat == ERR) { + fp->_fflags |= _FERR; + return (0); + } else + return (stat / szelem); + } else + return (0); +} diff --git a/sys/libc/gets.c b/sys/libc/gets.c new file mode 100644 index 00000000..309efa11 --- /dev/null +++ b/sys/libc/gets.c @@ -0,0 +1,34 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* GETS -- Read a newline terminated sequence from the standard input and +** return the resultant string minus the newline to the user. +*/ +char * +gets ( + char *buf /* user supplied output buffer */ +) +{ + register FILE *fp = stdin; + register char *op = buf; + register int ch; + + + while ((ch = getc (fp)) != EOF) { + if (ch == '\n') + break; + *op++ = ch; + } + *op = EOS; + + if (ch == EOF && op == buf) + return ((char *) NULL); + else + return (buf); +} diff --git a/sys/libc/getw.c b/sys/libc/getw.c new file mode 100644 index 00000000..c0dd0cf9 --- /dev/null +++ b/sys/libc/getw.c @@ -0,0 +1,28 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* GETW -- Get a word (integer) from the input stream. When used in conjunction +** with PUTW this permits storage and retrieval of binary words in any file, +** albeit somewhat inefficiently. +*/ +int +getw ( + FILE *fp /* input file */ +) +{ + int word; + register char *op = (char *)&word; + register int n = sizeof (int); + + + while (--n >= 0) + *op++ = getc (fp); + + return ((fp->_fflags & (_FEOF|_FERR)) ? EOF : word); +} diff --git a/sys/libc/index.c b/sys/libc/index.c new file mode 100644 index 00000000..fa7a4917 --- /dev/null +++ b/sys/libc/index.c @@ -0,0 +1,26 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#define import_spp +#include + + +/* INDEX -- Search string STR for char CH, returning a pointer to the first +** occurrence of CH in STR or NULL. +*/ +char * +index ( + char *str, /* string to be searched */ + int ch /* character we are searching for */ +) +{ + register char *ip = str; + + do { + if (*ip == ch) + return (ip); + } while (*ip++); + + return ((char *) NULL); +} diff --git a/sys/libc/isatty.c b/sys/libc/isatty.c new file mode 100644 index 00000000..b625299a --- /dev/null +++ b/sys/libc/isatty.c @@ -0,0 +1,20 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* ISATTY -- Test if the given file is a terminal. +*/ +int +isatty ( + XINT fd +) +{ + XINT x_fd = fd; + + return (XISATTY (&x_fd)); +} diff --git a/sys/libc/libc_proto.h b/sys/libc/libc_proto.h new file mode 100644 index 00000000..52590a8e --- /dev/null +++ b/sys/libc/libc_proto.h @@ -0,0 +1,326 @@ +/* atof.c */ +extern double u_atof(char *str); +/* atoi.c */ +extern int u_atoi(char *str); +/* atol.c */ +extern long u_atol(char *str); +/* caccess.c */ +extern int c_access(char *fname, int mode, int type); +/* callocate.c */ +extern int c_allocate(char *device); +extern int c_deallocate(char *device, int u_rewind); +extern void c_devstatus(char *device, int out); +extern int c_devowner(char *device, char *owner, int maxch); +/* calloc.c */ +extern char *u_calloc(unsigned int nelems, unsigned int elsize); +/* cclktime.c */ +extern long c_clktime(long reftime); +extern long c_cputime(long reftime); +/* cclose.c */ +extern int c_close(int fd); +/* ccnvdate.c */ +extern char *c_cnvdate(long clktime, char *outstr, int maxch); +/* ccnvtime.c */ +extern char *c_cnvtime(long clktime, char *outstr, int maxch); +/* cdelete.c */ +extern int c_delete(char *fname); +/* cenvget.c */ +extern char *u_envget(char *var); +extern int c_envgs(char *var, char *outstr, int maxch); +extern int c_envfind(char *var, char *outstr, int maxch); +extern int c_envgb(char *var); +extern int c_envgi(char *var); +extern void c_envputs(char *var, char *value); +extern void c_envreset(char *var, char *value); +/* cenvlist.c */ +extern void c_envlist(int fd, char *prefix, int show_redefs); +/* cenvmark.c */ +extern void c_envmark(int *envp); +extern int c_envfree(int envp, int userfcn); +extern int c_prenvfree(int pid, int envp); +/* cenvscan.c */ +extern int c_envscan(char *input_source); +/* cerract.c */ +extern void c_erract(int action); +/* cerrcode.c */ +extern int c_errcode(void); +/* cerrget.c */ +extern int c_errget(char *outstr, int maxch); +/* cerror.c */ +extern void c_error(int errcode, char *errmsg); +/* cfchdir.c */ +extern int c_fchdir(char *newdir); +/* cfilbuf.c */ +extern int c_filbuf(struct _iobuf *fp); +/* cfinfo.c */ +extern int c_finfo(char *fname, struct _finfo *fi); +/* cflsbuf.c */ +extern int c_flsbuf(unsigned int ch, struct _iobuf *fp); +/* cflush.c */ +extern void c_flush(int fd); +/* cfmapfn.c */ +extern int c_fmapfn(char *vfn, char *osfn, int maxch); +/* cfmkdir.c */ +extern int c_fmkdir(char *newdir); +/* cfnextn.c */ +extern int c_fnextn(char *vfn, char *extn, int maxch); +/* cfnldir.c */ +extern int c_fnldir(char *vfn, char *ldir, int maxch); +/* cfnroot.c */ +extern int c_fnroot(char *vfn, char *root, int maxch); +/* cfpath.c */ +extern int c_fpathname(char *vfn, char *osfn, int maxch); +/* cfredir.c */ +extern int c_fredir(int fd, char *fname, int mode, int type); +/* cfseti.c */ +extern void c_fseti(int fd, int param, int value); +/* cfstati.c */ +extern int c_fstati(int fd, int param); +/* cgetpid.c */ +extern int c_getpid(void); +/* cgetuid.c */ +extern char *c_getuid(char *outstr, int maxch); +/* cgflush.c */ +extern void c_gflush(int stream); +/* cimaccess.c */ +extern int c_imaccess(char *imname, int mode); +/* cimdrcur.c */ +extern int c_imdrcur(char *device, float *x, float *y, int *wcs, int *key, char *strval, int maxch, int d_wcs, int pause); +/* ckimapc.c */ +extern int c_kimapchan(int chan, char *nodename, int maxch); +/* clexnum.c */ +extern int c_lexnum(char *str, int *toklen); +/* cmktemp.c */ +extern int c_mktemp(char *root, char *temp_filename, int maxch); +/* cndopen.c */ +extern int c_ndopen(char *fname, int mode); +/* cnote.c */ +extern long c_note(int fd); +/* copen.c */ +extern int c_open(char *fname, int mode, int type); +/* coscmd.c */ +extern int c_oscmd(char *cmd, char *infile, char *outfile, char *errfile); +/* cpoll.c */ +extern int c_poll_open(void); +extern int c_poll(int fds, int nfds, int timeout); +extern void c_poll_close(int fds); +extern void c_poll_zero(int fds); +extern void c_poll_set(int fds, int fd, int type); +extern void c_poll_clear(int fds, int fd, int type); +extern int c_poll_test(int fds, int fd, int type); +extern int c_poll_get_nfds(int fds); +extern void c_poll_print(int fds); +/* cprcon.c */ +extern unsigned int c_propen(char *process, int *in, int *out); +extern int c_prclose(unsigned int pid); +extern int c_prstati(int pid, int param); +extern int c_prsignal(unsigned pid, int signal); +extern int c_prredir(unsigned pid, int stream, int new_fd); +extern int c_prchdir(int pid, char *newdir); +extern int c_prenvset(int pid, char *envvar, char *value); +/* cprdet.c */ +extern unsigned int c_propdpr(char *process, char *bkgfile, char *bkgmsg); +extern int c_prcldpr(unsigned job); +extern int c_prdone(unsigned job); +extern int c_prkill(unsigned job); +/* cprintf.c */ +extern int c_printf(char *format); +extern int c_fprintf(int fd, char *format); +extern void c_pargb(int ival); +extern void c_pargc(int ival); +extern void c_pargs(short sval); +extern void c_pargi(int ival); +extern void c_pargl(long lval); +extern void c_pargr(float rval); +extern void c_pargd(double dval); +extern void c_pargstr(char *strval); +/* crcursor.c */ +extern int c_rcursor(int fd, char *outstr, int maxch); +/* crdukey.c */ +extern int c_rdukey(char *obuf, int maxch); +/* cread.c */ +extern int c_read(int fd, char *buf, int maxbytes); +/* crename.c */ +extern int c_rename(char *old_fname, char *new_fname); +/* creopen.c */ +extern int c_reopen(int fd, int mode); +/* csalloc.c */ +extern char *c_salloc(unsigned nbytes); +extern void c_smark(int *sp); +extern void c_sfree(int sp); +/* cseek.c */ +extern int c_seek(int fd, long offset); +/* csppstr.c */ +extern short *c_sppstr(char *str); +/* cstropen.c */ +extern int c_stropen(short *obuf, int maxch, int mode); +/* cstrpak.c */ +extern char *c_strpak(short *sppstr, char *cstr, int maxch); +/* cstrupk.c */ +extern short *c_strupk(char *str, short *outstr, int maxch); +/* ctsleep.c */ +extern void c_tsleep(int nseconds); +/* cttset.c */ +extern void c_sttyco(char *args, int ttin, int ttout, int outfd); +extern void c_ttseti(int fd, int param, int value); +extern int c_ttstati(int fd, int param); +extern void c_ttsets(int fd, int param, char *value); +extern int c_ttstats(int fd, int param, char *outstr, int maxch); +/* cttycdes.c */ +extern void c_ttycdes(XINT tty); +/* cttyclear.c */ +extern void c_ttycr(int fd, XINT tty); +/* cttyclln.c */ +extern void c_ttycn(int fd, XINT tty); +/* cttyctrl.c */ +extern int c_ttyctrl(int fd, XINT tty, char *cap, int afflncnt); +/* cttygetb.c */ +extern int c_ttygb(XINT tty, char *cap); +/* cttygeti.c */ +extern XINT c_ttygi(XINT tty, char *cap); +/* cttygetr.c */ +extern float c_ttygr(XINT tty, char *cap); +/* cttygets.c */ +extern int c_ttygs(XINT tty, char *cap, char *outstr, int maxch); +/* cttygoto.c */ +extern void c_ttygoto(int fd, XINT tty, int col, int line); +/* cttyinit.c */ +extern void c_ttyinit(int fd, XINT tty); +/* cttyodes.c */ +extern XINT c_ttyodes(char *ttyname); +/* cttyputl.c */ +extern void c_ttype(int fd, XINT tty, char *line, int map_cc); +/* cttyputs.c */ +extern int c_ttyps(int fd, XINT tty, char *cap, int afflncnt); +/* cttyseti.c */ +extern void c_ttyseti(XINT tty, int param, int value); +/* cttyso.c */ +extern void c_ttyso(int fd, XINT tty, int onoff); +/* cttystati.c */ +extern XINT c_ttystati(XINT tty, int param); +/* ctype.c */ +/* cungetc.c */ +extern int c_ungec(int fd, int ch); +/* cungetl.c */ +extern int c_ungetline(int fd, char *str); +/* cvfnbrk.c */ +extern void c_vfnbrk(char *vfn, int *root, int *extn); +/* cwmsec.c */ +extern void c_wmsec(int msec); +/* cwrite.c */ +extern int c_write(int fd, char *buf, int nbytes); +/* cxgmes.c */ +extern void c_xgmes(int *oscode, char *oserrmsg, int maxch); +/* cxonerr.c */ +extern void c_xonerr(int errcode); +/* cxttysize.c */ +extern void c_xttysize(int *ncols, int *nlines); +/* cxwhen.c +extern void c_xwhen(int exception, PFI new_handler, PFI *old_handler); + */ +/* eprintf.c */ +extern void u_eprintf(char *format, ...); +/* fclose.c */ +extern int u_fclose(struct _iobuf *fp); +/* fdopen.c */ +extern struct _iobuf *u_fdopen(int fd, char *mode); +/* fflush.c */ +extern int u_fflush(struct _iobuf *fp); +/* fgetc.c */ +extern int u_fgetc(struct _iobuf *fp); +/* fgets.c */ +extern char *u_fgets(char *buf, int maxch, struct _iobuf *fp); +/* fopen.c */ +extern struct _iobuf *u_fopen(char *fname, char *modestr); +/* fputc.c */ +extern int u_fputc(char ch, struct _iobuf *fp); +/* fputs.c */ +extern void u_fputs(char *str, struct _iobuf *fp); +/* fread.c */ +extern int u_fread(char *bp, int szelem, int nelem, struct _iobuf *fp); +/* free.c */ +extern void u_free(char *buf); +/* freopen.c */ +extern struct _iobuf *u_freopen(char *fname, char *modestr, struct _iobuf *fp); +/* fseek.c */ +extern int u_fseek(struct _iobuf *fp, long offset, int mode); +/* ftell.c */ +extern long u_ftell(struct _iobuf *fp); +/* fwrite.c */ +extern int u_fwrite(char *bp, int szelem, int nelem, struct _iobuf *fp); +/* gets.c */ +extern char *u_gets(char *buf); +/* getw.c */ +extern int u_getw(struct _iobuf *fp); +/* index.c */ +extern char *u_index(char *str, int ch); +/* isatty.c */ +extern int u_isatty(int fd); +/* malloc.c */ +extern char *u_malloc(unsigned nbytes); +/* mktemp.c */ +extern char *u_mktemp(char *template); +/* perror.c */ +extern void u_perror(char *prefix); +/* printf.c */ +extern void u_printf(char *format, ...); +extern void u_fprintf(struct _iobuf *fp, char *format, ...); +/* +extern void u_doprnt(char *format, va_list *argp, struct _iobuf *fp); +extern void u_doarg(struct _iobuf *fp, short *formspec, va_list **argp, int prec[], int varprec, int dtype); +*/ +/* puts.c */ +extern int u_puts(char *str); +/* putw.c */ +extern int u_putw(int word, struct _iobuf *fp); +/* qsort.c */ +extern void u_qsort(char *base, int n, int size, int (*compar)(void)); +/* realloc.c */ +extern char *u_realloc(char *buf, unsigned newsize); +/* rewind.c */ +extern long u_rewind(struct _iobuf *fp); +/* rindex.c */ +extern char *u_rindex(char *str, int ch); +/* scanf.c */ +extern int u_scanf(char *format, ...); +extern int u_fscanf(struct _iobuf *fp, char *format, ...); +extern int u_sscanf(char *str, char *format, ...); +/* setbuf.c */ +extern void u_setbuf(struct _iobuf *fp, char *buf); +extern void u_setfbf(struct _iobuf *fp, char *buf, int size); +extern void u_setlinebuf(struct _iobuf *fp); +/* spf.c */ +extern int spf_open(char *buf, int maxch); +extern void spf_close(int fd); +/* sprintf.c */ +extern char *u_sprintf(char *str, char *format, ...); +/* stgio.c */ +extern int c_stggetline(int fd, char *buf, int maxch); +extern int c_stgputline(int fd, char *buf); +/* strcat.c */ +extern char *u_strcat(char *s1, char *s2); +/* strcmp.c */ +extern int u_strcmp(char *s1, char *s2); +/* strdup.c */ +extern char *u_strdup(char *str); +/* strcpy.c */ +extern char *u_strcpy(char *s1, char *s2); +/* strlen.c */ +extern int u_strlen(char *s); +/* strncat.c */ +extern char *u_strnt(char *s1, char *s2, int n); +/* strncmp.c */ +extern int u_strnp(char *s1, char *s2, int n); +/* strncpy.c */ +extern char *u_strny(char *s1, char *s2, int n); +/* system.c */ +extern int u_system(char *cmd); +/* ungetc.c */ +extern int u_ungetc(int ch, struct _iobuf *fp); +/* zztest.c */ +extern int thello_(void); +extern int tprint_(void); +extern int tcopy_(void); +extern int tscan_(void); +extern int onint(int *code, int *old_handler); +extern int tgettk_(void); diff --git a/sys/libc/malloc.c b/sys/libc/malloc.c new file mode 100644 index 00000000..af5506cf --- /dev/null +++ b/sys/libc/malloc.c @@ -0,0 +1,24 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* MALLOC -- Allocate an uninitialized block of memory at least nbytes in size. +*/ +char * +malloc ( + unsigned nbytes +) +{ + XINT x_nchars = (nbytes + sizeof(XCHAR)-1) / sizeof(XCHAR); + XINT x_ptr, x_dtype = TY_CHAR; + + iferr (MALLOC (&x_ptr, &x_nchars, &x_dtype)) + return (NULL); + else + return ((char *)&Memc[x_ptr]); +} diff --git a/sys/libc/mathf.f b/sys/libc/mathf.f new file mode 100644 index 00000000..89279451 --- /dev/null +++ b/sys/libc/mathf.f @@ -0,0 +1,75 @@ +c +c MATH -- C callable math functions. This is the only portable way +c to access the Fortran intrinsic functions from C. As a local +c optimization it is possible to add defines to map these external +c names onto the local Fortran library functions, but since C is not +c generally used intensively for computations and all floating point +c is done in double precision anyway, it is probably not worth it. +c + + integer function xnint (x) + double precision x + xnint = nint (x) + end + + double precision function xexp (x) + double precision x + xexp = exp(x) + end + + double precision function xlog (x) + double precision x + xlog = log(x) + end + + double precision function xlog10 (x) + double precision x + xlog10 = log10(x) + end + + double precision function xpow (x, y) + double precision x + double precision y + xpow = x ** y + end + + double precision function xsqrt (x) + double precision x + xsqrt = sqrt(x) + end + + double precision function xsin (x) + double precision x + xsin = sin(x) + end + + double precision function xcos (x) + double precision x + xcos = cos(x) + end + + double precision function xtan (x) + double precision x + xtan = tan(x) + end + + double precision function xasin (x) + double precision x + xasin = asin(x) + end + + double precision function xacos (x) + double precision x + xacos = acos(x) + end + + double precision function xatan (x) + double precision x + xatan = atan(x) + end + + double precision function xatan2 (x, y) + double precision x + double precision y + xatan2 = atan2(x,y) + end diff --git a/sys/libc/mkpkg b/sys/libc/mkpkg new file mode 100644 index 00000000..74349a1a --- /dev/null +++ b/sys/libc/mkpkg @@ -0,0 +1,168 @@ +# Mkpkg for the IRAF runtime C library. There is an additional dependence +# on the global C include which is not shown. Those files which +# reference have an implicit dependence on the VOS include +# files and , since the LIBC stdio routines reference the +# FIO internal data structures directly. + +$checkout libc.a lib$ +$update libc.a +$checkin libc.a lib$ +$exit + +libc.a: + $set XFLAGS = "$(XFLAGS) -/Wall" + + atof.c \ + + atoi.c + atol.c + caccess.c + calloc.c + callocate.c + cclktime.c + cclose.c + ccnvdate.c + ccnvtime.c + cdelete.c + cenvget.c + cenvlist.c + cenvmark.c + cenvscan.c + cerract.c \ + + cerrcode.c + cerrget.c + cerror.c + cfchdir.c + cfilbuf.c \ + + cfinfo.c \ + + cflsbuf.c \ + + cflush.c + cfmapfn.c + cfmkdir.c + cfnextn.c + cfnldir.c + cfnroot.c + cfpath.c + cfredir.c + cfseti.c + cfstati.c + cgetpid.c + cgetuid.c + cgflush.c + cimaccess.c + cimdrcur.c + ckimapc.c + clexnum.c \ + + cmktemp.c + cnote.c + copen.c + coscmd.c + cndopen.c + cpoll.c \ + + cprcon.c \ + + cprdet.c + cprintf.c + crcursor.c + crdukey.c + cread.c \ + + crename.c + creopen.c + csalloc.c + cseek.c + csppstr.c + cstropen.c + cstrpak.c + cstrupk.c + ctsleep.c + cttset.c + cttycdes.c + cttyclear.c + cttyclln.c + cttyctrl.c + cttygetb.c + cttygeti.c + cttygetr.c + cttygets.c + cttygoto.c + cttyinit.c + cttyodes.c + cttyputl.c + cttyputs.c + cttyseti.c + cttyso.c + cttystati.c + ctype.c + cungetc.c + cungetl.c + cvfnbrk.c + cwrite.c \ + + cxgmes.c \ + + cxonerr.c + cxttysize.c + cxwhen.c \ + + cwmsec.c + eprintf.c + fclose.c \ + + fdopen.c + fflush.c \ + + fgetc.c + fgets.c + fopen.c \ + + fputc.c + fputs.c + fread.c + freadline.c + free.c + freopen.c + fseek.c + ftell.c + fwrite.c + gets.c + getw.c + index.c + isatty.c + malloc.c + mathf.f + mktemp.c + perror.c \ + + printf.c \ + + puts.c + putw.c + qsort.c + realloc.c + rewind.c + rindex.c + scanf.c + setbuf.c + stgio.c + strcat.c + strcmp.c + strdup.c + strcpy.c + strlen.c + strncat.c + strncmp.c + strncpy.c + spf.c + sprintf.c \ + + system.c + ungetc.c \ + + ; diff --git a/sys/libc/mktemp.c b/sys/libc/mktemp.c new file mode 100644 index 00000000..433e64ae --- /dev/null +++ b/sys/libc/mktemp.c @@ -0,0 +1,24 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#include + +/* MKTEMP -- Make a unique temporary file name. This procedure is syntactically +** equivalent to the UNIX procedure of the same name, but the XXXXXX are not +** required in the input filename. +*/ +char * +mktemp ( + char *template /* root filename, e.g., "tmp$xx" */ +) +{ + static char unique[SZ_FNAME]; + + if (c_mktemp (template, unique, SZ_FNAME) > 0) { + (void) strcpy (template, unique); + return (unique); + } else + return (NULL); +} diff --git a/sys/libc/perror.c b/sys/libc/perror.c new file mode 100644 index 00000000..53aa923a --- /dev/null +++ b/sys/libc/perror.c @@ -0,0 +1,36 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_xnames +#define import_stdio +#define import_libc +#include + +#define SZ_OSERRMSG 80 + +int sys_nerr; /* UNIX standard */ +char *sys_errlist[1]; /* UNIX standard */ +int u_oserrcode; +char u_oserrmsg[SZ_OSERRMSG+1]; + + +/* PERROR -- Print a short error message on the standard output describing +** the last system error (e.g., exception). The prefix string supplied +** as the argument is first printed, followed by an ":", followed by the +** system dependent error message describing the error. +*/ +void +perror ( + char *prefix /* prefix string */ +) +{ + u_oserrcode = c_errget (u_oserrmsg, SZ_OSERRMSG); + sys_nerr = 0; + sys_errlist[0] = u_oserrmsg; + + fputs (prefix, stderr); + fputs (": ", stderr); + fputs (u_oserrmsg, stderr); + fputc ('\n', stderr); +} diff --git a/sys/libc/printf.c b/sys/libc/printf.c new file mode 100644 index 00000000..03b155bb --- /dev/null +++ b/sys/libc/printf.c @@ -0,0 +1,245 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_stdio +#define import_ctype +#define import_stdarg +#include + + +/* PRINTF -- Emulation of the UNIX printf facilities with the IRAF FMTIO +** interface as the backend. All features of the UNIX printf are supported +** without modification. Additional format codes are supported in conformance +** with the IRAF printf, e.g., hms format, variable radix, tabstops, etc., +** but these are upward compatible with standard UNIX usage. +*/ + +#define SZ_FMTSPEC 25 /* max size single format spec */ +#define SZ_OBUF SZ_COMMAND /* sz intermediate buffer */ +#define MAX_PREC 4 /* max "*" deferred args */ +#define NOARG (-1) /* % spec with no data value */ + + +/* PRINTF -- Formatted print to the standard output. +*/ +void +printf (char *format, ...) +{ + va_list argp; + void u_doprnt(); + + va_start (argp, format); + u_doprnt (format, &argp, stdout); + va_end (argp); +} + + +/* FPRINTF -- Formatted print to a file. +*/ +void +fprintf (FILE *fp, char *format, ...) +{ + va_list argp; + void u_doprnt(); + + va_start (argp, format); + u_doprnt (format, &argp, fp); + va_end (argp); +} + + +/* U_DOPRNT -- Process the format to the output file, taking arguments from +** the list pointed to by argp as % format specs are encountered in the input. +** The main point of this routine is to handle the variable number of arguments. +** The actual encoding is all handled by the IRAF FPRINF and PARG calls. +** N.B. we assume chars are stacked as ints, and floats are stacked as doubles. +*/ +void +u_doprnt ( + char *format, /* "%w.dC" etc. format spec */ + va_list *argp, /* pointer to first value arg */ + FILE *fp /* output file */ +) +{ + register int ch; /* next format char reference */ + XCHAR formspec[SZ_FMTSPEC]; /* copy of single format spec */ + XCHAR *fsp; /* pointer into formspec */ + int done, dotseen; /* one when at end of a format */ + int varprec; /* runtime precision is used */ + int prec[MAX_PREC]; /* values of prec args */ + + void u_doarg (); + + + while ( (ch = *format++) ) { + if (ch == '%') { + fsp = formspec; + *fsp++ = ch; + varprec = 0; + dotseen = 0; + done = 0; + + while (!done) { + ch = *fsp++ = *format++; + + switch (ch) { + case EOS: + --format; + done++; + break; + + case 'l': + /* arg size modifier; ignored for now */ + fsp--; + break; + + case '*': + prec[varprec++] = va_arg ((*argp), int); + break; + + case '.': + dotseen++; + break; + + case 'r': /* nonstandard UNIX */ + if ((ch = *fsp++ = *format++) == '*') { + int radix; + int radchar; + + radix = va_arg ((*argp), int); + if (radix < 0) + radchar = 'A'; + else if (radix > 9) + radchar = radix - 10 + 'A'; + else + radchar = todigit (radix); + *(fsp-1) = radchar; + } else if (ch == EOS) { + --format; + break; + } + /* fall through */ + + case 'b': /* nonstandard UNIX */ + case 'c': + case 'd': + case 'o': + case 'x': + case 'u': + *fsp = EOS; + u_doarg (fp, formspec, &argp, prec, varprec, TY_INT); + done++; + break; + + case 'E': /* ANSI emulation */ + *(fsp-1) = 'e'; + goto rval; + case 'G': /* ANSI emulation */ + *(fsp-1) = 'g'; + goto rval; + + case 'z': /* nonstandard UNIX */ + case 'h': /* nonstandard UNIX */ + case 'H': /* nonstandard UNIX */ + case 'm': /* nonstandard UNIX */ + case 'M': /* nonstandard UNIX */ + case 'e': + case 'f': + case 'g': + /* If no precision was specified, default to 14 digits + * for %[efgz] and 3 digits for %[hm]. + */ +rval: if (!dotseen) { + *(fsp-1) = '.'; + if (ch == 'h' || ch == 'm' || + ch == 'H' || ch == 'M') { + *fsp++ = '3'; + } else { + *fsp++ = '1'; + *fsp++ = '4'; + } + *fsp++ = ch; + } + + *fsp = XEOS; + u_doarg (fp, formspec, &argp, prec, varprec, TY_DOUBLE); + done++; + break; + + case 's': + *fsp = EOS; + u_doarg (fp, formspec, &argp, prec, varprec, TY_CHAR); + done++; + break; + + case 't': /* nonstandard UNIX */ + case 'w': /* nonstandard UNIX */ + *fsp = EOS; + u_doarg (fp, formspec, &argp, prec, varprec, NOARG); + done++; + break; + + case '%': + putc (ch, fp); + done++; + break; + } + } + + } else + putc (ch, fp); + } +} + + +/* U_DOARG -- Encode a single argument acording to the simplified format +** specification given by formspec. This is the interface to the IRAF +** formatted output procedures. +*/ +void +u_doarg (fp, formspec, argp, prec, varprec, dtype) +FILE *fp; /* output file */ +XCHAR *formspec; /* format string */ +va_list **argp; /* pointer to data value */ +int prec[]; /* varprec args, if any */ +int varprec; /* number of varprec args */ +int dtype; /* datatype of data value */ +{ + register int p; + XCHAR sbuf[SZ_OBUF+1]; + XINT fd = fileno (fp); + XINT ival; + XDOUBLE dval; + char *cptr; + + + /* Pass format string and any variable precision arguments. + */ + FPRINTF (&fd, formspec); + for (p=0; p < varprec; p++) { + ival = prec[p]; + PARGI (&ival); + } + + /* Pass the data value to be encoded, bump argument pointer by the + * size of the data object. If there is no data value the case + * is a no-op. + */ + switch (dtype) { + case TY_INT: + ival = va_arg ((**argp), int); + PARGI (&ival); + break; + case TY_DOUBLE: + dval = va_arg ((**argp), double); + PARGD (&dval); + break; + case TY_CHAR: + cptr = va_arg ((**argp), char *); + PARGSTR (c_strupk (cptr, sbuf, SZ_OBUF)); + break; + } +} diff --git a/sys/libc/puts.c b/sys/libc/puts.c new file mode 100644 index 00000000..246b7bf6 --- /dev/null +++ b/sys/libc/puts.c @@ -0,0 +1,25 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* PUTS -- Put a null terminated string to the standard output, followed by a +** newline. +*/ +int +puts ( + char *str /* input string */ +) +{ + register FILE *fp = stdout; + register char *ip; + + + for (ip=str; *ip != EOS; ip++) + putc (*ip, fp); + return (putc ('\n', fp)); +} diff --git a/sys/libc/putw.c b/sys/libc/putw.c new file mode 100644 index 00000000..d5cf6d8a --- /dev/null +++ b/sys/libc/putw.c @@ -0,0 +1,27 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + +/* PUTW -- Put a word (integer) to the output stream. When used in conjunction +** with GETW this permits storage and retrieval of binary words to any file, +** albeit somewhat inefficiently. +*/ +int +putw ( + int word, /* data word to be output */ + FILE *fp /* output file */ +) +{ + register char *ip; + register int n = sizeof (int); + + + for (ip=(char *)&word; --n >= 0; ip++) + putc (*ip, fp); + + return (ferror(fp) ? EOF : word); +} diff --git a/sys/libc/qsort.c b/sys/libc/qsort.c new file mode 100644 index 00000000..345fc3bd --- /dev/null +++ b/sys/libc/qsort.c @@ -0,0 +1,221 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +/* +** Copyright (c) 1980 Regents of the University of California. +** All rights reserved. +** +** Redistribution and use in source and binary forms are permitted +** provided that the above copyright notice and this paragraph are +** duplicated in all such forms and that any documentation, +** advertising materials, and other materials related to such +** distribution and use acknowledge that the software was developed +** by the University of California, Berkeley. The name of the +** University may not be used to endorse or promote products derived +** from this software without specific prior written permission. +** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +** WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +*/ + +#define import_libc +#include + +/* +** QSORT -- Quicker sort. Adapted from the BSD sources. +*/ + +#define THRESH 4 /* threshold for insertion */ +#define MTHRESH 6 /* threshold for median */ + +static int (*qcmp)(); /* the comparison routine */ +static int qsz; /* size of each record */ +static int thresh; /* THRESHold in chars */ +static int mthresh; /* MTHRESHold in chars */ +static void qst(); + + +/* QSORT -- First, set up some global parameters for qst to share. Then, +** quicksort with qst(), and then a cleanup insertion sort ourselves. +** Sound simple? It's not... +*/ +void +qsort ( + char *base, + int n, + int size, + int (*compar)() +) +{ + register char c, *i, *j, *lo, *hi; + char *minval, *maxval; + + + if (n <= 1) + return; + + qsz = size; + qcmp = compar; + thresh = qsz * THRESH; + mthresh = qsz * MTHRESH; + maxval = base + n * qsz; + + if (n >= THRESH) { + qst (base, maxval); + hi = base + thresh; + } else + hi = maxval; + + /* First put smallest element, which must be in the first THRESH, in + * the first position as a sentinel. This is done just by searching + * the first THRESH elements (or the first n if n < THRESH), finding + * the min, and swapping it into the first position. + */ + for (j=lo=base; (lo += qsz) < hi; ) + if ((*qcmp)(j, lo) > 0) + j = lo; + if (j != base) { + /* Swap j into place */ + for (i=base, hi=base+qsz; i < hi; ) { + c = *j; + *j++ = *i; + *i++ = c; + } + } + + /* With our sentinel in place, we now run the following hyper-fast + * insertion sort. For each remaining element, min, from [1] to [n-1], + * set hi to the index of the element AFTER which this one goes. + * Then, do the standard insertion sort shift on a character at a time + * basis for each element in the frob. + */ + for (minval=base; (hi = minval += qsz) < maxval; ) { + while ((*qcmp) (hi -= qsz, minval) > 0) + /* void */; + if ((hi += qsz) != minval) { + for (lo = minval + qsz; --lo >= minval; ) { + c = *lo; + for (i=j=lo; (j -= qsz) >= hi; i=j) + *i = *j; + *i = c; + } + } + } +} + + +/* QST -- Do a quicksort. + * First, find the median element, and put that one in the first place as the + * discriminator. (This "median" is just the median of the first, last and + * middle elements). (Using this median instead of the first element is a big + * win). Then, the usual partitioning/swapping, followed by moving the + * discriminator into the right place. Then, figure out the sizes of the two + * partions, do the smaller one recursively and the larger one via a repeat of + * this code. Stopping when there are less than THRESH elements in a partition + * and cleaning up with an insertion sort (in our caller) is a huge win. + * All data swaps are done in-line, which is space-losing but time-saving. + * (And there are only three places where this is done). + */ +static void +qst ( + char *base, + char *maxval +) +{ + register char c, *i, *j, *jj; + register int ii; + char *mid, *tmp; + int lo, hi; + + /* At the top here, lo is the number of characters of elements in the + * current partition. (Which should be maxval - base). + * Find the median of the first, last, and middle element and make + * that the middle element. Set j to largest of first and middle. + * If maxval is larger than that guy, then it's that guy, else compare + * maxval with loser of first and take larger. Things are set up to + * prefer the middle, then the first in case of ties. + */ + lo = maxval - base; /* number of elements as chars */ + + do { + mid = i = base + qsz * ((lo / qsz) >> 1); + if (lo >= mthresh) { + j = ((*qcmp)((jj = base), i) > 0 ? jj : i); + if ((*qcmp)(j, (tmp = maxval - qsz)) > 0) { + /* switch to first loser */ + j = (j == jj ? i : jj); + if ((*qcmp)(j, tmp) < 0) + j = tmp; + } + if (j != i) { + ii = qsz; + do { + c = *i; + *i++ = *j; + *j++ = c; + } while (--ii); + } + } + + /* Semi-standard quicksort partitioning/swapping + */ + for (i = base, j = maxval - qsz; ; ) { + while (i < mid && (*qcmp)(i, mid) <= 0) + i += qsz; + while (j > mid) { + if ((*qcmp)(mid, j) <= 0) { + j -= qsz; + continue; + } + tmp = i + qsz; /* value of i after swap */ + if (i == mid) { + /* j <-> mid, new mid is j */ + mid = jj = j; + } else { + /* i <-> j */ + jj = j; + j -= qsz; + } + goto swap; + } + + if (i == mid) { + break; + } else { + /* i <-> mid, new mid is i */ + jj = mid; + tmp = mid = i; /* value of i after swap */ + j -= qsz; + } + + swap: + ii = qsz; + do { + c = *i; + *i++ = *jj; + *jj++ = c; + } while (--ii); + i = tmp; + } + + /* Look at sizes of the two partitions, do the smaller + * one first by recursion, then do the larger one by + * making sure lo is its size, base and maxval are update + * correctly, and branching back. But only repeat + * (recursively or by branching) if the partition is + * of at least size THRESH. + */ + i = (j = mid) + qsz; + if ((lo = j - base) <= (hi = maxval - i)) { + if (lo >= thresh) + qst(base, j); + base = i; + lo = hi; + } else { + if (hi >= thresh) + qst(i, maxval); + maxval = j; + } + + } while (lo >= thresh); +} diff --git a/sys/libc/realloc.c b/sys/libc/realloc.c new file mode 100644 index 00000000..21446345 --- /dev/null +++ b/sys/libc/realloc.c @@ -0,0 +1,28 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* REALLOC -- Reallocate a buffer, i.e., change the size of an already +** allocated buffer. If necessary the buffer is moved, preserving any +** data in the buffer. +*/ +char * +realloc ( + char *buf, + unsigned newsize +) +{ + XINT x_nchars = (newsize + sizeof(XCHAR)-1) / sizeof(XCHAR); + XINT x_ptr, x_dtype = TY_CHAR; + + x_ptr = buf ? Memcptr(buf) : NULL; + iferr (REALLOC (&x_ptr, &x_nchars, &x_dtype)) + return (NULL); + else + return ((char *)&Memc[x_ptr]); +} diff --git a/sys/libc/rewind.c b/sys/libc/rewind.c new file mode 100644 index 00000000..0185916c --- /dev/null +++ b/sys/libc/rewind.c @@ -0,0 +1,19 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#include + + +/* REWIND -- Position the named stream to beginning of file, i.e., arrange +** for the next read or write to read or write the first byte of the file. +*/ +long +rewind ( + FILE *fp /* operand file */ +) +{ + return ((long) fseek (fp, 0L, 0)); +} diff --git a/sys/libc/rindex.c b/sys/libc/rindex.c new file mode 100644 index 00000000..74169120 --- /dev/null +++ b/sys/libc/rindex.c @@ -0,0 +1,27 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#define import_spp +#include + + +/* RINDEX -- Search string STR for char CH, returning a pointer to the last +** occurrence of CH in STR or NULL. +*/ +char * +rindex ( + char *str, /* string to be searched */ + int ch /* character we are searching for */ +) +{ + register char *ip = str; + register char *last = NULL; + + do { + if (*ip == ch) + last = ip; + } while (*ip++); + + return (last); +} diff --git a/sys/libc/scanf.c b/sys/libc/scanf.c new file mode 100644 index 00000000..1ada2000 --- /dev/null +++ b/sys/libc/scanf.c @@ -0,0 +1,558 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#define import_ctype +#define import_stdarg +#include + + +/* +** SCANF -- Formatted input. The syntax of the calls and of the format strings +** are UNIX standard, but the lexical forms of numbers recognized are IRAF +** standard. +*/ + +#define SCAN_STRING 0 +#define SCAN_FILE 1 +#define SZ_NUMBUF 256 /* maximum numeric field len */ +#define SZ_UCC 128 /* maximum size user char class */ +#define HUGE 999 +#define ISHEX(c) ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) + +struct _format { + int f_type; /* field type (doxscef[%) */ + int f_skipfield; /* skip next field scanned */ + int f_width; /* max chars in field */ + int f_longword; /* output longword */ + int f_halfword; /* output halfword */ + int f_delimset; /* ucc chars are delimiters */ + char f_ucc[SZ_UCC+1]; +}; + +/* Character input including pushback. Character input may come either from +** a file or from a string, depending on the value of the "intype" flag. +** We cannot open the string as a file because file buffer characters are +** of type XCHAR. +*/ +struct _input { + int i_type; /* file input if !0, else str */ + int i_nchars; /* nchars read thus far */ + union { + FILE *fp; /* file pointer if file */ + char *ip; /* char pointer if string */ + } u; +}; + +#define input()\ + (in->i_nchars++, in->i_type ? (int)getc(in->u.fp) : (int)*in->u.ip++) +#define unput(ch)\ + (in->i_nchars--, in->i_type ? ungetc((ch),in->u.fp) : (int)(*--(in->u.ip))) +#define ateof()\ + (in->i_type ? feof(in->u.fp) : *(in->u.ip-1) == EOS) + + +static int u_doscan (struct _input *in, char *format, va_list *argp); +static char *u_crackformat (char *format, struct _format *fmt); +static int u_scannum (struct _input *in, va_list **argp, + struct _format *fmt, int *eofflag); +static char *u_setucc (char *format, struct _format *fmt); +static int u_scanstr (struct _input *in, va_list **argp, + struct _format *fmt, int *eofflag); + + + +/* SCANF -- Scan the standard input. The output arguments must be +** pointers. The number of fields successfully converted is returned as +** the function value. EOF is returned for a scan at EOF. +*/ +int +scanf (char *format, ...) +{ + va_list argp; + struct _input in; + int status; + + extern int u_doscan(); + + + va_start (argp, format); + in.i_type = SCAN_FILE; + in.i_nchars = 0; + in.u.fp = stdin; + + status = u_doscan (&in, format, &argp); + va_end (argp); + return (status); +} + + +/* FSCANF -- Formatted scan from a file. +*/ +int +fscanf (FILE *fp, char *format, ...) +{ + va_list argp; + int status; + struct _input in; + + extern int u_doscan(); + + + va_start (argp, format); + in.i_type = SCAN_FILE; + in.i_nchars = 0; + in.u.fp = fp; + + status = u_doscan (&in, format, &argp); + + va_end (argp); + return (status); +} + + +/* SSCANF -- Formatted scan from a string. +*/ +int +sscanf (char *str, char *format, ...) +{ + va_list argp; + struct _input in; + int status; + + extern int u_doscan(); + + + va_start (argp, format); + in.i_type = SCAN_STRING; + in.i_nchars = 0; + in.u.ip = str; + + status = u_doscan (&in, format, &argp); + + va_end (argp); + return (status); +} + + +/* U_DOSCAN -- Step along the format string, processing each %[*][w][lh]C +** field specification and returning each argument using the pointer +** supplied in the argument list. Ordinary characters appearing in the format +** string must match actual characters in the input stream. Input may be +** taken from either a string or a file. The technique used to handle the +** variable number of arguments is machine dependent. +*/ +static int +u_doscan ( + struct _input *in, /* input descriptor */ + char *format, /* format string */ + va_list *argp /* pointer to first argument */ +) +{ + register int ch; + struct _format fmt; + int nscan = 0, match; + int eofflag = 0; + char *u_crackformat(), *u_setucc(); + int u_scanstr(), u_scannum(); + + + while ( (ch = *format++) ) { + if (ch == '%' && *format != '%') { + /* Parse format specification. + */ + format = u_crackformat (format, &fmt); + + /* Extract, decode, and output the next field according to + * the field specification just generated. + */ + ch = *format++; + if (ch == 'n') { + *(va_arg ((*argp), int *)) = in->i_nchars; + continue; + } else if (ch == '[') { + format = u_setucc (format, &fmt); + } else if (isupper (ch)) { + fmt.f_longword++; + ch = tolower (ch); + } + if (ch <= 0) + return (EOF); + fmt.f_type = ch; + + if (ch == 's' || ch == 'c' || ch == '[') + match = u_scanstr (in, &argp, &fmt, &eofflag); + else + match = u_scannum (in, &argp, &fmt, &eofflag); + + if (match && !fmt.f_skipfield) + nscan++; + if (eofflag) + break; + + } else if (isspace (ch)) { + /* Skip optional whitespace. */ + while (isspace (ch = input())) + ; + if (ateof()) { + eofflag++; + break; + } + unput (ch); + + } else { + /* Match normal character. */ + if (ch == '%') + format++; + match = ch; + if (match != (ch = input())) { + if (ateof()) + eofflag++; + else + unput (ch); + break; + } + } + } + + if (eofflag) + return (nscan ? nscan : EOF); + else + return (nscan); +} + + + +/* U_CRACKFORMAT -- Decode a %[*][w][lh]C input field format specification, + * returning the decoded format parameters in the output structure fmt. + * The number of format characters is returned as the function value. The + * format string pointer is left pointing at the C character. + */ +static char * +u_crackformat ( + char *format, /* pointer to %+1 in format string */ + struct _format *fmt /* output format descriptor */ +) +{ + register int ch; + register int width = 0; + + + fmt->f_skipfield = 0; + fmt->f_longword = 0; + fmt->f_halfword = 0; + + /* Skip output if "*" present. */ + ch = *format++; + if (ch == '*') { + fmt->f_skipfield++; + ch = *format++; + } + + /* Get max field width, if any. */ + while (isdigit (ch)) { + width = width * 10 + tointeg (ch); + ch = *format++; + } + fmt->f_width = (width == 0) ? HUGE : width; + + /* Datatype size modifier. */ + if (ch == 'l') { + fmt->f_longword++; + ch = *format++; + } else if (ch == 'h') { + fmt->f_halfword++; + ch = *format++; + } + + return (--format); +} + + +/* U_SCANNUM -- Extract a numeric token from the input stream. The lexical +** range of numbers recognized is as follows (ignoring leading +-): +** +** INDEF all types +** [0-7]+ o +** [0-9]+ d +** [0-9][0-9a-fA-F]* x +** '.'[0-9]+([eEdD]([+-])?[0-9]+)? f,e +** [0-9][0-9:]'.'[0-9]+([eEdD]([+-])?[0-9]+)? f,e (sexagesimal) +** +** If the conversion fails the token is pushed back into the input, ready +** to be rescanned. Argp is bumped if skipfield is false whether or not +** a legal number is matched (else one might assign a string to a pointer +** to int in the next format, overruning memory). If the match fails 0 is +** output to argp and 0 is returned as the function value, indicating no +** match. +*/ +static int +u_scannum ( + struct _input *in, /* input descriptor */ + va_list **argp, /* where output goes */ + struct _format *fmt, /* format descriptor */ + int *eofflag /* set to 1 on output if end of input */ +) +{ + char numbuf[SZ_NUMBUF+1]; + register int ch; + register long num = 0; + register char *op = numbuf; + int floating = 0, radix=10, n; + int neg=0, ndigits=0, match=1; + int dotseen=0, expseen=0; + + + ch = fmt->f_type; + n = fmt->f_width; + + if (ch == 'd') + radix = 10; + else if (ch == 'o') + radix = 8; + else if (ch == 'x') + radix = 16; + else if ( (floating = (ch == 'f' || ch == 'e' || ch == 'g') )) { + radix = 10; + dotseen = expseen = 0; + } + + while (isspace ( (ch = input()) )) + ; + + if (ch == '-' || ch == '+') { + if (ch == '-') { + neg++; + *op++ = ch; + } + ch = input(); + --n; + } + + /* Check for INDEF. Abbreviations are not permitted; if the match + * fails the input must be restored. + */ + if (ch == 'I' && op == numbuf && n >= 5) { + char *ip = "INDEF"; + + for (n=5; --n >= 0 && (ch == *ip++); ch=input()) + *op++ = ch; + *op = EOS; + if (!ateof()) + unput (ch); + + if (n < 0) { + /* If the 6th char is not a legal character in an identifier + * then we have a match. + */ + if (! (isalnum (ch) || ch == '_')) { + if (fmt->f_skipfield) + return (1); + else if (floating) + goto out_; + else { + if (fmt->f_longword) + *(va_arg ((**argp), long *)) = INDEFL; + else if (fmt->f_halfword) + *(va_arg ((**argp), short *)) = INDEFS; + else + *(va_arg ((**argp), int *)) = INDEFI; + return (1); + } + } + } + + /* No match; neither INDEF nor a number. Push back chars and exit. + * (the FIO ungetc may be called repeatedly). + */ + for (--op; op >= numbuf; --op) + unput (*op); + + match = 0; + num = 0; + numbuf[0] = '0'; + goto out_; + } + + /* Extract token into numbuf. If the token contains only digits it + * will have been converted to binary and left in the variable num. + */ + for (*op++ = ch; --n >= 0; *op++ = ch = input()) { + if (isdigit (ch)) { + ch = tointeg (ch); + if (ch >= radix) + break; + ndigits++; + num = num * radix + ch; + + } else if (radix == 16 && ISHEX(ch)) { + if (isupper (ch)) + ch = tolower (ch); + ndigits++; + num = num * 16 + ch - 'a' + 10; + + } else if (ch == '.') { + if (!floating || dotseen) + break; + dotseen++; + } else if (ch == ':') { + if (!floating || ndigits == 0 || dotseen || expseen) + break; + + } else if (ch == 'e' || ch == 'E' || ch == 'd' || ch == 'D') { + if (!floating || expseen || (ndigits == 0 && !dotseen)) + break; + expseen++; + *op++ = ch = input(); + if (! (ch == '+' || ch == '-' || isdigit(ch))) + break; + + } else + break; + } + + *--op = EOS; + if (ateof()) + *eofflag = 1; + else + unput (ch); + + if (ndigits == 0) + match = 0; /* not a number */ + if (neg) + num = -num; +out_: + if (fmt->f_skipfield) + return (match); + + /* Output value. + */ + if (floating) { + float rval; + double dval, atof(); + + if (fmt->f_longword) { + *(va_arg ((**argp), double *)) = atof (numbuf); + } else if (fmt->f_halfword) { + dval = atof (numbuf); + rval = (dval == INDEFD) ? INDEFR : dval; + *(va_arg ((**argp), float *)) = rval; + } else + *(va_arg ((**argp), double *)) = atof (numbuf); + } else { + if (fmt->f_longword) + *(va_arg ((**argp), long *)) = num; + else if (fmt->f_halfword) + *(va_arg ((**argp), short *)) = num; + else + *(va_arg ((**argp), int *)) = num; + } + + return (match); +} + + +/* U_SETUCC -- Extract a user defined character class from the format string. +** A full 128 char table is not used since it is more expensive to prepare +** than it is worth for small sets. +*/ +static char * +u_setucc ( + char *format, + struct _format *fmt +) +{ + register char *op = fmt->f_ucc; + register int n = SZ_UCC; + + fmt->f_delimset = (*format == '^') ? *format++ : 0; + while (--n && *format && (*op = *format++) != ']') { + if (*op == '\\' && *format == ']') + *op = *format++; + op++; + } + *op = EOS; + + return (format); +} + + + +/* U_SCANSTR -- Extract a whitespace delimited sequence of characters. +*/ +static int +u_scanstr ( + struct _input *in, /* input descriptor */ + va_list **argp, /* output arglist */ + struct _format *fmt, /* numeric format expected */ + int *eofflag /* set to 1 on output if end of input */ +) +{ + register int ch, n; + register char *ip, *op; + int delimset; + char *ucc = ""; + + + op = fmt->f_skipfield ? (char *)NULL : va_arg ((**argp), char *); + ch = fmt->f_type; + n = fmt->f_width; + if (ch == 'c' && n == HUGE) + n = 1; + + /* Set up character class to be matched. + */ + delimset = 1; + if (ch == 'c') + ucc = ""; + else if (ch == 's') + ucc = " \t\n"; + else if (ch == '[') { + ucc = fmt->f_ucc; + delimset = fmt->f_delimset; + } + + /* Skip leading whitespace only for format %s. + */ + if (ch == 's') { + while (isspace (ch = input())) + ; + } else + ch = input(); + + /* Extract chars matching set into output buffer. + */ + while (--n >= 0 && (ch > 0 || !ateof())) { + /* Is char in set ucc. */ + for (ip=ucc; *ip != EOS; ip++) + if (ch == *ip) { + if (delimset) + goto done_; + if (op) + *op++ = ch; + goto next_; + } + + /* Char not in set if we get here. */ + if (delimset) { + if (op) + *op++ = ch; + } else + break; +next_: + ch = input(); + } +done_: + if (ateof()) + *eofflag = 1; + else { + unput (ch); + } + + if (op && fmt->f_type != 'c') + *op = EOS; + + return (1); +} diff --git a/sys/libc/setbuf.c b/sys/libc/setbuf.c new file mode 100644 index 00000000..845c9f9d --- /dev/null +++ b/sys/libc/setbuf.c @@ -0,0 +1,68 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_stdio +#define import_fset +#include + + +/* SETBUF -- Assign a buffer to be used by the i/o system to access a file. +** Should be called after opening the file but before doing any i/o. +*/ +void +setbuf ( + FILE *fp, + char *buf +) +{ + void setbuffer(); + + setbuffer (fp, buf, BUFSIZ); +} + + +/* SETBUFFER -- Assign a buffer of arbitrary size to be used by the i/o system +** to access a file. Should be called after opening the file but before doing +** any i/o. If the the pointer buf has the value NULL, i/o is unbuffered +** (or as close to unbuffered as we can manage). +*/ +void +setbuffer ( + FILE *fp, + char *buf, + int size +) +{ + register XINT fd = fileno(fp); + + + if (buf == NULL) + c_fseti (fd, F_BUFSIZE, 1); + else { + c_fseti (fd, F_BUFPTR, Memcptr(buf)); + c_fseti (fd, F_BUFSIZE, size); + } +} + + +/* SETLINEBUF -- Set line buffered mode for a file. A line buffered file + * buffers each line and flushes it to the output device when newline is + * seen. We may be even after doing i/o to the file. + */ +void +setlinebuf ( + FILE *fp +) +{ + register XINT fd = fileno(fp); + + extern int c_fstati(); + extern void c_fseti(); + + + if (c_fstati (fd, F_BUFSIZE) < SZ_LINE) + c_fseti (fd, F_BUFSIZE, SZ_LINE); + c_fseti (fd, F_FLUSHNL, YES); +} diff --git a/sys/libc/spf.c b/sys/libc/spf.c new file mode 100644 index 00000000..2953ed76 --- /dev/null +++ b/sys/libc/spf.c @@ -0,0 +1,65 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* +** SPF.C -- String spoolfile utility package. Used to capture in a string +** buffer the output of a routine set up to write to a file. +** +** Example: +** +** fd = spf_open (buf, maxch) +** fprop (pp, fdopen(fd,"w")); +** spf_close (fd); +** +** leaves the output of the fprop() function in the user buffer "buf". +*/ + +static XCHAR *spf_buf; +static char *spf_userbuf; +static int spf_maxch; + + +/* SPF_OPEN -- Spoolfile open. Open a string spoolfile to be written into as +** a file, using ordinary file i/o. Only one such file can be open at a time. +*/ +int +spf_open ( + char *buf, /* user string buffer */ + int maxch /* max chars of storage */ +) +{ + XINT x_maxch = maxch, x_mode = NEW_FILE; + char *malloc(); + + + spf_userbuf = buf; + spf_maxch = maxch; + + /* Malloc always returns a buffer which aligned to at least XCHAR. */ + spf_buf = (XCHAR *) malloc ((maxch + 1) * sizeof(XCHAR)); + + return (STROPEN (spf_buf, &x_maxch, &x_mode)); +} + + +/* SPF_CLOSE -- Close the spoolfile string, which should have been written +** into via file i/o while the string was open. This leaves SPP chars in +** the string; pack the string and return a pointer to the string. +*/ +void +spf_close ( + XINT fd /* file descriptor of stringbuf */ +) +{ + XINT x_fd = fd; + + CLOSE (&x_fd); + c_strpak (spf_buf, spf_userbuf, spf_maxch); + free ((char *)spf_buf); +} diff --git a/sys/libc/sprintf.c b/sys/libc/sprintf.c new file mode 100644 index 00000000..24d408a0 --- /dev/null +++ b/sys/libc/sprintf.c @@ -0,0 +1,58 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_stdio +#define import_stdarg +#include + +#define SZ_OBUF SZ_COMMAND /* sz intermediate buffer */ + + +/* SPRINTF -- Formatted print to a string. If char and XCHAR are the +** same size we open the output string as a file and write directly into +** it. Otherwise we must write into an intermediate buffer, then pack +** XCHAR into the char output string. This is not as bad as it sounds +** as the operation is negligible compared to the encoding operation. +*/ +char * +sprintf (char *str, char *format, ...) +{ + register XCHAR *ip; + register char *op; + XCHAR obuf[SZ_OBUF], *fiobuf; + XINT x_fd, x_maxch = SZ_OBUF, x_mode = NEW_FILE; + va_list argp; + + extern int u_doprnt(); + + + va_start (argp, format); + + /* Select output buffer. */ + if (sizeof (XCHAR) == sizeof (char)) + fiobuf = (XCHAR *)str; + else + fiobuf = obuf; + + /* Make it the file buffer. Call FIO to open the string as a file. + */ + x_fd = STROPEN (fiobuf, &x_maxch, &x_mode); + + /* Format the data into obuf. */ + u_doprnt (format, &argp, FDTOFP(x_fd)); + + /* FIO does not write the EOS until the string file is closed. + * Move obuf to str if it is not already there. + */ + CLOSE (&x_fd); + if (fiobuf == obuf) + for (ip=obuf, op=str; (*op++ = *ip++) != EOS; ) + ; + + va_end (argp); + + return (str); +} diff --git a/sys/libc/stgio.c b/sys/libc/stgio.c new file mode 100644 index 00000000..498a020a --- /dev/null +++ b/sys/libc/stgio.c @@ -0,0 +1,60 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#include + + +/* STGIO.C -- STDGRAPH graphics terminal i/o interface. This is a C binding +** for the VOS STDGRAPH graphics kernel text i/o routines. These are used to +** do direct i/o to the graphics terminal, whether or not the terminal is in +** graphics mode. When the terminal is not in graphics mode, i.e., when the +** "workstation is deactivated", these routines are equivalent to the FIO +** putline and getline procedures. +** +** nchars|EOF = c_stggetline (STDIN, buf) +** c_stgputline (STDOUT, buf) +*/ + + +/* C_STGGETLINE -- Get a line of text from the graphics terminal. +*/ +int +c_stggetline ( + XINT fd, /* input stream */ + char *buf, /* user string buffer */ + int maxch /* max bufer size */ +) +{ + XCHAR xbuf[maxch+1]; + XINT x_fd = fd; + int status; + + iferr (status = STG_GETLINE (&x_fd, xbuf)) + return (EOF); + else { + c_strpak (xbuf, buf, maxch); + return (status); + } +} + + +/* C_STGPUTLINE -- Put a line of text to the graphics terminal. +*/ +int +c_stgputline ( + XINT fd, /* input stream */ + char *buf /* user string buffer */ +) +{ + XCHAR xbuf[SZ_LINE+1]; + XINT x_fd = fd; + + c_strupk (buf, xbuf, SZ_LINE); + iferr (STG_PUTLINE (&x_fd, xbuf)) + return (ERR); + else + return (OK); +} diff --git a/sys/libc/strcat.c b/sys/libc/strcat.c new file mode 100644 index 00000000..49798ba0 --- /dev/null +++ b/sys/libc/strcat.c @@ -0,0 +1,24 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#include + + +/* STRCAT -- Concatenate S2 onto S1. +*/ +char * +strcat ( + char *s1, /* output string */ + char *s2 /* string to be appended */ +) +{ + register char *ip, *op; + + for (op=s1; *op++; ) + ; + for (--op, ip=s2; (*op++ = *ip++); ) + ; + + return (s1); +} diff --git a/sys/libc/strcmp.c b/sys/libc/strcmp.c new file mode 100644 index 00000000..7b7dc54a --- /dev/null +++ b/sys/libc/strcmp.c @@ -0,0 +1,22 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#include + + +/* STRCMP -- Compare two strings. -N is returned if S1 < S2, 0 if S1 == S2, +** and +N if S1 > S2. +*/ +int +strcmp ( + char *s1, + char *s2 +) +{ + while (*s1 == *s2++) + if (*s1++ == '\0') + return (0); + + return (*s1 - *--s2); +} diff --git a/sys/libc/strcpy.c b/sys/libc/strcpy.c new file mode 100644 index 00000000..cbc072f0 --- /dev/null +++ b/sys/libc/strcpy.c @@ -0,0 +1,21 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#include + +/* STRCPY -- Copy string S2 to S1. +*/ +char * +strcpy ( + char *s1, /* output string */ + char *s2 /* string to be moved */ +) +{ + register char *ip, *op; + + for (ip=s2, op=s1; (*op++ = *ip++); ) + ; + + return (s1); +} diff --git a/sys/libc/strdup.c b/sys/libc/strdup.c new file mode 100644 index 00000000..4568d89f --- /dev/null +++ b/sys/libc/strdup.c @@ -0,0 +1,22 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#include + +/* STRDUP -- Save a copy of a string. +*/ +char * +strdup ( + char *str /* string to copy */ +) +{ + register char *ip, *op, *out; + int len = strlen (str); + + out = calloc (1, strlen (str) + 1); + for (ip=str, op=out; (*op++ = *ip++); ) + ; + + return (out); +} diff --git a/sys/libc/strlen.c b/sys/libc/strlen.c new file mode 100644 index 00000000..c6c2f813 --- /dev/null +++ b/sys/libc/strlen.c @@ -0,0 +1,21 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + */ + +#define import_libc +#include + + +/* STRLEN -- Length of a string. +*/ +int +strlen ( + char *s +) +{ + register char *ip=s; + + while (*ip++) + ; + + return (ip - s - 1); +} diff --git a/sys/libc/strncat.c b/sys/libc/strncat.c new file mode 100644 index 00000000..9deae4eb --- /dev/null +++ b/sys/libc/strncat.c @@ -0,0 +1,26 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#include + + +/* STRNCAT -- Concatenate at most N chars from S2 onto S1. +*/ +char * +strncat ( + char *s1, /* output string */ + char *s2, /* string to be appended */ + int n /* max length of S1 */ +) +{ + register char *ip, *op; + + for (op=s1; *op++; ) + ; + for (--op, ip=s2; (*op++ = *ip++) && --n >= 0; ) + ; + *--op = '\0'; + + return (s1); +} diff --git a/sys/libc/strncmp.c b/sys/libc/strncmp.c new file mode 100644 index 00000000..089df283 --- /dev/null +++ b/sys/libc/strncmp.c @@ -0,0 +1,22 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#include + +/* STRNCMP -- Compare up to the first N characters of two strings. -N is +** returned if S1 < S2, 0 if S1 == S2, and +N if S1 > S2. +*/ +int +strncmp ( + char *s1, + char *s2, + int n +) +{ + while (--n >= 0 && *s1 == *s2++) + if (*s1++ == '\0') + return (0); + + return (n < 0 ? 0 : *s1 - *--s2); +} diff --git a/sys/libc/strncpy.c b/sys/libc/strncpy.c new file mode 100644 index 00000000..79e99495 --- /dev/null +++ b/sys/libc/strncpy.c @@ -0,0 +1,27 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_libc +#include + + +/* STRNCPY -- Copy exactly N characters from S2 to S1, truncating or null +** padding S2; the output string may not be null terminated if the length +** of S2 is N or more. +*/ +char * +strncpy ( + char *s1, /* output string */ + char *s2, /* string to be moved */ + int n +) +{ + register char *ip, *op; + + for (ip=s2, op=s1; --n >= 0 && (*op++ = *ip++); ) + ; + while (--n >= 0) + *op++ = '\0'; + + return (s1); +} diff --git a/sys/libc/system.c b/sys/libc/system.c new file mode 100644 index 00000000..44265864 --- /dev/null +++ b/sys/libc/system.c @@ -0,0 +1,26 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_knames +#include + + +/* SYSTEM -- Send a command to the host system. OK is returned if the command +** executes properly, else a positive integer error code identifying the error +** which occurred. +*/ +int +system ( + char *cmd /* command to be sent to host system */ +) +{ + PKCHAR nullstr[1]; + XINT status; + + nullstr[0] = EOS; + ZOSCMD (cmd, nullstr, nullstr, nullstr, &status); + + return ((int) status); +} diff --git a/sys/libc/ungetc.c b/sys/libc/ungetc.c new file mode 100644 index 00000000..2773f4e1 --- /dev/null +++ b/sys/libc/ungetc.c @@ -0,0 +1,29 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. +*/ + +#define import_spp +#define import_libc +#define import_xnames +#define import_stdio +#include + + +/* UNGETC -- Push a character back into the input stream. Pushback is last +** in first out, i.e., the last character pushed back is the first one +** read by GETC. Characters (and strings) may be pushed back until the +** FIO pushback buffer overflows. +*/ +int +ungetc ( + int ch, + FILE *fp +) +{ + XINT x_fd = fileno(fp); + XCHAR x_ch = ch; + + iferr (UNGETC (&x_fd, &x_ch)) + return (EOF); + else + return (ch); +} diff --git a/sys/libc/zzdebug.x b/sys/libc/zzdebug.x new file mode 100644 index 00000000..88cf9551 --- /dev/null +++ b/sys/libc/zzdebug.x @@ -0,0 +1,7 @@ +# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + +task hello = t_hello, + print = t_print, + copy = t_copy, + scan = t_scan, + gettok = t_gettok diff --git a/sys/libc/zztest.c b/sys/libc/zztest.c new file mode 100644 index 00000000..b43fe705 --- /dev/null +++ b/sys/libc/zztest.c @@ -0,0 +1,98 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + */ + +#define import_libc +#define import_stdio +#define import_spp +#define import_error +#define import_xwhen +#include + +thello_() +{ + fputs ("hello, world\n", stdout); +} + + +tprint_() +{ + char buf[128]; + + sprintf (buf, "\tabcdef %0*d[%-5.2s], %h\n", 5, 99, "wxyz", 12.5); + fputs (buf, stdout); +} + + +tcopy_() +{ + FILE *in, *out; + int ch; + + if ((in = fopen ("junk", "r")) == NULL) + c_erract (EA_ERROR); + if ((out = fopen ("junk2", "wb")) == NULL) + c_erract (EA_ERROR); + + while ((ch = getc (in)) != EOF) + putc (ch, out); + + fclose (in); + fclose (out); +} + + +tscan_() +{ + char buf[SZ_LINE]; + char str[SZ_LINE]; + char cval; + int ival, nscan, n1, n2; + int onint(), oldint; + double dval; + + c_xwhen (X_INT, onint, &oldint); + + printf (">> \n"); + fflush (stdout); + + while (fgets (buf, SZ_LINE, stdin) != NULL) { + nscan = sscanf (buf, + "%n%c %*s %d %lg %s%n", &n1, &cval, &ival, &dval, str, &n2); + printf ("nscan=%d: %d '%c' %d %g '%s' %d\n", + nscan, n1, cval, ival, dval, str, n2); + printf (">> \n"); + fflush (stdout); + } + + eprintf ("all done\n"); +} + + +onint (code, old_handler) +int *code; /* NOTUSED */ +int *old_handler; +{ + write (2, "\7", 1); + *old_handler = 0; +} + + +tgettk_() +{ + XCHAR fname[SZ_FNAME+1]; + char token[SZ_LINE+1], delim; + int maxch = SZ_FNAME; + FILE *fp; + + clgstr_ (c_sppstr("fname"), fname, &maxch); + c_strpak (fname, token, maxch); + + fp = fopen (token, "r"); + if (fp == NULL) + c_erract (EA_ERROR); + + while (fscanf (fp, " %[^ \t\n,:()!^&+-*/;|?<>]%c", token,&delim) != EOF) + eprintf ("%s\n%c\n", token, delim); + + fclose (fp); +} -- cgit