C Language Programmer's Guide for the IBMO Personal Computer Disk Operating System Copyright @ 1983 Digital Research P.O. Box 579 160 Central Avenue Pacific Grove, CA 93950 (408) 649-3896 TWX 910 360 5001 All Rights Reserved COPYRIGHT Copyright@1983 by Digital Research Inc. All rights reserved. No part of this publication may be reproduced, transmitted, transcribed, stored in a retrieval system, or translated into any language or computer language, in any form or by any means, electronic, mechanical, magnetic, optical, chemical, manual or otherwise, without the prior written permission of Digital Research, Post Office Box 579, Pacific Grove, California, 93950. This manual is, however, tutorial in nature. Thus, the readers are granted permission to include the example programs, either in whole or in part, in their own programs. DISCLAIMER Digital Research makes no representations or warranties with respect to the contents hereof and specifically disclaims any implied warranties of merchantability or fitness for any particular purpose. Further, Digital Research reserves the right to revise this publication and to make changes from time to time in the content hereof without obligation of Digital Research to notify any person of such revision or changes. TRADEMARKS CP/M and CP/M-86 are registered trademarks of Digital Research. Digital Research C. ASM-86, LIB 86, LINK-86, RASM-86, and XREF-86 are trademarks of Digital Research. INTEL is a registered trademark of INTEL Corporation. IBM is a registered trademark of International Business Machines. IBM Personal Computer is a tradename of International Business Machines. VAX is a registered trademark of Digital Equipment Corporation. PDP-11 is a trademark of Digital Equipment Corporatign. UNIX is a registered trademark of Bell Laboratories. The C Language Programmer's Guide for the IBM Personal Computer Disk Operating System was prepared using the Digital Research TEX Text Formatter and printed in the United States of America. First Edition: May 1983 Foreword Digital Research C" is a full-function implementation of the standard C programming language. This implementation runs under the IBM8 Personal Computer Disk Operating System based on the INTEL@ 8086/8088 family of microprocessors. Unlike many competitive C language implementations, Digital Research C enables you to write programs that are completely portable among CP/M8 , the IBM Personal Computer Disk Operating System, and the UNIX8 operating system. The Digital Research C system consists of six executable components: the C compiler, a reverse preprocessor, a linkage editor, a library utility, a relocatable assembler, and an assembly language cross reference utility. The system subroutine libraries support four 8086/8088 program memory models: small, compact, medium, and big. System libraries are completely compatible with UNIX Version 7. Compiler options accomodate direct control over many aspects of the compilation process and provide programmer access to useful compiler generated listings and interlistings. An extensive error warning and reporting system expedites program development with explicit diagnostic messages. Three documents supply the necessary information for using the C language, C system software, and the programmer's utilities. • Digital Research. C Language Programmer's Guide. Pacific Grove, California: Digital Research, 1983 (hereafter cited as Programmer's Guide). • Digital Research. Programmer's Utilities Guide for the IBM Personal Computer Disk Operating System. Pacific Grove, California: Digital Research, 1983 (hereafter cited as Programmer's Utilities Guide). • Kernighan, Brian W., and Dennis M. Ritchie. The C Programming Language Englewood Cliffs, New Jersey: Prentice-Hall, 1978 The C Language Programmer's Guide consists of six sections and six appendixes. The manual provides all the information you need to operate the C system software. o Section 1 defines the computer resources you need to use the C software and the individual components that make up the C system. A simple demonstration program helps you get your system up and running. e Section 2 explains how to use the compiler. A second demonstration program provides a more detailed description of the compiling, linking, and running procedure. iii • Section 3 describes each function in the C system library. A directory at the beginning of the section helps you locate specific function descriptions easily. • Section 4 explains the use of files and other input/output conventions. • Section 5 explains how to interface assembly routines with C modules. • Section 6 covers internal data representation. Appendixes include a listing of error messages, summaries of system library functions and compiler options, a useful programming style guide, and some sample C source code modules. This programmer's guide does not attempt to describe features of the C language. The Kernighan and Ritchie manual provides both an excellent C language reference section for the experienced programmer and a tutorial introduction to help the novice programmer get started in C. The Programmer's Utilities Guide presents in depth explanations of the Digital Research linkage editor, library utility, and relocatable assembler. Together, the three manuals provide all the information you need to use Digital Research C to its fullest potential. Digital Research is interested in your comments on programs and documentation. Please use the Software Performance Reports enclosed in each product package to help us provide you with better software products. iv Table of Contents I Getting Started With C 1.1 System Requirements . . . . 1.2 Run-time Requirements 1.3 C Components . . . . . . 1.4 Minimum Configuration . . 1.5 A Simple Demonstration . . . . . . . . . . . . . 2 Operating C 2.1 Compiler Operation . . . . . . . . . . . . . . . . 2-1 2.1.1 Compiler Command Lines . . . . . . . . . . . 2-2 2.1.2 Stopping the Compiler . . . . . . . . . . . 2-2 2.1.3 Compiler Command Line Options . . . . . . . 2-2 2.1.4 Memory Allocation Data . . . . . . . . . . . 2-14 2.1.5 Error Messages . . . . . . . . . . . . . . . 2-14 2.2 Start-up Routines and Stand-alone Programs . . . . 2-15 2.3 Reverse Preprocessor Operation . . . . . . . . . . 2-16 2.4 Memory Models . . . . . . . . . . . . . . . . . . . 2-17 2.4.1 Small Memory Model . . . . . . . . . . . . . 2-18 2.4.2 medium memory Model . . . . . . . . . . . . 2-19 2.4.3 Compact Memory Model . . . . . . . . . . . . 2-20 2.4.4 Big Memory Model . . . . . . . . . . . . . . 2-21 2.5 Compiling, Linking, and Running TEST.C . . . . . . 2-22 3 C System Library 3.1 UNIX V7 Compatibility . . . . . . . . . . . . . . . 3-1 3.2 System Library Routines . . . . . . . . . . . . . . 3-2 4 input/Output Conventions 4.1 Regular File Access . . . . . . 4.2 Stream File Access . . . . . . . . . . . . . . . . v Table of Contents (continued) 4.3 Peripheral Devices . . . . . . . . . . . . . . . . 4-3 4.4 Standard 1/0 Files . . . . . . . . . . . . . . . . 4-3 5 Assembler Routine Interfacing 5.1 External Naming Conventions . . . . . . . . . . . . 5-1 5.2 Calling an Assembly Routine from a C Module . . . . 5-2 5.3 Calling a C Module from an Assembly Routine . . . . 5-3 5.4 Parameter Passing . . . . . . . . . . . . . . . . . 5-3 5.5 Function Return Values . . . . . . . . . . . . . . 5-6 5.6 Accessing External Data . . . . . . . . . . . . . . 5-6 6 Internal Data Representation 6.1 Character Storage . . . . . . . . . . . . . . . . . 6-1 6.2 Integer Storage . . . . . . . . . . . . . . . . . . 6-2 6.3 Single-precision Floating-point . . . . . . . . . . 6-3 6.4 Double-precision Floating-point . . . . . . . . . . 6-3 vi Appendixes A System Library Routine Summary B Compiler Option Summary . . . C Error Messages . . . . . D Variations among Compilers E C Style Guide . . . . . . . . . . . . . . . . . . . . . E-1 F Sample C Modules . . . . . . . . . . . . . . . . . . . F-1 vii Tables, Figures, and Listings Tables 1-1. C System and Programmer's Utilities Disk Files 1-2 2-1. Compiler Command Line Options . . . . . . . . . 2-3 3-1. Variable Type Macro Definitions . . . . . . . . 3-3 3-2. Storage Class Macro Definitions . . . . . . . . 3-3 3-3. System Library Function Directory . . . . . . . 3-4 3-4. ctype Functions . . . . . . . . . . . . . . . . 3-14 3-5. perror Error Codes . . . . . . . . . . . . . . 3-36 3-6. Output Conversion Characters . . . . . . . . . 3-39 3-7. Input Conversion Characters . . . . . . . . . . 3-48 4-1. Functions for Regular File Access . . . . . . . 4-2 4-2. Functions for Stream File Access . . . . . . . 4-2 4-3. Standard 1/0 File Definitions . . . . . . . . . 4-3 Function Return Registers . . . . . . . . . . . 5-6 B-1. Compiler Command Line Options . . . . . . . . . B-1 C-1. Error Messages . . . . . . . . . . . . . . . . C-1 E-1. Variable Type Macro Definitions . . . . . . . . E-3 E-2. Storage Class Macro Definitions . . . . . . . . E-3 Figures 1-1. Minimum C System Operation . . . . . . . . . . 1-4 2-1. Small Memory Model . . . . . . . . . . . . . . . 2-18 2-2. Medium Memory Model . . . . . . . . . . . . . . 2-19 2-3. Compact Memory Model . . . . . . . . . . . . . . 2-20 2-4. Big Memory Model . . . . . . . . . . . . . . . . 2-21 5-1. Stack for Small and Compact Model . . . . . . . 5-5 5-2. Stack for Medium and Big Model . . . . . . . . . 5-5 6-1. Character Storage . . . . . . . . . . . . . . . 6-1 6-2. Short Integer Storage . . . . . . . . . . . . . 6-2 6-3. Long Integer Storage . . . . . . . . . . . . . 6-2 6-4. Single-precision Floating-point Storage . . . . 6-3 6-5. Double-precision Floating-point Storage . . . . 6-4 viii Tables, Figures, and Listings (continued) LiStings F-1. - Printf Module . u . . . . . . . . F-1 F-2. PRINTF Internal Ro tine . . . . . . . F-3 F-3. PRNT8 Procedure . . . . . . . . . . . . . . . . F-7 F-4. Prntx Function . . . . . . . . . . . . . . . . F-8 F-5. -Conv Function . . . . . . . . . . . . . . . . F-9 F-6. -Putstr Function . . . . . . . . . . . . . . . . F-10 F-7. -Prtl Function . . . . . . . . . . . . . . . . F-11 ix I Section I Getting Started with C 1.1 System Requirements To operate the C compiler, you must have all of the following computer resources. Memory requirements specified below are minimum values. • 8086 or 8088 CPU running DOS. • 108K of user program area in addition to the space occupied by the operating system. • Enough disk space to hold the compiler during compilation. • Enough disk space to hold the temporary file that the compiler generates. Typically, the temporary space required is one third to one-half the size of your source file or files. • Enough disk space to hold the object file that the compiler creates. 1.2 Run-time Requirements You must have all of the following computer resources to execute programs compiled with the C compiler and linked with the system subroutine libraries. Memory requirements specified below are minimum values. * 8086 or 8088 CPU running DOS 9 from 10K to 32K bytes for system library modules plus space for your program code 1.3 C Components The Digital Research C system consists of six executable components, four versions of the system subroutine library, and two sample test programs. The executable components are the C compiler, the reverse preprocessor program, the LINK-86'" linkage editor, the LIB 86'" library utility, the XREF-86" assembly language cross-reference utility program, and the RASM-86" relocatable assembler. The system libraries support four 8086/88 memory models: small, medium, compact, and big model. Refer to Section 2.4 for an explanation of memory models. The C system also provides five special purpose files that you include in a C program with the #include directive. The following table describes all the files on your C product disks. The following table describes all the files on your C product disks. Table 1-1. C System and Programmer's Utilities Disk Files Component Disk Fi7l7e Description compiler DRC.EXE compiler supervisory module DRC860.EXE preprocessor DRC861.EXE parser and code generator DRC862.EXE listing/disassembly file merge utility DRC.ERR compiler error messages DRCRPP.EXE reverse preprocessor program #include STDIO.H macro definitions for standard files input and output PORTAB.H macro definitions for program portability CTYPE.H ASCII character classification routines SETJMP.H nonlocal program jump routine ERRNO.H macro definitions for the perror function libraries SYSLIBS.L86 small model system subroutine library SYSLIBM.L86 medium model system subroutine library SYSLIBC.1,86 compact model system subroutine library SYSLIBB.1,86 big model system subroutine library library LIB86.EXE standard Digital Research 8086 editor and 8088 library utility linkage LINK86.EXE standard Digital Research editor 8086/88 linkage editor relocatable RASM86.EXE standard Digital Research 8086 assembler and 8088 assembler XREF86.EXE standard Digital Research assembly language cross reference utility program Table 1-1. (continued) Componen~_T-Disk File I Description sample SAMPLEX C program ready to compile, programs link, and run TEST.C C test program that ensures proper component functioning STARTUP.A86 Sample start-up routine 1.4 Minimum Configuration You must have the following three files to execute the C compiler in minimum configuration: • DRC.EXE compiler supervisory module • DRC860.EXE preprocessor • DRC861.EXE parser and code generator The compiler supervisory module, DRC.EXE, executes the other compiler modules in the proper sequence. DRC860.EXE is the preprocessor and DRC861.EXE is the parser and code generator. The compiler error messages file, DRC.ERR, and the listing/disassembly file-merge utility, DRC862.EXE, are not required during compilation. If DRC.ERR is not on-line during compilation, the compiler returns error messages by number only. DRC862.EXE merges listing and disassembly files together for a complete interlist display when you use the compiler interlist option. The listing file contains the source code lines from your C program. The disassembly file contains compiler generated assembly code. The assembly code the compiler generates is actually an approximation of the correct 8086/88 assembly code. It is provided for debugging purposes only. If DRC862.EXE is not on-line during compilation, the interlist option is ineffective and the compiler outputs the listing and disassembly files separately. Following compilation, the linkage editor requires one of the system library files to create the executable program. The library files do not have to be on-line during compilation. The following diagram illustrates the minimum C system in operation. 1-3 SYSLIBB186 (OR) SYS L I BM.1_86 (OR) SYSLIBC186 (OR) SYSLIBS.L86 SYSTEM -0-.SYM FILE LIBRARY --,%-.MAP FILE SOURCE C --- OBJECT LINK-86 EXECUTABLE 0 LAM COMPILER LAM PROGRAM PROGRAM PROGR__ CPROGRAM.C DRC.EXE CPROGRAM.OBJ LINK86.EXE CPROGRAM.EXE DRC860.EXE DRC861.EXE Figure 1-1. Minimum C System Operation 1.5 A Simple Demonstration The following simple demonstration illustrates the standard procedure used to create an executable program written in C. If you are an experienced C programmer, you might want to skip this section and continue with Section 2. The following instructions assume you already know how to use your operating system. The instructions are for C on a DOS-based system with two floppy-disk drives. First, make back-up copies of your master C product disks and store the original disks in a safe place. Your operating system disk should be in drive A. 1) Create a C work disk. Using a file copy program, such as COPY, create a C work disk that contains the three compiler files required for minimum configuration, the linkage editor, the small model system library, and SAMPLE.C. If you do not have enough room on disk for all the files, you can place the linkage editor and library on a separate disk. Your work disk or disks should contain all of the following files: • DRC.EXE compiler supervisory module • DRC860.EXE preprocessor • DRC861.EXE parser and code generator • LINK86.EXE linkage editor • SYSLIBS.1,86 small model system library • SAMPLE.C sample program With your operating system disk in drive A, place your new C work disk that contains SAMPLE.C in drive B. SAMPLE.C uses a simple for-loop and the printf function to print a short series of messages. You can display the SAMPLE.C source program on your terminal with the DOS TYPE command. Make sure drive B is the default drive and enter the following command: B>TYPE SAMPLEX The following output appears on your terminal screen: maino int val; for (val = 0; val - 3; val++) printf("%d TESTING C\n", val); printf("\n"); printf("FINISHED!\n"); B> 2) Compile the program. To compile the SAMPLE.C source program, enter the following command. Be sure drive B is the default drive. B>DRC SAMPLE Note that you do not have to specify the C filetype for the source program. First, the compiler searches the default drive for SAMPLE with no filetype. When the compiler cannot find SAMPLE, it automatically searches for SAMPLE.C. The compiler displays a sign-on banner as shown in the following display. Siqn-on banners might vary slightly for different versions of the compiler. Next the preprocessor and parser/code generator modules display short messages indicating execution. At the end of compilation, the compiler displays a memory allocation message. The memory allocation message indicates the amount of space that the compiler allocates for the different parts of the program. Values in the memory allocation message might vary slightly for different versions of the C compiler. Section 2.1.4 describes the different parts of the memory allocation message in more detail. -------------------------------------------------- Digital Research C Version X.X Serial No. XXXX-XXXX-XXXXXX All Rights Reserved Copyright (c) 1983 Digital Research, Inc. -------------------------------------------------- Digital Research C Version X.X Preprocessor Digital Research C Version X.X Code Gen sample.c: code: 67 static: 27 extern: 160 B> The compiler compiles SAMPLE.C according to the 8086 small memory model by default. Refer to Section 2.4 for an explanation of memory models. The compiler then creates the relocatable object file for the program. The compiler names the object file with the same filename as the input source file but with a OBJ filetype. This is the default object file naming convention. A directory for disk B should have the new file SAMPLE.OBJ. If you are using two separate work disks, copy SAMPLE.OBJ onto the disk that contains LINK-86 and the small model system library. Place the LINK-86 disk in drive B. 3) Link the program. The SAMPLEX file is compiled according to the small memory model. Therefore, you must link SAMPLE.OBJ with the small model system subroutine library. You do not have to specify the library name explicitly in the linker command line if the library file is on the default drive. The compiler creates a special object record in SAMPLE.OBJ. This record contains information that tells LINK-86 which system library to search for any required routines. To start LINK-86, enter the following command. Be sure drive B is the default drive. B>LINK86 SAMPLE 1-6 LINK-86 assumes a filetype of OBJ for the object file you specify in the command line. LINK-86 displays a sign-on message and some allocation messages on your terminal as shown in the following display. Values in the allocation messages might vary slightly for programs compiled with different versions of the C compiler. -------------------------------------------------- LINK-86 Linkage Editor Version X.X Serial No. XXXX-XXXX-XXXXXX All Rights Reserved Copyright (c) 1982,1983 Digital Research, Inc. -------------------------------------------------- CODE OME DATA OODBC USE FACTOR: 04% B> If you get no error messages, the program has been linked successfully. LINK-86 creates a directly executable program. The directory for disk B should have the new command file SAMPLE.EXE. Refer to Section 7 of the Programmer's Utilities Guide to learn how LINK-86 works. 4) Run the Program To run the SAMPLE.EXE program, enter the following command. Be sure drive B is the default drive. Notice that you do not have to specify the EXE filetype. B>SAMPLE The following output appears on your terminal screen: 0 TESTING C 1 TESTING C 2 TESTING C 3 TESTING C FINISHED B> 1-7 If your C software does not seem to operate correctly, check the system requirements listed in Section 1.1 and the run-time requirements listed in Section 1.2. Make sure your equipment complies with the specified guidelines. Section 2. 5 provides a more detailed explanation of the compiling, linking, and running procedures. End of Section 1 1-8 Section 2 Operating C The Digital Research C compiler is especially suited to commercial systems and applications development. Enhanced diagnostic features, such as compiler information message display, error reporting, and a listing/disassembly file-merge utility, provide expanded visibility of compiler-generated information to simplify debugging and program maintenance. 2.1 Compiler Operation To use the full C compiler configuration, the following five files must be on-line: • DRC.EXE compiler supervisory module • DRC860.EXE preprocessor • DRC861.EXE parser and code generator • DRC862.EXE listing/disassembly file-merge utility • DRC.ERR compiler error messages You can place DRC860.EXE, DRC861.EXE, and DRC862.EXE on different drives for space considerations using the -0, -1, and -2 compiler command line options, respectively. Command line options are described in Section 2.1.3. DRC.EXE, and DRC.ERR must both be on the default drive. Your source program file can be on any logical drive. The compiler takes a C source program as input and generates an object program in the Intel relocatable object file format. During compilation, the compiler creates temporary work files named CTEMP.TOK and COBJ.TMP. Unless compilation is unsuccessful, you never see a temporary file listed in a directory. The compiler erases the files automatically when compilation is finished. The size of a temporary file varies with the size of your source program. The total amount of temporary space required during compilation is approximately one-third to one-half the size of your source file or files. If you do not have enough work space on disk for the compiler, you can break up large programs into modules and compile each module separately. C Language Programmer's Guide 2.1 Compiler Operation 2.1.1 Compiler Command Lines The command line invokes the compiler, specifies the source file to compile, and passes special instructions to the compiler in the form of command line compiler options. A command line cannot exceed 128 characters. Compiler command lines use the following general format: DRC source file option switches Note that you do not have to specify the X filetype explicitly for the source program in the command line. The compiler assumes a C filetype unless you specify otherwise. 2.1.2 Stopping the Compiler To stop the compiler during processing, press any console key. The compiler displays the following message: Stop DRC (Y/N)? Type a lowercase or uppercase Y to stop processing. The compiler immediately returns control to the operating system. If you type any character except Y, the compiler resumes processing. 2.1.3 Compiler Ca and Line Options Command line option switches are reserved characters (letters and digits) that send special instructions to the compiler. An option switch specification consists of a dash followed by the reserved character. You cannot place spaces between the dash and the reserved character. However, you must place at least one space between each dash/character combination that you use in a command line. Notice that certain option switches require an additional parameter. You cannot place spaces between the option letter and the parameter . Under DOS, you can enter command line option switches in lowercase or uppercase and you can place option switches anywhere in a command line. For example, the following three command line examples produce the same results. B>DRC PROGRAM.C -OPROGMED.OBJ -M -F -H B>drc -m -f -h -oprogmed.obj program B>DRC -M -OPROGMED.OBJ PROGRAM -f -h The rest of Section 2.1.3 describes the command line option switches in alphabetical order. Table 2-1 is a summarized description of the option switches listed alphabetically. 2-2 C Language Programmer's Guide 2.1 Compiler Operation Table 2-1. Compiler Command Line Options Opt Description -alfilesl Invoke LINK-86 automatically. "files" are the object files and libraries to link. Specify the filename and [I] for a LINK-86 command line input file. -b Enable big memory model. (Default is small model.) -c Enable compact memory model. (Default is small model.) -dinamel Define "name" as the value 1. Works like #define in the source code, but defines names in lowercase only. _f Use 8087 math coprocessor. -h Suppress sign-on banner. -ildrive:l Search specified disk drive for #include files. _j Disable short/long jump optimizer. -linamel Generate program listing. Send listing to "name". (Default "name" is CON). -M Enable medium memory model. (Default is small model.) -n Disable code optimizer for faster compilation. -olfilenamel Specify name for object file. -P Execute preprocessor module only. Place output in file CTEMP.TOK. -qlnumberl Set number of code generator nodes to save space in symbol table. (Default is 500; minimum is 100.) -rlnamel Request program interlisting (reverse asspmhly). Spnd intprligting to "n;;mp". (Default "name" is CON). 2-3 C Language Programmer's Guide 2.1 Compiler Operation Table 2-1. (continued) Option Description -vInumberl Set compiler message display level. Should appear before other switches in command line. "number" can range from 1 to 5 to produce the following information: -vl Display general information messages only. -v2 Display a # character as compiler processes each function. -v3 Display function name as compiler processes each function. -v4 Display start/end messages for #include files. -v5 Display filename and line number as compiler processes each line. "number" wInumberl Set error message display level. can be 0, 1, or 2. -wO Display all error messages. -wl Suppress error warning messages. -w2 Suppress all error messages. _x Call an assembly routine to save and restore registers rather than generate code to do it in-line. Program compiles smaller but runs slower. -zldrive:l Place temporary work files on specified disk drive. _01drive: I specify location of compiler preprocessor module (DRC860.EXE). _11drive: I Specify location of compiler parser and code generator module (DRC861.EXE). -21drive; I S p e c i f y 1 o c a t i o n of c o m p i 1 c r listing/disassembly file merge utility (DRC862.EXE). -31drive:1 Specify location of LINK-86 (LINK86.EXE) . 2-4 -a option The -a option switch executes LINK-86 automatically at the end of compilation. You must specify object files and any libraries other than the system library after the -a in the compiler command line. Alternatively, you can specify a LIDIK-86 input file using the INPUT option. Refer to Section 7.11, "Command Input File Options," in the Programmer's Utilities Guide for more information on the LINK-86 INPUT option. The following command line example compiles a program named PROGRAM.C and automatically links the object file that the compiler creates with the small model system library. Notice that you do not have to specify the object file name or library file name explicitly after the -A if that object file is the only file to be linked with the system library on the default drive. B>DRC PROGRAM -A In this example, the compiler, LINK-86, and the small model system library are all on the default drive (B:). You can use the -3 option switch to specify a drive other than the default drive for LINK-86. The compiler compiles PROGRAM.C according to the small memory model and names the object file PROGRAM.OBJ both by default. The compiler creates a special object record in PROGRAM.OBJ that tells LINK-86 which system library to search for required routines depending on which memory model you specify for compilation. Note that the appropriate system library file must be on the default drive. Otherwise, LINK-86 displays the NO FILE error message, indicating that you must specify the library and drive location explicitly. The object record automatically specifies the LINK-86 SEARCH option for library files. Therefore, LINK-86 only links modules from the system library that are referenced in PROGRAM.C. Without the SEARCH option, LINK-86 links in the entire system library, making the executable program unnecessarily large. The preceding example creates an executable program named PROGRAM.EXE. To link multiple object files and libraries, you must specify each filename explicitly after the -A, including the name of the object file that the compiler creates. Use commas to separate each filespec after the -A in the command line. The following example compiles the program named PROGRAM.C, then links the object file that the compiler creates with an object file named PROGTWO.OBJ and the small model system library. Notice that you do not have to specify the OBJ filetype explicitly for the object files after the -A. B>DRC PROGRAM -APROGRAM,PROGTWO The next example is identical to the first example, except the small model system library is on the D drive. Notice that you must specify 2-5 u Language erogrammer-s k3uiae Z.-L t-umpiier vperaLiun the object file that the compiler creates explicitly after the -A whenever you have additional explicit filespecs. B>DRC PROGRAM -APROGRAK,D:SYSLIBS.L86[S] Remember, in this case, you must specify the object file that the compiler creates, the library file drive location, the library filename, and the LINK-86 SEARCH option explicitly. The last example is exactly the same as the first example, except LINK-86 is on drive D. In this case, the system library is on the default drive. You do not have to specify the object file and library file explicitly. B>DRC PROGRAM -A -31): Remember, compiler command lines cannot exceed 128 characters. -b option The -b option switch enables compilation according to the big memory model. (Refer to Section 2.4 for a description of memory models.) For example, the following command line compiles PROGRAM.C according to the big model: B>DRC PROGRAM -B The compiler creates the object file with the same filename as the input source file, but with an OBJ filetype. This is the default object file naming convention. In this example, the filename is PROGRAM. You should rename PROGRAM.OBJ to better identify the file as a big model object file. A name such as PROGBIG.OBJ is easier to identify. Alternatively, you can use the -o option to rename the object file at compile time as shown in the following example: B>DRC PROGRAM -OPROGBIG.OBJ -B -c option The -c option switch enables compilation according to the compact memory model. (Refer to Section 2.4 for a description of memory models.) For example, the following command line compiles PROGRAM.C according to the compact model: B>DRC PROGRAM -C The compiler creates an object file with the same filename as the input source file, but with an OBJ filetype. This is the default object file naming convention. In this example, the filename is PROGRAM. You should rename PROGRAM.OBJ to better identify the file as a compact model object file. A name such as PROGCPT.OBJ is 2-6 k- LdllyUdYU rLUyLa11UL1CL 0 UU~UC - -"L'.- easier to identify. Alternatively, you can use the -o option to rename the object file at compile time as shown in the following example. B>DRC PROGRAM -OPROGCPT.OBJ -C -d option The -d option switch works like a #define in the source code. However, any name that you specify after the -d in the command line equates to the value 1. For example, the following command line directs the compiler to equate the name factor with the value 1 in the source file PROGRAM.C. B>DRC PROGRAM -Dfactor The next example directs the compiler to equate the name ref-22 with the value 1 in the source file PROGRAM.C. B>DRC PROGRAM -Dref-22 f option The -f option switch directs the compiler to use the INTEL 8087 math coprocessor for floating-'I?oint arithmetic as shown in the following example: B>DRC PROGRAM -F You must have the 8087 microprocessor to use the -f option. If you do not specify -f, the compiler calls routines in the system library for floating-point math. If you execute a program compiled with the -f option on a computer that does not have an 8087 math co processor, the program does not execute properly. -h option The -h option switch directs the compiler to suppress the standard compiler sign-on banner and other compiler module sign-on messages. The compiler supervisory module, DRC.EXE, displays the sign-on banner by default. Following the banner, the preprocessor and parser/code generator modules display their sign-on messages by default as shown below. Sign-on banners might differ slightly for 2-7 different versions of the compiler. The memory allocation message appears last. When you specify -h, the compiler only displays the memory allocation message. ----------------------------------------- Digital Research C Version X.X Serial No. XXX-XXXX-XXXXXX All Rights Reserved Copyright (c) 1983 Digital Research, Inc. -------------------------------------------------- Digital Research C Version X.X Preprocessor Digital Research C Version X.X Code Gen test.c: code: 350 static: 695 extern: 36 The following command line example directs the compiler not to display the sign-on banner or module sign-on messages during the compilation of PROGRAM.C. The compiler only displays the memory allocation message. B>DRC PROGRAM -H -i option The -i option switch directs the compiler to search a specified disk drive for #include files. #include files facilitate the handling of declarations and groups of #define definitions. You specify #include files with the #include directive. Refer to Chapter 4.11, "The C Preprocessor," in The C Programming Language by Kernighan and Ritchie for more information on file inclusion. The following example directs the compiler to search drive C: for #include files specified in PROGRAM.C. B>DRC PROGRAM -IC: -j option The -j option switch directs the compiler to disable the short/long jump optimizer. The jump optimizer converts long program branches to short branches wherever possible in the program. The result is a smaller object file. If you disable the jump optimizer, the result is faster compilation, but a bigger object file. The following example disables the jump optimizer for the compilation of PROGRAM.C. B>DRC PROGRAM -J 2-8 -1 option The -1 option switch directs the compiler to generate a listing of the source program. The preprocessor module, DRC860.EXE, actually generates the listing. You can specify a device name to which to send the listing. The compiler sends the listing to the console (CON) by default. The following example directs the compiler to send the listing to the printer (LPT1). B>DRC PROGRAM -LLPT1 -m option The -m option switch enables compilation according to the medium memory model. (Refer to Section 2.4 for a description of memory models.) For example, the following command line compiles PROGRAM.C according to the medium model: B>DRC PROGRAM -M The compiler creates the object file with the same filename as the input source file, but with an OBJ filetype. This is the default object file naming convention. In this example, the filename is PROGRAM. You should rename PROGRAM.OBJ to better identify the file as a medium model object file. A name such as PROGMED.OBJ is easier to identify. Alternatively, you can use the -o option to rename the object file at compile time as shown in the following example: B>DRC PROGRAM -OPROGMED.OBJ -M -n option The -n option switch directs the compiler to disable the code optimizer as shown in the following example: B>DRC PROGRAM -N If you use the -n option, the result is faster compilation, but a bigger object file. -o option Use the -o option switch to specify a name for the object file the compiler creates. The compiler creates the object file with the same filename as the input source file, but with an OBJ filetype. 2-9 C Language Programmer's Guide 2.1 Compiler operation This is the default object file naming convention. The following command line example compiles PROGRAM.C and renames the object file ONE.OBJ. B>DRC PROGRAM -OONE.OBJ -p option The -p option switch directs the compiler to only execute the preprocessor module, DRC860.EXE. The preprocessor creates a temporary work file named CTEMP.TOK. If you use the -p option, the compiler stops after executing the preprocessor module and leaves CTEMP.TOK on disk. The reverse preprocessor program, DRCRPP.EXE, accepts the data in CTEMP.TOK as input and generates a modified version of your original input source file. Refer to Section 2.3 for additional information on the reverse preprocessor. The following example executes the preprocessor and creates CTEMP.TOK for PROGRAM.C. B>DRC PROGRAM.C -P -q option Use the -q option switch to set the number of code generator nodes for optimization. Nodes are the pieces of data the code generator uses to build assembly instructions. The code optimizer works on groups of nodes. You can set the size of these node groups. The default number of code generator nodes is 500. Use a smaller number of nodes to save space in the symbol table. The minimum value is 100. Use a larger number of nodes to optimize larger portions of code. The following example sets the number of code generator nodes for PROGRAM.C to 1000. A value of 1000 actually provides maximum optimization. B>DRC PROGRAM -Q1000 -r option The -r option directs the compiler to generate a program interlisting. An interlisting is a combination of the source code lines from your C program and the compiler-generated assembly code. DRC862.EXE is the listing disassembly file merge utility module. It merges the listing and disassembly files together for a complete interlist display when you use the -r option. The listing file contains the source code lines from your C program. The disassembly file contains compiler generated assembly code. The assembly code the compiler generates is actually an approximation of 8086/88 assembly code. It is provided for debugging purposes only. 2-10 ~_ ~WMJUC~jt! ~LVIJLCLIHILML ~ I~U.LU" 4 . L k-UHIP I _L tf L Upt~ L C2 L. I U1 I If DRC862.EXE is not on-line during compilation, the interlist option is ineffective and the compiler outputs the listing and disassembly files separately. You can use the -2 option switch to specify a drive other than the default drive for DRC862.EXE. Following compilation, the linkage editor requires one of the system library files to create the executable program. The library files do not have to be on-line during compilation. You can specify a device name to which to send the interlisting. The compiler sends the interlisting to the console (CON) by default. The following example directs the compiler to generate an interlisting and sends it to the printer (LPT1). B>DRC PROGRAM -RLPT1 -v __92ti2n The compiler can produce a variety of messages other than sign-on and error messages to provide general compilation information and to indicate different stages of compilation. Use the -v option to set the compiler information message display level. Specify the -v as the first option switch in a command line. The -v option does not affect the display of sign-on and error messages. You can specify a number ranging from 1 to 5 after the -v to select the various types of information message display. If you do not specify a number as shown in the following example, the compiler assumes -vl and displays only general information messages: B>DRC PROGRAM -V General information includes messages such as "Using program.obj as output file" and messages relating to other option switches. This is why you must specify the -v as the first option switch in a command line. The -v must be able to read the rest of the command line to display the appropriate messages. The -v parameters 1 through 5 produce the following compiler information messages: -vl Display general information messages only. -v2 Display a # character as compiler processes each function. -v3 Display function name as compiler processes each function. -v4 Display start/end messages for include files. -v5 Display filename and line number as compiler processes each line. U LAftquage Pf6gfaMffier'9 GUIdo~ 2.1 uompiier uperation Each -v parameter except -v2 and -v3 operates in a hierarchical fashion. In other words, when you specify -v2, the compiler automatically activates -vl, and so on. However, the -v2 and -v3 switches are mutually exclusive. When you specify -v3, the compiler automatically activates -vl but not -v2. Note that when you specify -v4 or -v5, the compiler activates the -v3 switch and not -v2. For example, the following command line directs the compiler to display all messages corresponding to -v5, -v4, -v3, and -vl switches: B>DRC PROGRAM -V5 -w option Use the -w option switch to set the compiler error message display level. Compiler error messages can be divided into two different categories: error reports and error warnings. Error reports indicate mistakes in your source program, such as syntax errors and improper data type specifications. Error warnings effectively indicate that some error can occur if you do not take some corrective action. Refer to Section 2.1.5 for additional information on error messages. You can specify a number ranging from 0 to 2 after the -w to select the display level. The parameters 0 through 2 produce the following results: -wO display all error messages suppress error warning messages suppress all error messages For example, the following command line directs the compiler to display only error reports: B>DRC PROGRAM -W1 -x option Use the -x option to call special assembly routines from the system library that save and restore registers for interfacing C modules and assembly routines. You cannot access these routines explicitly from a program. If you do not use -x, the compiler generates code to save and restore registers in-line. Using -x, your program compiles smaller but runs slower. Refer to Section 5 for more information on interfacing assembly routines with C modules. The following command line example calls the special assembly routines to save and restore registers in PROGRAM.C. B>DRC PROGRAM -X 2-12 - -11J -j- ~ I -z option During compilation, the compiler creates temporary work files named CTEMP.TOK and COBJ.TMP. If you do not have enough work space on disk for the temporary files, you can use the -z option switch to place them on a specified disk drive. You specify the drive after the -z in the command line. The compiler erases the files automatically when compilation is finished. The following example directs the compiler to place the temporary files on the D: drive B>DRC PROGRAM -ZD: -0 option Use the -0 option switch to specify a drive other than the default drive for the compiler preprocessor module, DRC860.EXE. This option is handy if you do not have enough room on one disk for all the compiler modules. The following example informs the compiler supervisory module that the preprocessor is on the F: drive. B>DRC PROGRAM -OF: Use the -1 option switch to specify a drive other than the default drive for the compiler parser and code generator module, DRC861.EXE. This option is handy if you do not have enough room on one disk for all the compiler modules. The following example informs the compiler supervisory module that the parser and code generator module is on the D: drive. B>DRC PROGRAM -lD: Note that the compiler writes the temporary files on the default drive unless you specify otherwise, using the -z option switch. -2 option Use the -2 option switch in conjunction with -r to specify a drive other than the default drive for the compiler listing/disassembly file merge utility, DRC862.EXE. This option is handy if you do not have enough room on one disk for all the compiler modules. The following example directs the compiler to generate a program interlisting and informs the compiler supervisory module that the listing/disassembly file merge utility is on the C: drive. The compiler sends the interlisting to the console (CON) by default. B>DRC PROGRAM -R -2C: 2-13 -3 option Use the -3 option switch in conjunction with -a to specify a drive other than the default drive for the link editor, LINK86.EXE. This option is handy if you do not have enough room on one disk for both the compiler and link editor. The following command line example automatically invokes LINK-86 after compilation, but informs the compiler that LINK-86 is on the D: drive. B>DRC PROGRAM -APROGRAK -3D: 2.1.4 Memory Allocation Data At the end of compilation,'the compiler displays a single message that indicates the amount of memory used for certain memory areas. The message appears as shown below: Ifilename:1 code: nnnn static: nnnn extern: nnnn The filename is the name of the input source file. The three numbers represented in the preceding example by nnnn are decimal values that indicate the number of bytes used for each memory area. The static area includes all variables specifically declared as static and all literal character strings. The external area includes all variables declared explicitly or implicitly external 2.1.5 Error Messages Compiler error messages can be divided into two different categories: error reports and error warnings. Error reports indicate mistakes in your source program, such as syntax errors and improper data type specifications. Error reports include messages, such as number 52 "Right parenthesis ) is missing" and number 7 "Conflicting data type specified for a function." Error warnings effectively indicate that an error can occur if you do not take some corrective action. For example, error message 83 is a warning that suggests caution using the indirection operator with integers. Error message 83 listed in Appendix C, reads as follows: 83 WARNING: Indirection for non-pointers is not portable. Integers can be indirected successfully in Digital Research C (small & medium models only) and PDP-11 C. Indirection is not portable. This is an ERROR WARNING message. If your program uses the indirection operator with integers and is configured according to the compact or big memory model, an error can occur. 2-14 C Language Programmer's Guide 2.1 Compiler Operation Some warnings, such as number 95, "WARNING: Subscript is truncated to short int," simply inform you of a certain activity taking place during compilation. Each compiler error message corresponds to an assigned error number. Refer to Appendix C for a summary of error messages listed in numerical order. Appendix C also provides suggestions on how to correct certain errors. The compiler displays both types of error message in the following format: filename: line number: Error number: message text The filename is the name of your input source file. The line number indicates which line in the source program contains the error. The number that follows the word Error in the message corresponds to the assigned error message number listed in Appendix C. The message text is a literal description of the error. The message text does not display if the DRC.ERR file is not on-line during compilation You can use compiler option switch -w to change the error message display level. You can have the compiler display all messages, suppress only the warning messages, or suppress all messages. Refer to Section 2.1.3, concerning the use of compiler option switches. 2.2 Start-up Routines and Stand-alone Programs A start-up routine controls the execution of a program. It sets up the operating environment for program execution by initializing the stack pointer, segment registers, and heap. The start-up routine is contained in the system library and linked into the executable program automatically. When the C compiler encounters the function name maino during compilation, the compiler generates a jump instruction to a routine named -START. -START is the standard start-up routine in the system library that sets up the operating environment to execute a program under DOS or CP/M-869 . After setting up the environment, START calls the program's "main" routine for execution. The Wmain" routine returns control to START at the conclusion of execution. Lastly, _START calls the ERIT function to return control to the operating system. The source file named STARTUP.A86 on one of your C product disks is an example of a start-up routine written in assembly language. Study STARTUP.A86 to learn more about start-up routines. You can compile and link programs intended for stand-alone execution. Stand-alone programs do not use the support services of an operating system, but interface directly with the system hardware. In other words, a stand-alone program is a systems level program such as an operating system. 2-15 C Language Programmer's Guide 2.2 Start-up Routines A stand-alone program accesses certain machine support subroutines in the system library, such as the long divide and long shift routines. You cannot access machine support subroutines explicitly. The compiler generates code to access them implicitly. To create an executable stand-alone program, object modules created with the C compiler must be linked with the appropriate system library and a start-up routine that sets up the desired target operating environment. Remember, when the C compiler encounters the function name maino during compilation, the compiler generates a jump instruction to a routine named START. The - START module in the system library sets up the operating environment for DOS or CP/M-86. You must write a new start-up routine for your new target environment. The new start-up routine that you write must also be named - START. However, when linking the program, your new start-up routine module must appear first in the LINK-86 command line. As a result, LINK-86 does not link in the standard -START that is contained in the system library. LINK-86 produces an EXE file that is executable in your desired target environment. The following LINK-86 command line example creates a stand-alone program named PROG from the object modules MOD1.OBJ, MOD2.OBJ, and MOD3.OBJ. The file STARTUP1.OBJ contains the start-up routine, _START, specially written for the target environment. LINK-86 searches the default drive automatically for the proper system library. B>LINK86 PROG=STARrUPl,NODl,NOD2,NOD3 Note that the start-up module must appear first in the LINK-86 command line. The system library must always appear after the new start-up module in the command line if the system library is specified explicitly. The object modules can appear in any order You can specify a different drive location for the system library in the link command line. The following example links the three object modules with the compact model library. The library is on the d drive. B>LINK86 PROG=STARTUP1,MODI,MOD2,MOD3,d:SYSLIBC.L86[SI The LINK-86 search option, [S] , after the library specification selects only the routines from the library that the program requires. If you omit the search option, LINK-86 links the entire library into the EXE file, making the executable program unnecessarily large. You can use the LINK-86 MAP option to make sure the proper routines are loaded from SYSLIB. Refer to the Programmer's Utilities Guide for more information on LINK-86. 2.3 Reverse Preprocessor Operation The reverse preprocessor program, DRCRPP.EXE, is useful to determine how the compiler's preprocessor module, DRC860.EXE, handles macro ~ ~MlkjUa~j~ rLUqLC11R1[ML Z k3U~LU~ 4 . j lk~vcln" rLCpLuk-u5nul instruction expansions. This can be handy when the compiler reports confusing error messages pertaining to macros. The preprocessor module creates a temporary work file during compilation named CTEMP.TOK. If you use the -p compiler option, the compiler stops after executing the preprocessor module and leaves CTEMP.TOK on disk. The reverse preprocessor program accepts the data in CTEMP.TOK as input and generates a modified version of your original compiler input file. The reverse preprocessor incorporates all #include files and expands all macro instructions to generate the modified file. Use the following command line to invoke the reverse preprocessor: B>DRCRPP DRC TEST -V3 -C -OTESTCPT.OBJ Note that you must place at least one space between each option switch specification in the command line. The -c option switch directs the compiler to compile TEST.C according to the compact memory model. The -v3 option switch tells the compiler to display the name of each program module and function as the compiler processes it. Remember, -v3 automatically activates -vl. Therefore, the compiler also displays general information messages. C Language Programmer's Guide 2.5 TEST.C However, -v2 and -v3 are mutually exclusive. Refer to Section 2.1.3 for more information on option switches. The -c option tells the compiler to name the object file TESTCPT.OBJ to better identify the file as a compact model object file. Note that you do not have to specify the C filetype for the source program explicitly in the command line. If you do not specify a filetype, the compiler first searches for the filename with no filetype. If the compiler cannot find the filename with no filetype, it automatically searches for that filename with a X filetype. If the compiler cannot find the filename with a C filetype, it prints the message "Unable to open filename.C for output". The following output should appear on your terminal screen: Digital Research C Version X.X Serial No. XXXX-XXXX-XXXXXX All Rights Reserved Copyright (c) 1983 Digital Research, Inc. -------------------------------------------------- Digital Research C Version X.X -- Preprocessor Compact Computation Model enabled Using test.obj as output file Digital Research C Version X.X -- Code Gen Processing: main test.c: code: 350 static: 695 extern: 36 B> The compiler displays the sign-on banner first. During processing, the preprocessor and the parser/code generator modules display their sign-on messages indicating execution. The compiler displays general information messages and the name of each module and function processed in the TEST.C program, as requested with the -v3 option switch. In the preceding display, "Compact Computation Model enabled" and "Using test.obj as output file" are general information messages. "Processing: main" indicates that there is only one function in TEST.C named "main". The memory allocation message appears last. Section 2.1.4 describes the different parts of the memory allocation message. If you get no error messages, TEST.C has been compiled successfully. Section 2.1.5 explains error messages. 2-23 The compiler creates the relocatable object program named TESTCPT.OBJ according to the compact memory model. If you are using two separate work disks, copy TESTCPT.OBJ onto the disk that contains LINK-86 and the compact model library. 3) Linking TEST.OBJ The compiler creates a special object record in TESTCPT.OBJ. The record contains information that tells LINK-86 which system library to search for any required routines. LINK-86 searches the library automatically if the library is on the default drive, as it is in this example. Enter the following command. Be sure drive B is the default drive. B>LINK86 TIKSTCPT LINK-86 assumes a OBJ filetype for the object files in the command line unless you specify otherwise. A sign-on banner and some memory allocation messages display on your terminal as shown below. The values in the allocation messages might vary for programs compiled with different versions of the C compiler. --------------------------------------------------- LINK86 Linkage Editor Version X.X Serial No. XXXX-XXXX-XXXXXX All Rights Reserved Copyright (c) 1982,1983 Digital Research, Inc. --------------------------------------------------- CODE 03E88 DATA 01OA8 USE FACTOR: 07% B> If you get no error messages, the program has been linked successfully. LINK-86 creates the directly executable program. A directory for disk B should have the new command file TESTCPT.EXE. If the system library is not on the default drive, LINK-86 displays the NO FILE error message, indicating that you must specify the appropriate drive explicitly in the link command line. For example, the following command line links TESTCPT.OBJ with the compact model system library on the D: drive. B>LIMK86 TEST, D:SYSLIBS.L86[S] 2-24 The SEARCH option, [S] , after the library name, tells LINK-86 to select only the routines from the library that the program requires. If you omit the SEARCH option, LINK 86 links the entire library into the EXE file, making the executable program unnecessarily large. A LINK-86 command line input file is handy if you want to avoid having to type a long, complicated command line over and over. Command line input files work with the LINK-86 INPUT option. Refer to Section 7.11, "Command Input File Options," in the Programmer's Utilities Guide for more information. 4) Running TESTCPT.EXE To execute TESTCPT.EXE, enter the following command. Be sure drive B is the default drive. Notice that you do not have to spec i f y the . EXE f iletype expl ic itly f or TESTCPT.EXE. B>TESTCPT The following output should appear on your terminal. WELCOME TO DIGITAL RESEARCH C This sample program tests the C compiler, linker, and libraries. If the number in parentheses matches the number to the immediate left, each component is working properly. Test int math: 4567 * 10 = 45670 (45670) Test long int math: 1234 * 4567 = 5635678 (5635678) Test float math: 1.234 + 0.001 = 1.235 (1.235) Test double math: 5635678.0 / 1234.0 = 4567.0 (4567.0) Good Luck! B> You can compile, link, and run the TEST.C program according to any of the four memory models: small, medium, compact, or big. For example, if you want to try the medium model, use the -m compiler option to enable medium model compilation. Be sure to specify a different object file name to distinguish one model from another. You can use the -o compiler option to name the object file TESTMED.OBJ. 2-25 . I I If your C software does not operate correctly, check the system requirements listed in Section 1.1 and the run-time requirements listed in Section 1.2. Make sure your equipment complies with the specified guidelines. If you still cannot get your software to operate correctly, fill out the Software Performance Report included in your C product package. Describe your problem in detail and mail the report to the Digital Research Technical Support Center. A prompt reply will follow. End of Section 2 2-26 Section 3 C System Library The C system library, SYSLIB, is a collection of subroutines for input/output, dynamic memory allocation, system traps, and data conversion. SYSLIB is configured for four 8086 memory models: small, medium, compact, and big. Refer to Section 2.4 for a description of memory models. • SYSLIBS.1,86 • SYSLIBM.L86 • SYSLIBC.1,86 • SYSLIBB.1,86 All four SYSLIB files are on your C product disks. 3.1 UNIX V7 Compatibility The C system library is compatible with UNIX Version 7, allowing programs to move easily from UNIX to IBM DOS or CP/M-86. The system library simulates many UNIX operating system calls and features. However, IBM DOS does not support the following UNIX operating system calls. • the fork/exec, kill, lock, nice, pause, ptrace, sync, and wait primitives • the acct system call • the alarm function, or the stime, time, ftime, and times system calls • the dup and dup2 duplicate file descriptor functions • the getuid, getgid, geteuid, getegid, setuid, and setgid functions • the indir indirect system call • the ioctl, stty, and gtty system calls • the link system call • the chdir, chroot, mknod, mount, umount, mpx, pipe, pkon, pkof f , prof il, sync, stat, f stat, umask, and utime system calls • the phys system call 3-1 C Language Programmer's Guide J. I UIN.LA V1 k-ultipat-lul-LILY The following UNIX library functions are not available in C for DOS. o assert crypt DBM getenv getgrent, getlogin, getpw, and getpwent functions 13tol, lto13 monitor itom, madd, msub, mult, mdiv, min, mout, pow, gcd, and rpow nlist pkopen, pkclose, pkread, pkwrite, and pkfail plot popen, pclose sleep system ttyslot Entry points have been added to file open and creat calls to distinguish between ASCII and binary files. 3.2 System Library Routines This section presents the system library subroutines that you can reference explicitly in a C program. Subroutines in the system library that have one or two underscores preceding the function name or that have the function name in capital letters are not accessible directly. They are designed for access internally by other functions in the library. A directory of system library functions in Table 3-3 lists each function name in alphabetical order with the page number for the function explanation. Each explanation demonstrates proper use of the function with four categories of information: 1) Declarations: examples of proper variable type and storage class declarations. 2) Calling Syntax: the proper format used to reference the function. 3) Arguments: a description of the different parameters enclosed in parentheses that follow each function name. 4) Returns: a description of what each function returns. In certain cases, what a function actually does is most important and the return value is insignificant. V Language Vr6~MIEW9 UU188 3.) 3y6LU111 iiiU11111 IkUULIIILJ The declarations in this section use standard C type and storage class specifiers. However, PORTAB.H contains a set of variable type declaration keywords (Table 3-1) and storage class declaration keywords (Table 3-2) that you can use to ensure consistent internal representation of data types across different processors. Declaration keywords in PORTAB.H are macro definitions specified with #define. Using standard type specifiers can be unsafe in programs designed to be portable because of variations in internal representation among different compilers. For example, an integer declared with the keyword int might be 16-bits long on one processor and 32-bits on a different processor. However, an integer declared with the macro WORD is 16-bits on any processor. The standard 1/0 file STDIO.H already includes PORTAB.H. Therefore, if your program does not include STDIO.H, you must include PORTAB.H explicitly to use the macros shown in Tables 3-1 and 3-2. The specifier FILE used in this section is defined in STDIO.H. Refer to Chapter 7.6, "File Access," in The C Programming Language by Kernighan and Ritchie for additional information. Refer to Chapter 4.11, "The C Preprocessor," in The C Programmi!12 Languag by Kernighan and Ritchie for more information on file inclusion and macro substitution. The following tables show the portability macros for variable types and storage classes defined in PORTAB.H. Table 3-1. Variable Type Macro Definitions Macrc Standard Type LONG signed long (32 bits) WORD signed short (int) (16 bits) UWORD unsigned short (int) (16 bits) BOOLEAN short (int) (16 bits) BYTE signed char (8 bits) UBYTE unsigned char (8 bits) VOID void (function return) DEFAULT int Table 3-2. Storage Class Macro Definitions Macro Standard Class REG register variable LOCAL auto variable MLOCAL module static variable GLOBAL global variable definition EXTERN global variable reference 3-3 C Language Programmer's Guide 3.2 System Library Routines The C compiler accepts entry in both uppercase and lowercase; however, you must type all library function names in lowercase, as shown in the calling syntax portion of each function explanation. Table 3-3. System Library Function Directory F_T Page Function Page unction abs 3-6 isatty 3-33 access 3-7 log 3-34 atan 3-60 loglo 3-34 atoi 3-8 longjmp 3-53 atol 3-8 lseek 3-35 atof 3-8 malloc 3-10 brk 3-9 mktemp 3-36 calloc 3-10 open 3-37 chmod 3-11 opena 3-37 chown 3-11 openb 3-37 clearerr 3-22 perror 3-38 close 3-12 printf 3-40 Cos 3-13 putc 3-44 creat 3-14 putchar 3-44 creata 3-14 putl 3-44 creatb 3-14 puts 3-46 ctype 3-15 putw 3-44 execl 3-18 qsort 3-47 exit 3-17 rand 3-48 -exit 3-17 read 3-49 exp 3-19 realloc 3-10 fabs 3-20 rewind 3-26 fclose 3-21 rindex 3-32 fdopen 3-23 sbrk 3-9 feof 3-22 scanf 3-50 ferror 3-22 setjmp 3-53 fflush 3-21 sin 3-13 fgetc 3-27 sprintf 3-40 fgets 3-31 sqrt 3-54 fileno 3-22 sscanf 3-50 fopen 3-23 srand 3-48 fprintf 3-40 strcat 3-55 fputc 3-44 strcmp 3-56 fputs 3-46 strcpy 3-57 fread 3-25 strlen 3-58 free 3-10 strncat 3-53 freopen 3-23 strncmp 3-56 fscanf 3-50 strncpy 3-57 fseek 3-26 swab 3-59 ftell 3-26 ttyname 3-61 fwrite 3-25 tan 3-60 getc 3-27 tell 3-35 getchar 3-27 toascii 3-62 getl 3-27 tolower 3-62 getpass 3-29 toupper 3-62 gets 3-31 ungetc 3-63 getpid 3-30 unlink 3-64 getw 3-27 write 3-65 index 3-32 3-4 You can make direct calls to the operating system from a C program with the IBMDOS routine. The routine uses two arguments as shown in the f(5-1lowing syntax diagram. ret = -IBMDOS (argl, arg2) The first argument is the BDOS function number as defined in the operating system. The second argument depends on which BDOS function is called. Refer to your operating system manuals for more information on BDOS function calls. 3-5 abs Function The abs function returns the absolute value of a number. The abs function is implemented as a macro in STDIO.H. Therefore, arguments that involve side effects might not work as expected and should not be used. For instance a call to abs that uses the ++ operator in the argument increments the argument value twice. a = abs(*x++) increments the value x twice. Do not declare functions that are implemented as macros. Declarations: int val; int ret; /* can be any type Calling Syntax: ret = abs(val); Arguments: val the input value can be any number Returns: ret the absolute value of val, can be any type 3-6 access Function The access function checks whether the calling program can access a specified file. Under DOS, the file is accessible if it exists. Declarations: char *name; int mode; int ret, accesso; Calling Syntax: ret = access(name, mode); Arguments: name points to a null-terminated filename mode can be one of four values: 4 checks read access 2 checks write access 1 checks execute access 0 checks directory path access DOS ignores the 0 argument. Returns: ret -- 0 if file access is allowed or -1 if not allowed Note: DOS checks to see if the specified file exists. 3-7 atoi, atof, atol Functions The atoi, atof, and atol functions convert an ASCII digit string to an integer, float, or long binary number, respectively. The compiler ignores all leading spaces, but permits a leading sign. Conversion proceeds until the number of digits in the string is exhausted. Each function returns a 0 when there are no more digits to convert. See Chapter 2.7, "Type Conversions," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: char *string; int iret, atoio; long lret, atol(); double fret, atofo; Calling Syntax: iret = atoi(digit string) lret = atol(digit string) fret = atof(digit string) Arguments: digit string -- a pointer to a null-terminated string that contains the number to convert. Returns: iret atoi returns the converted string as an integer. lret atol returns the converted string as a long binary number. fret atof returns the converted string as a double precision floating-point number. Each function returns 0 when there are no more digits to convert. Note: the atoi, atof, and atol functions do not detect or report overflow. Therefore, you cannot specify a limit to the number of contiguous digits processed or determine the number of digits a function processes. 3-8 brk, sbrk Functions The brk and sbrk functions extend the dynamic portion of your program called the heap. The brk function sets the upper bound of the program to an absolute address. The upper bound is called the break in UNIX terminology. The sbrk function extends the program by an incremental number of bytes. See Chapter 8.7, "Example--A Storage Allocator," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: int ret, brko; char *addr; char *strt, *sbrko; int incr Calling Syntax: ret brk(addr); strt sbrk(incr); Arguments: addr the new break address incr the incremental number of bytes to extend the heap Returns: ret brk returns a 0 if successful, or a -1 if it fails. strt sbrk returns a pointer that marks the beginning of the allocated area, or a 0 if it fails. calloc, malloc, realloc, free Functions The calloc, malloc, realloc, and free functions manage a block of dynamic area in memory called the heap. The malloc function allocates space for the heap and returns the starting address of the area. The heap is an area of contiguous bytes aligned on a word boundary The sbrk function allocates additional heap space if necessary. The calloc function allocates space for an array. Specify the size of the array in bytes. See Chapter 7.9, "Some Miscellaneous Functions," in The C Programming Language by Kernighan and Ritchie for related information on the calloc function. The realloc function changes the size of a block and returns the starting address of the block. The free function releases a block previously allocated with these allocation functions. The free function can accept addresses returned from calloc, malloc, and realloc only. See Chapter 8.7, "Example--A Storage Allocator," in The C Programming Language for related information on the free function. Declarations: int size, number; char *ret, *addr, *malloco, *calloco, *realloco; Calling Syntax: ret = malloc(size); ret = calloc(number, size); ret = realloc(addr, size); free(addr); Arguments: size the number of bytes to allocate number the number of array elements to allocate addr points to the beginning of the allocated region Returns: ret -- the starting address of the allocated region if successful, and 0 if the function fails 3-10 chmod, chown Functions Under UNIX, the chmod and chown system calls allo ' w you to change the protection mode and owner ID of an existing file. DOS treats these calls as NO-OPS if the file exists. Declarations: char *name; int mode, owner, group, ret, chmodo, chowno; Calling Syntax: ret = chmod(name,mode); ret = chown(name,owner,group); Arguments: name points to a null terminated filename mode the new mode for the file owner the new owner of the file group the new group number Returns: ret -- 0 if the file exists, or -1 if the file does not exist 3-11 close Function The close function terminates access to a file or device. The close function acts on files that have been accessed with the open or creat functions. You must specify a file descriptor for the close function, not a stream address. The fclose function closes stream files. See Chapter 8.3, "Open, Creat, Close, Unlink," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: int ret, closeo, fd; Calling Syntax: ret = close(fd); Arguments: fd the file descriptor of the file to close Returns: ret 0 if the function succeeds, or -1 if the function detects an unknown file descriptor 3-12 cos, sin Function The cos function returns the trigonometric cosine for double precision floating-point numbers. The sin function returns the trigonometric sine for double-precision floating-point numbers. You must express all arguments in radians. Declarations: double coso; double sino; double val; double ret; Calling Syntax: ret = cos(val); ret = sin(val); Arguments: val a double-precision floating-point number that expresses an angle in radians Returns: ret the cosine or sine expressed in radians of the argument value Note: you can pass numbers declared as either float or double to cos and sin. Floats convert to double automatically. 3-13 creat, creata, creatb Function The creat, creata, and creatb functions create new disk files for regular, low-level access. All three functions return a unique number called a file descriptor. The file descriptor is a positive short integer used to identify a file in a C program. Under DOS the file descriptor can range from 0 to 15. Refer to Chapter 8.1, "File Descriptors," in The C Programming Language by Kernighan and Ritchie for more information on file descriptors. There is no difference between creat and creata. Both functions create ASCII files. Use creatb to create binary files. Chapter 8.2, "Low Level I/0--Read and Write," in The C Programming Language has related information on the creat function. Declarations: char *name; int mode; int fd, creato, creatao, creatbo Calling Syntax: fd = creat(name,mode); fd = creata(name,mode); fd = creatb(name,mode); Arguments: name a null-terminated filename string mode the UNIX file mode, ignored by DOS Returns: fd -- the file descriptor for the opened file or -1 if an error occurs Note: UNIX programs that use binary files compile successfully, but execute improperly. ctype Functions The file CTYPE.H defines a number of functions that classify ASCII characters. These functions test whether a character belongs to a certain character class. Each function returns a 0 if the classification test is false and a nonzero value if the test is true. See Chapter 7.9, "Some Miscellaneous Functions," in The C Programming Language by Kernighan and Ritchie for related 1-nformation on ctype tunctions. The following table defines the ctype functions. Table 3-4. ctype Functions Function Meaning isalpha(c) c is a letter. isupper(c) c is uppercase. islower(c) c is lowercase. isdigit(c) c is a digit. isalnum(c) c is alphanumeric. isspace(c) c is a white space character. ispunct(c) c is a punctuation character. isprint(c) c is a printable character. iscntrl(c) c is a control character. isascii(c) c is an ASCII character (< Ox8O). The white space characters are the space (Ox2O), tab (OxO9), carriage return (OxOd), line-feed (OxOa), and form-feed (OxOc) characters. Punctuation characters are not control or alphanumeric characters. The printing characters are the space (Ox2O) through the tilde (Ox7e) . A control character is less than a space (Ox2O) . Declarations: #include int ret; char c; /* or int c; 3-15 C Language Programmer's Guide ctype Functions Calling Syntax: ret = isalpha(c); ret = isupper(c); ret = islower(c); ret = isdigit(c) ; ret = isalnum(c) ; ret = isspace(c) ; ret = ispunct(c); ret = isprint(c); ret = iscntrl(c) ; ret = isascii(c); Arguments: c -- the character to classify Returns: ret -- 0 if the classification test is false, or a nonzero value if the test is true Note: the ctype functions are implemented as macros. Therefore, arguments that involve side effects, such as *p++, might not work as expected and should be avoided. The functions return meaningless values if arguments are not ASCII characters. Do not declare functions that are implemented as macros. 3-16 C Language Programmer's Guide exit, -exit Functions exit, -exit Functions The exit function passes control to DOS. An optional completion code might return. The completion code is operating system dependent. DOS does not support the code. exit deallocates all memory and closes any open files. exit also flushes the buffer for stream output files. The -exit function immediately returns control to DOS, without flushing or closing open files. See Chapter 7.7, "Error Handling- Stderr and Exit," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: int code; Calling Syntax: exit(code); -exit(code); Arguments: code -- the optional, system-dependent completion code Returns: No return values 3-17 execl Function The execl function passes control from an executing C program to another C program. You can chain any number of C programs for execution. However, once you pass control to a new program, you cannot effectively return to the original program. The new program overlays the original program in memory. Therefore, if you chain back to the original program, all data from the first execution are lost. Specify the name of a file that contains the program to chain to and any arguments that the new program needs during execution. You must have at least one argument in addition to the filename. The argument must point to a null-terminated string that is the same as the filename string. This calling syntax procedure is based on UNIX conventions. Declarations: int execl(); char *name, *argl, *arg2; Calling Syntax: ret = execl(name, argl, arg2, ..., NULLPTR); Arguments: name a pointer to a null-terminated filename string argX pointers to null-terminated character strings NULLPTR macro defined in PORTAB.H equal to 0 Returns: ret -- -1 if the function fails Note: if execl returns to the original program, an error has occurred. The function returns a -1 and the errno external variable is set to indicate the error. Refer to the perror function for additional information. 3-18 exp Function The exp function returns the constant e raised to a specified exponent. The constant e is the base of natural logarithims equal to 2.71828182845905. Declarations: double val; double ret; double expo; Calling Syntax: ret = exp(val); Arguments: val the exponent expressed as a double-precision floating-point number Returns: ret the value of e raised to the specified exponent Note: you can pass numbers declared as either float or double to exp. Floats convert to double automatically. 3-19 fabs Function The fabs function returns the absolute value of a double-precision floating-point number. Declarations: double ret; double fabso; double val; Calling Syntax: ret = fabs(val); Arguments: val a double-precision floating-point number Returns: ret the absolute value of the floating-point number Note: you can pass numbers declared as either float or double to fabs. Floats convert to double automatically. 3-20 fclose, Mush Functions The fclose function writes all data in a stream file to disk and closes the file. The fflush function writes all data in a stream file to disk but leaves the file open. A pointer identifies the stream to close. See Chapter 7.6, "File Access," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: int ret, fcloseo, fflusho; FILE *Stream; Calling S ntax: ret = fclose(stream); ret = fflush(stream); Arguments: stream -- a pointer to a stream file control structure Returns: ret -- 0 if the function succeeds, or -1 if the function encounters a bad stream address or a write failure 3-21 feof, ferror, clearerr, fileno Functions The feof, ferror, clearerr, fileno functions enable stream file manipulation in a system-independent manner. Use the feof function to detect the end-of-file in a stream. Use the ferror function to detect errors in a stream file. The clearerr function clears any error detected. This is most useful for functions such as putw, where no error indication returns for output failures. The fileno function returns the file descriptor associated with an open stream. See the fdopen function. Declarations: int ret, fd; int feofo, ferroro, filenoo; FILE *stream; Calling Syntax: ret = feof(stream); ret = ferror(stream); clearerr(stream); fd = fileno(stream); Arguments: stream -- a pointer to a stream file control structure Returns: ret feof returns a nonzero value if the specified stream is at the end-of-file, and zero if it is not. ret ferror returns a nonzero value if an error occurs in a specified stream file. clearerr returns no value fd -- fileno returns the file descriptor associated with the specified file. 3-22 fopen, freopen, fdopen Functions The fopen, freopen, and fdopen functions associate an 1/0 stream with a file or device. The fopen and fopena functions are exactly the same. Both functions open an existing ASCII file for 1/0 as a stream. The fopenb function opens an existing binary file for 1/0 as a stream. See Chapter 7.6, "File Access," and Chapter 8.5, "Example--An Implementation of Fopen and Getc," in The C Programming Language by Kernighan and Ritchie for related information on fopen. The freopen and freopa functions substitute a new ASCII file for an open stream. The freopb function substitutes a new binary file for an open stream. The fdopen function adds a stream file control structure to a file opened for regular access. Declarations: FILE *fopeno, *fopenao, *fopenbo; FILE *freopeno, *freopao, *freopbo; FILE *fdopeno; FILE *stream; char *name, *access; int fd; Calling Syntax: stream = fopen(name, access); stream = fopena(name, access); stream = fopenb(name, access); stream = freopen(name, access, stream); stream = freopa(name, access, stream); stream = freopb(name, access, stream); stream = fdopen(fd, access); Arguments: name a pointer to a null-terminated filename string stream a pointer to a btredai file cunLrol structure access the access string can be one of three characters: r read the file w write the file a append to a file 3-23 Returns: stream -- the stream address if the function succeeds, or 0 if the function fails Note: UNIX programs that use fopen on binary files compile and link correctly, but execute improperly. 3-24 fread, fwrite Functions The fread and fwrite functions transfer a stream of bytes between a stream file and primary memory. fread transfers bytes from a stream file to memory. fwrite transfers bytes from memory to a stream file. Declarations: int freado, fwriteo; char *buff; int size, nitems; FILE *stream; Calling Syntax: nitems = fread(buff, size, nitems, stream); nitems = fwrite(buff, size, nitems, stream); Arguments: buff the primary memory buffer address size the number of bytes in each item nitems the number of items to transfer stream points to an open stream file Returns: nitems the number of items read or written, or 0 if an error occurs, including EOF 3-25 fseek, ftell, rewind Functions The fseek, ftell, and rewind functions position the read/write pointer in a stream file. fseek and rewind have no effect on a console or listing device. ftell returns a meaningless value for nonfile devices. The fseek function sets the read/write pointer to an arbitrary offset in the stream. The rewind function sets the read/write pointer to the beginning of the stream. The ftell function returns the present position of the read/write pointer in the stream. Declarations: int ret, fseeko, rewindo; FILE *stream; long offset, ftell(); int ptrname; Calling Syntax: ret = fseek(stream, offset, ptrname); ret = rewind(stream); offset ftell(stream); Arguments: stream points to a stream file offset a signed offset measured in bytes ptrname The offset can start from one of three points. 0 from beginning of file 1 from current position 2 from end of file Returns: ret 0 if the function succeeds and -1 if it fails offset current position of the pointer in the stream Note: ASCII file seek and tell operations do not account for carriage returns. The functions delete carriage returns. A CTRL-Z character at the end of the file is handled properly. 3-26 getc, getchar, fgetc, getw, getl Functions The getc, getchar, fgetc, getw, and getl functions perform input from a stream. The getc function reads a single character from an input stream. This function is implemented as a macro in STDIO.H. Arguments do not create side effects. The getchar function reads a single character from the standard input. It is identical to getc(stdin) in all respects. See Chapter 7.2, "Standard Input and Output--Getchar and Putchar," and Chapter 7.6, "File Access," in The C Programming Language by Kernighan and Ritchie for related information on getc and getchar. The fgetc function is a function implementation of getc, used to reduce object code size. The getw function reads a 16-bit word from a stream, high-order byte first. getw is compatible with the read function. No special alignment is required. The getl function reads a 32-bit long integer from a stream, in 8086 byte order. No special alignment is required. Declarations: int icharac, getcharo, fgetco; FILE *stream; int iword, getwo; long ilong,getl(); Calling Syntax: icharac = getc(stream); icharac = getcharo; icharac = fgetc(stream); iword = getw(stream); ilong = getl(stream); Arguments: stream a pointer to a stream file control structure Returns: ichar the character read from the stream iword the word read from the stream ilong the long word read from the stream, or -1 if a read failure occurs 3-27 Note: errors that return from getchar are incompatible with UNIX prior to UNIX Version 7. Errors that return from getl or getw are valid values that might normally occur in a file. Use feof or ferror to detect an end-of-file or read error. 3-28 getpass Function The getpass function reads a password from the console device. The function issues a specified prompt, then reads the input response without echoing the input to the console. The function returns a pointer that points to the password, which is a null terminated string. The st,ring can contain eight or fewer characters. Declarations: char *prompt; char *getpass; char *pass; Calling Syntax: pass = getpass(prompt); Arguments: prompt -- a pointer to a null-terminated prompt string Returns: pass -- a pointer to the password Note: the return value points to static data that is overwritten upon each call to getpass. 1~ 3-29 getpid Function The getpid function is provided for UNIX V7 compatibility and serves no purpose under DOS. Under UNIX, getpid returns a dummy process ID. Under DOS the return value is unpredictable. Declarations: int pid, getpido; Calling Syntax: pid = getpido; Arguments: getpid uses no arguments Returns: pid -- a dummy process-ID on single-tasking operating systems 3-30 gets, fgets Functions The gets and fgets functions read strings from stream files. fgets reads a string including a newline (line-feed) character. gets deletes the newline and reads only from the standard input. Both functions terminate the strings with a null character. You must specify a maximum character count with fgets, but not with gets. This count includes the terminating null character. See Chapter 7.8, "Line Input and Output," in The C Programming Language by Kernighan and Ritchie for related information on fgets. Declarations: char *addr; char *stg; char *getso, *fgetso; int max; FILE *stream; Calling Syntax: addr = gets(stg); addr = fgets(stg, max, stream); Arguments: stg pointer to a null terminated string max the maximum character count stream points to the input stream Returns: addr -- the string address 1~ 3-31 index, rindex Functions The index and rindex functions locate a specified character in a string. index returns a pointer to the first occurrence of the character. rindex returns a pointer to the last occurrence of the character. See Chapter 4.1, "Basics," in The C Programming Language by Kernighan and Ritchie for related information on index. Declarations: char charac; char *stg; char *Ptr; char *indexo, *rindexo; Calling Syntax: ptr = index(stg, charac); ptr = rindex(stg, charac); Arguments: stg pointer to a null-terminated string charac the character to look for Returns: ptr -- the address of the specified character, or 0 if the character does not occur in the string 3-32 %, DalIqUO%JU CLVIJLctjjjItjCL o ~U~U= isatty Function A DOS program can use the isatty function to determine whether a file descriptor is attached to the DOS console device (CON). Declarations: int ret, isattyo, fd; Calling Syntax: ret = isatty(fd); Arguments: fd an open file descriptor Returns: ret 1 if the file descriptor is attached to CON, and 0 if not attached to CON 3-33 log, loglO Function The log function returns the natural logarithim of a double precision floating-point number. The loglO function returns the base 10 logarithim of a double-precision floating-point number. Declarations: double val; double ret; double logo; double loglO(); Calling Syntax: ret = log(val); ret = loglO(val); Arguments: val a double-precision floating-point number Returns: ret the natural or base 10 logarithim of the double-precision floating-point number Note: you can pass numbers declared as either float or double to log and loglO. Floats convert to double automatically. 3-34 - -alIqUage ~LUqLC11W1tt=L ~ ~U~Ue Iseek, tell Function The lseek function positions a file referenced with a file descriptor to an arbitrary offset. Do not use'this function with stream files, because the data in the stream buffer might be invalid. Use the fseek function with stream files. See Chapter 8.4, "Random Access--Seek and Lseek," in The C Programming Language by Kernighan and Ritchie for related information. The tell function determines the file offset for an open file descriptor. Declarations: int fd; int ptrname; long offset; long ret, lseeko, tell(); Calling Syntax: ret = lseek(fd, offset, ptrname); ret = tell(fd); Arguments: fd the open file descriptor offset a signed byte offset in the file ptrname the offset interpretation, can be one of three numbers: 0 - from the beginning of the file 1 - from the current file position 2 - from the end of the file Returns: ret -- resulting absolute file offset, or -1 if an error occurs Note; these functions are incumpdtible with version5 1 throuyh 6 of UNIX. 3-35 C Language Programmer's Guide mktemp Function mktemp Function The mktemp function creates a temporary filename. The calling argument is a character string ending in six X characters. The temporary filename overwrites these characters. Declarations: char *string; char *mktempo; Calling Syntax: string mktemp(string) Arguments: string the address of the template string Returns: string the original address argument 3-36 C Language Programmer's Guide open, opena, openb Functions open, opena, openb Function The open and opena functions open an existing ASCII file with a file 10-1 descriptor. The openb function opens an existing binary file. You can open a file for reading, writing, or updating. See Chapter 8.3, "Open, Creat, Close, Unlink," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: char *name; int mode; int fd, openo, openao, openbo; Calling Syntax: fd = open(name, mode); fd = opena(name, mode); fd = openb(name, mode); Arguments: name points to a null-terminated filename string mode type of access, can be one of three values: 0 - Read-Only 1 - Write-Only 2 - Read-Write (update) Returns: fd -- the file descriptor to access the file or -1 if the function fails Note: UNIX programs that use binary files compile correctly, but execute improperly. 3-37 perror Function The perror function writes a short message on the standard error file that describes the last operating system error to occur. The function prints a prefix string specified as a perror argument, then a colon and the error message. The system library simulates the UNIX notion of an external variable, errno, that contains the last error to return from the operating system. The perror function and the errno external variable report errors that occur during a DOS system call. The #include file ERRNO.H contains symbolic definitions for the errors that DOS returns. The ERRNO.H file also includes the names for all errors defined in UNIX V7. Therefore, you do not have to change programs that reference these definitions. The following table lists error numbers, symbolic names, and messages available that perror can report. Table 3-5. perror Error Codes Number Name Error Message 0 Error undefined on DOS 1 Error undefined on DOS 2 ENOENT No Such File 3 Error undefined on DOS 4 Error undefined on DOS 5 EIO 1/0 Error 6 Error undefined on DOS 7 E2BIG Arg List too Long 8 Error undefined on DOS 9 EBADF Bad file Number 10 Error undefined on DOS 11 Error undefined on DOS 12 ENOMEM Not enough core 13 EACCES Permission denied 14 - Error undefined on DOS 15 - Error undefined on DOS 16 - Error undefined on DOS 17 - Error undefined on DOS 18 - Error undefined on DOS 19 - Error undefined on DOS 20 - Error undefined on DOS 21 - Error undefineU oil DOS 22 EINVAL Invalid argument 23 ENFILE File table overflow 24 EMFILE Too many open files 25 ENOTTY Not a typewriter 26 Error undefined on DOS Table 3-5. (continued) Number Name Error Message 27 EFBIG File too big 28 ENOSPC No space left on device 29 Error undefined on DOS 30 EROFS Read-Only file system 31 - Error undefined on DOS 32 - Error undefined on DOS 33 - Error undefined on DOS 34 - Error undefined on DOS 35 ENODSPC No directory space Declarations: char *s; Calling Syntax: perror(stg); Arguments: stg -- points to the prefix string to print Returns: perror does not return a value. Note: certain error messages are not defined in DOS. 3-39 printf, fprintf, sprintf Function The printf functions convert and format data for output. To reference a printf function, you specify a format string and a series of arguments to format. The format string consists of a series of conversion specifications. The number of conversion specifications in the format string must match the number of arguments that follow. Each conversion specification corresponds to one argument. The function converts and formats each argument consecutively as listed in the function reference. See the following page for more information on format strings. The printf function outputs to the standard output file. The fprintf function outputs to an arbitrary stream file. The sprintf function outputs to a string (memory) . Refer to Chapter 7.3, "Formatted Output--Printf," and Chapter 7.6. "File Access," in The C Programming Language by Kernighan and Ritchie for more details on Ch-ese three f-unc-F-Ions. Declarations: int ret, printfo, fprintfo; char *format; FILE *stream; char *string; char rst, *sprintfo; /* Args can be any type Calling Syntax: ret = printf (format, argl, arg2 ... ret = fprintf(stream, format, argl, arg2 ... rst = sprintf(string, format, argl, arg2 ... Arguments: format the format string argX the data arguments to format stream points to a stream file opened for output string points to a string buffer 3-40 Returns: ret the number of characters output, or -1 if an error occurs rs points to the string buffer, or 0 if an error occurs Format Strings: A percent sign, %, in the format string indicates the start of a conversion specification. After the percent sign, you can use a combination of reserved formatting symbols, digits strings, and conversion characters to specify a particular format for the data. Conversion characters operate primarily on numeric data and must appear last in a conversion specification. If a character after the percent sign is not a reserved formatting symbol, digit, or conversion character, the function prints that character literally. Table 3-6 defines the conversion characters. Table 3-6. Output Conversion Characters Operator T Meaning d Converts a binary number to decimal ASCII and inserts in output stream. 0 Converts a binary number to octal ASCII and inserts in output stream. x Converts a binary number to hexadecimal ASCII and inserts in output stream. c Uses the argument as a single ASCII character. s Uses the argument as a pointer to a null-terminated ASCII string, and inserts the string into the output stream. lo-I Table 3-6. (continued) Operator Meaning u Converts an unsigned binary number to decimal ASCII and inserts in output stream. % Prints a % character. f Converts a float or double number to ASCII decimal and inserts in output stream. The precision string controls the number of decimal places. Default is six digits to the right of the decimal point. e Same as f, except number converts to scientific notation. 9 Converts float or double numbers using the d, f, or e conversion character depending on which yields the full precision with a minimum number of characters. The input value must be float or double. You can use the following reserved formatting symbols and digit strings between the percent sign and a conversion character. Remember, the conversion character must appear last in a conversion specification. • A minus sign, -, justifies the converted output to the left, instead of the default right justification. • A digit string specifies a field width. This value gives the minimum width of the output field. If the digit string begins with a 0 character, zero padding results instead of blank padding. An asterisk, *, takes the value of the width field as the next argument in the argument list. 3-42 A period, ., separates the field width from the precision string. A digit string that follows a period specifies the precision for floating-point conversion. The precision is the number of digits that follow the decimal point. An asterisk tells the function to use the value of the precision field from the next argument in the argument list. The character L or 1 specifies a 32-bit long value. 1~ 3-43 putc, putchar, fputc, putw, putl Functions The putc, putchar, fputc, putw, and putl functions output characters and words to stream files. The putc function outputs a single 8-bit character to a stream file. This function is implemented as a macro in STDIO.H. Therefore, do not use arguments that involve side effects. Do not declare functions that are implemented as macros. The fputc function is equivalent to putc. However, fputc is not implemented as a macro The putchar function outputs a character to the standard output stream file. This function is also implemented as a macro in STDIO.H. Avoid using functions that involve side effects with putchar. In The C Programming Language by Kernighan and Ritchie, Chapter 7.6, "File Access," has related information on putc and Chapter 7.2, "Standard Input and Output--Gerchar and Putchar," has related information on putchar. The putw function outputs a 16-bit word to a specified stream file. The word is output high-order byte first and is compatible with the write function call. The putl function outputs a 32-bit longword to a specified stream file. The bytes are output in 8086 order like the write function call. Declarations: char charac; FILE *stream; int ret, fputco, wrd, putwo; long lret, putl(), lng; Calling Syntax: ret = putc(charac, stream); ret = fputc(charac, stream); ret = putchar(charac); ret = putw(wrd, stream); lret = putl(lng, stream); Argumcnts: charac the character to output stream points to the output stream file wrd the word to output lng the long to output Returns: ret -- the word or character output, -1 indicates an output error lret -- the long output with putl, -1 indicates an output error Note: a -1 return from putw or putl is a valid integer or long value. Use ferror to detect write errors. 3-45 puts, fputs Function The puts and fputs functions output a null-terminated string to an output stream. Neither routine copies the trailing null to the output stream. The puts function outputs a null-terminated string to the standard output, and appends a newline character. The fputs function outputs the string to a specified output stream. The fputs function does not append a newline character. Chapter 7.8, "Line Input and Output," in The C Programming Language by Kernighan and Ritchie has related iiiformation on fputs. Declarations: int ret, putso, fputso; char *stg; FILE *stream; Calling Syntax: ret = puts(stg); ret = fputs(stg, stream); Arguments: stg the string to be output stream the output stream Returns: ret -- the last character output or -1 if an error occurs Note: the inconsistency between puts and fputs is required for compatibility with UNIX. 3-46 qsort Function The qsort function is a quick sort routine. You supply a vector of elements and a comparison function that compares two elements. The qsort function sorts the elements in the vector according to your comparison function. A vector is a series of elements specified by a base address, the number of elements in the vector, and the size of each element in bytes. A call to the comparison function that you write must use the following format: return = compare(a,b); Your comparison function must return values according to the following criteria: return value is < 0 if a < b return value is = 0 if a = b return value is > 0 if a > b Declarations: int ret, qsorto; char *base; int number; int size; int compareo; Calling Syntax: ret = qsort(base, number, size, compare); Arguments: base the base address of the element vector number the number of elements to sort size size of each element in bytes compare the address of the user written comparison function Returns: ret -- qsort always returns a value of 0 3-47 rand, srand Functions The rand and srand functions constitute the C language random number generator. Call srand with the seed to initialize the generator. Call rand to retrieve random numbers. The random numbers are C int quantities. Declarations: int srando, seed; int rnum, rando; Calling Syntax: rnum = srand(seed); rnum = rando; Arguments: seed an int random number seed Returns: rnum a random int number 3-48 read Function The read function reads data from a file opened with a file descriptor using open or creat. You can read any number of bytes, starting at the current file pointer. Under DOS, the most efficient reads begin and end on 128-byte boundaries. See Chapter 8.2, "Low Level I/0--Read and Write," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: int ret, reado; int fd; char *buffer; int bytes; Calling Syntax: ret = read(fd, buffer, bytes); Arguments: fd a file descriptor open for read buffer the buffer address bytes the number of bytes to be read Returns: ret -- number of bytes actually read, or -1 if an error occurs 3-49 scanf, fscanf, sscanf Functions The scanf functions convert data for input. The functions read characters from an input source, convert them according to a format string, and store them in specified arguments. Arguments must be pointers. The functions continue to read characters until the input field width is exhausted. To reference a scanf function, you specify the format string and a series of arguments. The format string consists of a series of conversion specifications. The number of conversion specifications in the format string must match the number of arguments that follow. Each conversion specification corresponds to one argument. See below for more information on format strings. The scanf function reads from the standard input, fscanf reads from an open stream f ile, and sscanf reads from a null-terminated string. Refer to Chapter 7.4, "Formatted Input--Scanf," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: char *format, *string; int nitems, scanfo, fscanfo, sscanfo; FILE *stream; /* args can be pointers of any type Calling Syntax: nitems = scanf(format, argl, arg2 ... nitems = fscanf(stream, format, argl, arg2 ... nitems = sscanf(string, format, argl, arg2 ... Arguments: format the control string argX pointers to locations to store converted data stream a stream file opened for input string null-terminated input string Returns: nitems the number of items converted, or -1 if an 1/0 error occurs 3-50 ___1 --------- - - Format String: Format strings for scanf functions consist of the following items: o Blanks, tabs, or newlines (line-feeds) that match optional white space in the input data. o An ASCII character (not %) that matches the next character of the input stream. o Conversion specifications, consisting of a leading %, an optional asterisk, *, and a conversion character. The asterisk tells the function to suppress assignment of the data and skip to the next one. Conversion characters indicate the interpretation of the input field. Table 3-7 defines valid conversion characters. Table 3-7. Input Conversion Characters Character Meaning % A single % matches in the input at this point; no conversion is performed. d Converts a decimal ASCII integer and stores it where the next argument points. 0 Converts an octal ASCII integer. x Converts a hexadecimal ASCII integer. s A character string, ending with a space, is input. The argument pointer is assumed to point to a character array big enough to contain the string and a trailing null character, which are added. c Stores a single ASCII character, including spaces. To f ind the next nonblank character, use %ls. 3-51 Table 3-7. (continued) Character Meaning h Converts a short integer. The corresponding argument must be a pointer to a short integer. e or f Converts a string to floating point binary. The corresponding argument should be double. Stores a string that does not end with spaces. The character string is enclosed in brackets. If the first character after the left bracket ~is not -, the input is read until the scan comes to the first character outside the brackets. If the first character after the left bracket is ^, the input is read until the first character within the brackets. Note: you cannot determine the success of literal matches and suppressed assignments. 3-52 setjmp, longjmp Function The setjmp and longjmp functions enable a program to execute a nonlocal GOTO. Use the setjmp function to save the program environment at specific point in the flow of execution and to specify a return location for the longjmp call. You can then call longjmp from any point after the setjmp call. The longjmp function simulates a return from a call to setjmp. First, longjmp returns a value to setjmp as specified in the second argument in the longjmp call. Secondly, execution continues at the instruction immediately following the setjmp call in the program. if the function that invokes setjmp returns before longjmp is called, the saved environment is lost. The setjmp function saves the program environment in a variable of type jmp_buf. The type jmp_buf is defined in the include file setjmp.h. Declarations: #include int xret, ret, setjmpo; jmp_buf env; Calling Syntax: xret = setjmp(env); longjmp(env, ret); Arguments: env contains the saved environment ret the desired return value from setimp Returns: xret 0 when setjmp is called initially, then copied from ret when longjmp is callea 3-53 sqrt Function The sqrt function returns the square root of a double-precision floating-point number. Declarations: double sqrto; double val; double ret; Calling Syntax: ret = sqrt(val); Arguments: val a double-precision floating-point number Returns: ret the square root of the specified double-precision floating-point number Note: you can pass numbers declared as either float or double to sqrt. Floats convert to double automatically. 3-54 k, IJULIqUOYC L1UqLU1LUUk..L 0 UULUU strcat, strncat Functions The strcat and strncat functions concatenate strings. The strcat function concatenates two null-terminated strings. The strncat function concatenates a null-terminated string and a specified number of characters from a second string. See Chapter 2.8, "Increment and Decrement Operators," in The C Programming Language by Kernighan and Ritchie for related information on the strcat function. Declarations: char *stgl, *stg2, *ret; char *strcato, *strncato; int max; Calling Syntax: ret = strcat(stgl, stg2); ret = strncat(stgl, stg2, max); Arguments: stgl the first string stg2 the second string, appended to stgl max the maximum number of characters in stgl Returns: ret points to the first string Note: if you use strcat(stgl,stgl) , the function does not terminate and usually destroys the operating system. The end-of-string marker becomes lost. Therefore, strcat continues until it runs out of memory, including memory the operating system occupies. 3-55 C Language Programmer's Guide strcmp, strncmp Functions strcmp, strncmp Function The strcmp and strncmp functions compare strings. The strcmp function compares two null-terminated strings. strncmp limits the comparison to a specified number of characters in each string. See Chapter 5.5, "Character Pointers and Functions," in The C Programming Language by Kernighan and Ritchie for related information on the strcmp function. Declarations: char *stgl, *stg2; int val, strcmpo, strncmpo, max; Calling Syntax: val = strcmp(stgl, stg2); val = strncmp(stgl, stg2, max); Arguments: stgl a null-terminated string address stg2 a null-terminated string address max the maximum number of characters to compare Returns: val the number of characters: < 0 if stgl < stg2 = 0 if stgl = stg2 > 0 if stgl > stg2 Note: different machines and compilers might interpret the characters as signed or unsigned. 3-56 C Language Programmer's Guide strcpy, strncpy Functions strcpy, strncpy Functions The strcpy and strncpy functions copy one null-terminated string to another. The strcpy function uses null-termination. strncpy specifies a maximum number of characters to copy. See Chapter 5.5, "Character Pointers and Functions," in The C Programming Language by Kernighan and Ritchie for related information on the s py function. Declarations: char *stgl, *stg2, *ret; char *strcpyo, *strncpyo; int n; Calling Syntax: ret = strcpy(stgl, stg2); ret = strncpy(stgl, stg2, max); Arguments: stgl the destination string stg2 the source string max the maximum character count Returns: ret points to the first string Note: if strncpy exceeds the maximum number of characters specified, the destination string is not null-terminated. 3-57 C Language Programmer's Guide swab Function swab Function The swab function copies one area of memory to another. The high and low bytes in the destination copy are reversed. You can use this function to copy binary data from a 68000 processor to an 8086 processor. The number of bytes to swap must be an even number. See Chapter 5.2, Pointers and Function Arguments," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: C Language Programmer's Guide strcpy, strncpy Functions strcpy, strncpy Functions The strcpy and strncpy functions copy one null-terminated string to another. The strcpy function uses null-termination. strncpy specifies a maximum number of characters to copy. See Chapter 5.5, "Character Pointers and Functions," in The C Programming Language by Kernighan and Ritchie for related information on the strcpy function. Declarations: char *stgl, *stg2, *ret; char *strcpyo, *strncpyo; int n; Calling Syntax: ret = strcpy(stgl, stg2); ret = strncpy(stgl, stg2, max); Arguments: stgl the destination string stg2 the source string max the maximum character count Returns: ret points to the first string Note: if strncpy exceeds the maximum number of characters specified, the destination string is not null-terminated. 3-57 C Language Programmer's Guide strlen Function strIen Function The strlen function returns the length of a null-terminated string. See Chapter 2. 3, "Constants, and 5. 3, "Pointers and Arrays, " in The C Programming Language by Kernighan and Ritchie for additional information. is Declarations: char *stg; int len, strleno; Calling Syntax: len = strlen(stg); Arguments: stg points to a string Returns: len the string length is 3-58 C Language Programmer's Guide swab Function swab Function The swab function copies one area of memory to another. The high and low bytes in the destination copy are reversed. You can use this function to copy binary data from a 68000 processor to an 8086 processor. The number of bytes to swap must be an even number. See Chapter 5.2, Pointers and Function Arguments," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: int ret, swabo; char *from, *to; int nbytes; Calling Syntax: ret = swab(from, to, nbytes); Arguments: from the address of the source buffer to the address of the destination nbytes the number of bytes to copy Returns: ret -- swab always returns 0 0 3-59 C Language Programmer's Guide tan, atan Function tan, atan Function The tan function returns the trigonometric tangent of a double precision floating-point number. The atan function returns the trigonometric arctangent of a double-precision floating-point number. You must express all arguments in radians. Declarations: double val; double ret; double tano; double atano; Calling Syntax: ret = tan(val); ret = atan(val); Arguments: val a double-precision floating-point number that expresses an angle in radians Returns: ret the tan or arctangent expressed in radians of the argument value Note: you can pass numbers declared as either float or double to tan and atan. Floats convert to double automatically. 0 3-60 C Language Programmer's Guide ttyname Function ttyname Function The ttyname function returns a pointer to the null-terminated filename of the console device associated with an open file descriptor. Declarations: char *name, *ttynameo; int fd; Calling Syntax: name = ttyname(fd); Arguments: fd -- an open file descriptor Returns: name -- If the file descriptor is open and attached to the DOS console device, the function returns a pointer to the null-terminated string CON. Otherwise, the function returns a NULL character. 3-61 C Language Programmer's Guide toascii, tolower, toupper toascii, tolower, toupper Functions The toascii, tolower, and toupper functions are character conversion functions implemented as macros in the include file CTYPE.H. You must include CTYPE.H in any program that uses any of these three functions. Do not declare functions that are implemented as macros. Arguments that involve side effects might work incorrectly and should be avoided. The tolower function converts an uppercase letter to the corresponding lowercase letter. The toupper function converts a lowercase letter to the corresponding uppercase letter. The toascii function simply turns off all bits in a character representation that are not part of a standard ASCII character. toascii is provided for compatibility with other systems. Declarations: #include int ret; Calling Syntax: ret = tolower(charac); 40 ret = toupper(charac); ret = toascii(charac); Arguments: charac -- a single character to convert Returns: ret -- the converted character Note: tolower and toupper can accept character arguments represented by integers in the range 0 to 255. C Language Programmer's Guide ungetc Function ungetc: Function The ungetc function pushes a character back to an input stream. The next getc, getw, or getchar operation incorporates the character. One character of buffering is guaranteed if something has been read from the stream. The fseek function erases any pushed back characters. You cannot use ungetc with EOF (-l) . See Chapter 7.9, "Some Miscellaneous Functions," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: char charac; FILE *stream; int ret, ungetc Calling Syntax: ret = ungetc(charac, stream); Arguments: charac the character to push back stream the stream address Returns: ret -- If the character is successfully pushed back, the function returns charac. If an error occurs, the function returns -1. 3-63 C Language Programmer's Guide unlink Function unlink Function The unlink function deletes a named f ile f rom the f ile system. The function fails if the file is open or nonexistent. See Chapter 8.3, "Open, Creat, Close, Unlink," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: int ret, unlinko; char *name; Calling Syntax: ret = unlink(name); Arguments: name points to a null-terminated filename Returns: ret 0 if the function succeeds, or -1 if the function fails 40 3-64 C Language Programmer's Guide write Function write Function The write function transfers data to a file opened with a file descriptor. Transfer begins at the present file pointer, as set by previous transfers or by the lseek function. You can write any arbitrary number of bytes to the file. The number of bytes actually written returns. If the number of bytes written does not match the number requested, an error has occurred. Under DOS, the most efficient writes begin and end on 128-byte boundaries. See Chapter 8.2, "Low Level I/0--Read and Write," in The C Programming Language by Kernighan and Ritchie for related information. Declarations: int ret, writeo; int fd; char *buffer; int bytes; Calling Syntax: ret = write(fd, buffer, bytes); Arguments: fd the open file descriptor buffer the starting buffer address bytes the number of bytes to write Returns: ret -- the number of bytes actually written, or -1 if an error occurs Note: due to the buffering scheme used, all data is not written to the file until the file is closed. End of Section 3 3-65 Section 4 Input/Output Conventions In C, all input and output is done by reading and writing files. Even peripheral devices such as your terminal are treated as files in a C program. A C program can access f iles in two dif f erent ways: as a regular f ile or as a stream f ile. C provides three input/output files called the standard 1/0 files that simplify input/output to your terminal and other common 1/0 sources. The C Programming Language by Kernighan and Ritchie does not use the terms regular and stream. However, the manual provides complete descriptions of both types of file access. In this section, we refer to the appropriate chapters in The C Programming Language that contain additional information. 4.1 Regular File Access Regular file access is considered low-level 1/0 because it provides no added services, such as data buffering. Regular access is a direct entry into the operating system. See Chapter 8.2, "Low Level I/0--Read and Write," in The C Programming Language by Kernighan and Ritchie for more information on low-level 1/0. To create a disk file for regular access, use the creat, creata, and creatb functions. All three functions return a unique number called a file descriptor. The file descriptor is a positive short integer used to identify the file in a C program. Under DOS, the file descriptor can range from 0 to 15. Refer to Chapter 8.1, "File Descriptors," in The C Programming Language by Kernighan and Ritchie for more information on file descriptors. Use creat and creata to create ASCII files and creatb to create binary files. DOS stores ASCII files with a carriage return and line-feed at the end of each line. A CTRL-Z character (Oxla) indicates the end-of-file. However, C programs normally end lines with only a line-feed. This means that in C for DOS, read and write operations for ASCII files must insert and delete carriage return characters where appropriate. Also, read operations for ASCII files must delete the terminating CTRL-Z, and close operations for ASCII files must insert the CTRL-Z when appropriate. Byte level end-of file is not available for binary files. Use the open, opena, and openb functions to open existing files for regular access. All three functions return a file descriptor. You annot use these functions to create new files. C Language Programmer's Guide 4.1 Regular File Access The following table contains all the system library functions you can use for regular file access. The page number refers to the function descriptions in Section 3. Table 4-1. Functions for Regular File Access 40 Function Page No. Function I Page No. close 3-11 opena 3-35 creat 3-13 openb 3-35 creata 3-13 read 3-49 creatb 3-13 tell 3-33 lseek 3-33 unlink 3-64 open 3-35 write 3-65 L 4.2 Stream File Access Unlike regular file access, stream file access employs a form of local buffering, making single-byte I/Omore efficient. Stream file access uses a 512-byte buffer, which corresponds to a physical blocksize on many peripheral devices. A stream is identified by a pointer to a data control structure that contains all the information relevant to the stream. Refer to Chapter 7.6, "File Access," in The C Programming Language by Kernighan and Ritchie for additional information. The following list contains all the system library functions you can use for stream file access. The page number refers to the function descriptions in Section 3. Table 4-2. Functions for Stream File Access Function Page No. Function Page No. fclose 3-19 ftell 3-24 fdopen 3-21 fwrite 3-23 feof 3-20 getc 3-25 ferror 3-20 getchar 3-25 fflush 3-19 getl 3-25 fgetc 3-25 gets 3-29 fgets 3-29 getw 3-25 fileno 3-20 printf 3-38 fopen 3-21 putc 3-44 fprintf 3-38 putchar 3-44 fputc 3-41 putl 3-44 fputs 3-43 puts 3-46 fread 3-23 putw 3-44 freopen 3-21 rewind 3-24 fscanf 3-50 scanf 3-50 fseek 3-24 ungetc 3-63 C Language Programmer's Guide 4.3 Peripheral Devices 4.3 Peripheral Devices Peripheral devices, such as your terminal or printer, are treated as files in C. Like UNIX, peripheral devices under DOS use special names for identification in a program. * CON stands for a console device o LPT1 stands for a listing device 4.4 Standard 1/0 Files C provides three files that simplify 1/0 procedures from common sources, such as your terminal. The three files are the standard input, standard output, and standard error files. You can access these files as either regular or stream files. A C program begins execution with all three files open and initially connected to your terminal. Therefore, a program can handle terminal 1/0 without having to open files explicitly. You can indicate a source other than the terminal and redirect 1/0 with the < and > characters. See Section 4.4.1. The standard 1/0 uses routines from the system library, SYSLIB. The file STDIO.H contains certain macro definitions and variables used by the system library routines for opening, closing, reading, and writing the standard 1/0 files. You must include STDIO.H in any source program that references a system library function. Remember, STDIO.H already includes the portability file PORTAB.H. Table 4-3 shows the definitions in STDIO.H for the standard 1/0 files. You can list STDIO.H to examine the entire file. Table 4-3. Standard 1/0 File Definitions File File Descriptor T St ream Name standard input 0 stdin standard output 1 stdout standard error 2 stderr 4.4.1 Input/Output Redirection You can redirect the flow of standard input and output from a command line using the < and > characters. Specify a filename or device after the < character to indicate an input source other than the terminal. The following example executes a file named PROG.EXE, with the standard input coming from a different file named INDAT. 40 prog character to indicate an output destination other than the terminal. The following example executes a file named PROG.EXE with standard input coming from a different file named INDAT and standard output going to the list device. prog lptl Refer to The C Programming Language by Kernighan and Ritchie for more information on 1/0 redirection. End of Section 4 4-4 Section 5 Assembler Routine Interfacing RASM-86 is an 8086/8088 relocatable assembler that uses a compatible subset of the ASM-86- assembly language. You can use RASM-86 to write assembly language programs that interface with C modules. RASM-86 generates relocatable object files compatible for linking with LINK-86. Refer to your Programmer's Utilities Guide for complete explanations of RASM-86 and LINK-86. This section defines the conventions and guidelines you must observe to properly interface C functions with assembly language routines. Section 5.4 presents a RASM-86 routine to assemble and a sample C module that you can link with the routine. The information presented in this section is for the experienced assembly language programmer. 5.1 External Naming Conventions Names for external functions and varibles are significant up to eight characters in Digital Research C, although you can use many more characters. The number of significant characters in external names varies for different compilers. For example, UNIX C compilers place an underscore character at the beginning of all external names, effectively making the names significant to seven characters only. For portability considerations, it is preferable to limit all external names to seven significant characters. Digital Research C does not prefix an underscore on external names. However, certain routines in the system library have one or two underscores preceding the function name. You must not attempt to reference these routines directly. They are designed for access internally by other functions in the library. RASM-86 converts all characters to uppercase. However, the C compiler distinguishes between uppercase and lowercase. Therefore, you must use all uppercase characters to specify assembler function names and to declare assembly routine variables in your C source code. The following examples show some proper and improper external names: ASM-ROUTINE0 Proper function name. C compiler recognizes the name as ASM ROUT. asm-routineo Improper function name. RASM-86 converts the name to uppercase. int CALCVALUE; Proper variable name. C compiler recognizes the name as CALCVALU. C Language Programmer's Guide 5.1 External Naming Conventions int CALC-VALUE; Proper variable name. C compiler recognizes the name as CALC-VAL. int calc-val; Improper variable name. RASM-86 converts the name to uppercase. 5.2 Calling an Assembly Routine from a C Module Three steps are required to call an assembly language routine from a C module. 1) Declare the function names external in the C source code using the C language extern declaration. Refer to Chapter 5.4, "Address Arithmetic," in The C Programming Language by Kernighan and Ritchie for more information on C external declarations. Remember, RASM-86 converts all characters to uppercase. Therefore, function names declared in the C program must be in uppercase. For example, the following C declarations specify FUNC_l, FUNC-2, and FUNC-3 as external functions: extern int FUNC 1(); extern int FUNC 2(); extern long FUNC-3(); 2) Declare the function names PUBLIC in the assembly routine using the RASM-86 PUBLIC directive. Refer to Section 3.7 in the Programmer's Utilities Guide for information on the PUBLIC directive. PUBLIC FUNC 1 PUBLIC FUNC 2 PUBLIC FUNC-3 3) Call or reference the assembly routines from the C module C Language Programmer's Guide 5.3 Calling a C Module 5.3 Calling a C Module from an Assembly Routine Two steps are required to call a C function from an assembly routine: 1) Declare the C function names external in the assembly routine using the RASM-86 EXTRN directive. Refer to Section 3.8 in the Programmer's Utilities Guide for information on the EXT directive. The following RASM-86 directive statements specify FUNC-1, FUNC-2, and FUNC-3 as external: EXTRN FUNC 1:NEAR EXTRN FUNC 2:NEAR EXTRN FUNC-3:NEAR Notice that the functions are labeled NEAR in the preceding EXTRN directives. You must use the NEAR label for modules designed according to the 8086 small and compact memory models. For modules designed according to the medium and big memory models, you must use the FAR label. 2) Call the C functions from the assembly routine. Notice that you do not have to explicitly declare the C functions as public in the C code. 5.4 Parameter Passing The following conventions apply to the passing of parameters in C • C functions pass parameters on the hardware stack. • The compiler places each parameter on the stack reading from right to left. • All parameters pass by value. • Parameters that evaluate to one byte pass as a word value. • Multiword values such as long integers, floats, and doubles, pass with the high-order word under the low-order word. * The called assembly routine must save and restore the contents of the SI and DI registers if the routine uses those registers. C Language Programmer's Guide 5.4 Parameter Passing When a C program calls a C function or an assembly routine, the compiler generates a standard entry/exit protocol that performs necessary manipulation of register contents. The extry/exit protocol is shown below. FUNCTION: ;start of entry protocol PUSH BP ;save old frame pointer MOV BP,SP ;set up new frame pointer PUSH DI PUSH SI ;save register variables SUB SP,nnn ;allocate any necessary locals ;end of entry protocol (the called function body) ;start of exit protocol LEA SP,-4[BP] ;reset stack pointer for pop POP SI ;restore register variables POP DI POP BP ;restore frame pointer RET ;use RETF for medium/big models Figures 5-1 and 5-2 show the stack upon entry to a hypothetical assembly language function named TESTFUNC. Figure 5-1 shows the stack for the small and compact memory models. Figure 5-2 shows the stack for the medium and big models. TESTFUNC has six parameters to pass as shown below. TESTFUNC(var_a, var-b, var-c, var_d, var_e, "greetings") The variables var-a through var-e have the following type definitions: int var-a; long var_b; char var c; float var d; double var_e; C Language Programmer's Guide 5.4 Parameter Passing OFFSET FROM STACK OFFSET FROM REGISTER SP REGISTER BP +0 RETURN ADDRESS +2 +2 VAR-A WORD VALUE +4 +4 VAR-13 LOW WORD +6 +6 VAR-B HIGH WORD +8 +8 VAR-C WORD VALUE +10 +10 VAR-D LOW WORD +12 +12 VAR-D LOW MID WORD +14 +14 VAR-D HIGH MID WORD +16 +16 VAR-D HIGH WORD +18 +18 VAR-E LOW WORD +20 +20 VAR-E LOW MID WORD +22 +22 VAR-E HIGH MID WORD +24 +24 VAR-E HIGH WORD +26 +26 POINTER TO "GREETINGS" +28 Figure 5-1. Stack for Small and Compact Model OFFSET FROM STACK OFFSET FROM REGISTER SP REGISTER BP +0 RETURN ADDRESS LOW WORD +2 +2 RETURN ADDRESS HIGH WORD +4 +4 VAR-A WORD VALUE +6 +6 VAR-B LOW WORD +8 +8 VAR-13 HIGH WORD +10 +10 VAR-C WORD VALUE +12 +12 VAR-D LOW WORD +14 +14 VAR-D LOW MID WORD +16 +16 VAR-D HIGH MID WORD +18 +18 VAR-D HIGH WORD +20 +20 VAR-E LOW WORD +22 +22 VAR-E LOW MID WORD +24 +24 VAR-E HIGH MID WORD +26 +26 VAR-E HIGH WORD +28 +28 POINTER TO "GREETINGS" +30 Figure 5-2. Stack for Medium and Big Model The compiler statically allocates space for the string constant "greetings", and passes a pointer to this static location as indicated in Figures 5-1 and 5-2. Note that floats always convert to double before passing as parameters. C Language Programmer's Guide 5.4 Parameter Passing Unlike most languages implemented for the 8086/8088, the calling C routine removes the parameters from the stack after returning from the called routine. The compiler generates an ADD SP, instruction in the C program immediately following the call to the assembly routine. The stands for the number of bytes pushed onto the stack. The instruction modifies the stack pointer, effectively removing the parameters. If you call a C routine from an assembly routine, you must modify the stack pointer explicitly in the assembly routine to remove the parameters. 5.5 Function Return Values The values that a function returns are passed back to the calling program in certain registers. Table 5-1 shows which registers contain the return values for each C data type. Table 5-1. Function Return Registers Data Type Registers int, char, short AX long, float High word in BX Low word in AX double High word in DX High middle word in CX Low middle word in BX Low word in AX 5.6 Accessing External Data The C compiler places each C program variable declared explicitly or implicitly external into a data segment with the common attribute. To access external variables from an assembly module, or to define such variables in an assembly module for access f rom a C module, you must define each variable as a separate common data segment in the assembly module. Consequently, the variable name becomes the segment name in the assembly module. You cannot reference segment names in an assembly routine. Therefore, you must assign new variable names and allocate space for each one. Three steps are required to access external data. 1) Declare the variables that the C program is to share with the assembly routine as external variables in the C source program. For example, consider a hypothetical assembly language.function call from a C program. ret = NEXTFUNC(VAR-1, VAR-2, VAR-3, VAR-4, VAR-5) C Language Programmer's Guide 5.6 Accessing External Data NEXTFUNC and its five parameters must be declared external in the calling C program. Remember, RASM-86 converts all characters to uppercase. extern float NEXTFUNCO; extern int VAR 1; extern long VAR 2; extern char VAR~-3; extern float VAR 4; extern double VAR-5; 2) Declare TESTFUNC as PUBLIC in the assembly routine. Then declare each parameter as a separate data segment within the assembly routine. You cannot declare the variables PUBLIC in the assembly routine. You must declare each data segment with a RASM-86 COMMON combine type. Refer to Section 3.2.3 in the Programmer's Utilities Guide for more information on combine types. Once the variable names are declared as segments, you can not reference them as local variables in the assembly routine. Therefore, if you plan to reference the variables as local in the routine, you must assign different names for proper access. Also, you must allocate storage for the variables using the appropriate RASM-86 allocation directives. Refer to Sections 3.14 through 3.17 in the Programmer's Utilities Guide for information on allocation jTrectives. PUBLIC TESTFUNC VAR 1 DSEG COMMON WORD VAR-ONE RW 1 VAR 2 DSEG COMMON WORD VAR7TWO RW 2 VAR 3 DSEG COMMON WORD VAR7THREE RB 1 VAR 4 DSEG COMMON WORD VAR FOUR RW 2 VAR 5 DSEG COMMON WORD VAR FIVE RW 4 C Language Programmer's Guide 5.6 Accessing External Data 3) Group all the COMMON data segments together into the data group (dgroup) using the RASM-86 GROUP directive. Refer to Section 3.3 in the Programmer's Utilities Guide for more information on the GROUP directive. DGROUP GROUP DATA is DGROUP GROUP VAR 1 DGROUP GROUP VAR 2 DGROUP GROUP VAR 3 DGROUP GROUP VAR-4 DGROUP GROUP VAR-5 End of Section 5 0 0 Section 6 Internal Data Representation There are only four fundamental data types in the C language: • character • integer • single-precision floating-point • double-precision floating-point This section describes the format that Digital Research C uses to represent each type internally. 6.1 Character Storage C stores a character value as a single, 8-bit, unsigned binary number, as shown in Figure 6-1. Character values are always positive numbers ranging from 0 to 255. Use the declaration keyword char to declare character data. I I x x x x x x x x BITS 7 6 5 4 3 2 1 0 Figure 6-1. Character Storage C Language Programmer's Guide 6.2 Integer Storage 6.2 Integer Storage There are two different sizes for integers: short and long. Short integers can be either signed or unsigned. C stores a short signed integer value as a 16-bit, two's complement binary number. Short signed integers range from -32768 to +32767, inclusive. You can use the keywords int or short to declare short signed integers. Use the keyword unsigned with int to declare unsigned short integers. Unsigned integers range from 0 to 65535. Figure 6-2 shows the storage format for short integers. -*--HIGH MEMORY LOW MEMORY-,*- HIGH ORDER BY TE I x x x x x x x x x x x x x x x x 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Figure 6-2. Short Integer Storage C stores a long integer as a 32-bit, two's complement binary number, as shown in Figure 6-3. Long integers are always signed numbers ranging from -2147483648 to +2147483647. Use the keyword long to declare long integers. -HIGH MEMORY LOW MEMORY BYTE3 BYTE2 BYTE1 BYTEO I 1 -1 1 1 --1 1 1 -11 1 1 ---1 x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x 31 24 23 16 15 8 7 0 Figure 6-3. Long Integer Storage C Language Programmer's Guide 6.3 Single-precision 6.3 Single-precision Floating-point C stores a single-precision floating-point number in four consecutive bytes using the IEEE format. The 32-bits contain three fields as shown in Figure 6-4: a sign bit, an 8-bit biased exponent, and a 23-bit mantissa with a 24th implicit normalized bit. The normalized bit is always 1 for nonzero numbers. The bit is recognized implicitly and is not stored. The binary point is situated to the immediate right of the normalized bit. The exponent has a bias of 7F hexidecimal (127 decimal) . Therefore, the hexidecimal number 80 represents an exponent of +1. The hexidecimal number 7E represents an exponent of -1. The mantissa is precise to 7 digits. Single-precision floating-point numbers range from 1.18 times 10 to the minus 38th power up to 3.40 times 10 to the 38th power (1.18*10**-38 <= jxj <=3.40*10**38). -HIGH MEMORY LOW MEMORY--*.- BYTE3 BYTE2 BYTE1 BYTEO I 1 -1 1 1 -1 1 1 -1 1 1 --1 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X 31 30 23 22 0 BIASED EXPONENT MANTISSA SIGN BIT Figure 6-4. Single-precision Floating-point Storage 6.4 Double-precision Floating-point C stores a double-precision floating-point number in eight consecutive bytes using the IEEE format. The 64-bits contain three fields: a sign bit, an 11-bit biased exponent, and a 52-bit mantissa with a 53rd implicit normalized bit. The normalized bit is always 1 for nonzero numbers. The bit is recognized implicitly and is not stored. The binary point is situated to the immediate left of the normalized bit. 6-3 C Language Programmer's Guide 6.4 Double-precision Floating-point The exponent has a bias of 3FF hexidecimal (1023 decimal) . Therefore, the hexidecimal number 400 represents an exponent of +1. The hexidecimal number 3FE represents an exponent of -1. The mantissa is precise to 15 digits. Double-precision floating-point numbers range from 9.46 times 10 to the minus 308th power up to 1. 80 times 10 to the 308th power. (9.46*10**-308 <= jxj <= 1.80*10**308) C performs all floating-point arithmetic in double-precision. Figure 6-5 shows the format for double-precision floating-point numbers. When a program specifies single-precision numbers in an expression, C pads the fractional portion of those numbers with zeros, effectively lengthening the numbers to double-precision. When a double-precision number converts to single-precision, C f irst rounds the double-precision number before truncating it to single-precision length. HIGH MEMORY LOW MEMORY BYTE 7 BYTE 6 BYTE 5 BYTE 4 BYTE 3 BYTE 2 BYTE 1 BYTE 0 r I I I I I I I I I I I I I I I I XXXXXXXX 00000000 XXXXXXXX 00000000 XXXXXXXX 00000000 XXXXXXXX 00000000 L 1 653 0 LBIASED ISSA EXPONENT SIGN BIT~ Figure 6-5. Double-precision Floating-point Storage End of Section 6 6-4 Appendix A System Library Routine Summary There are four versions of the system subroutine library, SYSLIf~. There is one for each of the four 8086/88 memory models: small, medium, compact, and big. • SYSLIBS.1,86 • SYSLIBM.1,86 • SYSLIBC.L86 • SYSLIBB.L86 Most of the modules in the system library are accessible directly from your C program using the appropriate function names. However, certain routines in the system library are designed for access internally by other functions in the library and cannot be accessed explicitly from a program. You cannot access any of the modules in the following list. Notice that all module names in the system library are in capital letters and function names are in lowercase. Module names might vary slightly for different versions of the system libraries. A.1 Unaccessible System Library Modules The following list identifies unaccessible system library modules ALLOCC DPCNVT INCDEC _PRTINT BIGLISI DPFNCS LDIV -PRTLD BLKIO DPOPNS LISI _PRTSHORT CFP ERRNO LNGEQOPS PTRCMP CFP87 EXEC LOGIC SIGNAL CHCK _FDECLS LONGAR SPLSLP CHINIT _FILBUF LONGJMP STRCMP CLEANUP -FILESZ MAIN -§TRSTUFF CRT1 FLSBUF RULDIVEQ TTYIN _DOPRT YPTRAN MULT32 ULDIV -DOSCAN FTOA -OPEN XLFNCS C Language Programmer's Guide A.1 Unaccessible Modules The following list contains the system library modules contained in each SYSLIB file that you can access explicitly using the proper function names. Section 3 explains each function in detail. A.2 Accessible System Library Modules The following list identifies accessible system library modules. ACCESS FOPEN LSEEK SCANF ATOI FPRINTF MALLOC SETBUF ATOL FPUTC MKTEMP SPRINTF CALLOC FPUTS MULDIVEQ SSCANF CHMOD FREAD MULT32 STRCAT CHOWN FREOPEN OPEN STRCMP CLOSE FSCANF PERROR STRCPY CREAT FSEEK PRINTF STRLEN CTYPE FTELL PUTL STRNCAT EXIT FWRITE PUTS STRNCMP EXIT GETL PUTW STRNCPY fABS GETPASS QSORT SWAB FCLOSE GETPID RAND TTYNAME FDOPEN GETS READ UNGETC FFLUSH GETW REWIND UNLINK FGETC INDEX RINDEX WRITE FGETS ISATTY SBRK Each of the accessible routines in the system libraries performs a certain function. Groups of functions fall into related categories according to what each routine does. For example, one group of functions pertains to stream 1/0. Another group operates on strings. There are eight general categories for system functions. • DOS specific • Regular 1/0 • Stream 1/0 • Strings • Memory management • UNIX look-alikes • Double floating-point • Miscellaneous The following lists present the accessible system routines in the appropriate category. Refer to Section 3 for a complete description of each function. Remember, function names are in lowercase. C Language Programmer's Guide A.2 Accessible Modules Regular File Access Functions close opena creat openb creata read creatb tell lseek unlink open write Stream File Access Functions clearerr fputc gets fclose fputs getw fdopen fread printf feof freopen putc ferror fscanf putchar fflush fseek putl fgetc ftell puts fgets fwrite putw fileno getc rewind fopen getchar scanf fprintf getl ungetc String Functions atoi strcat atol strcmp index strcpy mktemp strlen rindex strncat sprintf strncmp sscanf strncpy ASCII Character Macros isalnum islower isupper isalpha isprint toascii isascii ispunct tolower iscntrl isspace toupper isdigit C Language Programmer's Guide A.2 Accessible Modules Memory Management Functions brk calloc free malloc realloc sbrk Double-precision Floating-point Functions atan log atof loglo Cos sin exp sqrt fabs tan Utility Functions abs getpass qsort access getpid rand chmod - IBMDOS setjmp chown isatty srand exit longjmp swab -exit perror ttyname End of Appendix A Appendix B Compiler Option Summary Command line option switches are reserved letters that send special instructions to the compiler. An option switch specification consists of a dash followed by the option letter. You cannot place spaces between the dash and the letter. However, you must place at least one space between each dash/option letter combination that you use in the command line. Option switch specifications must follow the source file in the command line. The following table lists the compiler command line option switches and a brief description of each. Notice that certain option switches require an additional parameter. Table B-1. Compiler Command Line Options Option Description -alfilesl Invoke LINK86 automatically. Ifilesl are the object files and libraries to link. Specify the filename and [I] for a LINK86 command line input file. b Enable big memory model. (Def ault is small model.) -c Enable compact memory model. (Default is small model.) -dinamel Define Inamel as the value 1. Works like #define in the source code. Defines names in lowercase only. _f Use 8087 math coprocessor. -h Suppress sign-on messages. -ildrive:l Search specified disk drive for #include files. _j Disable short/long jump optimizer. _11namel Generate program listing. Send listing to Inamel. (Default Inamel is CON:) -M Enable medium model. (Default is small model.) -n Disable code optimizer for faster compilation. C Language Programmer's Guide B Compiler Option Summary Table B-1. (continued) Option Description -olfilenamel Specify name for object file. _p Execute preprocessor module only. Place output in file CTEMP.TOK. -qlnumberl Set number of code generator modes to save space in symbol table. (Default is 500, minimum is 100.) -rlnamel Request program interlisting (reverse assembly). Send interlisting to Inamel. (Default Inamel is CON:) -vInumberl Set compiler message display level. Should appear before other switches in command line. Inumberl can range from 1 to 5 to produce the following information: -vl Display general information messages only. -v2 Display a # character as compiler processes each function. -v3 Display function name as compiler processes each function. -v4 Display start/end messages for #include files. -v5 Display filename and line number as compiler processes each line. -wInumberl Set error message display level. I number I can be 0. 1, or 2. -wO Display all error messages. -wl Suppress error warning messages. -w2 Suppress all error messages. _x Call an assembly routine to save and restore registers rather than generate code to do it in-line. Program compiles smaller but runs slower. -zldrive:l Place temporary work files on specified disk drive. B-2 C Language Programmer's Guide B Compiler Option Summary Table B-1. (continued) Option Description -01drive:1 Specify location of compiler preprocessor module (DRC860.EXE). 11drive:1 Specify location of compiler parser and code generator module (DRC861.EXE). -21drive:1 S p e c i f y 1 o c a t i o n of compiler listing/disassembly file merge utility (DRC862.EXE). -31drive:1 Specify location of LINK86 (LINK86.EXE). End of Appendix B is 40 Appendix C Error Messages Compiler error messages can be divided into two different categories: error reports and error warnings. Error reports indicate mistakes in your source program, such as syntax errors and improper data type specifications. Error reports include messages such as "Right brace } is missing" and "Same statement label used more than once." Error warnings effectively indicate that some error might occur if you do not take some corrective action. For example, error message 83 is a warning that suggests caution using the indirection operator with integers. Some warnings, such as number 95 "Subscript is truncated to short int.", simply inform you of a certain activity taking place during compilation. You can use compiler option switch -w to reset the error message display level. You can have the compiler display all messages, suppress only the warning messages, or suppress all messages. Refer to Section 2.1.3 for information on how to use compiler option switches. All compiler error messages correspond to an assigned error number. Table C-1 presents the C error messages listed in numerical order. Each entry shows the message text, the most common cause of the error, and a suggestion for fixing the error. Error warnings are clearly distinguished from error reports in Table C-1. Table C-1. Error Messages Error Meaning 1 Out of memory. Allocate function returns NULL. Compilation stops because available memory is exhausted. Reduce the number of functions compiled in a single module. 2 Identifier not specified in type or storage class declaration. The compiler read a type or storage class declaration keyword, but could not find a corresponding identifier. Correct the syntax error in the source program. C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 3 A public function definition is declared external. Do not declare public function definitions external. Declare the public function name external using the keyword "extern" in any module that calls the function. Remove the keyword "extern" from the public function definition. 4 Parentheses () missing in function declaration. The compiler read an opening brace indicating the start of a function body, but did not f ind a corresponding parameter list in the function declaration. You must place parentheses () af ter the function name in any function declaration that does not have(parameters. 5 ... not declared as a function. The identifier shown in the message text was referenced as a function. The identifier has been declared, but not as a function. Change the declaration or use different names for variables and functions. 6 Two functions have the same name. The program uses one function name to identify two different functions. Change one of the function names. 7 Conflicting data type specified for a function. The compiler detects conflicting data type references for a function. This often happens when a function is declared implicitly as an integer and is declared later as returning a non-integer type. Declare the function to return the appropriate data type before its first use. 0 C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 8 Data type not specified in variable declaration. The compiler read a variable name that has no type or storage class declaration. Functions automatically default to an integer return value. Declare the variable name with an appropriate type, storage class, or both. 9 Global variable declared with "register" storage class. The register storage class is not meaningful for extern or static variables. Delete the register storage class in the variable declaration. 10 Conflicting data type specified for a function. The compiler detects conflicting data type references for a function. This often happens when a function is declared implicitly as an integer and is declared later as returning a non-integer type. Declare the function to return the appropriate data type before its first use. 11 Conflicting storage class keywords in declaration. The compiler read a declaration with conflicting storage classes, such as "auto register" or "static extern". Specify only one storage class in each declaration. 12 Conflicting data type keywords in declaration. The compiler read a declaration with conflicting data types, such as "float int" or "long float". Specify only one data type in each declaration. C Language Programmer's Guide C Error Messages Table C-1. (continued) Error meaning 13 Use the keywords unsigned/long/short with int only. You can use the type qualifiers unsigned, long, and short on int data items only. Change any incorrect declarations in your source program. 14 Do not use the "unsigned long" type declaration. Some compilers permit use of the "unsigned long" type declaration. You cannot use it in Digital Research C. Delete the keyword "unsigned". 15 Conflicting type qualifiers "short/long" in declaration. You cannot use the type qualifiers short and long in the same variable or function declaration. Choose one type qualifier for each declaration. 16 Conflicting definitions for structure tag identifier. The program uses an identifier as a structure tag. That identifier is already defined as something else. Change the first declaration of the identifier or choose a different structure tag. 17 Identifier or left brace I missing in struct or union declaration. Each struct and union declaration requires either a left brace I or an identifier. Correct the syntax error in the source code. C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 18 Storage class specified in struct or union declaration. You cannot declare elements of a struct or union with storage class keywords (static, extern, register, auto). Delete storage class keywords in all struct and union declarations. 19 Data type not specified in struct or union declaration. Each struct or union declarations must contain a data type specification. The compiler did not find one. Specify an appropriate type. 20 Use integer constants to define bit field width. You can use only integers to define the width of bit fields in a struct or union. Change the constant to an integer. 21 Conflicting offsets or data type declared for . In Digital Research C, all struct and union fields exist in the same name space. If you use the name in multiple declarations, each f ield must be unique or exist at the same offset with the same type. 22 A comma or semicolon is missing. A required comma or semicolon is missing. Correct the syntax error in the source code. 23 Internal compiler error. Compiler error . Contact the Digital Research Technical Support Center. C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 24 Do not use "static" or "extern" to declare parameters. You cannot use the storage class keywords listatic" or "extern" to declare parameters. because parameters pass on the stack and cannot be allocated statically. You can use "auto" and ',register" in parameter declarations. Delete any incorrect storage class declarations for parameters. 25 Data type not specified in parameter declaration. You must declare a data type for each parameter. Specify an appropriate type. 26 Do not use abstract declarator in parameter declaration. You must supply a identifier to declare parameters. For example, 'lint ; of is incorrect. Correct the syntax error in the source code. 27 ... not specified as a parameter. The compiler read a declaration for an identifier that is not in the list of parameters. Probably a syntax or typing mistake. Correct the syntax error in your source code or move the declaration after the opening left brace. 28 ... must be pointer or scalar. You cannot declare structures as parameters in Digital Research C. Change your source program. 29 Identifier not specified in parameter declaration. Parameter declaration syntax requires an identifier. The compiler cannot find one. Correct the syntax error in the source code. C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 30 Function body is specifed as a parameter. You can declare functions as parameters but those functions cannot contain statements. Correct the syntax error in the source code. 31 Use integer constant expression to specify array bounds. You must specify the bounds of an array with a constant expression that can be reduced to an integer. Correct the syntax error in the source code. 32 ... undefined for "goto" statement. A goto statement references a label that is not defined. Correct the goto statement or define the label. 33 WARNING: is declared, but not referenced. The identifier in the message text is declared but not referenced in the program. This is an ERROR WARNING MESSAGE. 34 ...struct or union referenced before declaration. A struct or union variable is referenced before the struct or union is declared. Define the struct or union. 35 Cannot initialize a function. You placed an equal sign after a function declaration specifying initialization. Correct the syntax error in the source code. C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 36 Initializing variable with "extern". You can initialize variables with the extern keyword. This is allowed in Digital Research C, but not described by Kernighan & Ritchie. , This is an ERROR WARNING MESSAGE. 37 Array dimensions are extended automatically. The syntax (array_namefl = I ... 1) is used, but more data items are supplied than stated in num. The size of the array is extended. Correct the size declaration for the array. 38 Switch expression cannot be floating-point. The expression in a switch statement must be nonfloating. Correct the semantic error in the source code. 39 Cannot read switch statement. 11case 11 ignored. The compiler read the construct "case" but did not process a switch statement. The 11case" construct is ignored. Correct the syntax error in the source code. Possibly missing a left brace after the switch. 40 Constant in "case" construct cannot be floating-point. The constant expression after the keyword 11case" is not a standard C language construct and does not work in Digital Research C. Correct the semantic error in the source code. C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 41 Cannot read switch statement. "default:" ignored. The compiler read a default: construct but did not process a switch statment. The default: construct is ignored. Correct the syntax error in the source code. I Probably missing a left brace after the switch. 42 Break location undefined. No loop or switch. The compiler read a break statement but did not process a for/while loop. Probably a syntax error. Correct the source program. 43 Continue location undefined. No loop or switch. The compiler read a continue statement but did not process a for/while loop. Probably a syntax error. Correct the source program. 44 Identifier not specified in "goto" statement. An identifier is required after a goto statement. The compiler did not find the identifier. Correct the syntax error in the source code. 45 Same statement label used more than once. You used the same label more than once in a function. Correct the semantic error in the source code. 46 ... defined more than once. The same variable or function name is def ined more than once in the same compilation. Correct the error in the source program. 0 0 C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 47 ... Undefined identifier. The program references an identifier before it is defined. Correct the error in the source program. 48 Unexpected end-of-file (EOF) on input file. A misplaced end-of -file is detected on the input file. Probably mismatched braces. Correct the error in the source program. 49 Comma or semicolon is missing. Syntax error. Correct the error in the source program. 50 Right brace I is missing. Syntax error. Correct the error in the source program. 51 Left brace I is missing. Syntax error. Correct the error in the source program. 52 Right parenthesis ) is missing. Syntax error. Correct the error in the source program. 53 Right square bracket ] is missing in array declaration. Syntax error in array declaration. Correct the error in the source program. C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 54 Function parameters cannot have parameters. The compiler read a parameter declaration for an identifier that already exists as a parameter to a function. Correct the error in the source program. 55 Right parenthesis ) is missing. Syntax error. Correct the error in the source program. 56 Do not list parameters in the function declaration. You cannot list identifiers between the parentheses in a function declaration such as int f () . List the identifiers in the function body definition. Correct the error in the source program. 57 Comma or semicolon is missing. Syntax error. Correct the error in the source program. 58 Right brace I is missing. Syntax error. Correct the error in the source program. 59 Comma or semicolon is missing. Syntax error. Correct the error in the source program. 60 Semicolon is missing. Syntax error. Correct the error in the source program. 0 0 C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 61 Too many initializers. Right brace I is missing. You specified more initial values than variable locations. Correct the error in the source program. 62 Left parenthesis ( is missing. Syntax error. Correct the error in the source program. 63 Keyword "while" is missing in "do ... while" construct. Probably mismatched braces. Correct the error in the source program. 64 Colon is missing. Syntax error. Correct the error in the source program. 65 Internal compiler error. Bad constant load. Internal compiler error. Contact the Digital Research Technical Support Center if this message displays isolated f rom any other error messages. 66 Internal compiler error. Unknown pointer size. Internal compiler error. Contact the Digital Research Technical Support Center if this message displays isolated f rom any other messages. 67 Use operators ++ and -- on int/char/long/short only. You used ++ and -- operators on function pointers. Correct the semantic error in the source code. C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 68 MESSAGE SPACE RESERVED 69 MESSAGE SPACE RESERVED 70 MESSAGE SPACE RESERVED 71 Cannot return certain types of expressions. The compiler read a return statement but can not return certain types of expressions, such as whole structures. Correct the semantic error in the source program. 72 Internal compiler error. Internal compiler error. Contact the Digital Research Technical Support Center. 73 Use constant expression to initialize static and extern variables. You can initialize statically allocated variables with a constant expression only. A statically allocated variable is one declared either static or extern. You can initialize automatic variables with nonconstant expressions. Correct the semantic error in the source program. 74 MESSAGE SPACE RESERVED 75 MESSAGE SPACE RESERVED 76 Variable is not large enough to hold a pointer. You specified a variable that is not large enough to hold a pointer. For example, a char variable was specified to hold an array name. Correct the semantic error in the source program. 0 is C Language Programmer's Guide C Error Messages Table C-1. (continued) Error meaning 77 Variable too large to hold initial value. You specified a variable that is not large enough to hold the initial value. Correct the semantic error in the source program. 78 Offsets into other segments not implemented. Internal compiler error. Contact the Digital Research Technical Support Center . 79 Use operators + - ++ -- with pointers only. You specified incorrect operators for use with pointers. Correct the semantic error in the source program. 80 MESSAGE SPACE RESERVED 81 Invalid parameter expression. Internal compiler error. Contact the Digital Research Technical Support Center if this message displays isolated from any other error messages. 82 MESSAGE SPACE RESERVED Cannot pass structures by value. 83 WARNING: Indirection for non-pointers is not portable. Integers can be indirected successfully in Digital Research C (small & medium models only) and PDP-11 C. This is an ERROR WARNING MESSAGE. 84 Cannot add arrays or structures. Do not use + operator with arrays. The program attempts to add arrays. Correct the semantic error in the source program. C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 85 MESSAGE SPACE RESERVED Type conflict for operands. 86 Use only += or - operators with pointers. You cannot use certain assignment operators, such as /=, in an expression that involves a pointer. Correct the semantic error in the source program. 87 Colon is missing. Syntax error. Correct the error in the source program. 88 Cannot add pointers. Do not use + operator with pointers. The addition operator, +, is used in an expression with two pointers. You cannot add pointers. Subtraction is acceptable. Correct the semantic error in the source program. 89 Incorrect expression syntax. Syntax error. Correct the error in the source program. Often mismatched parentheses. 90 Comma or right parenthesis expected in parmeter list. Syntax error. Correct the error in the source program. 91 Expression is missing before [ operator. An lvalue expression of type array or pointer is required on the left of the [ operator. Correct the semantic error in the source program. C Language Programmer's Guide C Error Messages Table C-1. (continued) 40 Error Meaning 92 An lvalue is required before [ operator. An expression of the wrong type exists on the lef t of the [ operator. The expression must be an array or pointer. Correct the semantic error in the source program. 93 Array or pointer required on left of [ operator. See error 92. 94 Array or pointer required. Cannot subscript. See error 92. 95 WARNING: Subscript is truncated to short int. In the 8086 implementation of C a single aggregate data structure cannot exceed 64K bytes. A long int is used as a subcript and the compiler discards the upper word. This is an ERROR WARNING MESSAGE. 96 Right square bracket I is missing. Syntax error. Correct the error in the source program. 97 identifier missing on right of . operator. A required identifer that names a struct or union member is missing after the period operator. Correct the syntax error in the source program. 98 Expression missing on left of . operator A required expression describing a struct or union is missing before the period operator. Correct the syntax error in the source program. C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 99 Left operand for . operator must be a struct. The operand to the left of a period operator is not a struct or union. Correct the semantic error in the source code. 100 WARNING: Non-local structure field assumed. The struct or union member used with the period operator is not defined as being in the same structure described by the left operand. This is an ERROR WARNING MESSAGE. 101 Identifier missing on right of -> operator. A required identifier that names a struct or union member is missing after the -> operator. Correct the syntax error in the source program. 102 Expression missing on left of - operator. A required expression describing a struct or union is missing before the -> operator. Correct the syntax error in the source program. 103 Left operand of -> operator must be a pointer. The operand to the left of a -> operator is not a pointer. Correct the semantic error in the source program. 104 WARNING: Non-local structure field assumed. The struct or union member used with the period operator is not defined as being in the same structure described by the left operand. This is an ERROR WARNING MESSAGE. 0 0 C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 105 Division by the constant 0. The compiler, in an attempt to optimize constant expressions, read an expression with a zero on the right of a divide operator. Correct the semantic error in the source program. 106 Operand types do not match. Cannot coerce to compatible types. Conflicting types for operands in an expression. The operands cannot be coerced automatically to compatible types. Specify compatible types for operands. 107 Cannot coerce operand type to double. The compiler attempts to coerce the type of an expression before performing an operation but can not. For example, double_var * pointer. Correct the semantic error in the source program. 108 Cannot coerce operand type to long. See error 107. Correct the semantic error in the source program. 109 Cannot coerce operand type to unsigned. See error 107. Correct the semantic error in the source program. 110 WARNING: Indirection for non-pointers is not portable. Integers can be indirected successfully in Digital Research C (small and medium models only) and PDP-11 C. This is an ERROR WARNING message. C Language Programmer's Guide C Error messages Table C-1. (continued) 40 Error Meaning 111 WARNING: & operator (address of) used redundantly. An array is specified without a subscript expression, and the ampersand operator is used redundantly. The compiler ignores the&. The expression is, by definition, the address of the array. This is an ERROR WARNING MESSAGE. 112 The & operator (address of) requires an lvalue. The & operator cannot accept the address of an rvalue expression. Correct the semantic error in the source program. 113 An lvalue is required with ++ or -- operator. The ++ and -- operators require an lvalue. The compiler did not find one. Correct the semantic error in the source program. 114 Incorrect operand type for ++ or -- operator. You cannot use the ++ and -- operators on arrays or structures. Correct the semantic error in the source program. 115 Data type not specified for expression after sizeof operator. When an expression is not found after the sizeof operator the compiler assumes a type declaration but finds none. Correct the semantic error in the source program. 116 An lvalue is required with ++ or -- operator. The ++ and -- operators require an lvalue but the compiler cannot find one. Correct the semantic error in the source program. 0 0 C Language Programmer's Guide C Error Messages Table C-1. (continued) Error Meaning 117 Incorrect operand type for ++ or -- operator. The ++ and -- operators require an operand of the appropriate type. Correct the semantic error in the source program. 118 MESSAGE SPACE RESERVED 119 Output file write error. Disk is probably full. Write function returns NULL indicating that available disk space for the output file is exhausted. Compilation is stopped. Use a disk that has more space. 120 WARNING: Not enough registers available for variables. You specified too many register variables in the program. There are not enough registers to hold all the variables. The register storage class is automatically converted to auto. This warning displays only if you specify the -v3, -v4, or -v5 option switches. 121 WARNING: Additional registers available for variables. Additional registers are available to hold register variables that you specified in the program. This warning displays only if you specify the -v3, -v4, or -v5 option switches. End of Appendix C Appendix D Variations among Compilers Digital Research C for the IBM Personal Computer Disk Operating System is designed to be compatible with the UNIX Version 7 operating system. This appendix presents the major variations among Digital Research C for the 8086/88, Digital Research C for the 68000, and the Kernighan/Ritchie description of UNIX C. * Digital Research C for the 8086 does not support the #line preprocessor command. The library functions aborto and signal() are available in the 68000 version of C but not the 8086. The =op form of the standard op= operators is not implemented on the 8086 version of C. It is implemented on the 68000 version. o Kernighan and Ritchie explain in The C Programming Language that you should define a global variable once and only once without the keyword extern but that you should specify the extern keyword for all other references to that global variable. This is not compatible with UNIX or most other C compilers. Therefore, Digital Research C for the 8086/88 requires that you declare each global variable as a common segment. This allows the variable to be declared in multiple modules without the extern keyword. End of Appendix D 0 Appendix E C Style Guide To make your C language programs portable, readable, and easy to maintain, follow the stylistic rules presented in this section. However, no rule can predict every situation; use your own judgment in applying these principles to unique cases. E.1 Modularity Modular programs reduce porting and maintenance costs. Modularize your programs, so that all routines that perform a specified function are grouped in a single module. This practice has two benefits: first, the maintenance programmer can treat most modules as black boxes for modification purposes; and second, the nature of data structures is hidden from the rest of the program. In a modular program, you can change any major data structure by changing only one module. E.1.1 Module Size A good maximum size for modules is 500 lines. Do not make modules bigger than the size required for a given function. E.1.2 Intermodule Communication whenever possible, modules should communicate through procedure calls. Avoid global data areas. Where one or more compilations require the same data structure, use a header file. E.1.3 Header Files In separately combined files, use header files to define types, symbolic constants, and data structures the same way for all modules. The following list gives rules for using header files. Use the #include "file.h" format for header files that are project-specific. use #include for system-wide files. Never use device or directory names in an include statement. Do not nest include files. Do not define variables other than global data references in a header file. Never initialize a global variable in a header file. E-1 C Language Programmer's Guide E.1 Modularity When writing macro definitions, put parentheses around each use of the parameters to avoid precedence mix-ups. E.2 Required Coding Conventions To make your programs portable, you must adhere strictly to the conventions presented in this section. Otherwise, the following problems can occur: • The length of a C int variable varies from machine to machine. This can cause problems with representation and with binary 1/0 that involves int quantities. • The byte order of multibyte binary variables differs from machine to machine. This can cause problems if a piece of code views a binary variable as a byte stream. • Naming conventions and the maximum length of identifiers differ from machine to machine. Some compilers do not distinguish between uppercase and lowercase characters. • Some compilers sign-extend char and short variables to int during arithmetic operations; some compilers do not. • Some compilers view a hex or octal constant as an unsigned int; some do not. For example, the following sequence does not always work as expected: LONG data; printf("%ld\n",(data & Oxffff)); The printf statement prints the lower 16 bits of the long data item data. However, some compilers sign-extend the hex constant Oxffff. • You must be careful of evaluation-order dependencies, particularly in compound BOOLEAN conditions. Failure to parenthesize correctly can lead to incorrect operation. E.2.1 Variable and Constant Names Local variable names should be unique in the first eight characters. Global variable names and procedure names should be unique in the first six characters. All variable and procedure names should be completely lowercase. E-2 C Language Programmer's Guide E.2 Coding Conventions Usually, names defined with a #define statement should be entirely uppercase. The only exceptions are functions defined as macros, such as getc and isascii. These names should also be unique to eight characters. You should not redefine global names as local variables within a procedure. E.2.2 Variable Types PORTAB.H contains a set of variable type declaration keywords (Table E-1) and storage class declaration keywords (Table E-2) that you can use to ensure consistent internal representation of data types across different processors. Declaration keywords in PORTAB.H are macro definitions specified with #define. Using standard type specifiers can be unsafe in programs designed to be portable because of variations in internal representation among different compilers. For example, an integer declared with the keyword int might be 16-bits long on one processor and 32-bits on a different processor. However, an integer declared with the macro WORD is 16-bits on any processor. The standard 1/0 file STDIO.H already includes PORTAB.H. Therefore, if your program does not include STDIO.H, you must include PORTAB.H explicitly to use the macros shown in Tables 3-1 and 3-2. Table E-1. Variable Type Macro Definitions Type C Base Type LONG signed long (32 bits) WORD signed short (16 bits) UWORD unsigned short (16 bits) BOOLEAN short (16 bits) BYTE signed char (8 bits) UBYTE unsigned char (8 bits) VOID void (function return) DEFAULT int (16/32 bits) Table E-2. Storage Class Macro Definitions Class T C Base Class REG register variable LOCAL auto variable MLOCAL module static variable GLOBAL global variable definition EXTERN global variable reference C Language Programmer's Guide E.2 Coding Conventions You should declare global variables at the beginning of the module. Define local variables at the beginning of the function in which they are used. You must always specify the storage class and type, even though the C language does not require this. E.2.3 Expressions and Constants Write all expressions and constants to be implementation independent. Always use parentheses to avoid ambiguities. For example, the construct if(c = getcharo == 1\nl) does not assign the value returned by getchar to c. Instead, the value returned by getchar is compared to '\n', and c receives the value 0 or 1 (the true/false output of the comparison). The value that getchar returns is lost. Putting parentheses around the assignment solves the problem: if((c = getcharo) == I\nl) Write constants for masking, so that the underlying int size is irrelevant. In the example LONG data; printf(1'%ld\n",(data & OxffffL); the printf statement is a long masking constant that solves the problem for all compilers. Specifying the one's complement often yields -Oxff instead of OxffOO. For portability, character constants must consist of a single character. Place multicharacter constants in string variables. Commas that separate arguments in functions are not operators. Evaluation order is not guaranteed. For example, the following function call might perform differently for different compilers. printf("%d %d\n",i++,i++); E.2.4 Pointer Arithmetic Do not manipulate pointers as ints or other arithmetic variables. C allows the addition or subtraction of an integer to or from a pointer variable. Do not attempt logical operations, such as AND or OR, on pointers. A pointer to one type of object can convert to a pointer to a smaller data type with complete generality. Converting a pointer to a larger data type can cause alignment problems. C Language Programmer's Guide E.2 Coding Conventions You can test pointers for equality with other pointer variables and constants, notably NULL. Arithmetic comparisons, such as -, do not work on all compilers and can generate machine-dependent code When you evaluate the size of a data structure, remember that the compiler might leave holes in a data structure to allow for alignment. Always use the sizeof operator. E.2.5 String Constants Allocate strings so that you can easily convert programs to foreign languages. The preferred method is to use an array of pointers to constant strings, which is initialized in a separate file. This way, each string reference then references the proper element of the pointer array. Never modify a specific location in a constant string, as in the following example: BYTE string[] = BDOS Error On x: string[141 = 'A'; Foreign language equivalents are not likely to be the same length as the English version of a message. Never use the high-order bit of an ASCII string for bit flags. Extended character sets make extensive use of the characters above Ox7F. E.2.6 Data and BSS Sections Usually, C programs have three sections: text (program instructions), data (initialized data), and BSS (uninitialized data). Avoid modifying initialized data if at all possible. Programs that do not modify the data segment can aid the swapping performance and disk utilization of a multiuser system. Also, if a program does not modify the data segment, you can place the program in ROM with no conversion. This means that the program does not modify initialized static variables. This restriction does not apply to the modification of initialized automatic variables. C Language Programmer's Guide E.2 Coding Conventions E.2.7 Recommended Module Layout The following list tells you what to include in a module. e At the beginning of the file, place a comment describing the the following items: - the purpose of the module - the major outside entry points to the module - any global data areas that the module requires - any machine or compiler dependencies o Include file statements. o Module-specific #define statements. * Global variable references and definitions. Every variable should include a comment describing its purpose. * Procedure def initions. Each procedure definition should contain the following items: - A comment paragraph, describing the procedure's function, input parameters, and return parameters. Describe any unusual coding techniques here. - The procedure header. The procedure return type must be explicitly specified. Use VOID when no value returns. - Argument definitions. You must explicitly declare storage class and variable type. - Local variable definitions. Define all local variables before any executable code. You must explicitly declare storage class and variable type. - Procedure code. Refer to Appendix F for a sample program. C Language Programmer's Guide E.3 Coding Suggestions E.3 Coding Suggestions The following suggestions increase program portability and make programs easier to maintain. • Keep source code within an 80-character margin for easier screen editing. • Use a standard indention technique, such as the following: - Begin statements in a procedure one tab stop (column eight) from the left margin. - Indent statements controlled by an if, else, while, do, or for one tab stop. If you require multiple nested indentions, use two spaces for each nesting level. Avoid going more than five levels deep. - Place the brackets surrounding each compound statement on a separate line, aligned with the indention of the controlling statement. For example, for(i=O;i UPPER) j = UPPER; output(j); Place a null statement controlled by an if, else, while, for, or do on a separate line, indented for readability. • To document your code, insert plenty of comments. If your code is particularly abstruse, inserting comments helps clarify it. • Put all maintenance documentation in the source code itself. If you do not, the documentation will not be updated when the code changes. • Use blank lines, form-feeds, and white space to improve readability. 40 End of Appendix E Appendix F Sample C Modules The modules in this appendix are written and documented in C code that follows the style conventions discussed in Appendix E. P r i n t f M o d u 1 e --------------------------- This module is called through the single entry point printf" to perform the conversions and output for the library functions: printf - Formatted print to standard output fprintf - Formatted print to stream file sprintf - Formatted print to string The calling routines are logically a part of this module, but are compiled separately to save space in the user's program when only one of the library routines is used. The following routines are present: -printf Internal printf conversion / output -prntB Octal conversion routine -prntx Hex conversion routine _conv Decimal ASCII to binary routine -putstr Output character to string routine -prntl Decimal conversion routine The following routines are called: strlen Compute length of a string putc Stream output routine ftoa Floating point output conversion routine This routine depends on the fact that the argument list is always composed of LONG data items. Configured for Whitesmith's C on VAX.0 "putc" arguments are reversed from UNIX. Include files: #include /* just the standard stuff Listing P-1. -Printf Module C Language Programmer's Guide F Sample C Modules Local DEFINEs #define HIBIT 31 /* High bit number of LONG Local static data: KLOCAL BYTE ptrbf = 0; /* Buffer Pointer MLOCAL BYTE *-ptrst = 0; /* - File/string (if any) RLOCAL BYTE *_fmt = 0; /* Format Pointer Listing F-1. (continued) C Language Programmer's Guide F Sample C Modules P R I N T F I N T E R N A L R 0 U T I N E --------------------------------------------- Routine "_printf" is used to handle all "printf" functions, including "sprintf", and "fprintf". Calling Sequence: -printf(fd,func,fmt,argl); Where: fd Is the file or string pointer. func Is the function to handle output. fmt Is the address of the format string. argl Is the address of the first arg. Returns: Number of characters output Bugs: It is assumed that args are contiguous starting at "argl", and that all are the same size (LONG), except for floating point. -printf(fd,f,fmt,al) LONG fd; /* Not really, but LONG (*f)(); /* Function pointer BYTE *fmt; /* Format string LONG *al; /* Arg list LOCAL BYTE C; /* Format character temp LOCAL BYTE *s; /* Output string pointer LOCAL BYTE adj; /* Right/left adjust flag LOCAL BYTE buf[301; /* Temporary buffer LOCAL LONG *adx; /* Arg Address temporary LOCAL LONG X; /* Arg Value temporary LOCAL LONG n; /* String Length Temp LOCAL LONG m; /* Field Length Temporary LOCAL LONG width; /* Field width LOCAL LONG prec; /* Precision for "%x.yf" LOCAL LONG padchar; /* '0' or ' ' (padding) LOCAL DOUBLE zz; /* Floating temporary LOCAL DOUBLE *dblptr; /* Floating temp. address LOCAL LONG ccount; /* Character count EXTERN -putstro; /* Reference function Listing F-2. PRINTF Internal Routine C Language Programmer's Guide F Sample C Modules ccount = 0; /* Initially no characters - ptrbf = buf; /* Set buffer pointer adx = al; /* Copy address variable -ptrst = fd; /* Copy file descriptor -fmt = fmt; /* Copy format address if(*-fmt == 'Ll *_fmt '1') /* Skip long output -fmt++; conversions /* This is the main format conversion loop. Load a character from the /* format string. If the character is '%', perform the appropriate /* conversion. Otherwise, just output the character. while( c fmt++ /* Pick up next format char*/ if(c (*f)(fd,c); /* If not '%', just output ccount++; /* Bump character count I else /* It is a convert x = *adx++; /* x = address of next arg if( *-fmt /* Check for left adjust adi = 'V; /* Is left, set flag fmt++; /* Bump format pointer else /* Right adjust adi = 'r'; padchar=(*_fmt=='O') ? '0' /* Select Pad character width = -convo; /* Convert width (if any) if( *-fmt /* '.' means precision spec*/ ++-fmt; /* Bump past prec = _convo,- /* Convert precision spec else /* None specified prec = 0; s = 0; /* Assume no output string switch ( c = *-fmt++ /* Next char is conversion case 'D': /* Decimal case 'd': prtl(x); /* Call decimal print rtn Break; /* Go do output Listing F-2. (continued) 40 C Language Programmer's Guide F Sample C Modules case 'o': /* octal case '0': Print -prntB(x); /* Call octal printer break; /* Go do output case :x': /* Hex case V: Print -prntx(x); /* Call conversion routine break; /* Go do output case 'S': /* String case S,: Output? s=x; /* Yes, (easy) break; /* Go finish up case 'C': /* Character case 'c': Output? *-Ptrbf++ x&0377; /* Just load buffer break; /* Go output case 'E': /* Floating point? case 'e': case 'F': case 'f': dblptr = adx-1; /* Assumes 64 bit float! zz = *dblptr; /* Load value adx =+ 1; /* Bump past second word ftoa (zz, buf, prec, c); /* Call floating conversion*/ prec = 0; /* Fake out padding routine*/ s = buf; /* just like string print break; /* Go output default: /* None of the above? (*f)(fd,c); /* Just Output ccount++; /* Count it. adx--; /* Fix arg address /* End switch if (s == 0) /* If s = 0, string is in /* "buf", *-Ptrbf = 101; Insure termination s = buf; /* Load address n = strlen (s); /* Compute converted length*/ n = (prec 0) /* Pad in front (*f)(fd,padchar); /* Thusly ccount++; /* Count it Listing F-2. (continued) C Language Programmer's Guide F Sample C Modules while (n--) /* Output Converted (*f)(fd,*s++); Data ccount++; /* Count it while (m-- > 0) /* If left adjust, (*f)(fd,padchar); Pad ccount++,- /* Count padded characters ptrbf = buf; /* Reset buffer pointer /* End else /* End while if((*f) == _putstr) /* If string output, (*f)(fd,'O'); /* Drop in terminator char return(ccount); /* Return appropriate value*/ /* End _printf Listing F-2. (continued) C Language Programmer's Guide F Sample C Modules P R N T 8 P R 0 C E D U R E ------------------------------- Routine "_prntS" converts a binary LONG value to octal ascii. The area at "_ptrbf" is used. Calling Sequence: -prntS(n); n" is the number to be converted. Returns: (none) VOID _prntB (n) LONG n; /* Number to convert REG WORD p; /* Counts bits REG WORD k; /* Temporary 3-bit value REG WORD sw; /* Switch 1 => output if (n==O) /* Handle 0 as special case ptrbf++ = '0'; /* Put in one zero return; And quit sw = 0; /* Indicate no output yet for (p=HIBIT; p >= 0; p =- 3) /* Use 3 bits at a time if ((k = (n>>p)&07) 11 sw) /* Need to output yet? if (p==HIBIT) /* lst digit has only 2 bits*/ k = k & 02; /* Mask appropriately ptrbf++ = '0' + k; /* ASCIIfy digit sw /* Set output flag /* End if /* End prnt8 Listing F-3. -PRNT8 Procedure F-7 C Language Programmer's Guide F Sample C modules P r n t x F u n c t i o n ----------------------------- The " prntx" function converts a binary LONG quantity to hex ASCII and stores the result in '*_ptrbf'. Leading zeros are suppressed. Calling sequence: _prntx(n); where "n" is the value to be converted. Returns: (none) VOID _prntx (n) LONG n; /* 32 bits REG LONG d; /* A digit REG LONG a; /* Temporary value if (a = n>>4) /* Peel off low 4 bits -prntx a & Oxfffffff); /* If - 0, print first d = n&017; /* Take low four bits *_ptrbf++ = d > 9 ? 'A'+d-10 : '0' + d;/* ASCIIfy into buffer Listing F-4. -Prntx Function F-8 C Language Programmer's Guide F Sample C Modules C o n v F u n c t i o n ----------------------------- Function "_conv" is used to convert a decimal ASCII string in the format to binary. Calling Sequence: val = _convo; Returns: "val" is the converted value Zero is returned if no value LONG convo REG BYTE c; /* Character temporary REG LONG n; /* Accumulator n = 0; /* Zero found so far while(((c= fmt++) >= 101) /* While c is a digit && ("E-<= 9,)) n n*10+c-101; /* Add c to accumulator -fmt--; /* Back up format pointer to*/ /* character skipped above return(n); /* See, wasn't that simple? Listing F-5. -Conv Function 0 C Language Programmer's Guide F Sample C Modules P u t s t r F u n c t i o n --------------------------- Function "_putstr" is used by "sprintf" as the output function argument to "_printf". A single character is copied to the buffer at "_ptrst". Calling Sequence: -putstr(str,chr); where "str" is a dummy argument necessary because the other output functions have two arguments. Returns: (none) VOID _putstr(str,chr) REG BYTE chr; /* The output character BYTE *str; /* Dummy argument *-~ptrst++ = chr; /* Output the character return(O); /* Go back Listing F-6. -Putstr Function F- 10 C Language Programmer's Guide F Sample C Modules P r t 1 F u n c t i o n --------------------------- Function "_prtl" converts a LONG binary quantity to decimal ASCII at the buffer pointed to by "_ptrbf". Calling Sequence: -prtl(n); where "n" is the value to be converted. Returns: (none) VOID _prtl(n) REG LONG n; /* Conversion input REG LONG digs[151; /* store digits here REG LONG *dpt; /* Points to last digit dpt = digs; /* Initialize digit pointer if (n >= 0) /* Fix n = -n; up else sign Ptrbf++ stuff for (; n != 0; n n/10) /* Divide by 10 till zero *dpt++ n%10; /* Store digit (reverse ord)*/ if (dpt digs) /*Zero value? *dpt++ = 0; /* Yes, store 1 zero digit while (dpt != digs) /* Now convert to ASCII --dpt; /* Decrement pointer ptrbf++ = '01 - *dpt; /* Note digits are negative!*/ Listing F-7. -Prtl Function End of Appendix F Index #define, 2-3, 3-3, E-3 C directive, E-3 #include, 1-1, E-1 calling -START, 2-16 a C module, 5-3 an assembly routine, 5-2 A calloc function, 3-10 carriage return, 3-15, 3-26, abort function, D-1 4-1 abs function, 3-6 chaining, 3-18 access function, 3-7 char, 5-6 allocation directives keyword, 6-1 RASM-86, 5-7 character arithmetic comparison, E-5 alphanumeric, 3-15 ASCII control, 3-15 character macros, 7-3 conversion, 3-62 characters, 3-15 data type, 6-1 digit string, 3-8 printable, 3-15 files, 3-2, 3-23, 3-37, 4-1 punctuation, 3-15 ASM-86, 5-1 space, 3-15 assembler, 5-1 storage, 6-1 assembly language, 5-1 string, 2-14 cross-reference utility chmod function, 3-11 program, 1-1 chown function, 3-11 assembly routine, 2-12, 5-1, clearerr function, 3-22 5-6, 5-7 close function, 3-12 calling, 5-2 COBJ.TMP, 2-1, 2-13 external, 5-3 code area, 2-14 public, 5-2 code generator, 1-2, 1-3 atan function, 3-60 location, 2-4, 2-13 atof function, 3-8 nodes, 2-3, 2-10 atoi function, 3-8 code optimizer, 2-9, 2-10 atol function, 3-8 disable, 2-3 auto variable macro, 3-3 command file, 1-7, 2-25 command line B compiler, 1-5, 2-2 length of, 2-2 big model commas, E-4 compilation, 2-6, 2-25 comments, E-6 enable, 2-3 common library, 1-1, 1-2, 3-1, A-1 attribute, 5-6 binary segment, D-1 data, 3-59 COMMON files, 3-2, 3-23, 3-37, 4-1 combine type RASM-86, bit flags, E-5 5-7 boolean macro, 3-3 data segment, 5-6 BP register, 5-5 compact model brk function, 3-9 compilation, BSS, E-5 enable, 2-3 buffering, 4-1, 4-2 library, 1-1 Index-1 compatibility with UNIX V7, conversion specification 3-1 printf function, 3-40 compiler, 1-1, 1-5, 2-23 scanf function, 3-50 code generator, 1-2, 1-3 cos function, 3-13 command line, 1-5, 2-2, 2-3, CP/M-86, 2-16, 3-1 B-1 CPU, 1-1 command line options, 2-2, creat function, 3-14, 4-1 2-3 creata function, 3-14, 4-1 default filetype, 2-23 creatb function, 3-14, 4-1 different versions, 1-5, cross-reference utility 1-7, 2-24, D-1 assembly language, 1-1, end of compilation, 1-5 1-2 error messages, 1-3 CTEMP.TOK, 2-1, 2-3, 2-10, full configuration, 2-1 2-13, 2-18 information messages, 2-4 ctype functions, 3-15 listing/disassembly file CTYPE.H, 1-2, 3-62 merge utility, 2-13 memory allocation message, D 2-14, 2-24 minimum configuration, 1-3 dash, 2-2 operation, 2-1 data options, 2-2 buffering, 4-1 parser, 1-2, 1-3 control structure, 4-2 preprocessor, 1-2, 1-3 group, 5-8 sign-on banner, 1-5, 2-24 segment, 5-6 stopping, 2-2 structures, E-1 supervisory module, 1-2 types, 6-1 suppress sign-on message, default 2-3 code generator notes, 2-10 work disk, 2-22 compiler filetype, 2-24 completion code, 3-17 object filename, 1-6, 2-5 components, 1-1 default drive CON, 2-9, 2-11, 4-3 compiler, 2-1 console device, 2-9, 2-11, system library, 2-25 3-61, 4-3 define, 2-3, 2-7 constant names, E-2 dgroup, 5-8 constants, E-4 DI register, 5-3 control characters, 3-15 directory system library control-Z, 3-26, 4-1 functions, 3-4 conversion disk file, 4-1 functions, 3-8 disk space, 1-1 precision, 6-4 DOS, 1-1, 3-2 conversion character, 3-62 Version 1, 3-1 %, 3-42, 3-52 double, 5-3, 5-6 c, 3-42, 3-52 double-precision d, 3-42, 3-52 floating-point e, 3-42, 3-52 data type, 6-1 f, 3-42, 3-52 storage, 6-3 g, 3-42 DRC.ERR, 1-2, 2-1, 2-16 o, 3-42, 3-52 DRC.EXE, 1-2, 1-3, 2-1 s, 3-42, 3-52 DRC860.EXE, 1-2, 1-3, 2-1, u, 3-42 2-4, 2-9, 2-10, 2-17 x, 3-42, 3-52 location, 2-4, 2-13 3-52 DRC861.EXE, 1-2, 1-3, 2-1, 2-4 location, 2-4, 2-13 Index-2 DRC862.EXE, 1-2, 1-3, 2-1, extern 2-4, 2-10 data, 2-14 location, 2-4, 2-13 explicit, 2-14 DRCRPP.EXE, 1-2, 2-10, 2-16 implicit, 2-14 keyword, 5-2, 5-6, D-1 E external area, 2-14 E2BIG, 3-38 data access, 5-6 EACCES, 3-38 declarations, 5-2 EBADF, 3-38 names, 5-1 EFBIG, 3-39 significant characters, 5 EINVAL, 3-38 EXTRN directive RASM-86, 5-3 EIO, 3-38 end of compilation, 1-5 F end-of-file, 3-22, 4-1 byte level, 4-1 fabs function, 3-20 ENFILE, 3-38 FAR RASM-86, 5-3 ENODSPC, 3-39 faster compilation, 2-3, 2-8 ENOENT, 3-38 2-9 ENOMEN, 3-38 fclose function, 3-21 ENOSPC, 3-39 fdopen function, 3-23 ENOTTY, 3-38 feof function, 3-22 entry points, 3-2 ferror function, 3-22 entry/exit protocol, 5-4 fflush function, 3-21 ENVAL, 3-38 fgetc function, 3-27 EROFS, 3-39 fgets function, 3-31 errno external variable, 3-38 file access ERRNO.H, 1-2 regular, 4-1 error stream, 4-2 message file, 1-2, 1-3 file descriptor, 3-22, 3-33 message text, 2-16 4-1 messages, 1-3, 1-7, 2-4, filename temporary, 3-36 2-12, 2-14, 2-15, C-1 fileno function, 3-22 display level, 2-4, 2-12 files, 4-1 number, 1-3, 2-15, C-1 access, 4-1 operating system, 3-38 ASCII, 4-1 suppress warning messages, binary, 4-1 2-4, 2-12, 2-15 close, 3-12, 3-21 reports, 2-14, C-1 create, 3-14, 4-1 warnings, 2-14, C-1 delete, 3-64 execl function, 3-18 open, 3-23, 4-1 executable components, 1-1 owner ID, 3-11 executable program, 1-3, 1-7, protection mode, 3-11 2-17, 2-25 standard 1/0, 4-3 exit and exit functions, filetype 3-17 C' 1-5, 2-23 exp function, 3-19 EXE, 1-7, 2-17, 2-25 exponent, 6-3 OBJ, 1-7, 2-24 expressions, E-4 float, 5-3, 5-6 floating-point, 6-1, 6-3 arithmetic, 2-7, 6-3 functions, A-4 fopen function, 3-23 for-loop, 1-5 form-feed, 3-15 Index-3 format string, 3-40 input file LINK-86, 2-25 scanf function, 3-50 INPUT option LINK-86, 2-5, formatting output, 3-40 2-25 fprintf function, 3-40 input/output, 4-1 fputc function, 3-44 int, 5-6 fputs function, 3-46 keyword, 6-2 fread function, 3-25 integer free function, 3-10 long, 6-2 freopen function, 3-23 short, 6-2 fscanf function, 3-50 storage, 6-2 fseek function, 3-26 unsigned, 6-2 ftell function, 3-26 Intel function 8087, 2-3 character classification, 3-15 ASM-86, 5-1 directory, 3-4 object file format, 2-1 error, 3-22 interlist external, 5-7 display, 1-3, 2-10 names, 3-4 option, 1-3, 2-10 reference, 3-2 interlisting generate, 2-3, return values, 3-2 2-10 system library, 3-4 intermodule communication, E-1 fwrite function, 3-25 internal data representation, 6-1 G isalnum function, 3-15 isalpha function, 3-15 getc function, 3-27 isascii function, 3-15 getchar function, 3-27 isatty function, 3-33 getl function, 3-27 iscntrl function, 3-15 getpass function, 3-29 isdigit function, 3-15 getpid function, 3-30 islower function, 3-15 gets function, 3-31 isprint function, 3-15 getw function, 3-27 ispunct function, 3-15 global isspace function, 3-15 data areas, E-2 isupper function, 3-15 variable macro, 3-3 GROUP directive RASM-86, 5-8 J H jump optimizer disable, 2-3, 2-8 hardware stack, 5-3 jump routine nonlocal, 1-2, header file, E-1 3-53 heap extention, 3-9 K management, 3-10 Kernighan and Ritchie, D-1 I L 1/0 redirection, 2-18 include file, 1-1, 1-2, 2-3, LIB86.EXE, 1-2 2-18, 3-3, 3-36 library, 1-1, 3-1 nesting, E-1 subroutines, 3-1 index function, 3-32 utility, 1-1, 1-2 indirection operator, 2-14 line number, 2-16 initialized data, E-14 line-feed, 3-15, 4-1 LINK-86, 2-4, 2-16 DEFAULT, 3-3 automatic invocation, 2-3, definitions, 1-2, 4-3, E-2 2-5 EXTERN, 3-3 input file, 2-5, 2-26 getc function, 3-27 INPUT option, 2-5, 2-26 GLOBAL, 3-3 location, 2-4, 2-14 instructions expansions, 2-7 MAP option, 2-16 LOCAL, 3-3 memory allocation message, LONG, 3-3 2-25 MLOCAL, 3-3 SEARCH option, 2-5, 2-16, putc function, 3-44 2-25 REG, 3-3 sign-on banner, 2-24 toascii function, 3-62 sign-on message, 1-7 tolower function, 3-62 LINK86.EXE, 1-2 toupper function, 3-62 location, 2-14 UBYTE, 3-3 linkage editor, 1-1, 1-2 ULONG, 3-3 listing UWORD, 3-3 device, 2-11 VOID, 3-3 generate, 2-3, 2-9 WORD, 3-3 listing/disassembly file malloc function, 3-10 merge utility, 1-2, 1-3, mantissa, 6-3 2-4, 2-10 MAP option LINK-86, 2-17 literal character strings, masking, E-4 2-14 math co-processor, 2-3 local medium model buffering, 4-2 compilation, 2-25 variable, 5-7, E-6 enable, 2-3, 2-25 log function, 3-34 library, 1-1, 1-2, 3-1, A-1 loglO function, 3-34 memory long, 5-3, 5-6 allocation message, 1-5, 1-7 divide, 2-17 compiler, 2-14, 2-23 integer storage, 6-2 LINK-86, 2-24 keyword, 6-2 management functions, shift, 2-17 3-10, A-1 longjump function, 3-53 models, 1-1 low level 1/0, 4-1 requirements, 1-1 lowercase message display level C programs, 5-1 compiler, 2-11 compiler, 3-4 microprocessor function names, 3-4 68000, 3-59, D-1 LPT1, 2-9, 2-11, 4-3 8086/8088, 1-1, 3-59 lseek function, 3-35 8087, 2-3, 2-7 minimum M C system, 1-4 configuration compiler, 1-3 machine support subroutines, mktemp function, 3-36 2-17 modular programs, E-1 macro, 2-17 module size, E-1 abs function, 3-6 BOOLEAN, 3-3 N BYTE, 3-3 ctype functions, 3-16 names constant, E-2 variable, E-2 NEAR RASM-86, 5-3 nodes code generator, 2-10 parser, 1-2, 1-3 nonlocal jump routine, 1-2, location, 2-4, 2-13 3-53 password, 3-29 percent sign 0 printf function, 3-41 scanf function, 3-51 object file peripheral device, 4-1, 4-3 default name, 1-6 perror function, 1-2, 3-38 is format, 2-1 pointer program, 2-24 arithmetic, E-4 specify name for, 1-6, 2-3, scanf function, 3-50 2-9, 2-23, 2-25 stream, 4-2 record, 2-5, 2-24 to static location, 5-5 open function, 3-37, 4-1 PORTAB.H, 1-2, 3-3, 4-3 opena function, 3-37, 4-1 portability, 1-2, 3-1 to 3-3, openb function, 3-37, 4-1 4-3, 5-1, E-1, E-2, E-4, operator E-7 AND, E-14 precision conversion, 6-14 op=, D-1 preprocessor, 1-2, 1-13, 2-13 OR, E-4 execute alone, 2-3, 2-10, sizeof, E-5 2-18 option letter, 2-2 location, 2-4 option switch, 2-2, B-1 printer, 4-3 -0, 2-4, 2-13 printf function, 1-5, 3-40 -1, 2-4, 2-13 problems, 1-7, 2-25 -2, 2-4, 2-13 procedure definitions, E-6 -3, 2-4 process ID, 3-30 -a, 2-3, 2-5, 2-14 program -b, 2-3, 2-6 area, 1-1 -c, 2-3, 2-6, 2-22 listing, 2-3, 2-9 -d, 2-3, 2-7 Programmer's Utilities Guide, -f, 2-3, 2-7 1-7, 2-5, 2-16, 2-25, -h, 2-3 5-1, 5-3, 5-7, 5-8 -i, 2-3 programming style, E-1 -j, 2-3, 2-8 PUBLIC directive RASM-86, -1, 2-3, 2-9 5-2, 5-7 -m, 2-3, 2-25 public C module, 5-3 -n, 2-3, 2-9 putc function, 3-44 -o, 2-3, 2-9, 2-22, 2-25 putchar function, 3-44 -p, 2-3, 2-10, 2-18 putl function, 3-44 -q, 2-3, 2-10 puts function, 3-46 -r, 2-3, 2-10, 2-13 putw function, 3-44 -v, 2-4, 2-11, 2-22 -w, 2-4, 2-12, 2-16 -x, 2-4, 2-12 -z, 2-4, 2-13 qsort function, 3-47 output formatting, 3-40 output/input, 4-1 R P rand function, 3-48 random number generator, parameter RASM-86, 5-1, 5-2, 5-7 external, 5-7 allocation directives, 5-7 passing, 5-3 COMMON combine type, 5-7 remove from stack, 5-6 Index-6 EXTRN directive, 5-3 screen editing, E-7 FAR label, 5-3 SEARCH option LINK-86, 2-5, GROUP directive, 5-8 2-16, 2-25 NEAR label, 5-3 segment, 5-7 PUBLIC directive, 5-2, 5-7 name, 5-6 uppercase, 5-1 registers initialize, 2-16 RASM86.EXE, 1-2 setjump function, 3-53 read function, 3-49 SETJUMP.H, 1-2 realloc function, 3-10 short, 5-6 redirection, 2-16, 4-3 integer storage, 6-2 register variable macro, 3-3 keyword, 6-2 register SI register, 5-3 BP, 5-15 side effects arguments, 3-6, DI, 5-3 3-16, 3-44, 3-62 restore, 2-12 sign-on banner SI, 5-3 compiler, 1-5, 2-23 SP, 5-5 LINK-86, 2-24 regular file, 4-1 sign-on message access, 4-1 LINK-86, 1-7 close, 3-12 suppress for compiler, 2-3 functions, 4-2, A-3 signal function, D-1 offset position, 3-35 significant characters, 5-1 open, 3-37 sin function, 3-13 output to, 3-65 single-byte 1/0, 4-2 read from, 3-49 single-precision relocatable floating-point, 6-3 assembler, 1-1, 1-2, 5-1 data type, 6-1 object file, 1-6, 5-1 storage, 6-3 object program, 2-24 Sizeof operator, E-5 reserved letters, 2-2 small model restore registers, 2-4, 2-12 compilation, 1-6, 2-26 return values, 5-6 library, 1-1, 1-2, 1-6, reverse 2-5, 3-1, A-1 assembly, 2-3 Software Performance Report, preprocessor, 1-2, 2-10, 2-26 2-17 sorting routine, 3-47 rewind function, 3-26 source rindex function, 3-32 file, 2-16 run-time requirements, 1-1 program, 1-5, 2-1 SP register, 5-5 S space, 3-15 array allocation, 3-10 Sample C Module, F-1 option switches, 2-2 sample programs, 1-1, 1-3 sprintf function, 3-40 SAMPLE.C, 1-3, 1-4, 1-5, 1-6 sqrt function, 3-54 SAMPLE.EXE, 1-7 srand function, 3-48 SAMPLE.OBJ, 1-6 sscanf function, 3-50 sbrk function, 3-9 stack, 5-3, 5-4, 5-6 scanf function, 3-50 initialize pointer, 2-16, 5-6 stand-alone programs, 2-16 standard error file, 4-3 input file, 4-3 input/output, 1-2, 3-3 SYSLIBC.L86, 1-2, 3-1, A-1 input read, 3-50 SYSLIBM.L86, 1-2, 3-1, A-1 output file, 4-3 SYSLIBS.L86, 1-2, 3-1, A-1 start-up routine, 1-3, 2-15 system calls STARTUP.A86, 1-3, 2-15 DOS, 3-38 static UNIX, 3-1 area, 2-14 system library, 1-1, 1-2, 3-1, data, 2-14, 5-5 A-1 variables, E-5 big model, 1-2 stderr, 4-3 compact model, 1-2 stdin, 4-3 functions, 3-4 STDIO.H, 1-2, 3-3, 3-6, 4-3 medium model, 1-2 stdout, 4-3 small model, 1-2, 1-6 storage class underscore, 3-2, 5-1, A-1 declarations, 3-2, 3-3 system requirements, 1-1 definitions, E-3 strcat function, 3-55 T strcmp function, 3-56 strcpy function, 3-57 tab, 3-15 stream file, 4-1 tan function, 3-60 access, 4-2 Technical Support, 2-25 close, 3-21 tell function, 3-35 control structure, 3-23, 4-2 temporary functions, 4-2, A-3 destination, 2-4, 2-13 input from, 3-27 filename, 3-36 open, 3-23 files, 1-1, 2-1, 2-13, 2-17 output to, 3-40, 3-44, 3-46 size of, 2-1 pointer, 4-2 space, 1-1, 2-1 read from, 3-25, 3-31, 3-50 terminal, 3-61, 4-3 read/write pointer, 3-26 test programs, 1-1. 1-3 write to, 3-25 TEST.C, 1-3, 2-22 string TESTCPT.EXE, 2-24, 2-25 comparison, 3-56 toascii function, 3-62 concatenate, 3-55 tolower function, 3-62 constant, 5-5, E-5 toupper function, 3-62 copy, 3-57 trouble-shooting, 1-7, 2-25 functions, A-7 ttyname function, 3-61 length, 3-58 two's complement, 6-2 variables, E-4 type definitions, E-3 strlen function, 3-58 typedef, E-3 strncat function, 3-55 strncmp function, 3-56 U strncpy function, 3-57 subroutine libraries, 1-1 underscore, 5-1, A-1 supervisory module, 1-2 system library, 3-2, 5-1 swab function, 3-59 ungetc function, 3-63 symbol table save space, 2-3, uninitialized data, E-5 2-10 UNIX, 4-3, A-4, D-1 symbolic C functions, 3-1, 3-2, 5-1 constants, E-1 system calls, 3-1 names, 3-38 V7 compatibility, 3-1, 3-38 syntax errors, 2-14 unlink function, 3-64 SYSLIBB.L86, 1-2, 3-1, A-1 unsigned keyword, 6-2 uppercase, 5-1 compiler, 3-4 Index-8 V variable, E-1 names, E-2 type declarations, 3-3 ypes, E-3 W t warning messages, 2-14, 2-16 white space characters, 3-15 word boundary, 3-10 work disk create, 2-23 write function, 3-65 x XREF-86, 1-1 XREF86.EXE, 1-2 Z zero padding, 6-4 0 Index-9