****************************************************************** * PRELIMINARY RELEASE -- DISCARD WHEN DECUS VERSION IS RECEIVED * ****************************************************************** DECUS C LANGUAGE SYSTEM Compiler & Library Software Support Manual by Martin Minow Edited by Robert B. Denny This document describes the RSX/VMS/RSTS/RT11 DECUS C language system runtime support library. It also contains all internal functions and such compiler internal information as is available. DECUS Structured Languages SIG Version of 15-Sep-80 (PRELIMINARY) Copyright (C) 1980, DECUS General permission to copy or modify, but not for profit, is hereby granted, provided that the above copyright notice is included and reference made to the fact that reproduction privileges were granted by DECUS. The information in this document is subject to change without notice and should not be construed as a commitment by Digital Equipment Corporation or by DECUS. Neither Digital Equipment Corporation, DECUS, nor the authors assume any responsibility for the use or reliability of this document or the described software. This software is made available without any support whatsoever. The person responsible for an implementation of this system should expect to have to understand and modify the source code if any problems are encountered in implementing or maintaining the compiler or its run-time library. The DECUS 'Structured Languages Special Interest Group' is the primary focus for communication among users of this software. UNIX is a trademark of Bell Telephone Laboratories. RSX, RSTS/E, RT11 and VMS are trademarks of Digital Equipment Corporation. CHAPTER 1 INTRODUCTION The C support library contains three major groups of functions: o Functions called by the compiler to perform certain mathematical operations (such as floating-point multiply or function entrance) that are not performed in-line. o Functions that may be called by C programs to perform operations, such as copying a string, that are more efficiently performed by optimized assembly language subroutines. o An implementation of (most of) the Unix Standard I/O library. The standard installation procedure yields two documents. The Runtime Support Library Reference Manual, containins normal user documentation on the C library. The Compiler and Library Software Support Manual contains the user documentation plus additional information on the internals of both the library and the C compiler. This is the Software Support Manual. CHAPTER 2 THE STANDARD LIBRARY The RSX standard run-time library is in LB:[1,1]C.OLB. The RT11 standard run-time library is in C:CLIB.OBJ. WARNING This version of the library is somewhat incompatible with previous versions of the Decus C compiler. This incompatibility allows greater compatibility with Unix Version 7, and the capability of generating global references and definitions containing the radix-50 '$' and '.' characters. The standard I/O interface header file is in C:STDIO.H, or LB:[1,1]STDIO.H and should be included in all C programs as follows: #include 2.1 Introduction to Unix-style Stream I/O This section presents an overview of the 'standard' I/O interface for C programs. These routines have proven easy to use and, while they do not provide the full functionality of RSX or RMS, they give the programer essentially all that is needed for everyday use. The discussion includes the following: - Opening and closing files - Reading data from files - Writing data to files Note that this file system is limited: files are sequential with only a limited amount of random-access capability. Also, little of the power of RMS/FCS is available. On the other hand, C Compiler & Library Page 2-2 Software Support Manual (** PRELIMINARY **) the limitations make C programs easily transportable to other operating systems. When a C program is started, three files are predefined and opened: stdin The 'standard' input file stdout The 'standard' output file stderr The 'standard' error file Stderr is always assigned to the command terminal. Stdin and stdout are normally assigned to the command terminal, but may be reassigned or closed when the program starts. 2.2 Opening and Closing Files The fopen and fclose functions control access to files. They are normally used as follows: #include /* Define standard I/O */ FILE *ioptr; /* Pointer to file area */ ... if ((ioptr = fopen("filename", "mode")) == NULL) error("Can't open file"); All information about an open file is stored in a buffer whose address is returned by fopen(). The buffer is dynamically allocated when the file is opened and deallocated when the file is closed. Its format is described under the heading IOV. The mode string contains flags defining how the file is to be accessed: r Read only w Write new file a Append to existing file (or write new) (Doesn't work on RT11 modes). It also defines some record-control information: n No newlines mode ('binary' files) u RSX: The user program allocates record buffers RT11: Console output is done using .ttyout If mode 'n' is specified, the RSX I/O routines do not interpret the end of a RMS logical record as defining the end of a human-readable line. This is necessary to process 'binary' information. On RT11, the I/O routines do not remove carriage-returns from input files, nor do they insert carriage-returns when newlines are output. Mode 'u' is treated differently on RSX and RT11. If specified C Compiler & Library Page 2-3 Software Support Manual (** PRELIMINARY **) on RSX the user maintains the file's record buffer. The program may only call the fget() and fput() routines. Each such call will be translated directly to an RMS/FCS GET$ or PUT$ call. (In RT11 mode, fput() may be used to write binary records which are subsequently read by fget(). The file should be opened with 'n' mode.) If mode 'u' is specified on RT11 mode when opening the console terminal, single character output will be performed (using the RT11 monitor routine .ttyout). If not specified, output will be one line at a time (using the monitor routine .print). The library initialization process opens stderr in mode 'u' and stdout in normal mode. This means that mixing I/O to both units will result in synchronization problems. To obtain single-character output on stdout, the program need simply execute: if (freopen("tt:", "wu", stdout) == NULL) error(""); The program calls fclose(ioptr) to terminate processing on a file. This closes the file and reclaims system-controlled buffer space. fmkdl(ioptr) may be called to close and delete an open file. 2.3 Reading Data from a File The simplest way to read a file is to call the getchar() or getc() routines which read the next character from a file. For example, the following program counts the number of characters in a file: #include main() { register int ccount; register int lcount; register int c; FILE *ioptr; if ((ioptr = fopen("foo.bar", "r")) == NULL) error("Cannot open file"); ccount = 0; lcount = 0; while ((c = getc(ioptr)) != EOF) { count++; if (c == '\n') lcount++; } printf("%d characters, %d lines.\n", ccount, lcount); } C Compiler & Library Page 2-4 Software Support Manual (** PRELIMINARY **) Other input routines include: gets Read a line from the standard input fgets Read a line from a file fgetss Read a line from a file, remove terminator ungetc Push one character back on a file fseek Position the file to a specific record These routines are used together with the ferr() and feof() functions which allow testing for error and end of file conditions, respectively. The package assumes that all error conditions are lethal and force end of file. 2.4 Writing Data to a File There are several routines for data output which are directly analagous to the data input routines: putchar Write a character to standard output putc Write a character to a specified file puts Write a string to the standard outpt fputs Write a string to a specified file fputss Write a record to a specified file ftell Return record location (for fseek) In addition, the printf() or fprintf() routine is used to format and print data (as was shown in the previous example). Printf() is flexible, powerful, and easy to use; and is perhaps the single most important routine in the file system. 2.5 Interaction with the Operating System The support library attempts to provide a consistant operating system interface on several implementations of quite different operating systems. The possiblities include: o Native RT11 o Native RSX-11M or IAS o RT11 emulated on RSTS/E o RSX-11M emulated on RSTS/E o RSX-11M emulated on VAX/VMS This section mentions the inconsistencies and random bugs that are more or less intentionally present. C Compiler & Library Page 2-5 Software Support Manual (** PRELIMINARY **) 2.5.1 Logical Unit Numbers RT11, RSTS/E, and RSX-11M use small integers to number all I/O channels. Unfortunately, the numbering is not consistent and channel usage differs among the various systems. This has resulted in several quirks: o On RT11, console terminal interaction uses the .ttyout and .print monitor functions. While no device is opened by the fopen() function, an channel number is reserved. o On RSX-11M, a channel must be allocated to the console terminal. When a C program starts, the 'command terminal' is opened on logical unit 1 and assigned to stderr. This is not done using the fopen() routine (although the stderr IOV structure is defined as if fopen() were called). Also, fclose() cannot close stderr. In addition to the standard I/O routines, there are two routines, msg() and regdmp(), that direct output to logical unit 1. These routines were used to debug the library, and are otherwise useful for disasters. Note that, on RT11, msg() and regdmp() use the .print monitor function. o On both systems, the first true files are stdin and stdout. These are opened on logical units 0 and 1 (RT11) or 2 and 3 (RSX). Code in fclose() double-checks that the logical unit number of the file being closed corresponds to the proper slot in the logical unit table. o Since the standard I/O routines know little about the operating system, they do not deal with certain special features. For example, on RT11, the 'user service routine' (USR) is used to open files. The file open routine does not attempt to locate IOV areas so that the USR does not swap over them. This can be a problem for very large programs. On RSX, logical unit numbers are assigned dynamically. This means that 'LUN assignment' cannot be reliably performed by task-build control files (or task initiation). C Compiler & Library Page 2-6 Software Support Manual (** PRELIMINARY **) 2.5.2 Wild-Card Files The fwild() and fnext() routines can be used to process 'wild-card' files. On RSX-11M and VMS/RSX emulation, the file name, extension, and/or file version may be expressed as '*' to indicate wild-card support. Due to restrictions in the RSX-11 Files-11 structure (ODS1), the ' ', ';0' and ';-1' version numbers will NOT function properly on native RSX-11. This means that '*.MAC' will not work, for instance. The algorithm in fwild() depends on the directory being sorted, as it is in the ODS2 file structure used on VAX/VMS. If you sort the directory to be used in an fwild() operation (use the SRD program available from DECUS with the /WB switch) in order of decreasing file version numbers, then the " ", ";0", and ";-1" versions will work. Wild-card devices, units, or UIC codes are not supported. Note that, on RSX11 emulated on VMS, the ';-1' (earliest version) requires special processing by the user program, as noted in the description of fwild(). On RSX-11M emulated on RSTS/E, the file name and/or extension may contain '*' or '?' wild-cards. Wild-card devices, units, or UIC (PPN) codes are not supported. On RT-11, the file name and/or extension may contain '*', '%' or '?' wild cards. The '?' wild-card is synonymous with '%'. Wild-card devices, or units are not supported. Since wild-card support is not an RT-11 system service, the filespec parsing and directory operations are handled by the C library fwild() and fnext() functions. The fwild/fnext module requires about 480 words of storage. Also, a file opened by wild-card uses a 1024 byte buffer, twice the normal size, which is shared between data and directory operations. 2.5.3 Memory allocation Memory is allocated using the malloc() function. It works correctly on all operating systems, expanding memory on RSX and RT11/RSTS. On 'native' RT11, all available memory is allocated by invoking the monitor .settop function with a '-2' argument. Neither library supports extended memory (PLAS) directives. The sbreak() routine may be used for permanent allocation of memory. Once memory has been allocated using sbreak(), it cannot be freed. CHAPTER 3 SUPPORT INFORMATION The C system has been implemented on VMS V2.0, RSX-11M V3.2, RSTS/E V7.0, and RT11 V03B. All installations should expect to have to modify the command procedures to suit their specific needs. While the compiler has been built from scratch on RT11, the procedures unrealistically assume a system with no disk memory limitations. The C system has not been tested on IAS, RSX11-D, RSX11M-PLUS, or HT11. The C system is distributed on 9-track magtape in 'DOS-11' format. The full distribution requires a 2400 foot (or three 600 foot) tapes. Please Note This is a DECUS 'product'; there is no support available from the authors. The person responsible for an implementation of this system should expect to have to understand and modify the source code if any problems are encountered in implementing or maintaining the compiler or its run-time library. The DECUS 'Structured Languages Special Interest Group' is the primary focus for communication among users of this software. This section contains information on the internals of the compiler, assembler, and run-time libraries. It is not complete; it is probably not accurate either. 3.1 The C compiler The compiler source is distributed on account [5,3]. There are four groups of files in this account: o The C compiler source is in modules named CC???.MAC. The root code is in CC0RT.MAC, while overlays are in CC00?.MAC, CC10?, CC20?, and CC3??. The overlays have C Compiler & Library Page 3-2 Software Support Manual (** PRELIMINARY **) the following functions: 0. Pass 0 reads the input source file, writing a temporary file after processing #define, #include, and #ifdef statements. 1. Pass 1 reads the expanded source file, parses the language and writes an 'intermediate code' file. In the intermediate file all operations have been converted into 'low-level' constructions. Variable and structure references are compiled into absolute expressions. All information needed by the code generator is contained in this file. Except for compiler flags and file names, nothing is retained in memory. 2. Pass 2 reads the code file, writing PDP-11 assembly language (in the format requested by the AS assembler). 3. Pass 3 contains some end of processing code to delete files. All internal files are in Ascii. In order to make the compiler portable between RSX, RSTS/E, and RT11, the file system is simple and inefficient. RT11 users may run into intermediate file size problems. The only (software) solution requires invoking the compilation with explicit size arguments for the output files: #out.s[N1],interm.tm1[N2],expand.tmp[N3]=in.c The expanded source file should be less than the size of the input file plus all #include files. The intermediate file size may be as much as twice the size of the expanded source file. o C programs are assembled into PDP-11 object code by the AS assembler, whose source files are named 'AS????.MAC'. The AS assembler is described in AS.DOC. o A support library for the two compilers is included in a group of files labeled A?????.MAC. The C compiler build process also builds the support library. This library is similar -- but not identical -- to the run-time support library. The compiler and assembler are installed by executing command files. There are several groups of command files supplied to assist in implementation on the various operating systems. It is highly likely that the files will have to be edited to suit each individual installation's needs. VMS, RSX, and RT11 files are run by the indirect command file processor, while RSTS/E C Compiler & Library Page 3-3 Software Support Manual (** PRELIMINARY **) files are run by the ATPK system program. RSTS/E installation requires must be run from a privlieged account. The following file conventions are used: VMS command files begin with the letter 'V', RSTS/E RT11 mode with the letter 'R', and RSTS/E RSX mode with the letter 'X'. Native RT11 command files begin with 'T' and native RSX-11M files begin with the letter 'M'. Thus, XMAKCC.CMD builds the CC compiler for RSTS/E RSX-11M mode. The '.TKB' files are indirect command files for the task-builder. Warning As distributed, the compiler and run-time libraries assume hardware support for the SXT (sign-extend) instruction. This is present on all PDP-11 CPU's with EIS, and on all versions of the LSI-11 (11/03, LSI-11, 11/23). If the compiler is to generate code that will run on the 11/05, 11/10, or 11/20, all RSX.MAC and RT11.MAC configuration files must be edited to define symbol C$$SXT equal to zero. Note that the compiler must be build with C$$SXT set correctly. As distributed, the RSX configuration files assume hardware EIS support. If this is not the case (hardware EIS is not needed for RSX-11M) edit the RSX.MAC control files to define symbol C$$EIS equal to zero. There are two RT11 configuration files, and the RSTS/E library build procedure builds an EIS library, CLIB.OBJ, as well as a library without EIS support, CLIBN.OBJ. The default 'native' RT11 command file builds a non-EIS library, naming it CLIB.OBJ. Programs linked against the non-EIS library will run on machines with EIS. Also, save-images linked on RT11 will run on RSTS/E and vice-versa without relinking. There are certain differences in task-image format between native RSX-11M and RSX-11M as emulated on RSTS/E. Thus, only source or object files are transportable between the two operating systems. 3.2 The C Run-time Support Library The C support library is distributed on two accounts, [5,4] and [5,5]. Account [5,4] contains only those routines which have no I/O dependencies, while account [5,5] contains the standard I/O C Compiler & Library Page 3-4 Software Support Manual (** PRELIMINARY **) library. Many routines are conditionally compiled to select RT11 or RSX mode. All routines should be compiled together with either RT11.MAC (no EIS support), RT11.EIS (hardware EIS support), or RSX.MAC, identical copies of which are present in each account. To build the libraries, execute one of the following command files: RMAKLB.CMD RT11 library on RSTS/E VMAKLB.COM RSX library on VMS XMAKLB.CMD RSX library on RSTS/E MMAKLB.CMD RSX library on RSX-11M TMAKLB.COM RT11 library on RT11 Account [5,1] contains a program, GETCMD.C which was used to build assembler command files. On RSTS/E, a command file, [5,1]RLBCMD.CMD, may be used to rebuild all library command files. All library source code is in PDP-11 MACRO. 3.3 The RSTS/E Interface Library Account [5,6] contains a library of subroutines that allow C programs access to all RSTS/E executive functionality. There is no documentation other than the source code and [5,6]README.506. 3.4 The RSX-11 Extensions Library Account [5,7] contains a library of subroutines that allow C programs access to all RSX-11M executive functionality, including AST's. Refer to [5,7]CX.DOC for more information. This library has not been completely tested, nor has it been tested on 'emulated' RSX-11M modes (under VMS or RSTS/E), nor on IAS or RSX11-PLUS. 3.5 RT11 Extensions Library Access to RT11 executive functionality may be had by calling the system library (SYSLIB). The C library call() routine may be used to generate the necessary calling sequences. Note that SYSLIB routines that depend on Fortran I/O conventions must not be called. C Compiler & Library Page 3-5 Software Support Manual (** PRELIMINARY **) 3.6 C Tools and Toys The distribution kit contains several accounts [6,*] with C programs and subroutines. Account [6,1] contains a library of 'software tools' which should be useful for all C installations. Among these are the following: echo Echo arguments onto the standard output. This program serves as the primary test of the run-time library. grep 'Get regular expression pattern.' This program reads one or more files, printing text lines that match a given pattern. kwik 'Key word in context' utility. sortc A file sort utility. sorts Sort-merge subroutines for incorporation into other programs. wc Count bytes, words, and lines in one or more files. ccxrf Cross-referenced listings for C source files. Please refer to README.??? files in the appropriate accounts for more information. 3.7 Building the Documentation The source of the library documentation is included within the library source (Macro) files. Before building the library documentation, compile and task-build the 'Macro to RNO' conversion program, [5,1]GETRNO.C and use it to process files. Note that GETRNO.C only runs in RSX mode. See the source of GETRNO for further details. The control files [5,1]RGTRNO.CMD and [5,1]RGTDOC.CMD illustrate the process on RSTS/E. CHAPTER 4 COMPILER INTERNAL INFORMATION As noted above, compiler work files are in human-readable Ascii. The parser generates a temporary file with an internal pseudo-code. The code generator converts this pseudo-code to PDP-11 assembly language. Except for compiler flags, all communication between passes is via intermediate files. 4.1 Intermediate Code File Format The intermediate code file consists of single line entries for each operation. The first byte is an operator, followed by parameter entries as needed. Numeric values are transmitted in octal. The following operators are defined: Location counter control: C Switch to the string P-section (.STNG.) O Switch to the data P-section (.DATA.) P Switch to the program P-section (.PROG.) Flow control: L [number] Define a local label J [number] Jump to a local label X Function exit N Function entry Data reservation, etc.: A Generate a .even pseudo-op B [number] Generate a .blkb [number] D Generate an external label G Generate a .globl H Generate a .byte C Compiler & Library Page 4-2 Software Support Manual (** PRELIMINARY **) I Generate a .word as a local pointer Y Generate a .word Special operations: W Generate a switch table Q Make a symbol table entry M Transmit a line number between passes Tree (expression) operators: R Return S Switch E Compile for effect T Jump if true F Jump if false K Initialize variable Z Tree item Note that 'trees' are the result of compiling expressions, such as (a + b * (c & 4)) * d Each non-terminal node of a tree generally consists of a left part, an operation, and a right part. Operator precedence has been resolved. The above example thus becomes: | ------------------ | | --------- | | | | | -------- | | | | | | | ----- | | | | | | ((a + (b * (c & 4))) * d) For example, here is a simple subroutine and the intermediate code it generates: fact(n) D fact | define function fact { N 0 4 | enter function if (n == 0) F 1 | if false, goto L1 Z [n == 0] | compile expr. value return(1); R | return C Compiler & Library Page 4-3 Software Support Manual (** PRELIMINARY **) Z 1 | compile expr. value J 2 | goto L2 return(n * fact(n - 1)); L 1 | Label L1, N != 0 R | return Z [n * fact(n - 1)] | compile expr. value L 2 | label L2 } X | Exit from function G fact | .globl fact The C source code is parsed by a top-down, recursive parser. Expressions are parsed bottom-up, by priority. Casts of types are processed by special routines. The parser does some optimizations, such as constant folding. Also, all automatic variables (local to a function), are assigned absolute offsets from the argument frame (Register 5), while structure elements are assigned absolute offsets from the base of the structure. 4.2 The Code Generator The code generator consists of a top-level input file reader, which processes 'easy things' directly. It calls subroutines to compile switch statements and expressions. The expression compiler performs various optimizations, calls a Sethi-Ullman register allocator, then a code generator. The Sethi-Ullman algorithm was described in the Journal of the ACM, Volume 17, No. 4, October 1970. pp. 715-728. 4.2.1 Optimizations and Register Allocation The following optimizations are performed: o Expressions are reordered. o Constant expressions are folded. o Dummy operations are eliminated, including -(-A), !(!A), ~(~A), (A & A) and (A | A). C Compiler & Library Page 4-4 Software Support Manual (** PRELIMINARY **) o Dummy address expressions are eliminated: *(&A) and &(*A) all become A. o Constant address arithmetic is performed in expressions such as &A + const. o Constant offsets from registers become index operations in expressions such as *(reg + constant) or *(reg - constant). o PDP11 autoincrement and autodecrement are used in expressions such as *p++ and *--p. o Conversion between integer and pointer datatypes are converted to multiply and divide operations. o Multiply by 1 is deleted. o The and operator is converted to BIC. o Null operations are deleted, including +0, -0, &-1, |0, ^0, |=0, etc. Register allocation is as follows: o R0 and R1 are always scratch registers. o R2, R3, and R4 may be reserved by the C program by using the 'register ...' construction. The parser tells the coder the highest register it can use (in the function initialization intermediate code operation). o The Sethi-Ullman algorithm stores the number of registers needed into each tree node. This number is always >= 2 to insure that R0 and R1 are available for scratch usage. o 'A tree is easy if the other tree uses few enough registers and there is a free register available.' o The GETREG subroutine claims registers. If the code table is modified, be sure that GETREG isn't called on a tree that isn't easy. C Compiler & Library Page 4-5 Software Support Manual (** PRELIMINARY **) 4.2.2 Code generation Almost all code is generated by expanding macro operators out of the code tables. There are four tables (CTAB, ETAB, STAB, RTAB) and a pseudo-table, TTAB. Only RTAB is complete, If an expansion which was attempted in CTAB or ETAB fails, it is retried in RTAB. If an expansion which was attempted in STAB fails, it is done by: [Rtab] mov Reg,-(sp) The code body is in Ascii; bytes with the parity (eighth) bit set are used macro operators: 'address of left', 'push right', etc. Code table entries are selected by the type of the arguments (int, char, long, unsigned, float, double, and pointer) and by kind (constant, address, easy, and any). Here is a typical code table (for addition): int any int con1 ; Add 1 to any integer [LL] ; Compile left (subtree) inc [R] ; INC Rx int any int addr ; Add var. to anything [LL] ; Compile left (subtree) add [AR],[R] ; ADD var,Rx int any int easy [SRV] ; NOP if it's an address [LL] ; Compile left (subtree) add [AR],[R] ; Add var,Rx int any int any [PR] ; Compile right to stack [LL] ; Compile left to reg. add (sp)+,[R] ; ADD (sp)+,Rx Here is another example, '= for effect' (as in 'A = B;'): int any int con0 ; I = 0; char any int con0 ; C = 0; C Compiler & Library Page 4-6 Software Support Manual (** PRELIMINARY **) [SLAC] ; Get left op. address clr[TL] [AL] ; CLR(B) var int addr int any char addr int any [LR] ; Compile right subtree mov[TL] [R],[AL] ; MOV(B) Rx,var int any int easy char any int easy [SRV] [SLAC] mov[TL] [AR], [AL] int any int any char any int any [PLA] [LR] mov[TL] [R],'(sp)+ 4.2.3 Macros Used in Code Generation The following are defined in the code generator: [M] Set modulo return [F] Set function return [R] Current register [R+1] Current register + 1 [AL] Address of left [ALN] Address of left, no side effect [AR] Address of right [ARN] Address of right, no side effect [OP0] Opcode [OP1] Opcode [AL+2] Address of left, long [AR+2] Address of right, long [TL] Type of left [T] Type of right or left [SRVA] Set right value anywhere [SRV] Set right value [SRAA] Set right address anywhere [SRA] Set right address C Compiler & Library Page 4-7 Software Support Manual (** PRELIMINARY **) [SLVA] Set left value anywhere [SLV] Set left value [SLAA] Set left address anywhere [SLA] Set left address [SLAC] Set left address current reg. [LL] Load left [LL+1] Load left into [R+1] [LR] Load right [PL] Push left [PLA] Push left address [PR] Push right [V] ADC or SBC for longs 4.3 Extended Hardware Support This version of the compiler contains some of the code necessary for generation of inline EIS (hardware integer multiply-divide) and FPU (hardware floating-point) operations. The code does not currently work: EIS instructions are always compiled by calling subroutines and all attempts to use floating-point result in a 'fatal compiler abort.' To add EIS support, you must write code table entries (in CC206 at label EISTAB) and debug pass 2. This is a fair chore. Adding floating-point support requires writing code table entries as well as a fair amount of code to perform conversions. This is liable to be a somewhat difficult undertaking. Do not assume that any of the code that currently exists actually works correctly -- it has never been tested. CHAPTER 5 LIBRARY FUNCTION DESCRIPTIONS This chapter contains descriptions of each of the C-callable runtime library functions. In addition, descriptions of internal routines are provided. In most cases the I/O functions match those of UNIX V7 closely, with differences normally called out. For more information, consult "The C Programming Language" by Kernighan and Ritchie (Prentice-Hall, ISBN 0-13-110163-3). C Compiler & Library Page 5-2 $$c5ta Convert Radix-50 to Ascii 5.1 Convert Radix-50 to Ascii _______ ________ __ _____ ********** * $$c5ta * ********** File name: c5ta.mac Usage mov rad50_word, r1 mov out_ptr, r0 call $$c5ta Return: r0 updated r1 random other registers preserved. Description: Convert one radix-50 word to three Ascii bytes. All letters will be in upper-case. The output buffer will not be null-trailed, nor will blank fields be supressed. Bugs C Compiler & Library Page 5-3 $$div2 Unsigned divide (Macro only) 5.2 Unsigned divide (Macro only) ________ ______ ______ _____ ********** * $$div2 * ********** File name: div2.mac Usage mov hi_div,r0 ;High-order dividend mov lo_div,r1 ;Low-order dividend mov divisor,r2 ;Divisor jsr pc,$$div2 ;Perform the division mov r0,hi_quotient ;High-order quotient mov r1,lo_quotient ;Low-order quotient mov r2,remainder ;Remainder Description Perform an unsigned double-precision division. Bugs C Compiler & Library Page 5-4 $$dtoa Convert double to Ascii 5.3 Convert double to Ascii _______ ______ __ _____ ********** * $$dtoa * ********** File name: dtoa.mac Usage $$dtoa(buff, conv, field, dplace, value) char *buff; /* Where it goes */ char conv; /* Conversion type */ int field; /* Maximum field width */ int dplace; /* Decimal part width */ double value; /* What to convert */ char * $$ecvt(negfl, scale, field, dplace, value) int *negfl; /* 0 if +, 1 if - value */ int *scale; /* Set to scale factor */ int field; /* Maximum field width */ int dplace; /* Decimal part width */ double value; /* What to convert */ char * $$fcvt(negfl, scale, field, dplace, value) int *negfl; /* 0 if +, 1 if - value */ int *scale; /* Set to scale factor */ int field; /* Maximum field width */ int dplace; /* Decimal part width */ double value; /* What to convert */ Description $$dtoa() is called by printf to convert a double-precision value to Ascii. The text is written to buff[]. Field and dplace are the conversion parameters "f" and "d" in the format string "%f.df" Conv is 'e', 'f', or 'g' to define the format. Note: the conversion character must be in lower-case. $$ecvt() and $$fcvt() perform the conversions, returning a pointer to an internal character buffer. On return, negfl will be non-zero if the value was less than zero, and scale will be set to the scaling factor. C Compiler & Library Page 5-5 $$dtoa Convert double to Ascii Diagnostics Bugs "%g" does not exist yet. It is equivalent to "%f". The code has not been tested as there is no fpu support yet. C Compiler & Library Page 5-6 $$fadd Floating-point support, add/subtract 5.4 Floating-point support, add/subtract ______________ ________ ____________ ********** * $$fadd * ********** File name: fadd.mac Usage double $$fadd(a, b) /* Floating add a + b */ double $$fsub(a, b) /* Floating sub a - b */ double a; double b; Description Called by the compiler to compile floating-point. Bugs C Compiler & Library Page 5-7 $$fdba File name to Ascii conversion 5.5 File name to Ascii conversion ____ ____ __ _____ __________ ********** * $$fdba * ********** File name: fdbta.mac Usage RSX: mov fdb_pointer, r1 mov buffer_pointer, r0 call $$fdba Return: r0 is updated to point to the null trailer. RT11: mov device_block_pointer, r1 mov buffer_pointer, r0 call $$fdba Return: r0 is updated to point to the null trailer. Description $$fdba may be called to convert an RSX file name block or RT11 device block to ascii. Note that the directory name ([UIC]) is not converted if it equals your default. Numbers are converted to octal on native RSX, and to decimal on RSTS/E emulation. The buffer size will not be checked. A version number which is negative (or zero) will not be converted. If the file name and extension are both blank neither will be converted. Note: on RSTS, the device name will be preceeded by "_" to supress further logical translation. Bugs C Compiler & Library Page 5-8 $$fmul Floating-point multiply/divide 5.6 Floating-point multiply/divide ______________ _______________ ********** * $$fmul * ********** File name: fmul.mac Usage double $$fmul(a, b); /* Floating multiply */ double a; double b; Description Called by the compiler to execute floating-point multiply. Bugs C Compiler & Library Page 5-9 $$fsav Floating-point support routines 5.7 Floating-point support routines ______________ _______ ________ ********** * $$fsav * ********** File name: fis.mac Usage $$fsav /* Floating save */ $$frta /* Return to caller a */ $$frtb /* Return to caller b */ Description These routines are used internally by the floating-point simulation package. They are never called by the C program. Bugs C Compiler & Library Page 5-10 $$gcmd Parse command line 5.8 Parse command line _____ _______ ____ ********** * $$gcmd * ********** File name: getcmd.mac Usage argc = $$gcmd(text, in, out, avp); char *text; /* Command line */ char **in; /* stdin filename */ char **out; /* For stdout filename */ char ***avp; /* Gets argv[] location */ Description: Parse the command line, building the argv[] table. If I/O redirection is encountered, in and out are modified accordingly. NOTE: $$gcmd will modify text. argv[] entries will point to bytes in text. $$gcmd() returns the number of arguments encountered. $$gcmd() is called in the following fashion: /* * Default input is on tty */ char **infile = &def_in; char *def_in = "tt:"; /* * Default output is on tty */ char **outfile = &def_out; char *def_out = "tt:"; /* * Define argv[] pointer and dummy command * line. */ char **argvp; char *dummy = "main"; int argc; C Compiler & Library Page 5-11 $$gcmd Parse command line ... argc = $$gcmd((strlen(cmdlin) == 0) ? dummy : cmdlin, &infile, &outfile, &argvp); if (argc < 0) error("Bad command line"); stdin = fopen(infile, "r"); if (**outfile == ">") stdout = fopen(*outfile + 1, "a"); else stdout = fopen(*outfile, "w"); Bugs C Compiler & Library Page 5-12 $$getc Get characters 5.9 Get characters ___ __________ ********** * $$getc * ********** File name: getc.mac Usage mov #iov,r4 ;r4 -> i/o vector call $$getc ;Get a character RSX: mov #iov,r4 ;r4 -> i/o vector mov #buffer,r0 ;r0 -> buffer mov buflen,r1 ;r1 := max. buffer size call $$get ;Get a record VF$EOF and/or VF$ERR are set on error or end of file. r0 := actual record length, -1 on error or end of file. Other registers preserved. RT11: mov #blknbr,r0 ;r0 := block to read call $$get ;Get a block VF$EOF and/or VF$ERR are set on error or end of file. r0 is zero if success, -1 on error or end of file. Other registers preserved. Description $$getc is the internal "get a byte" routine. The next byte in the indicated file is returned in r0. All other registers are preserved. $$get is the internal "get a record" routine. Note that the maximum record size (r1) is only needed on RSX. It is fixed at 512. bytes on RT11. If the file is defined as "stream" (the "n" flag was not set when the file was opened using fopen()), the end of C Compiler & Library Page 5-13 $$getc Get characters the line will be represented by the newline (\n) character, and NULL's will be removed. Bugs In stream files in RT11, all carriage-returns are removed. It would be more correct to remove carriage-return from or sequences. RT11 uses .ttyin to read from the user command terminal. It would be more correct to use .gtline as this would allow indirect command file tracking. C Compiler & Library Page 5-14 $$init Once-only initialization code 5.10 Once-only initialization code _________ ______________ ____ ********** * $$init * ********** File name: init.mac Usage Internal $$init() Description When a C program is started, a command line is parsed to form the argv[] array and the standard input, output, and error files are opened. Note the following: On RSX11/M (even emulated), argv[0] will be set to the task name. On RT11 modes, argv[0] will be set to a dummy value. On RT11, if no command line is passed to the program, it will prompt "Argv:" and read a line from the command terminal. To disable this, the user program must define a global flag as follows: $$narg = 1; main (argv, argc) { ... If $$narg is defined non-zero and no command line is passed to the program, main() will be called with one (dummy) argument. Internal This module contains code that may be sensitive to particular releases of the various operating systems. Also, there may be code that is sensitive to the various types of operating system emulators. The maintainer should strive to keep all such code in this module. C Compiler & Library Page 5-15 $$init Once-only initialization code Diagnostics Cannot open standard input [filename], code = nnnnnn Cannot open standard output [filename], code = nnnnnn No memory The "cannot open" messages are a user error if input or output are redirected. The associated error code is the FCS error code if the program is running under RSX, and the C library error code (described in IOV), if under RT11. The "no memory" message suggests a severe case of program immensity. All errors are fatal. Bugs It might be reasonable to make error messages non-fatal so $$init could be called by a user program. On RSX, the program aborts (by executing a BPT instruction) if stderr cannot be initialized or partition parameters obtained. C Compiler & Library Page 5-16 $$ltoa Convert long to ascii 5.11 Convert long to ascii _______ ____ __ _____ ********** * $$ltoa * ********** File name: ltoa.mac Usage $$ltoa(buff, radix, value); char *buff; /* Where it goes */ int radix; /* Conversion radix */ long value; /* What to convert */ Description Called by printf to convert a long integer from binary to Ascii, storing the result in buffer. The radix argument determines the conversion: d Signed decimal o Octal u Unsigned decimal X Hex (10-15 = A-F) x Hex (10-15 = a-f) Bugs C Compiler & Library Page 5-17 $$main Start of C programs 5.12 Start of C programs _____ __ _ ________ ********** * $$main * ********** File name: suport.mac Usage $$main:: /* Start of C programs */ extern int $$opsy; /* Operating system */ extern int $$rsts; /* Non-zero if RSTS/E */ extern int $$uic; /* RSX: Default uic */ extern int $$stnd; /* Stack end point */ extern int $$scca; /* RT11: .scca control */ extern char $$task[]; /* RSX: task name */ extern int $$tick; /* RT11: 50 or 60 Hertz */ Internal extern int (*$$pptr)(); /* Profile printer */ extern int $$argc; /* Argument count */ extern int *$$argv[]; /* Argument list ptr. */ extern char *$$mtop; /* Free memory start */ extern char *$$mend; /* Free memory end */ Description This module contains the run-time startoff for C programs. It intializes the C environment and calls the main() subroutine. On return from the main program, exit() is called to close all files and return to the operating system. The following globals are defined in this module: $$opsy Operating system unique value. This value is 7 on RT11, and set as per the GTSK$ directive on RSX-based systems. $$rsts This value is non-zero if the program is running on RSTS/E. It is zero if the program is running native RSX, RT11 or C Compiler & Library Page 5-18 $$main Start of C programs VMS compatibility mode. $$stnd The (top) end of the stack on entrance. $$scca On RT11, the .scca control word. This is needed to allow RSTS/E programs to trap end of file. $$task On RSX, the task name in Ascii. $$tick On RT11, the clock interrupt rate. This will equal either 50 or 60. $$uic On RSX, the default UIC word from GTSK$. Internal Other $$ values are for internal communication among runtime library routines. I.e., let them alone. Diagnostics On RSX, the task aborts with a BPT if the standard error file did not open. Otherwise, explanatory error messages are printed. Bugs C Compiler & Library Page 5-19 $$narg Define default for $$narg 5.13 Define default for $$narg ______ _______ ___ ______ ********** * $$narg * ********** File name: narg.mac Usage int $$narg = ; ... main() { ... } Description On native RT11, if no command line is provided when the program starts, it prints "Argv:" on the command terminal, reads one line, and builds the argv[] array. If this is undesirable, include a global definition of $$narg in a C program as follows: int $$narg = 1; This will supress the command terminal read operation. The argv[] vector will be set to a dummy value. If the user program does not define $$narg, it will be defined so as to enable the "Argv:" prompt. Note that $$narg must be initilized at compilation time. It is tested by the initialization code before the main() program is called. Bugs C Compiler & Library Page 5-20 $$putc Put a character to a file 5.14 Put a character to a file ___ _ _________ __ _ ____ ********** * $$putc * ********** File name: putc.mac Usage mov #iov,r4 ; r4 -> I/O vector mov byte,r0 ; r0 := byte to output call $$putc Description $$putc is the internal call to write one character to an indicated file. On return, all registers are preserved, even r0. Bugs There is a bug in RS11 emulation under RSTS/E such that "*" cannot be output by the .ttyout monitor call. You should reedit the code when the bug is fixed. C Compiler & Library Page 5-21 $$qiow Call RSX system to perform I/O 5.15 Call RSX system to perform I/O ____ ___ ______ __ _______ ___ ********** * $$qiow * ********** File name: qiow.mac Usage mov ,r0 mov IOV pointer,r4 mov onto the stack, right to left call $$qiow bcs Description Issue a qio$ directive for all I/O requests needing such. Uses r0, r1. This routine is used only in the RSX library. Using it in the RT11 library will cause the program to abort with by executing a BPT instruction. Bugs C Compiler & Library Page 5-22 $$svr1 Save registers r1-r5 on the stack 5.16 Save registers r1-r5 on the stack ____ _________ _____ __ ___ _____ ********** * $$svr1 * ********** File name: savr1.mac Usage jsr r5,$svr1 ;Save r1-r5 on the stack ... return ;Restore r1-r5 and return to caller Description Save general registers r1-r5 on the stack and return to the caller. When the caller executes an return (rts pc), it will cause the original r1-r5 to be restored and the program will return to the original caller. Bugs Except for the C-bit, condition codes are not preserved. C Compiler & Library Page 5-23 abort Abort program with an IOT trap 5.17 Abort program with an IOT trap _____ _______ ____ __ ___ ____ ********* * abort * ********* File name: abort.mac Usage abort() Description After closing all files, the program exits by executing a BPT trap. Bugs C Compiler & Library Page 5-24 abs Integer absolute value 5.18 Integer absolute value _______ ________ _____ ******* * abs * ******* File name: abs.mac Usage abs(val) int val; Description Return absolute value of the integer argument. Bugs C Compiler & Library Page 5-25 alloc Allocate memory 5.19 Allocate memory ________ ______ ********* * alloc * ********* File name: alloc.mac Usage char * alloc(n); /* -1 if no space */ Description Allocate the requested number of bytes, returning a pointer to the first. The program image will be expanded as needed. alloc() returns -1 if the requested space could not be allocated. free() is used to return the buffer to free space. See also the description of malloc(), realloc() and sbreak(). Diagnostics Bugs alloc() is obsolete. Use malloc() for new programs. C Compiler & Library Page 5-26 ascr50 Ascii to Radix-50 conversion 5.20 Ascii to Radix-50 conversion _____ __ ________ __________ ********** * ascr50 * ********** File name: ascr50.mac Usage ascr50(count, input, output) int count; int *output; char *input; Description Convert 'count' characters from ascii to Radix 50. If there aren't a multiple of 3 characters, blanks are padded on the end. The ascii string is moved to the output when finished. The input and output areas may be the same since three input characters are read for every two bytes of output. Bugs C Compiler & Library Page 5-27 asl$i EIS emulator module 5.21 EIS emulator module ___ ________ ______ ********* * asl$i * ********* File name: eis.mac Usage asl$i(a, b); /* Execute a << b */ asr$i(a, b); /* Execute a >> b */ mul$i(a, b); /* Execute a * b */ div$i(a, b); /* Execute a / b */ mod$i(a, b); /* Execute a % b */ Description All arguments are integers. These routines are called by the C compiler to perform the indicated operations. The module may be conditionally compiled to generated hardware EIS operations. Edit RT11.MAC or RSX.MAC to define C$$EIS as needed: 0 Emulate EIS operations 1 Generate EIS operations C$$EIS is defaulted zero for RT11, non-zero for RSX. Note: if n is negative, x << n == x >> (-n) and v.v. Bugs Divide by zero yields zero for the quotient and remainder. C Compiler & Library Page 5-28 asl$l Shift long << long 5.22 Shift long << long _____ ____ __ ____ ********* * asl$l * ********* File name: asll.mac Usage long asl$l(l, n) long l; long n; long asr$l(l, n) long l; long n; Description Performs shifting of long by long. Only the low-order six bits of the shift argument are examined. This is compatible with the hardware ASH instruction. Note that, if n is negative: (l << n) == (l >> (-n)) Bugs C Compiler & Library Page 5-29 asl$li Shift long << integer 5.23 Shift long << integer _____ ____ __ _______ ********** * asl$li * ********** File name: aslli.mac Usage long asl$li(l, n) long l; int n; long asr$li(l, n) long l; int n; Description Performs arithmetic shifting for integer shift arguments. Note that only the low-order six bits of the shift argument are examined. This is compatible with the hardware shift instruction. Bugs C Compiler & Library Page 5-30 asr$u Right shift unsigned >> integer 5.24 Right shift unsigned >> integer _____ _____ ________ __ _______ ********* * asr$u * ********* File name: asru.mac Usage unsigned asr$u(u, n) unsigned u; int n; Description Performs u >> n for unsigneds. Note that, if n is negative, it acts as if (u << (-n)) were executed. Bugs C Compiler & Library Page 5-31 atod Convert Ascii to double floating 5.25 Convert Ascii to double floating _______ _____ __ ______ ________ ******** * atod * ******** File name: atod.mac Usage double atod(buffer) char *buffer; Description Convert the argument string to a double-precision floating point binary number. The conversion stops on the first non-legal character. The caller is assumed to have already checked the argument for legality. Bugs Not quite written yet (as there is no compiler fpu support). C Compiler & Library Page 5-32 atoi Convert Ascii to integer 5.26 Convert Ascii to integer _______ _____ __ _______ ******** * atoi * ******** File name: atoi.mac Usage atoi(p) char *p; Description Convert string to integer. No data checking is performed. The conversion stops at the first non-integer. Leading spaces, tabs, plus-signs and/or newlines are ignored. The integer may be preceeded by a minus sign. Bugs C Compiler & Library Page 5-33 atol Convert Ascii to long 5.27 Convert Ascii to long _______ _____ __ ____ ******** * atol * ******** File name: atol.mac Usage long atol(p) char *p; Description Convert string to integer. No data checking is performed. The conversion stops at the first non-integer. Leading spaces, tabs, plus-signs and/or newlines are ignored. The integer may be preceeded by a minus sign. Bugs C Compiler & Library Page 5-34 break Change memory allocation 5.28 Change memory allocation ______ ______ __________ ********* * break * ********* File name: break.mac Usage char * old = sbrk(increment); int *old; int increment; char * old = brk(value); int *old; int *value; char * new = settop(value); int *value; int *new; Description sbrk() gets increment more memory. brk() sets the first unusable address to value. Both return a pointer to the beginning of the new memory area. settop() resets top of memory to value. Diagnostics NULL is returned if the memory requested is not available. There is no "shortened" return. Use settop() for this case. Bugs These routines only work on the RT11 library. Using them in RSX-mode will cause the job to abort with an IOT trap. These routines do not work together with alloc(). They should. C Compiler & Library Page 5-35 break Change memory allocation 5.29 Call (Fortran) subroutine from C ____ _________ __________ ____ _ ******** * call * ******** File name: call.mac Usage return_value = call(routine, count, &arg1, ... &argN); extern int routine(); /* PDP-11 function name */ int count; /* Number of arguments */ Description C Library user-callable interface between C programs and subroutines which follow the standard PDP11 calling sequence. Note that call() saves and restores registers r2-r5. The arguments are as follows: routine The name of the PDP11 routine to be called. count The number of arguments in the calling sequence. arg1 The first argument. For example: extern int sort(); int data_to_sort[NDATA]; int ndata = NDATA; call(sort, 2, &data_to_sort, &ndata); Note that, if the called function returns some other datatype such as a long, the routine and call() must be correctly declared: long call(); long myfun(); long larg; C Compiler & Library Page 5-36 call Call (Fortran) subroutine from C long result; result = call(myfun, 1, &larg); If call() is being used to return several different datatypes, type coersion may be effective: int call(); long myfun(); long larg; long result; result = (long)call(myfun, 1, &larg); Bugs: WARNING: watch out for trouble if the PDP-11 routine does any I/O. Floating-point data return has not been implemented. C Compiler & Library Page 5-37 callc Call C subroutine from (Fortran) program 5.30 Call C subroutine from (Fortran) program ____ _ __________ ____ _________ _______ ********* * callc * ********* File name: callc.mac Usage integer callc ivalue = callc(routine, arg1, ... argN) Description User-callable interface between Fortran programs and subroutines written in C. The arguments are as follows: routine The name of the C routine to be called. arg1 The (location of the) first argument. For example: call callc(sort, table, nelement) Bugs Untested. There will be I/O library conflicts since C files have not been initialized. The following problem will occur if a C subroutine is called from a Fortran main program: The C subroutine refers to the save register routine (CSV$) which refers to the C main program. This pulls in a large amount of I/O dependent code, which may cause conflicts. What is worse is that there will be two main programs. C Compiler & Library Page 5-38 callc Call C subroutine from (Fortran) program It is therefore recommended that there be a C main program that calls Fortran subroutines that may, in turn, call C subroutines. The programmer can also define a dummy program that resolves the globals referenced by CSV$ or modify callc.mac to provide the necessary globals. C Compiler & Library Page 5-39 caller Return name of profiled caller 5.31 Return name of profiled caller ______ ____ __ ________ ______ ********** * caller * ********** File name: caller.mac Usage char * caller(); Description If the routine which called the current function was compiled using the profile option, caller() returns a pointer to the name of the calling function. If the calling function was not compiled with profiling enabled, a pointer to the null string is returned. Example: foo() { foobar(); } foobar() { extern char *caller(); printf("foobar was called by %s\n", caller()); } Internal Warning -- this routine is sensitive to the format of the environment frame and profile information layout. If csv$, pcsv$, or $$prof change, this may have to be modified. Bugs C Compiler & Library Page 5-40 calloc Allocate and Initialize Memory 5.32 Allocate and Initialize Memory ________ ___ __________ ______ ********** * calloc * ********** File name: calloc.mac Usage char * calloc(n, m); /* NULL if no space */ Description Calloc() allocates space for n elements, each m bytes long. On return, the space is zero'ed. The program image will be expanded as needed. If the requested space cannot be allocated, calloc() returns NULL. See also the description of malloc(), realloc() and sbreak(). The space is returned by calling free(). Diagnostics Bugs C Compiler & Library Page 5-41 calltr Trace Path to the Caller 5.33 Trace Path to the Caller _____ ____ __ ___ ______ ********** * calltr * ********** File name: calltr.mac Usage calltrace(outfd); FILE *outfd; Description calltrace() prints the calling path (from main()) to the routine that called calltrace()) on the indicated file. The path is printed on one line as: [ main sub1 sub2 ] If a subroutine within the path was not compiled with profiling, or does not start with a call to the C register register save routine, it will be printed as (where is the octal address of the entry to the routine). Note that the last entry on the line is the routine that invoked calltrace(). A call trace will be printed on exit if tracing is enabled and the program aborts or calls error(). Internal Warning -- this routine is sensitive to the format of the environment frame and profile information layout. If csv$, pcsv$, or $$prof change, this may have to be modified. A special entry for error() is provided, which allows the proper "bug" address to be displayed, rather than the return address of error() itself. Bugs C Compiler & Library Page 5-42 concat Concatenate strings 5.34 Concatenate strings ___________ _______ ********** * concat * ********** File name: concat.mac Usage char * concat(out, in0, in1, ..., inN, 0); char *out; char *in0, in1, ... inN; Description Concat concatenates the argument strings. It returns a pointer to the first byte of out. Bugs C Compiler & Library Page 5-43 copy Copy a given number of bytes 5.35 Copy a given number of bytes ____ _ _____ ______ __ _____ ******** * copy * ******** File name: copy.mac Usage char * copy(out, in, nbytes) char *out; char *in; int nbytes; Description Copy the indicated number of bytes from the input area to the output area. Return a pointer to the first free byte in the output area. Bugs C Compiler & Library Page 5-44 cpystr String copy 5.36 String copy ______ ____ ********** * cpystr * ********** File name: cpystr.mac Usage char * cpystr(out, in); char *out; char *in; Description Copy "in" to "out". Return a pointer to the end of out. This allows the following usage: char *ptr; char buffer[BUFSIZ]; extern char *cpystr(); ptr = cpystr(buffer, text); ptr = cpystr(ptr, more_text); The above sequence appends more_text to the copy of text already moved into the buffer. Bugs C Compiler & Library Page 5-45 csv$ C register save and restore 5.37 C register save and restore _ ________ ____ ___ _______ ******** * csv$ * ******** File name: csv.mac Usage jsr r5,csv$ ... jmp cret$ Description C program Run-time Environment Each C subroutine starts with a call to CSV$ and exits by jumping to CRET$. Upon exit, the stack need not be equal to its value on entrance. During the execution of all C subroutines, register R5 points to the current "environment." Within a subroutine, it appears as follows: _______________ | | SP -> | 1st loc. var. | -10(R5) C$AUTO-2(R5) |_______________| | | | Saved R2 | -6(R5) |_______________| | | | Saved R3 | -4(R5) |_______________| | | | Saved R4 | -2(R5) |_______________| | | R5 -> | Saved R5 | |_______________| | | | Return add. | +2(R5) |_______________| | | C Compiler & Library Page 5-46 csv$ C register save and restore | First arg. | +4(R5) C$PMTR+0(R5) |_______________| | | | Second arg. | +6(R5) C$PMTR+2(R5) |_______________| Within a subroutine, Registers R0-R4 and the top of the stack, (sp) are available for use. Registers R0 and R1 are not preserved by subroutines and may be used to pass a return value. R5 must not be modified by a subroutine. All variable addressing must be done by offsets to R5. Subroutine arguments must be accessed by reference to C$PMTR. Subroutine local variables must be accessed by reference to C$AUTO. This permits modification of calling sequences without rewriting all subroutines. CSV$ refers to global symbol $$main to call the run-time startup program from the (RSX) library. Bugs C Compiler & Library Page 5-47 ctime Convert Time Buffer to Ascii 5.38 Convert Time Buffer to Ascii _______ ____ ______ __ _____ ********* * ctime * ********* File name: ctime.mac Usage char * ctime(buffer); struct TIME { int year; /* G.TIYR year - 1900 */ int month; /* G.TIMO Jan. = 1 */ int day; /* G.TIDA */ int hour; /* G.TIHR 00 .. 23 */ int minute; /* G.TIMI 00 .. 59 */ int second; /* G.TISC 00 .. 59 */ int tick; /* G.TICT 00 .. tsec-1 */ int tsec; /* G.TICP tick/second */ } buffer; dayofweek(buffer); struct TIME buffer; Description Ctime() converts the time information in buffer such as returned by rtime() to a character string in the format: Sun Sep 16 01:03:52 1973\0\0 All the fields have constant width. Note that there are two trailing 's for the benefit of programs converted from Unix (where the year is followed by a ). Ctime(0) returns the current time of day, calling rtime() internally. The format of the returned information is identical to the Unix function of the same name except that the Unix function has a trailing newline which is omitted here. dayofweek() returns the day of the week (Sunday = 0) for C Compiler & Library Page 5-48 ctime Convert Time Buffer to Ascii the date information in the argument buffer. Bugs There is no range checking on the information passed. C Compiler & Library Page 5-49 div$li Long division and modulus 5.39 Long division and modulus ____ ________ ___ _______ ********** * div$li * ********** File name: divl.mac Usage div$li(long, integer) div$l(long, long) mod$li(long, integer) mod$l(long, long) Description Division with long result. Called by the compiler when the appropriate code sequences are encountered. Bugs Warning -- an internal version of cret$ is present. Change one, change both. C Compiler & Library Page 5-50 envsave Multi-level function return 5.40 Multi-level function return ___________ ________ ______ *********** * envsave * *********** File name: envset.mac Usage int * envsave(); envreset( fp, hval, lval ) int *frame; /* Frame pointer */ int hval; /* High-order return */ int lval; /* Low-order return */ Description These functions permit a multi-level return from a C function to one of its dynamic ancestors in the stack. Envsave() returns the address of the frame of its caller. Later calls to envreset() with this pointer as an argument will create the illusion that the last function invoked by the caller of envsave() returned directly with a value equal to the parameter(s) to envreset(). Envreset() simulates a return to the function whose frame pointer matches frame (the result of a previous call to envsave()). Envreset() may be made to look as if it is returning a one or two word value. If only a single integer value is passed in addition to envreset(), it looks as if a 1-word value was returned. If two integers (or equivalently, a long) are specified, it looks like a long is returned. Thus any 1 or 2 word value may be returned because of the lax type checking in C. It is catastrophic to attempt to return to a function which has itself already returned!!! The following illustrates use of envsave() and envreset(): C Compiler & Library Page 5-51 envsave Multi-level function return int *save_frame; process() { ... save_frame = envsave(); if (subprocess()) { /* * Success */ } else { /* * Failure */ } } subprocess() { /* * Abort on error */ if (...) envreset(save_frame, 0) /* * Success */ return(1); } When subprocess() detects an error, it calls envreset() to return to the caller of process(), passing a "failure" flag. Bugs If the caller of envsave() has already returned, disaster will result. C Compiler & Library Page 5-52 error Error exit from C programs 5.41 Error exit from C programs _____ ____ ____ _ ________ ********* * error * ********* File name: error.mac Usage error(format, arglist); /* Fatal error exit */ Description An error message is written to stderr and the program exits. If profiling was enabled, a subroutine call trace will be written to stderr. The "exit status" will be set to "error". Diagnostics Bugs C Compiler & Library Page 5-53 exit Exit from C programs 5.42 Exit from C programs ____ ____ _ ________ ******** * exit * ******** File name: exit.mac Usage exit(); /* Exit, no return */ exits(status); /* Exit with status */ extern int $$exst; /* Exit status value */ Internal jmp $$exit ;Call exit routine jmp $$fail ;Exit without profile/wrapup Description On exit, the following sequence occurs: 1. The user-supplied wrapup() function is called. 2. Profiles (if requested) are printed. 3. All files are closed. 4. The program exits to the operating system. By calling exits() with an appropriate value, the program can pass an exit status code to the operating system monitor. The RT11 and RSX11 monitors define exit status codes differently; the value passed to exits() is not checked for consistancy. RT11 RSX Meaning 1. 1. Success -- no message is printed 2. 0. Warning 4. 2. Error 8. 4. Severe error Calling exit() is equivalent to calling exits(1). Note that the program may also set a value into $$exst and exit via exit(): C Compiler & Library Page 5-54 exit Exit from C programs extern int $$exst; ... $$exst = 4; exit(); Diagnostics Bugs C Compiler & Library Page 5-55 fclose Close a currently-open file 5.43 Close a currently-open file _____ _ ______________ ____ ********** * fclose * ********** File name: fclose.mac Usage fclose(iop); FILE *iop; Internal mov #iov,r4 ;r4 -> i/o vector mov ,r0 ;r0 == 0 to free i/o vector call $$clos ;close file. mov #iov,r4 ;r4 -> i/o vector mov ,r0 ;r0 == 0 to free i/o vector call $$fcls ;Free buffer space mov #iov,r4 ;r4 -> i/o vector call $$cflu ;Flush buffers for close Description Close the file. Returns 0 if ok, -1 if an error. The error code is saved in $$ferr. Note that stderr is never closed. On RT11-mode, the last block of a disk file which was open for output is filled with nulls. Internal $$cflu is called to write the last record. $$clos is called internally to close a file. $$fcls is called internally to free buffer space. After the file has been closed, record buffers (RSX-mode) and the file-name buffer (RT11-mode) will be freed. C Compiler & Library Page 5-56 fclose Close a currently-open file If r0 is zero on entry, the iov and any wild-card buffer will also be freed. This flag is set non-zero by freopen() or fnext() to close a file without freeing the iov. Bugs C Compiler & Library Page 5-57 feof Test for end of file 5.44 Test for end of file ____ ___ ___ __ ____ ******** * feof * ******** File name: feof.mac Usage feof(iop); FILE *iop; Description Return 1 if end of file on iop, else zero. Bugs C Compiler & Library Page 5-58 ferr Test for file error 5.45 Test for file error ____ ___ ____ _____ ******** * ferr * ******** File name: ferr.mac Usage ferr(iop); FILE *iop; Description Return 1 if an error has been seen on the indicated file. Bugs C Compiler & Library Page 5-59 fflush Flush output buffers 5.46 Flush output buffers _____ ______ _______ ********** * fflush * ********** File name: fflush.mac Usage fflush(iop); FILE *iop; Internal mov #iov,r4 ;r4 -> i/o vector call $$flsh ;Internal flush routine Return, all registers preserved. mov #bufadr,r0 ;r0 -> buffer start mov nbytes,r1 ;r1 := number of bytes mov #iov,r4 ;r4 -> i/o vector call $$put ;Internal put buffer routine Return, all registers preserved. Description Flush output buffers. This routine actually does I/O. $$ferr is set if anything unexpected happens. Internal $$flsh is called by other file I/O routines to flush the buffer. $$put is called by RSX-mode routines to write a record. $$put only runs under the RSX library. Using it in RT11-mode will cause the job to abort with a BPT trap. Bugs C Compiler & Library Page 5-60 fget Get a record 5.47 Get a record ___ _ ______ ******** * fget * ******** File name: fget.mac Usage fget(buffer, maxbytes, iop); char *buffer; int maxbytes; FILE *iop; Description Read a record from the indicated file. Maxbytes is the maximum record size. On RSX, the file must have been opened using the "u" (user buffer) flag. On RT11, the file must have been written by fput(). The actual number of bytes read is returned. Use feof() to test for end of file. Internal On RT11, when the record is written by fput(), it is preceeded by a two-byte byte count. Bugs C Compiler & Library Page 5-61 fgets Read a line from a file 5.48 Read a line from a file ____ _ ____ ____ _ ____ ********* * fgets * ********* File name: fgets.mac Usage char * fgets(buffer, maxbytes, iop); char *buffer; int maxbytes; FILE *iop; char * fgetss(buffer, maxbytes, iop); char *buffer; int maxbytes; FILE *iop; Description Fgets() reads a string into the buffer from the indicated file. Maxbytes is the maximum number of bytes to read. The string is terminated by a newline character, which is followed by a null. Fgets() normally returns buffer. It returns NULL on end of file or error. Fgetss() is identical to fgets() except that the terminating newline is removed. (This is compatible with gets(), but is not compatible with the Unix standard library.) Bugs Note that fgets keeps the newline, while fgetss() and gets() delete it. To delete the newline after executing fgets(), execute the following: buffer[strlen(buffer) - 1] = 0; C Compiler & Library Page 5-62 flun Get logical unit number 5.49 Get logical unit number ___ _______ ____ ______ ******** * flun * ******** File name: flun.mac Usage flun(iop) FILE *iop; Description Return the logical unit number associated with the file. (On RT11, the channel number is returned.) Bugs C Compiler & Library Page 5-63 fmkdl Mark File for Deletion 5.50 Mark File for Deletion ____ ____ ___ ________ ********* * fmkdl * ********* File name: fmkdl.mac Usage fmkdl(iop); FILE *iop; Description fmkdl() closes and deletes the specified file. Returns 0 on success, -1 on error. Bugs On RT11, the job is aborted with an error message if the file wouldn't parse. $$ferr is set to "file not found" if the program tries to delete something (like the line-printer) that it shouldn't. Note that RT11 does not flush the last buffer before deleting the file. C Compiler & Library Page 5-64 fopen C library file opener 5.51 C library file opener _ _______ ____ ______ ********* * fopen * ********* File name: fopen.mac Usage FILE * fopen(name, mode); char *name; /* File to open */ char *mode; /* Open modes */ FILE * freopen(name, mode, iop); char *name; /* File to open */ char *mode; /* Open modes */ FILE *iop; /* I/O pointer */ Internal mov iov,r4 ;r4 -> iov if any, else r4 := 0 call $$flun ;Get a Lun slot, initialize fdb ;return, r4 -> iov, r3 := lun ;r0, r1 random ;error: return to caller via $$fope ;Note: available RSX luns start at 2, ;while RT11 luns start at zero. mov iov,r4 ;r4 -> iov call $$fopt ;C$PMTR+2(r5) => options string ;return: option flags in fdb ;r0 random ;error: return to caller via $$fope mov iov,r4 ;r4 -> iov call $$fcsi ;C$PMTR+0(r5) => file name ;file name is parsed and fdb setup. ;r0-r3 random ;error: return to caller via $$fope mov size,r0 ;Memory needed call $$falo ;Allocate it ;return, r0 -> allocation C Compiler & Library Page 5-65 fopen C library file opener ;no room: return to caller via $$fope mov iov,r4 ;r4 -> iov mov lun,r3 ;r3 := lun jmp $$fopa ;RT11 file open (ascii file spec.) ;C$PMTR+0(r5) => ASCII file spec. ;Parse the file using .CSISPC, open it, ;returning to the caller via cret$ or ;$$fope if error. mov iov,r4 ;r4 -> iov mov lun,r3 ;r3 := lun mov dblk,r1 ;r1 -> Rad50 device descriptor jmp $$fopr ;open by rad50 device descriptor ;RT11 only -- used to open the device ;for directory processing. Exit via ;cret$$ or $$fope if error. mov iov,r4 ;r4 -> iov jmp $$fopn ;Open the file and return to the ;caller via $$fopx or $$fope if error. ;On RSX, fixup append mode if the file ;wasn't found. mov iov,r4 ;r4 -> iov call $$fopo ;Normal open, then exit via $$fopx ;On RSX, $$fopo returns if append open ;and "file not found" -- this is ok ;for fopen(), but bad news for fnext(). ;on return (RSX), r0 -> fcb ;Other errors exit via $$fope mov iov,r4 ;r4 -> iov, file is open jmp $$fopx ;Normal exit from fopen ;On RSX, $$fopx allocates the record ;buffer. mov iov,r4 ;r4 -> iov (or r4 == 0) mov code,r0 ;r0 := error code (to go to $$ferr) jmp $$fope ;Error exit from fopen ;$$fope deallocates buffers Description Fopen opens a new or existing file in the indicated mode: r Read the existing file sequentially w Create and write the file sequentially a Append to the file n Don't do newlines on each record. u RSX-mode: User does all buffering RT11-mode: use .ttyin and .ttyout C Compiler & Library Page 5-66 fopen C library file opener Either "r", "w", or "a" must be given. "n" and "u" are optional. "n" should be given for "binary" files. The "u" flag is treated quite differently for RSX and RT11 modes. On RSX, "u" means that the program does all I/O by calling fget() and/or fput(). Calling any other function (for example fprintf) is an error. On RSX, "n" or "u" mode files will be created with the "variable-length" attribute. On RSTS/RSX emulation, text files (neither "n" nor "u" specified) will be created with "stream" attribute. On RT11, if fopen decides that the file being opened is really the user's command terminal, single-character I/O will be performed (by calling .ttyin and .ttyout). Note that the "special-mode" bits must be set in the JSW by the program if it requires true single-character or immediate return input. Output to the terminal will be performed without buffering, which is useful for screen updating, but otherwise expensive. Fopen() returns NULL on errors -- $$ferr gets an error code. On RT11, this will be a RSTS/E compatible code (described in iov), while on RSX, this will be the FCS error code. On RT11, the file name pointed to by the 'io_name' field of the iov is either the file name string as passed to fopen() or an ascii string reconstructed from the 4-word Rad50 device block if the file was opened as part of a fwild/fnext sequence. By saving the ascii string, RSTS/E is able to re-parse logical device names and PPN's, which are not present on native RT11. Note that "no buffer space available" (IE.NBF or E$$NSP) and "invalid lun" (IE.ILU or E$$NOC) may be generated by fopen. On RT11, if the file cannot be opened because the user's program has already opened the channel, an E$$ILU error will be returned. The same file may not be used for both reading and writing except if the program writes a disk file, then repositions and reads it using ftell()/fseek(). In this case, the program should call rewind() or freopen() to reinitialize the file before using fseek(). Except in the one specific case of the RT11 console terminal open in "u" mode, an open file must not be used for reading and writing at the same time. Freopen() substitutes the named file in place of the C Compiler & Library Page 5-67 fopen C library file opener open file -- indicated by iop. The file currently open on iop is closed. Freopen returns iop. If the open failed, iop will be deallocated. Note that freopen loses any pending fwild/fnext status. Internal The following routines/globals are for use by fopen/fwild. If any of these routines detect an error, they return to the fopen() caller with an appropriate error code in $$ferr. $$fcsi Parse file name and setup fdb $$fopt Scan options word. $$flun Get free Lun slot $$falo Get memory for fopen $$fopa RT11 open with Ascii name $$fope Error exit from fopen $$fopn Normal open, hack append $$fopr RT11 open with Rad50 block $$fopx Normal exit from fopen $$csib Work block for the mighty csi $$dfnb Default file name block Bugs The RT11 file system does not support files greater than 65535 blocks long. RT11 does not get the actual keyboard name of the console terminal, although this isn't too hard to do on RT11/RSTS/E. Freopen() cannot be used to assign a file to stderr as there is code throughout the i/o package for special treatment of stderr. For example, it cannot be closed by a user-written program. The code is general, hence big. RSX users who typically overlay everything may find pleasure in breaking the code into many tiny modules. C Compiler & Library Page 5-68 fput Put a binary record 5.52 Put a binary record ___ _ ______ ______ ******** * fput * ******** File name: fput.mac Usage fput(buffer, nbytes, iop); char *buffer; int nbytes; FILE *iop; Description The specified record is written to the file. The file probably should have been opened with 'n' so newlines aren't stuffed here and there. On RT11, the file is only readable by fget. Nbytes is always returned. A call to ferr() after calling fput() is advised. Bugs C Compiler & Library Page 5-69 frec Return True if record-oriented file 5.53 Return True if record-oriented file ______ ____ __ _______________ ____ ******** * frec * ******** File name: frec.mac Usage frec(iop); FILE *iop; Description Return 1 if the file is record-oriented. Note: in this context, record-oriented files are not file-structured disks, nor are they the user's console terminal. Other terminals, along with devices such as line-printers, qualify, however. Bugs C Compiler & Library Page 5-70 fseek File pointer reposition (seek) 5.54 File pointer reposition (seek) ____ _______ __________ ______ ********* * fseek * ********* File name: fseek.mac Usage fseek(iop, offset, param); FILE *iop; /* What device to seek */ long offset; /* New read position */ int param; /* Zero for abs. seek */ Description fseek() moves the i/o read pointer to the indicated position. The position must have been returned by ftell(). Param must be zero. The file/device must be seekable. fseek() returns zero if correct, EOF if an error occurs. If no error occurred, error and eof flags are reset. flseek() is an alternate entry with identical parameters and actions. Bugs C Compiler & Library Page 5-71 fspool Spool to Default Queue 5.55 Spool to Default Queue _____ __ _______ _____ ********** * fspool * ********** File name: fspool.mac Usage fspool(fp); FILE *fp; /* Open file IOV */ Description This routine is called in lieu of fclose() when it is desired to spool the file to the system line printer. There is no control over the disposition or printout parameters. Fspool() returns zero if the file was spooled, it returns an error code if spooling could not be initiated. If called on native RT11, the file will be closed and an "illegal device error" (E$$NOD = 6) will be returned. If the program needs access to the power of the queue manager print spooler on native RSX, the RSX extensions library spwn() routine should be used to spawn a command line to MCR after closing the file as usual. If the program needs access to the power of the queue manager on RSTS/E, it should close the file and use the routines in the RSTS/E extensions library to execute the UU.SPL system function call. On RSTS/E V7.0, the file is spooled to any line printer (RSX mode) or to LP0: in RT11 mode. The particular line printer cannot be selected without modifying the source of fspool(). If the file was opened by calling fwild()/fnext(), internal buffers will not be freed, allowing the program to call fnext() for subsequent files. Bugs C Compiler & Library Page 5-72 fspool Spool to Default Queue On RSTS/E RT11 mode, error codes will follow the description of the spooling system function call. C Compiler & Library Page 5-73 ftell Tell file position 5.56 Tell file position ____ ____ ________ ********* * ftell * ********* File name: ftell.mac Usage long ftell(iop); FILE *iop; /* What device to seek */ Description ftell() returns the position of the read/write pointer of the indicated file. This value may be fed back to the file system by calling fseek(). Note that the value is a pointer to the record, not a block or byte pointer. On RSX, the program shouls flush the current record before calling ftell(). (Flush() is a noop on RT11.) If reading lines of text, the correct sequence is: position = ftell(fd); if (fgets(buffer, sizeof buffer, fd) != EOF) { /* * 'position' locates the record * read by the call to fgets() */ } Bugs On RSX, the value returned is the position of the file pointer as a byte offset from the start of the file. However, on RT11, the block/byte pointers (each one word) are returned in the two word result. Returning a byte offset might be more useful, as it allows all of fseek() to be implemented. C Compiler & Library Page 5-74 ftty Return True if terminal file 5.57 Return True if terminal file ______ ____ __ ________ ____ ******** * ftty * ******** File name: ftty.mac Usage ftty(iop) FILE *iop; Description Return 1 if the file is a terminal-type device. In general, this means the user's command terminal. Bugs C Compiler & Library Page 5-75 fwild Wild-card file opener 5.58 Wild-card file opener _________ ____ ______ ********* * fwild * ********* File name: fwild.mac Usage FILE * fwild(name, mode); char *name; /* File to open */ char *mode; /* Open modes */ FILE * fnext(iop); FILE *iop; /* I/O pointer */ Description Fwild() opens a new or existing file (whose file name may contain "wild-cards"). Open modes are identical to those given in fopen(). On return, the file name has been parsed, but no file has yet been opened. A NULL return means that the file name did not parse correctly. Fnext() opens the first or next file which was defined by a previous call to fwild(). If fnext() returns NULL, there are no (more) files that match the wild-card specification. fwild/fnext handle RSX file version numbers correctly on VMS compatibility mode (which uses the ODS2 disk structure). Fwild/fnext do not handle version numbers correctly on native RSX systems which use the FILES-11 (ODS1) disk structure. For example, a program can request "foo.*;3", "foo.*;*", "foo.*;0", and "foo.*;-1". Omitting a version number "foo.*" is equivalent to "foo.*;0". Note that version number 0 means the "newest" file, while version number -1 means the oldest. (Version numbers are not used on RT11 or RSTS/E.) For native RSX systems (using the FILES-11 disk structure), an explicit version number and the wildcard version number work correctly. Version numbers 0 and -1 C Compiler & Library Page 5-76 fwild Wild-card file opener work only if the directory has been reorganized by using the SRD utility program. If the directory has not been reorganized (such that the youngest version appears first in the directory), fnext() will yield unpredictable results. On RT-11, the wildcard filename match is handled internally to fwild/fnext. The parser will handle several forms of wild file specs, including imbedded '*' and the single character wildcard '%', and acts the same as the DIRECTORY wildcard handler. For convenience, a '?' acts the same as a '%' in a match string. Note: if a program executes fclose(), all file name information will be lost. The following sequence illustrates proper use of fwild()/fnext(): if (gets(name_buff) == NULL) exit(); if ((fd = fwild(name_buff, "r")) == NULL) error("Can't open %s\n", name_buff); for (count = 0; fnext(fd) != NULL; count++) { /* * Process each file */ while (fgets(buffer, sizeof buffer, fd) != NULL) { /* * Process each record */ } } /* * fnext() fails; the channel is closed. * count has the number of files processed. */ if (count == 0) error("No matching files found"); The following summarizes the types of wild-card processing available on the various implementations of the C support library: Environment Supports Native RSX "*" matches any filename, filetype, or version number. Version ;0 and ;-1 are supported on ODS2 systems. UIC's may not contain wildcards. RSX/VMS As above, note that version ;-1 means the "earliest" version. Note warning below. Directory identifiers may not be C Compiler & Library Page 5-77 fwild Wild-card file opener wildcarded. VMS systems support ODS2. RSX/RSTS Uses RSTS/E wildcard conventions: "*" replaces filename or filetype. "?" matches any character. PPN's may not be wildcarded. Version numbers are not supported on RSTS/E. Native RT11 "*" replaces any string, "%" or "?" match any non-blank character. RT11/RSTS Uses RSTS/E wildcard conventions noted above. Bugs On native RSX systems using ODS1 (FILES-11) disk structures, version numbers will be processed properly only if directories have been sorted (by using the SRD utility program, for example). If directories are not sorted, and fwild() is invoked with version number ;0 or ;-1, it will yield unpredictable results. The command language scan (CSI1$) on VMS compatibility mode does not parse version number -1 (because it has a different meaning on native VMS) and fwild() will consequently fail. If you want the oldest version, fwild() should be invoked with a file name of the type "foo.*" or "foo.*;0" and, before calling fnext() for the first time, you should set the correct bits in the IOV flag word as follows: if ((fd = fwild(file, "r")) == NULL) error("can't open file %s", file); if ((fd->io_flag & IO_VER) != 0 && version_minus_1_wanted) fd->io_flag |= IO_VM1; Flag bit IO_VER signals "version 0 or -1", while bit IO_VM1 signals version minus 1. Again, note that this must be done before the first call to fnext(). On native RT11 and all RSTS/E modes, fwild/fnext will fail if the device is not directory structured (even if no wildcard file is specified). If this is a problem, you should write: if ((fd = fwild(filename, mode)) != NULL) iswild = 1; else if ((fd = fopen(filename, mode) != NULL) iswild = 0; C Compiler & Library Page 5-78 fwild Wild-card file opener else error("cannot open the file"); The program must then test iswild to determine if it must call fnext() or if processing should be initiated directly. On all RSTS/E modes, there may be problems with logical name translation as file name strings must be parsed more than once. Thus, if a programer defines a logical name which is identical to a valid physical device name, a wildcard lookup may access the wrong unit. This problem is described in the RSTS/E documentation. Fwild/fnext was designed to work only with disk devices. It will not necessarily work correctly with other directory-structured devices, such as magtape. Internal If you are always running on RSTS/E, or always running on RSX-11 (native or VMS compatibility mode) or always running on native RT11, you should consider editing fwild.mac to remove unnecessary code. This routine depends on some internal knowledge about RSTS/E and about the implementation of RSX-11 file control services on RSTS/E. It may need modification for subsequent releases of RSTS/E. The implementors do not apologize for the size of this module. The distribution of the C language system includes source code for the SRD (sort directories) utility program. C Compiler & Library Page 5-79 getchar Get characters 5.59 Get characters ___ __________ *********** * getchar * *********** File name: getcha.mac Usage getchar(); getc(iop); FILE *iop; Description Getchar() reads one character from the standard input file. getc() reads one character from the indicated input file. Both return EOF on error or end of file. To continue reading after EOF, the program may execute: iop->io_flag &= ~(IO_ERR | IO_EOF); Bugs The "continue after EOF" sequence works on RT11/RSTS when reading from the terminal. It does not work on VMS compatibility mode (subsequent reads continue to give EOF). It has not been tested on other modes. C Compiler & Library Page 5-80 gets Read a line from stdin 5.60 Read a line from stdin ____ _ ____ ____ _____ ******** * gets * ******** File name: gets.mac Usage char * gets(buffer); char *buffer; Description gets() reads a string into the buffer from the standard input (stdin). The string is terminated by a newline character, which is replaced in the buffer by a null. Gets() returns buffer or NULL on end of file or error. Bugs C Compiler & Library Page 5-81 gettty Get control teletype name 5.61 Get control teletype name ___ _______ ________ ____ ********** * gettty * ********** File name: gettty.mac Usage gettty(buffer); char *buffer; Description Store the device name of the control teletype in buffer. Return 0 on success, -1 on error. Bugs On RT11 under RSTS/E, the actual keyboard number is not returned. (I dunno about "real" RT11). C Compiler & Library Page 5-82 getw Get a word 5.62 Get a word ___ _ ____ ******** * getw * ******** File name: getw.mac Usage getw(iop); FILE *iop; Description getw() reads one (16-bit) word from the indicated file. The program must call feof() or ferr() to test for end of file or error. Bugs C Compiler & Library Page 5-83 iov I/O vector definition 5.63 I/O vector definition ___ ______ __________ ******* * iov * ******* File name: iov.mac Usage RSX format: typedef struct iov { int io_flag; /* Control flags */ int io_uget; /* Unget char storage */ int io_bcnt; /* Buffer free count */ char *io_bptr; /* Buffer free pointer */ char *io_rbuf; /* Record buffer start */ int io_rbsz; /* Record buffer size */ char *io_bbuf; /* Block buffer start */ char *io_wild; /* Wildcard lookup buf */ int io_uic; /* Binary UIC */ int io_iosb[2]; /* I/O status block */ int io_fdb[0]; /* File data block */ } FILE; RT11 format: typedef struct iov { int io_flag; /* Control flags */ int io_uget; /* Unget char storage */ char *io_name; /* File name pointer */ char *io_wild; /* Wild card lookup buf */ int io_lun; /* RT11 channel number */ int io_bcnt; /* Buffer free count */ char *io_bptr; /* Buffer free pointer */ int io_bnbr; /* Disk block number */ char io_bbuf[512]; /* Data buffer */ } FILE; Bits in iov.io_flag: #define IO_OPN 0100000 /* Open file */ #define IO_REC 0040000 /* Record device */ #define IO_TTY 0020000 /* Console terminal */ #define IO_EOF 0010000 /* EOF seen */ #define IO_ERR 0004000 /* Error seen */ #define IO_FIL 0002000 /* Disk file */ #define IO_BAD 0001000 /* Buffer needs filling */ C Compiler & Library Page 5-84 iov I/O vector definition #define IO_NOS 0000400 /* No newlines needed */ #define IO_UBF 0000200 /* User does buffering */ #define IO_BZY 0000100 /* Buffer write needed */ #define IO_WF1 0000040 /* fwild "first time" */ #define IO_VER 0000020 /* fwild version hack */ #define IO_VM1 0000010 /* version ;-1 */ #define IO_WLD 0000004 /* file is wild */ #define IO_MOD 0000003 /* Open mode mask */ /* read = 0 */ /* write = 1 */ /* append = 2 */ /* Non-zero = output */ #define IO_EOR (IO_ERR | IO_EOF) extern int $$ferr; /* Error word */ extern FILE *stdin; /* Standard input file */ extern FILE *stdout; /* Standard output file */ extern FILE *stderr; /* User's command tty */ Internal extern FILE *$$luns[]; /* IOV pointer table */ extern FILE *$$lune; /* IOV table end */ extern (int)(char *$$lmax); /* RSX $$luns dim. */ extern char **$$ifil; /* -> stdin file name */ extern char **$$ofil; /* -> stdout file name */ extern int $$nlun; /* RSX: Number of luns */ FILE *$$eiov; /* RSX: Stderr iov */ Description Define the I/O vector structure used for communication by all I/O routines in the C library. Note that it is slightly different for RSX and RT11 modes. Note also that certain bits in IO_FLAG are only meaningful for one flavor of I/O. The RSX-mode IOV contains an entire file data block (FDB). Also, 'io_uic' contains the binary UIC of the directory via which the file is being accessed, not the 'owner' UIC. It is this UIC which is given when iovtoa() is called. The RT11-mode IOV contains only enough information to read and write files plus a pointer to an Ascii string with the file name argument to fopen(). The file name is needed for iovtoa() and to allow deleting files given the IOV pointer. The following files are defined here: stdin The standard input file. C Compiler & Library Page 5-85 iov I/O vector definition stdout The standard output file. stderr The error output file. Note: on RSX systems, stderr is opened on LUN 1. $$ferr (error word) is also defined here. This is set non-zero if an error occurred when performing I/O. On RSX, the standard I/O error code is returned. On RT11, an error code compatible with RSTS/E usage is returned: Global Value Meaning E$$ILF 02. 002 Illegal file name E$$NOR 04. 004 No room for user on device E$$FNF 05. 005 Can't find file or account E$$NOD 06. 006 Not a valid device E$$ILU 07. 007 I/O channel in use E$$NOO 09. 011 I/O channel not open E$$EOF 11. 013 End of file on device E$$FAT 12. 014 Fatal system I/O failure E$$ERR 13. 015 User data error on device E$$FND 16. 020 File already found (protected) E$$NOC 17. 021 Too many open files on unit. E$$NSP 32. 040 No memory space for buffer Error 12 is set only if an "impossible" error occurs. While this may indicate a bug in the RT11 library, it is more likely to be a user programming error (like passing garbage to an I/O routine). Error 7 is set if fopen tries to open a channel that is already in use. Internal In RSX, buffering is done by the RSX file-management services (FCS). The block buffer pointer is unused (but reserved for anybody who cares to add random access). In RT11, buffers are managed by the C support package, functions $$putc, $$flsh, $$getc, and $$get. In these packages, the buffer control words are used as follows: If IO_BPTR equals zero, the buffer is unused. IO_BCNT will also equal zero and the get block ($$get) routine will be called to fill the first buffer, setting up all other pointers/counters. In all other cases, the following pertains: IO_BCNT Contains the number of bytes that can be inserted into the buffer before it must be written onto the disk file. IO_BPTR Contains the address of the first free C Compiler & Library Page 5-86 iov I/O vector definition location in the buffer. IO_BNBR When writing, this contains the number of the block to write when this block fills. When reading, it contains the number of the next block, which is read when this block empties. Bugs C Compiler & Library Page 5-87 iovtoa Convert file name to ascii 5.64 Convert file name to ascii _______ ____ ____ __ _____ ********** * iovtoa * ********** File name: iovtoa.mac Usage char * iovtoa(iop, buffer); FILE *iop; char *buffer; Description Convert the file name to Ascii and put it in the buffer. On RSX, the file name and file type are decompiled from the internal format. On RT11, the text that the user passed to fopen() is copied to the buffer. iovtoa() returns a pointer to the null trailing the buffer. Bugs C Compiler & Library Page 5-88 isalpha Return TRUE if alphabetic argument 5.65 Return TRUE if alphabetic argument ______ ____ __ __________ ________ *********** * isalpha * *********** File name: isalph.mac Usage isalpha(c); int c; Description Return 1 if c is an alphabetic character, 0 otherwise. Bugs C Compiler & Library Page 5-89 isdigit Return TRUE if digit argument 5.66 Return TRUE if digit argument ______ ____ __ _____ ________ *********** * isdigit * *********** File name: isdigi.mac Usage isdigit(c); int c; Description Return 1 if c is an Ascii digit, 0 otherwise. Bugs C Compiler & Library Page 5-90 islower Return TRUE if lower-case alphabetic argument 5.67 Return TRUE if lower-case alphabetic argument ______ ____ __ __________ __________ ________ *********** * islower * *********** File name: islowe.mac Usage islower(c); int c; Description Return 1 if c is a lower-case alphabetic character, 0 otherwise. Bugs C Compiler & Library Page 5-91 isupper Return TRUE if Upper-case alphabetic argument 5.68 Return TRUE if Upper-case alphabetic argument ______ ____ __ __________ __________ ________ *********** * isupper * *********** File name: isuppe.mac Usage isupper(c); int c; Description Return 1 if c is an Upper-case alphabetic character, 0 otherwise. Bugs C Compiler & Library Page 5-92 itoa Integer to Ascii 5.69 Integer to Ascii _______ __ _____ ******** * itoa * ******** File name: itoa.mac Usage char * itoa(value, string); int value; char *string; Description itoa converts the value to a (signed) decimal string. The string is null-trailed. itoa returns a pointer to the trailing null. Note that the result can be computed (more flexibly) by executing sprintf(buffer, "%d", value); Bugs C Compiler & Library Page 5-93 itoa8 Convert integer to octal Ascii 5.70 Convert integer to octal Ascii _______ _______ __ _____ _____ ********* * itoa8 * ********* File name: itoa8.mac Usage char * itoa8(value, buffer); int value; char *buffer; Description: The value is converted to octal and stored in the buffer. A pointer to the trailing null is returned. Note that the result can be computed (more flexibly) by executing sprintf(buffer, "%o", value); Bugs: This routine does not generate leading zeros. If they are needed, use: sprintf(buffer, "%06o", value); C Compiler & Library Page 5-94 itoax Convert an integer to hexidecimal Ascii 5.71 Convert an integer to hexidecimal Ascii _______ __ _______ __ ___________ _____ ********* * itoax * ********* File name: itoax.mac Usage char * itoax(value, buffer); int value; char *buffer; Description: Convert the integer to hexidecimal ascii. The string is null-trailed. Values from 10 to 15 (decimal) are represented by "A" to "F". Itoax() returns a pointer to the trailing null. Note that the result can be computed (more flexibly) by executing sprintf(buffer, "%x", value); Bugs: C Compiler & Library Page 5-95 malloc Allocate and free memory 5.72 Allocate and free memory ________ ___ ____ ______ ********** * malloc * ********** File name: malloc.mac Usage char * malloc(size); /* NULL if no space */ unsigned size; /* Number of bytes */ mfree(p); free(p); char *p; /* Was allocated */ Internal mov size,r0 ; Internal call call $$aloc ; to malloc() Return: r0 -> space (or 0), other registers preserved mov pointer,r0 ; Internal call call $$free ; to free() Return: r0 random, other registers preserved $$link(); /* Print memory list */ Return: all registers preserved Description malloc() allocates the indicated number of bytes, returning a pointer to the first. If the allocation request cannot be satisfied, malloc returns NULL. The program image is expanded as needed. free() and mfree() return a buffer to free space. Nothing is returned. See also the description of realloc() and sbreak(). C Compiler & Library Page 5-96 malloc Allocate and free memory Internal All free memory is allocated in linked lists which are stored in monotonically linked, noncontiguous areas. Each block has is preceeded by a one word header: pointer to next block + "busy bit" The pointer is to the next following block. The last block points to the first. The "busy bit" will be set if the data in the block is in use. Note that a block need not contain any data. Free space is coalesced during the allocation search. Subroutine $$link() writes the allocation list onto stderr. It was written to debug malloc() and is conditionally compiled. Note that it preserves all registers. Diagnostics The program may abort if free() is passed a random pointer or if the program writes outside of an area reserved by malloc(). Note that only certain cases are trapped by this test. Bugs C Compiler & Library Page 5-97 memdmp Dump memory and registers 5.73 Dump memory and registers ____ ______ ___ _________ ********** * memdmp * ********** File name: memdmp.mac Usage memdmp(start, end); /* Memory dump routine */ char *start; /* First to dump */ char *end; /* Last to dump */ regdmp(); /* Register dump */ Internal call regdmp ;Register dump mov #end,-(sp) ;Last address (or first) mov #start,-(sp) ;First address (or last) call memdmp ;Dump memory mov #start,r0 ;First address (or first) mov #end,r1 ;Last address (or last) call $$dump ;Dump memory mov value,r0 ;What to convert mov #buffer,r1 ;Where it goes call $$toct ;Convert it Return: r0 unchanged r1 -> first free byte in buffer r2-r5 unchanged Description Dump registers and/or memory. All registers are preserved. If memdmp is called with a zero argument, the stack will be dumped. Note that this routine does not use the C I/O library. C Compiler & Library Page 5-98 memdmp Dump memory and registers Bugs Condition codes are not preserved. On RSX, these routines require that the terminal has been assigned as logical unit number 1. C Compiler & Library Page 5-99 msg Print a message on the console 5.74 Print a message on the console _____ _ _______ __ ___ _______ ******* * msg * ******* File name: msg.mac Usage msg(text) char *text; Internal mov #text,r0 call $$msg Description Print a message on the console terminal. This routine does not use the standard library. Return: all registers are preserved. Bugs On RSX, this routine requires the command terminal having been assigned as logical unit number 1. C Compiler & Library Page 5-100 mul$l Multiply long * long 5.75 Multiply long * long ________ ____ _ ____ ********* * mul$l * ********* File name: mull.mac Usage long mul$l(a, b); /* long = long * long */ long a; long b; long mul$li(a, b); /* Long = long * int */ long a; int b; Description Multiply the long arguments. This routine is called by the C compiler to compile long multiplies. Bugs C Compiler & Library Page 5-101 peek Peek at a location in RSTS/E 5.76 Peek at a location in RSTS/E ____ __ _ ________ __ ______ ******** * peek * ******** File name: peek.mac Usage peek(location) int *location; Description Peek to a location in the RSTS/E monitor. The job will be aborted with a BPT if not running under RSTS/E. Bugs C Compiler & Library Page 5-102 printf Formatted print routine 5.77 Formatted print routine _________ _____ _______ ********** * printf * ********** File name: printf.mac Usage printf(format, arg1, ...); char *format; fprintf(iov, format, arg1, ...); FILE *iov; char *format; sprintf(buffer, format, arg1, ...); char *buffer; char *format; Description printf() converts, formats, and prints its arguments, under control of the first argument, writing output via putchar(). fprintf() writes its output to the indicated file. sprintf() writes its output to the indicated string buffer. The first argument is a character string which contains two types of objects: plain characters, which are simply copied to the output stream, and conversion specifications, each of which causes conversion and printing of the next successive argument to printf. Each conversion specification is introduced by the character %. Following the %, there may be - an optional minus sign "-" which specifies left adjustment of the converted argument in the indicated field. - an optional digit string specifying field width; if the converted argument has fewer characters than the field width, it will be blank-padded on the left (or right, if the left-adjustment indicator has been C Compiler & Library Page 5-103 printf Formatted print routine given) to make up the field width. If the field width is given as '?', the next argument is used. - an optional period "." which serves to separate the field width from the next digit string; - an optional digit string (precision) which specifies the number of digits to appear after the decimal point for e- and f-conversion, or the maximum number of characters to be printed from a string. If the precision is given as '?', the next argument is used. - a character which indicates the type of conversion to be applied. The conversion characters and their meanings are d Signed-decimal u Unsigned-decimal o Octal X Hexadecimal, 10-15 are represented by A-F x Hexadecimal, 10-15 are represented by a-f The integer argument is converted to decimal, octal, or hexadecimal notation respectively. Any of the conversion characters may be preceeded by 'l' to signal "long" integer argument. Note that the Unix usage of capital letters to represent long arguments is not supported. f The argument is converted to decimal notation in the style "[-]ddd.dd" where the number of d's after the decimal point equals the precision specification for the argument. If precision is missing, 6 digits are given; if explicitly 0, no digits and no decimal point are printed. The argument should be float or double. e The float or double argument is converted in the style "[-]d.ddde+-dd" where there is one digit before the decimal point and the number after is equal to the precision specified for the argument; if the precision is missing, 6 digits are produced. g Floating point of some sort. c The argument character is printed. (Note that 'lc' takes a long integer argument.) r Remote format. The next printf() argument is C Compiler & Library Page 5-104 printf Formatted print routine the format. Note that this is not a subroutine. The current format is not processed further. For example: bug(args) { error("Error at %r", &args); } This routine might be called as follows: bug("Error %d at %s\n", val, name); s The argument is taken to be a string (character pointer) and characters from the string are printed until a null character or until the number of characters indicated by the precision specification is reached; however if the precision specification is 0 or missing all characters up to null are printed. If no recognizable character appears after the %, that character is printed; thus % may be printed by the use of the string %%. In no case does a non-existant or small field width cause truncation of a field; padding takes place only if the specified field width exceeds the actual width. Characters generated by printf() are printed by calling putchar(). Bugs e, f, and g conversion haven't been written yet. C Compiler & Library Page 5-105 profile Print profile information 5.78 Print profile information _____ _______ ___________ *********** * profile * *********** File name: profil.mac Usage $$prof(); extern int $$prnl; extern char *$$pfil; Description $$prof is called on exit if functions have been compiled with the profile option. The profile is written to file "profil.out". This is defined by a global symbol $$pfil. By changing the value of $$prnl, the program can control the number of profile entries written on each line. The default value writes 4 entries per line. Changing $$prnl to N writes N entries on each line, simplifing post-processing (sorting) of the data. For example: $$prnl = 0; writes each entry on a separate line. The following example shows how to change the output file name: extern char *$$pfil; ... $$pfil = "ti:"; Data is written using the format string "%8s %6u". If more than one entry is written to a line, succeeding entries will be preceeded by one space. C Compiler & Library Page 5-106 profile Print profile information Note that, by writing the data one entry per line, the profile output may easily be sorted either by function name or by frequency count. Bugs C Compiler & Library Page 5-107 putc Put one character to a file 5.79 Put one character to a file ___ ___ _________ __ _ ____ ******** * putc * ******** File name: putcha.mac Usage putchar(c); char c; putc(c, iop); char c; FILE *iop; Description Putchar() writes one character to the standard output file. Putc() writes one character to the named output file. Normally, the character is returned. EOF is returned on errors. Bugs C Compiler & Library Page 5-108 putw Put a 16-bit word to a file 5.80 Put a 16-bit word to a file ___ _ ______ ____ __ _ ____ ******** * putw * ******** File name: putw.mac Usage putw(word, iop); int word; FILE *iop; Description putw() writes one word to the indicated file. It returns EOF on error, 0 on success Bugs C Compiler & Library Page 5-109 r50toa Convert Radix-50 to Ascii 5.81 Convert Radix-50 to Ascii _______ ________ __ _____ ********** * r50toa * ********** File name: r50toa.mac Usage r50toa(buff, r5vec, r5cnt); char *buff; /* Output text buffer */ int *r5vec; /* Input rad50 buffer */ int r5cnt; /* How many rad50 words */ Description: Convert r5cnt words of radix 50 data to Ascii. All letters will be in upper-case. The output buffer will not be null-trailed, nor will blank fields be supressed. Bugs C Compiler & Library Page 5-110 rand Random number generator 5.82 Random number generator ______ ______ _________ ******** * rand * ******** File name: rand.mac Usage rand(max) int max; extern long seed; /* Random number seed */ Description Generate a pseudorandom number. If max is zero, return a number in the range 0 .. 32767. If max is non-zero, return mod(number, max); The algorithm is: seed = (69069 * seed + 1); temp = (seed >> 8) & 32767; return ((max == 0) ? temp : temp % max); The algorithm is based on the mth$random function in the VMS common run-time library. As rand() returns a 16-bit integer, the middle of the generated random number is used. Note that the algorithm is prone to nonrandom sequences when considering the next pseudorandom number. Bugs C Compiler & Library Page 5-111 realloc Reallocate memory 5.83 Reallocate memory __________ ______ *********** * realloc * *********** File name: reallo.mac Usage char * realloc(buff, size); char *buff; /* Buffer from malloc() */ unsigned size; /* New size for buff */ Description Realloc() changes the size of the block pointed to by buff, returning a pointer to the (possibly moved) block. The contents will be unchanged up to the lesser of the new and old sizes. Realloc() also works if buff points to a block freed since the last call of malloc(), realloc(), or calloc(); thus sequences of free(), malloc(), and realloc() can exploit the search strategy of malloc() to do storage compaction. See also the description of malloc(), calloc() and sbreak(). Diagnostics The program will abort if buff is not the address of a buffer allocated by malloc() or calloc(). Bugs C Compiler & Library Page 5-112 rewind Rewind a file for re-reading 5.84 Rewind a file for re-reading ______ _ ____ ___ __________ ********** * rewind * ********** File name: rewind.mac Usage rewind(iop); FILE *iop; Description Rewind the indicated file. Return -1 if failure, 0 if ok. On RT11, if the file was opened for output, it is closed and reopened for input. Diagnostics RT11 exits fatally if the file name won't parse. As the filename was stored by fopen(), this probably means that the user program has stored randomly in memory. Bugs C Compiler & Library Page 5-113 rtime Convert Date and Time 5.85 Convert Date and Time _______ ____ ___ ____ ********* * rtime * ********* File name: rtime.mac Usage rtime(buffer); struct TIME { int year; /* G.TIYR year - 1900 */ int month; /* G.TIMO Jan. = 1 */ int day; /* G.TIDA */ int hour; /* G.TIHR 00 .. 23 */ int minute; /* G.TIMI 00 .. 59 */ int second; /* G.TISC 00 .. 59 */ int tick; /* G.TICT 00 .. tsec-1 */ int tsec; /* G.TICP tick/second */ } buffer; Description Stores the current time of day in the buffer. The format is compatible with the RSX11-M GTIM$ executive service. Bugs C Compiler & Library Page 5-114 sbreak Allocate memory from operating system 5.86 Allocate memory from operating system ________ ______ ____ _________ ______ ********** * sbreak * ********** File name: sbreak.mac Usage char * sbreak(amount); int amount; Description sbreak() allocates the indicated amount of memory from the operating system. The allocation is permanent. Diagnostics NULL is returned if the memory requested is not available. There is no "shortened" return. Bugs Internal Sbreak() does not modify its argument. C Compiler & Library Page 5-115 scanf Formatted input conversion 5.87 Formatted input conversion _________ _____ __________ ********* * scanf * ********* File name: scanf.mac Usage scanf(fmt, pointer(s)); char *fmt; /* Format string */ fscanf(fd, fmt, pointer(s)); FILE *fd; /* Input file pointer */ char *fmt; /* Format string */ sscanf(buf, fmt, pointer(s)); char *buf; /* Input text buffer */ char *fmt; /* Format string */ Description Using the format string, these functions parse the input file (or given text file), storing the results in the pointer arguments. The three routines differ as follows: scanf Reads from the standard input file. fscanf Reads from the indicated file. sscanf Reads from the text buffer. The format string may contain control characters to direct the conversion of the input textual data: ' ' Blanks, tabs, or newlines are ignored in format strings. To match whitespace, use "%[ \t\n]". x An ordinary character (not %) must match the next input character. % Conversion specifications consist of a '%', an optional '*' (to supress assignment), an optional maximum numeric field width, and a C Compiler & Library Page 5-116 scanf Formatted input conversion conversion specifier. Unless value assignment was supressed by the '*' format modifier, the next field is converted and stored in the variable pointed to by the corresponding argument. An input field is defined as a string of non-space characters, extending to the first inappropriate character or until the field width (if given) is exhausted. The following conversion characters are specified: % A single '%' is expected in the input, no assignment is done. d An integer of the specified class (decimal, o octal, or hexadecimal) is expected. The x corresponding argument should be an integer pointer. If the format specifer is given in upper-case, or preceeded by 'l', a long integer will be stored. For example, "%ld" is identical to "%D". Leading whitespace will be ignored. A null field is not converted. Scanf() returns a count of the number of fields converted, but does not indicate which fields were ignored. s A character string is expected. The input field will be terminated by a space, tab, or newline. The corresponding argument should point to a buffer large enough to contain the text and a terminating NULL. Leading whitespace will be ignored. c A single character is read. Leading white space is not supressed -- to read the next non-blank character, use "%1s". If a field width is given the corresponding argument is a pointer to a vector of characters and the indicated number of characters are read. e A floating-point number is converted and stored f appropriately. If the format indicator is capitalized, or preceeded by 'l', a double- precision floating-point number will be stored. The floating-point format is the same as in the C language: an optionally signed string of digits possibly containing a decimal point, followed by an optional exponent field which consists of an 'E' or 'e' followed by an optionally signed integer. [ ] A string not to be delimited by white-space characters. Unless the first character is '^', C Compiler & Library Page 5-117 scanf Formatted input conversion the format constitutes an acceptance list: the input field is all characters until the first character which is not in the set within brackets. Note that leading whitespace is not ignored. If the first character after the left bracket is '^', the format defines a stop list: the input field is all characters until the first character specified within the bracketed string. The corresponding argument points to a character vector. The result will be null-terminated. Scanf() returns the number of successfully matched and assigned input items. If the end of input was reached, EOF (-1) is returned. For example: main() { register int c; int i; char text[10]; c = scanf("%d%9s", &i, &text); printf("i = %d, text = %s\n", i, text); } If the input line is "150 foobar", the program will print: i = 150, text = foobar Diagnostics Scanf() returns -1 if an end of file (end of string) condition exists and no data was stored. It returns -2 if a palpably incorrect format, such as "%" is encountered. Bugs No floating point -- trying it will crash the program. C Compiler & Library Page 5-118 setcc Trap Control/C (RSTS/E RT11 mode only) 5.88 Trap Control/C (RSTS/E RT11 mode only) ____ _________ _______ ____ ____ _____ ********* * setcc * ********* File name: setcc.mac Usage setcc(function); extern int function(); Description The function is defined as a CTRL/C trap routine. Executing setcc(0) disables CTRL/C trapping. Note: If the routine is reentered (because CTRL/C was typed during the execution of function()), the program aborts. Bugs Runs on RSTS/E RT11 mode only. C Compiler & Library Page 5-119 sleep Delay job a given number of seconds 5.89 Delay job a given number of seconds _____ ___ _ _____ ______ __ _______ ********* * sleep * ********* File name: sleep.mac Usage sleep(delay); int delay; Description Sleep a specified number of seconds. Bugs C Compiler & Library Page 5-120 strcmp String comparison 5.90 String comparison ______ __________ ********** * strcmp * ********** File name: strcmp.mac Usage strcmp(a, b); char *a; char *b; Description Compare two strings, return -1 a < b 0 a == b +1 a > b Bugs C Compiler & Library Page 5-121 strcpy String copy 5.91 String copy ______ ____ ********** * strcpy * ********** File name: strcpy.mac Usage char * strcpy(out, in); char *out; char *in; Description Copy "in" to "out". Return out. Bugs It might be more useful if it returned out + strlen(in). (See cpystr()). C Compiler & Library Page 5-122 streq String equality 5.92 String equality ______ ________ ********* * streq * ********* File name: streq.mac Usage streq(a, b); char *a; char *b; Description Return TRUE if the strings are equal. Bugs C Compiler & Library Page 5-123 strlen String length 5.93 String length ______ ______ ********** * strlen * ********** File name: strlen.mac Usage strlen(s); char *s; Description Return the length of the argument string. Bugs C Compiler & Library Page 5-124 swabb Byte swap (argument is a buffer pointer) 5.94 Byte swap (argument is a buffer pointer) ____ ____ _________ __ _ ______ ________ ********* * swabb * ********* File name: swabb.mac Usage swabb(buffer); char *buffer; Description: Return buffer[0] and buffer[1] as a byte-swapped integer. Buffer need not be on any particular byte or word boundary. Bugs C Compiler & Library Page 5-125 swabi Byte swap, (argument is an integer) 5.95 Byte swap, (argument is an integer) ____ _____ _________ __ __ ________ ********* * swabi * ********* File name: swabi.mac Usage swabi(value); int value; Description Return value byte-swab'ed. Bugs C Compiler & Library Page 5-126 time Time of day 5.96 Time of day ____ __ ___ ******** * time * ******** File name: time.mac Usage long time(0); long time(tloc); long *tloc; Description time returns the time of day in seconds. If tloc is non-null, the return value is also stored in the place to which tloc points. See rtime() for a more flexible routine. Bugs The Unix time function returns the time since 00:00:00 GMT, Jan 1, 1970, measured in seconds. This function returns the time of day in seconds. C Compiler & Library Page 5-127 tolower Convert upper-case alphabetic to lower-case 5.97 Convert upper-case alphabetic to lower-case _______ __________ __________ __ __________ *********** * tolower * *********** File name: tolowe.mac Usage tolower(c); int c; Description If c is a upper-case alphabetic, return it's lower-case equivalent. Otherwise, return c. Bugs C Compiler & Library Page 5-128 toupper Convert lower-case alphabetic to upper-case 5.98 Convert lower-case alphabetic to upper-case _______ __________ __________ __ __________ *********** * toupper * *********** File name: touppe.mac Usage toupper(c); int c; Description If c is a lower-case alphabetic, return it's upper-case equivalent. Otherwise, return c. Bugs C Compiler & Library Page 5-129 trace Profile support entry module (with trace) 5.99 Profile support entry module (with trace) _______ _______ _____ ______ _____ ______ ********* * trace * ********* File name: pcsv.mac Usage #include extern FILE *$$flow; $$flow = fopen("trace.out", "w"); /* or $$flow = stderr; to trace to the console */ ... $$flow = NULL; /* Turn off flow trace */ Internal jsr r5,pcsv$ .word name ; Pointer to name Where name has the structure: name: .word 0 ; Counter .asciz /name/ ; function name Description This module is called whenever a function that was compiled with the profile option is executed. It checks that the stack will remain above 600 octal when the function executes and optionally prints a flow-trace. If $$flow is set to a file descriptor, the function name, location the function is called from, and the calling environment, are printed on each call to a function compiled with the profile option. The output format is: function_namecallerenvironment Where function_name is the name of the function being C Compiler & Library Page 5-130 trace Profile support entry module (with trace) called, caller is the address of the calling program (actually, the return address), and environment is the R5 argument pointer (for local addressing within the routine being called). The information will be written to $$flow with a newline before and after. If profiling has been enabled and the program exits via error() or via an operating-system trap (such as an illegal memory reference), a register dump and subroutine trace will be written to stderr. See the description of calltrace() for details. Internal See csv$ for details of the calling environment. When this routine is entered for the first time, it sets up to intercept synchronous system traps, and loads the error exit address and profile pointer. The trap service routines are in the "traps" module. See the description there for more information. Bugs C Compiler & Library Page 5-131 traps Trap handlers 5.100 Trap handlers ____ ________ ********* * traps * ********* File name: traps.mac Usage Internal $$sstt:: ; RSX synchronous trap ; vector $$t410:: ; RT11 Entry after traps ; to vectors 4 and 10 Description This module contains code which is executed after a synchronous trap is detected by the operating system. All such traps are regarded as fatal errors and the program will be terminated. The following traps are processed: Illegal memory reference (trap through vector 4) Illegal instruction (trap through vector 10) BPT (assuming a debugging aid is not present) IOT Illegal TRAP (this may be a Fortran error) Illegal EMT (RSX only) Floating point exception (RSX only) Memory management violation Before exiting to the operating system, the registers at the time the trap occurred will be written, in octal, to stdout. Note also that a calling sequence traceback will be written to stdout by error(). If a trap occurred, the program will exit to the operating system with a "severe error" status. Internal C Compiler & Library Page 5-132 traps Trap handlers The first call to pcsv$ will initialze trapping. On RSX11-M, the SVTK$ executive service will be called. On RT11, the .tprset monitor request will be executed. As .trpset only traps illegal memory reference (trap to 4) and illegal instruction (trap to 10), the other interesting vectors are initialized by absolute references (.ASECT). Diagnostics Bugs Currently may loop if a trap occurrs within the trap handler. Internal Don't forget to handle floating-point when it's implemented. C Compiler & Library Page 5-133 ungetc Push back a byte onto an input file 5.101 Push back a byte onto an input file ____ ____ _ ____ ____ __ _____ ____ ********** * ungetc * ********** File name: ungetc.mac Usage ungetc(c, iop); char c; FILE *iop; Description Push one character back on the indicated stream. Abort by executing a BPT instruction if more than one character is pushed back. Bugs C Compiler & Library Page 5-134 unwind Execute non-local goto 5.102 Execute non-local goto _______ _________ ____ ********** * unwind * ********** File name: unwind.mac Usage setexit(); unwind(); Description: These routines are useful for dealing with errors and interrupts encountered in a low-level subroutine of a program. setexit() saves its stack environment in a static place for later use by unwind(). It returns 0. Unwind() restores the environment saved by the last call of setexit(). It then returns in such a way that execution continues as if the call of setexit() had just returned. All accessible data have values as of the time unwind() was called. The return from setexit() will have the value 1. For example: if (setexit()) { /* Unwind called */ } else { /* Setexit setup called */ } The routine that called setexit() must still be active when unwind() is called. Bugs C Compiler & Library Page 5-135 wdleng Expensive way to say sizeof(int) 5.103 Expensive way to say sizeof(int) _________ ___ __ ___ ___________ ********** * wdleng * ********** File name: wdleng.mac Usage wdleng() Description Return word length. Bugs This may be replaced by: #define wdleng() (sizeof (int)) C Compiler & Library Page 5-136 wrapup Dummy routine called on exit 5.104 Dummy routine called on exit _____ _______ ______ __ ____ ********** * wrapup * ********** File name: wrapup.mac Usage wrapup() Description This routine (which does nothing) is called on exit if the user's program does not provide a wrapup() routine. Wrapup will be called only once. Bugs C Compiler & Library Page 5-137 zero Clear a block of memory 5.105 Clear a block of memory _____ _ _____ __ ______ ******** * zero * ******** File name: zero.mac Usage zero(addr, nbytes); char *addr; int nbytes; Description: Clear the block of core. No value is returned. Bugs APPENDIX A USEAGE INFORMATION $$init Once-only initialization code $$main Start of C programs $$main:: /* Start of C programs */ extern int $$opsy; /* Operating system */ extern int $$rsts; /* Non-zero if RSTS/E */ extern int $$uic; /* RSX: Default uic */ extern int $$stnd; /* Stack end point */ extern int $$scca; /* RT11: .scca control */ extern char $$task[]; /* RSX: task name */ extern int $$tick; /* RT11: 50 or 60 Hertz */ $$narg Define default for $$narg int $$narg = ; ... main() { ... } C Runtime Library Page A-2 Useage Information (** PRELIMINARY **) abort Abort program with an IOT trap abort() abs Integer absolute value abs(val) int val; alloc Allocate memory char * alloc(n); /* -1 if no space */ ascr50 Ascii to Radix-50 conversion ascr50(count, input, output) int count; int *output; char *input; asr$u Right shift unsigned >> integer unsigned asr$u(u, n) unsigned u; int n; C Runtime Library Page A-3 Useage Information (** PRELIMINARY **) atod Convert Ascii to double floating double atod(buffer) char *buffer; atoi Convert Ascii to integer atoi(p) char *p; atol Convert Ascii to long long atol(p) char *p; break Change memory allocation char * old = sbrk(increment); int *old; int increment; char * old = brk(value); int *old; int *value; char * new = settop(value); int *value; int *new; C Runtime Library Page A-4 Useage Information (** PRELIMINARY **) call Call (Fortran) subroutine from C return_value = call(routine, count, &arg1, ... &argN); extern int routine(); /* PDP-11 function name */ int count; /* Number of arguments */ callc Call C subroutine from (Fortran) program integer callc ivalue = callc(routine, arg1, ... argN) caller Return name of profiled caller char * caller(); calloc Allocate and Initialize Memory char * calloc(n, m); /* NULL if no space */ calltr Trace Path to the Caller calltrace(outfd); FILE *outfd; C Runtime Library Page A-5 Useage Information (** PRELIMINARY **) concat Concatenate strings char * concat(out, in0, in1, ..., inN, 0); char *out; char *in0, in1, ... inN; copy Copy a given number of bytes char * copy(out, in, nbytes) char *out; char *in; int nbytes; cpystr String copy char * cpystr(out, in); char *out; char *in; ctime Convert Time Buffer to Ascii char * ctime(buffer); struct TIME { int year; /* G.TIYR year - 1900 */ int month; /* G.TIMO Jan. = 1 */ int day; /* G.TIDA */ int hour; /* G.TIHR 00 .. 23 */ int minute; /* G.TIMI 00 .. 59 */ int second; /* G.TISC 00 .. 59 */ C Runtime Library Page A-6 Useage Information (** PRELIMINARY **) int tick; /* G.TICT 00 .. tsec-1 */ int tsec; /* G.TICP tick/second */ } buffer; dayofweek(buffer); struct TIME buffer; envsave Multi-level function return int * envsave(); envreset( fp, hval, lval ) int *frame; /* Frame pointer */ int hval; /* High-order return */ int lval; /* Low-order return */ error Error exit from C programs error(format, arglist); /* Fatal error exit */ exit Exit from C programs exit(); /* Exit, no return */ exits(status); /* Exit with status */ extern int $$exst; /* Exit status value */ C Runtime Library Page A-7 Useage Information (** PRELIMINARY **) fclose Close a currently-open file fclose(iop); FILE *iop; feof Test for end of file feof(iop); FILE *iop; ferr Test for file error ferr(iop); FILE *iop; fflush Flush output buffers fflush(iop); FILE *iop; fget Get a record fget(buffer, maxbytes, iop); char *buffer; int maxbytes; FILE *iop; C Runtime Library Page A-8 Useage Information (** PRELIMINARY **) fgets Read a line from a file char * fgets(buffer, maxbytes, iop); char *buffer; int maxbytes; FILE *iop; char * fgetss(buffer, maxbytes, iop); char *buffer; int maxbytes; FILE *iop; flun Get logical unit number flun(iop) FILE *iop; fmkdl Mark File for Deletion fmkdl(iop); FILE *iop; fopen C library file opener FILE * fopen(name, mode); char *name; /* File to open */ char *mode; /* Open modes */ FILE * freopen(name, mode, iop); C Runtime Library Page A-9 Useage Information (** PRELIMINARY **) char *name; /* File to open */ char *mode; /* Open modes */ FILE *iop; /* I/O pointer */ fput Put a binary record fput(buffer, nbytes, iop); char *buffer; int nbytes; FILE *iop; frec Return True if record-oriented file frec(iop); FILE *iop; fseek File pointer reposition (seek) fseek(iop, offset, param); FILE *iop; /* What device to seek */ long offset; /* New read position */ int param; /* Zero for abs. seek */ fspool Spool to Default Queue fspool(fp); FILE *fp; /* Open file IOV */ C Runtime Library Page A-10 Useage Information (** PRELIMINARY **) ftell Tell file position long ftell(iop); FILE *iop; /* What device to seek */ ftty Return True if terminal file ftty(iop) FILE *iop; fwild Wild-card file opener FILE * fwild(name, mode); char *name; /* File to open */ char *mode; /* Open modes */ FILE * fnext(iop); FILE *iop; /* I/O pointer */ getchar Get characters getchar(); getc(iop); FILE *iop; C Runtime Library Page A-11 Useage Information (** PRELIMINARY **) gets Read a line from stdin char * gets(buffer); char *buffer; gettty Get control teletype name gettty(buffer); char *buffer; getw Get a word getw(iop); FILE *iop; iov I/O vector definition RSX format: typedef struct iov { int io_flag; /* Control flags */ int io_uget; /* Unget char storage */ int io_bcnt; /* Buffer free count */ char *io_bptr; /* Buffer free pointer */ char *io_rbuf; /* Record buffer start */ int io_rbsz; /* Record buffer size */ char *io_bbuf; /* Block buffer start */ char *io_wild; /* Wildcard lookup buf */ int io_uic; /* Binary UIC */ int io_iosb[2]; /* I/O status block */ int io_fdb[0]; /* File data block */ } FILE; C Runtime Library Page A-12 Useage Information (** PRELIMINARY **) RT11 format: typedef struct iov { int io_flag; /* Control flags */ int io_uget; /* Unget char storage */ char *io_name; /* File name pointer */ char *io_wild; /* Wild card lookup buf */ int io_lun; /* RT11 channel number */ int io_bcnt; /* Buffer free count */ char *io_bptr; /* Buffer free pointer */ int io_bnbr; /* Disk block number */ char io_bbuf[512]; /* Data buffer */ } FILE; Bits in iov.io_flag: #define IO_OPN 0100000 /* Open file */ #define IO_REC 0040000 /* Record device */ #define IO_TTY 0020000 /* Console terminal */ #define IO_EOF 0010000 /* EOF seen */ #define IO_ERR 0004000 /* Error seen */ #define IO_FIL 0002000 /* Disk file */ #define IO_BAD 0001000 /* Buffer needs filling */ #define IO_NOS 0000400 /* No newlines needed */ #define IO_UBF 0000200 /* User does buffering */ #define IO_BZY 0000100 /* Buffer write needed */ #define IO_WF1 0000040 /* fwild "first time" */ #define IO_VER 0000020 /* fwild version hack */ #define IO_VM1 0000010 /* version ;-1 */ #define IO_WLD 0000004 /* file is wild */ #define IO_MOD 0000003 /* Open mode mask */ /* read = 0 */ /* write = 1 */ /* append = 2 */ /* Non-zero = output */ #define IO_EOR (IO_ERR | IO_EOF) extern int $$ferr; /* Error word */ extern FILE *stdin; /* Standard input file */ extern FILE *stdout; /* Standard output file */ extern FILE *stderr; /* User's command tty */ iovtoa Convert file name to ascii char * iovtoa(iop, buffer); FILE *iop; char *buffer; C Runtime Library Page A-13 Useage Information (** PRELIMINARY **) isalpha Return TRUE if alphabetic argument isalpha(c); int c; isdigit Return TRUE if digit argument isdigit(c); int c; islower Return TRUE if lower-case alphabetic argument islower(c); int c; isupper Return TRUE if Upper-case alphabetic argument isupper(c); int c; itoa Integer to Ascii char * itoa(value, string); int value; char *string; C Runtime Library Page A-14 Useage Information (** PRELIMINARY **) itoa8 Convert integer to octal Ascii char * itoa8(value, buffer); int value; char *buffer; itoax Convert an integer to hexidecimal Ascii char * itoax(value, buffer); int value; char *buffer; malloc Allocate and free memory char * malloc(size); /* NULL if no space */ unsigned size; /* Number of bytes */ mfree(p); free(p); char *p; /* Was allocated */ memdmp Dump memory and registers memdmp(start, end); /* Memory dump routine */ char *start; /* First to dump */ char *end; /* Last to dump */ regdmp(); /* Register dump */ C Runtime Library Page A-15 Useage Information (** PRELIMINARY **) msg Print a message on the console msg(text) char *text; peek Peek at a location in RSTS/E peek(location) int *location; printf Formatted print routine printf(format, arg1, ...); char *format; fprintf(iov, format, arg1, ...); FILE *iov; char *format; sprintf(buffer, format, arg1, ...); char *buffer; char *format; profile Print profile information $$prof(); extern int $$prnl; extern char *$$pfil; C Runtime Library Page A-16 Useage Information (** PRELIMINARY **) putc Put one character to a file putchar(c); char c; putc(c, iop); char c; FILE *iop; putw Put a 16-bit word to a file putw(word, iop); int word; FILE *iop; r50toa Convert Radix-50 to Ascii r50toa(buff, r5vec, r5cnt); char *buff; /* Output text buffer */ int *r5vec; /* Input rad50 buffer */ int r5cnt; /* How many rad50 words */ rand Random number generator rand(max) int max; extern long seed; /* Random number seed */ C Runtime Library Page A-17 Useage Information (** PRELIMINARY **) realloc Reallocate memory char * realloc(buff, size); char *buff; /* Buffer from malloc() */ unsigned size; /* New size for buff */ rewind Rewind a file for re-reading rewind(iop); FILE *iop; rtime Convert Date and Time rtime(buffer); struct TIME { int year; /* G.TIYR year - 1900 */ int month; /* G.TIMO Jan. = 1 */ int day; /* G.TIDA */ int hour; /* G.TIHR 00 .. 23 */ int minute; /* G.TIMI 00 .. 59 */ int second; /* G.TISC 00 .. 59 */ int tick; /* G.TICT 00 .. tsec-1 */ int tsec; /* G.TICP tick/second */ } buffer; sbreak Allocate memory from operating system char * sbreak(amount); int amount; C Runtime Library Page A-18 Useage Information (** PRELIMINARY **) scanf Formatted input conversion scanf(fmt, pointer(s)); char *fmt; /* Format string */ fscanf(fd, fmt, pointer(s)); FILE *fd; /* Input file pointer */ char *fmt; /* Format string */ sscanf(buf, fmt, pointer(s)); char *buf; /* Input text buffer */ char *fmt; /* Format string */ setcc Trap Control/C (RSTS/E RT11 mode only) setcc(function); extern int function(); sleep Delay job a given number of seconds sleep(delay); int delay; strcmp String comparison strcmp(a, b); char *a; char *b; C Runtime Library Page A-19 Useage Information (** PRELIMINARY **) strcpy String copy char * strcpy(out, in); char *out; char *in; streq String equality streq(a, b); char *a; char *b; strlen String length strlen(s); char *s; swabb Byte swap (argument is a buffer pointer) swabb(buffer); char *buffer; swabi Byte swap, (argument is an integer) swabi(value); int value; C Runtime Library Page A-20 Useage Information (** PRELIMINARY **) time Time of day long time(0); long time(tloc); long *tloc; tolower Convert upper-case alphabetic to lower-case tolower(c); int c; toupper Convert lower-case alphabetic to upper-case toupper(c); int c; trace Profile support entry module (with trace) #include extern FILE *$$flow; $$flow = fopen("trace.out", "w"); /* or $$flow = stderr; to trace to the console */ ... $$flow = NULL; /* Turn off flow trace */ C Runtime Library Page A-21 Useage Information (** PRELIMINARY **) traps Trap handlers Internal $$sstt:: ; RSX synchronous trap ; vector $$t410:: ; RT11 Entry after traps ; to vectors 4 and 10 ungetc Push back a byte onto an input file ungetc(c, iop); char c; FILE *iop; unwind Execute non-local goto setexit(); unwind(); wdleng Expensive way to say sizeof(int) wdleng() C Runtime Library Page A-22 Useage Information (** PRELIMINARY **) wrapup Dummy routine called on exit wrapup() zero Clear a block of memory zero(addr, nbytes); char *addr; int nbytes;