AG90 03_Pgmg Intro_Dec81 03 Pgmg Intro Dec81
AG90-03_PgmgIntro_Dec81 AG90-03_PgmgIntro_Dec81
User Manual: AG90-03_PgmgIntro_Dec81
Open the PDF directly: View PDF .
Page Count: 140
Download | |
Open PDF In Browser | View PDF |
HONEYWELL . I . LEVEL 68 INTRODUCTION TO PROGRAMMING ON MULTICS SOFTWARE LEVEL 68 INTRODUCTION TO PROGRAMMING ON MULTICS SUBJECT Introduction to Programming in the Multics Operating System Environment, Intended as a Guide for Applications Programmers SPECIAL INSTRUCTIONS This manual presupposes some basic knowledge of the Multics operating system. This information can be found in the 2-volume set,New Users'Introduction to M ultics (Order Nos. CH24 and CH25). This manual supersedes AG90, Revision 2, which was titled Multics Programmer's Manual. Together with the 2-volume set, New Users' Introduction to Multics, it supersedes AL40, Revision 1, which was titled Multics Introductory Users' Guide. The manual has been extensively revised and does not contain change bars. SOFTWARE SUPPORTED Multics Software Release 9.0 ORDER NUMBER AG90-03 July 1981 Honeywell PREFACE The purpose of this manual is to introduce the Multics environment to applications programmers who have experience on another operating system but are new to Multics. It is very important that you understand exactly who this manual is for, and what assumptions this manual makes about its audience, before you begin to use it. The intended audience of this manual is applications programmers. It is assumed that you have programmed on some other system(s) and that you have some basic knowledge of at least one higher level language (COBOL, FORTRAN, PL/I, etc.). No attempt is made here to teach you how to program. This manual is only intended to show you how to do the things--You know how to do on another system on Multics. As an applications programmer, you look at an operating system from the viewpoint of some programming language. This manual does not attempt to discuss the use of any particular language on Multics, but rather, concerns itself with those practices which are appropriate no matter which language you use. For information on speCific languages you should refer to the Language Users' Guides. The names of these guides are included in the list of useful manuals for new programmers given at the end of this preface. This manual assumes that you are registered on Multics, and that you know how to log in and use a terminal. It also assumes that you have some general familiarity with the fundamental concepts and facilities of the Multics system. This information is available in the following publications: New Users' Introduction to Multics - Part I New Users' Introduction to Multics - Part TI ----- --- Order No. CH24 Order No. CH25 You should feel comfortable with the use of segments, directories, text editors, access control, commands, and active functions. If you don't, you should review the manuals listed above, as no review of this material will be presented here. The information and specifications in tbiB document are subject to change without notice. This document contains information about Honeywell products 01' IIel'ViceII that may not be available outside the UDited Statee. c-Jt your Honeywell Marketing Bepreeentatbe. (£) Honeywell Information Systems Inc., 1981 File No.: 1L13 AG90-03 Section 1 of this manual offers an overview of the Multics operating system in general terms, to give you some idea of why programming on Multics may be different from working on other systems. Section 2 offers a step-by-step approach to the essentials of programming on Multics. It shows you how to create, compile, execute, revise, and document your programs in this environment, how to manipulate your segments, and how to create storage system links. Sample terminal sessions are also included. Section 3 takes you one linking on Multics. step further by showing you the uses of dynamic Section 4 provides you with an introduction to Multics input/output processing, showing you how to use the terminal for I/O and how to begin using I/O commands. Section 5 discusses the use of a Multics debugging tool. Section 6 discusses the use of a Multics performance measurement tool. Section 7 explains the Multics absentee facility, which offers capabilities similar to batch processing on other systems. Section 8 offers a reference to all of the Multics including a brief description of each command. commands by function, The appendixes of this manual contain material which is specific particular language, somewhat advanced, or useful only to certain users. Appendix programming. A shows you how to use Multics to best advantage to a in PL/I Appendix B offers a step-by-step explanation of a PL/I text editor program. (This is for people who are ready to begin systems programming work.) Appendix C briefly introduces you to various Multics sUbsystems. Appendix D shows you how to use the Edm text editor. The information presented here is a subset of that contained in the primary Multics reference document, the Multics Programmers' Manual (MPM). The MPM should be used as a reference to Multics once you have become familiar with the concepts covered in this introductory guide. The MPH consists of the following individual manuals: Reference Guide Order No. AG91 Commands and Active Functions Order No. AG92 Subroutines Order No. AG93 Subsystem Writers' Guide Order No. AK92 Peripheral Input/Output Order No. AX49 Communications Input/Output Order No. CC92 iii AG90-v3 Throughout this manual, references are made to the MPM Reference Guide, the MPM Commands and Active Functions, the MPM Subroutines~nd the MPM-subSystem Writers' Guide manuals. For convenience, these references are as follows: MPM MPM MPM MPM Reference Guide Commands Subroutines Subsystem Writers' Guide Other Multics manuals of interest to new programmers are listed below. • • Languages: Multics APL Order No. AK95 Multics Basic Order No. AM82 Multics COBOL Users' Guide Order No. AS43 Multics COBOL Reference Order No. AS44 Manual Multics FORTRAN Users' Guide -- -- Order No. CC70 Multics FORTRAN Reference Manual Order No. AT58 Multics PL/I Language Specification Order No. AG94 Multics PL/I Reference Manual Order No. AM83 Subsystems: Multics FAST Subsystem Users' Guide Order No. AU25 Multics GCOS Environment Simulator Order No. AN05 Multics Graphics System Order No. AS40 Logical Inquiry and Update System Reference Manual Order No. AZ49 Multics Relational Data Store (MRDS) Reference Manual--- ---- ---- Order No. AW53 Multics Report Program Generator Reference Manual Order No. cc69 Multics Order No. AW32 Sort/Merge WORDPRO Reference Guide • Order No. AZ98 Micellaneous: Multics Pocket Guide - Commands and Active Functions Order No. AW17 Index to Multics Manuals ----- ------ ----- Order No. AN50 The Multics operating system is referred to in this manual as either "Multics" or "the system". The Emacs, Qedx, Ted, and Edm text editors are referred to as "Emacs", "Qedx", "Ted", and "Edm" respectively. iv AG90-03 CONTENTS Page Section Section 2 The Multics Approach • • • • Segmented Virtual Memory • Process, Address Space, and Execution Paint • • • • • • • • Segments and Addressing Dynamic Linking • • • • • • • • • Controlled Sharing And Security Access Control Lists Administrative Control Programming on Multics Designing and Writing Programs Source Segments • • • • • Compiling Programs Object Segments •••••••• Executing Programs • • • • • • Some Results of Execution Revising and Documenting Programs Sample Terminal Sessions • A Note on Examples • • • • • • Archiving Segments • • • • • • • • • Binding Segments • • • • • • • • • • Li nks •••••• • • • • • • • • • 1-i 1-2 1-4 1-6 1-7 1-10 1-12 1-12 2-1 2-1 2-2 2-3 2-5 2-6 2-6 2-7 2-8 2-8 2-8 2-11 2-11 Section 3 Dynamic Linking • • • A Naming Convention Search Rules • • • • A Note on Initiated Segments Uses of Dynamic Linking Search Paths • • • • • • • • • • • 3-1 3-1 3-1 3-3 3-5 3-7 Section 4 Input/Output Processing • • • • • • • • • • The Five Basic Steps Of Input/Output •• Using The Terminal For I/O • • • • • • Using Segments As Storage Files Using I/O Commands And Subroutines • Card Input and Conversion • • • • • 4-1 4-2 4-5 4-8 Section 5 A Debugging Tool The Stack Probe 5-1 5-1 5-5 Section 6 A Performance Measurement Tool 6-1 Section 7 Absentee Facility • • • • 7-1 v 4-10 4-12 AG90-03 CONTENTS (cont) Page Section 8 Reference to Commands by Function • • • • Access to the System • • • • • • • • • Storage System, Creating and Editing Segments • • • • • • • • • • • • • • Storage System, Segment Manipulation • Storage System, Directory Manipulation Storage System, Access Control • • • • • Storage System, Address Space Control Formatted Output Facilities Language Translators, Compilers, and Interpreters •• • • • • • • • • • • Object Segment Manipulation • • • • • Debugging and Performance Monitoring Facilities • • • • • • • • Input/Output System Control Command Level Environment • • • • Communication Among Users Communication with the System Accounting • • • • • • • • • • • • Control of Absentee Computations Miscellaneous Tools • • • • 8-6 8-6 8-7 8-8 8-9 8-9 8-10 8-10 Appendix A Using Multics to Best Advantage • A-1 Appendix B A Simple Text Editor B-1 Appendix C Multics Subsystems Data Base Manager Fast • • • • • • Gcos Environment Simulator Graphics • • • • • • • • • • Logical Inquiry and Update Report Program Generator • Sort/Merge • • • • • Wordpro C-1 C-1 C-1 C-1 C-2 C-2 C-2 C-2 C-2 Appendix D •••••••• The Edm Editor Requests • • • • • • • • • • • Guidelines • • • • • • • • • • • ••• Request Descriptions • • • • • • Backup (-) Request ••••••••• Print Current Line Number (~) Request •• Comment Mode (,) Request Mode Change (.) Request. Bottom (b) Request • • • • • • Delete (d) Request • • • • Find (f) Request Insert (i) Request Kill (k) Request •• •• Locate (1) Request •••• Next (n) Request • • • • Print (p) Request •• Quit (q) Request Retype (r) Request • Substitute (s) Request Top (t) Request •• • •••••••• Verbose (v) Request • • • • • Write (w) Request • • • • • 0-1 0-1 Index 8-1 8-1 8-2 8-2 8-3 8-3 8-4 8-5 8-5 8-6 D-2 0-2 0-3 D-3 0-3 0-4 0-4 D-4 0-5 D-5 0-5 0-6 0-6 0-6 0-6 0-7 0-7 0-8 0-8 0-8 i-1 vi AG90-03 CONTENTS (cont) Page ILLUSTRATIONS Figure Figure Figure Figure Figure Figure Figure Figure Figure Figure Figure 1-1. 1-2. 1-3· 1-4. 1-5. 2-1- 2-2. 3-14-1. 4-2. 4-3· Figure 5-1. Figure 5-2. Figure 6-1. Figure 7-1. Traditional System vs. Multics Virtual Memory . Processes Sharing a Segment . • . . Two-Dimensional Address Space • . . . • . • • . The Life of a Segment • • . • . • • • . . • • • Resolving a Linkage Fault (Snapping a Link) Sample Terminal Session #1 . . . • Sample Terminal Session #2 Initiated Segments Flow of Data • . • . . Standard Attachments Attachments After Execution of file_output Command • . • . . . . . . . ". . . State of Stack • . . • • . • • • . . Allocation of Stack Frames . . . . • Use of profile Command With -list Control Argument . • . • . • . ..•. Interactive vs Absentee Usage • • . . • . . vii 1-3 1-5 1-8 1-9 1-11 2-9 2-10 3-4 4-3 4-6 4-13 5-2 5-4 6-4 7-2 AG90-03 SECTION 1 THE MULTICS APPROACH The Multics approach is quite different from that of a traditional batch operating system. The intent of this section is to show you how Multics is different, by giving you a general overview of the system's "personality", then describing in more detail three of its major characteristics: segmented virtual memory, dynamic linking, and controlled sharing and security. As these characteristics are discussed, important concepts associated with each will be introduced and explained. Familiarity with these concepts will help you when you read later sections of this manual and begin to program on Multics. Multics is a large, powerful, well-established system, which is constantly being refined, and provides a wide range of commands, languages, and subsystems. Despite its size and complexity, Multics is easy to learn and use. It has been designed to serve a wide variety and number of users, all cooperating and sharing resources. Multics offers its users the following advantages: • support for online usage: Multics has been designed to support online processing as well as batch processing. You can accomplish all of your programming tasks as either an interactive (online) user or an absentee (batch) user. Applications, debugging tools, data base management facilities, administrative tools and utilities are all accessi ble online. In one terminal session, you can write, compile, execute and debug your program. (See "Sample Terminal Sessions" in Section 2, and "Probe" in Section 5.) • consistent user interface: A great deal of thought has gone into making similar parts of Multics work in similar ways. For example, common control arguments such as -all and -brief are used with many different commands, and in each case, the control argument performs a similar function. In addition, all parts of the system have been designed to work together. • uniformity of control language: Batch processing on Mul tics is supported by the absentee facility (described in Section 7). An absentee job is processed like an interactive terminal session; it's directed by the same language as that used for interactive jobs. In other words, no special job control language (JCL) is ever required on Mul tics. The system commands and routines provide the logical branching, conditional execution, input/output control, and file system specifications necessary to direct any job. • ease of use: On Multics, users are not asked to give information or make decisions ahead of time. There are many examples of this. You don't have to know or specify either a segment's size or its location to use it. You don't have to make your need for tape drives and similar resources known in advance. Intelligent defaults mean that you need not create a correspondence between a file and an I/O name. Dynamic linking (described later in this section) means that you need not name or prefetch programs you want to execute. You can set up a tempor~ry working array for your PL/I or FORTRAN program in its own segment, without specifying how much space you need or worrying that the array will get too big. You will find that this lack of required prespecification greatly simplifies your use of the system. 1-1 AG90-03 SEGMENTED VIRTUAL MEMORY The most significant difference between the Multics programming environment and that of most other contemporary computer programming systems lies in its approach to addressing online storage. Most computer systems have two sharply distinct environments: a resident file storage system in which programs are created, and translated programs and data are stored; and an execution environment consisting of a processor and a "core image", which contains the instructions and data for the processor. Supervisor procedures provide subroutines for physically moving copies of programs and data back and forth between the two environments. In Multics, there is one conceptual memory, which is known as the virtual memory. The traditional distinction between secondary storage and main memory has no meaning, because a single infinitely large memory is simulated by the software, with data stored in finite segments which appear to be in memory at all times. Figure 1-1 illustrates this difference between a traditional system and the Multics virtual memory. With the line between the two traditional environments deliberately blurred, program construction on Mul tics is simplified: most programs need only be cognizant of one environment instead of two. This blending of the two environments is accomplished by extending the processor/ core image environment. In Mul tics, your share of the processor is termed a process, and your core image is abstracted into what is called an address space. In a sense, each segment is a core image, and your process can have lots of them. The easiest way to think about the terms process and address space is to imagine your process as a private computer and your address space as a private memory for your process to work in. (See "Process, Address Space, and Execution Point" next in this section.) Another important difference between the Mul tics environment and that of most other systems is that an address in Multics has two parts: a segment identifier and a location, or offset, within the segment. Traditional Address I Segment I Offset Multics Address (See "Segments and Addressing" later in this section.) 1-2 AG90-03 o o o CORE IMAGE o N L..;.-._ _ _..... TRADITIONAL SYSTEM r------------------------------USER1----------------------------~ SEG 1 o SEG2 o o SEG3 o r---- USER 2 - - - - -...~.... SEG 1 SEG 4 o ••• ••• MULTICS VIRTUAL MEMORY Figure 1-1. Traditional System vs. Multics Virtual Memory 1-3 AG90-03 Process, Address Space, and Execution Point When you log in to the system, you are allocated environment known as a process. A process consists of a called an address space, over which a single execution (i.e., to fetch instructions and make data references). system resources in an collection of segments point is free to roam ----- A process executes programs on your behalf, either directly in response to your instructions or automatically as part of supporting the programs you invoke directly. The programs executed on your behalf and the data they reference make up your address space, and that address space combined with the act ion of execut ing those programs make up your process. Your execution point is whatever is executing at any moment. Space within the virtual memory is dynamically assigned to your aaaress space. Its contents are a function of the sequence of instructions that are processed between the time you log in and the time you log out, and thus it dynamically shrinks and grows as necessary. Your address space is different from the usual core image in that it is larger and it is segmented. A segment may be of any size from 0 to 255K, and an address space may have a large number of segments (typically about 200). Usually, each separately translated program resides in a different segment; collections of data which are large enough to be worthy of a separate name are placed in a segment by themselves. The system assigns attributes (access control and length, for example) to each of these segments based on their logical use. There is a distinct address space for each user who is logged in, even though many users may share the very same segments in their address spaces. Your process is created when you log in, and destroyed when you log out, when you request a new process with the new proc command, or when some kinds of errors occur. You may view your process as if all system resources are dedicated to it alone--as if you have a processor all to yourself--when in reality, all resources are being shared among many processes. Not only are there other interactive processes running, there are also absentee processes running as "background" to the interactive ones, and there are various daemon processes running, which are associated with the normal operation of the system and not connected to any user. All of these processes are continually cooperating and competing for processor time and main storage resources. The processor is multiplexed between processes according to rules defined for the system as a whole, with the object of sharing resources in an equitable manner. Processes can share with each ether, and this sharing is of two types. First, any references to a segment by more than one process are references to the same segment. Second, a large part of the address space in all processes is identical, because the parts of the system shared by all users are given segment numbers (described below) that are the same for all processes. Figure 1-2 illustrates this sharing of segments. You should remember that each process's virtual memory is private to it. This means that changes made to one process's virtual memory assignments do not affect those of other processes. In addition, when a segment is being shared, it means that multiple users may not only read the segment, but also write it. 1-4 AG90-03 ~ 7' D D [] 0 USER 1 D PROCESS 1 z D o USER 2 PROCESS 2 Figure 1-2. Processes Sharing a Segment 1-5 AG90-03 Segments and Addressing It's important to understand that a Mul tics segment is not a file. A segment can be addressed directly, like memory. It doesn't have to be read or written record by record like a file on other systems. On Multics, everything is in a segment: program source code program object code data files mail boxes work areas temporary storage exec coms There are two main reasons why segments are used in Multics. The first is that they make it possible for all your process's programs and data to be easily and directly addressable. The second is that they make it possible to protect and share programs and data by controlling access at the hardware level. (For more on this, see "Controlled Sharing and Security" later in this section.) The segment ; ~ often described as the basic unit of storage in Multics because all locating (addressing) of data in the system is done in terms of segments. The physical mo~ement of information between main memory and secondary storage is fully automatic in Multics (it is done by the paging mechanism). The usual complex combination of file access methods and job control language which you are probably used to is replaced by a simple two-dimensional addressing scheme. This scheme involves the user-assigned symbolic name of the segment (its pathname), and the address of the desired item within the segment. Even relative addresses are usually given in symbolic terms through the data description facilities of the language you're using. Thus, each segment appears to its user as independent memory, symbolically located. Segments don't have to be in specific storage locations. They can be relocated anywhere in memory and grow and shrink as need be. 1-6 AG90-03 References to any portion of your address space consist of a segment name and a location wi thin the segment; all addresses are interpreted as offsets within segments. To increase the efficiency of a storage reference, a segment number becomes associated with a segment name when the segment is initiated (added to your process's address space). A segment is said to be known to a process when it has been uniquely associated with a segment number in that process. The segment number is a temporary alias for the segment name, which is more easily translated into a storage address by the hardware. When you write:[symbolic_offset] the hardware uses: [offset_number] The association between a segment name and a segment number is retained until the segment is terminated (removed from your process's address space). If it is terminated and initiated again, the number will be different. (See the discussion of initiating and terminating segments in Section 3.) Thus, every address or pointer is a pair of numbers: the segment number and the offset wi thin the segment. This pair of numbers forming an address represents the coordinate of a location in the two-dimensional address space. See Figure 1-3 for a graphic representation of a two-dimensional address space. See Figure 1-4 for an illustration of the life of a segment. A program can create a segment by issuing a call to the system specifying the symbolic name as an argument. Different users can incorporate the same segment into their programs just by specifying its name. (A program need not copy a segment to use it.) A program can address any item wi thin a segment using "segment, 1" where segment is the symbolic name of the segment and 1 is the location of the desired item within the segment. The ALM (Multics assembly language) instruction shown below illustrates a symbolic reference to location "x" in segment "data": Ida data$x For more information on the Multics virtual memory, see Guide. th~ MPM Reference DYNAMIC LINKING Many programs make .calls to external subroutines or use external variables. On most systems, these external references are resolved during loading or linkage editing. When the program is loaded into memory, external subroutines are loaded from libraries or user data sets, and storage is allocated for external variables. On Multics, external references are resolved when the program~; i.e., the point at which something is used is the point at which it is found. This means that a compiled program on Multics is directly executable. Segmentation is what makes this possible - it gives each segment a "zero" location, so no relocation is necessary. 1-1 AG9o-o3 SUPERVISOR USER PROGRAMS, DATA, COMMANDS , y 256K IZ w ~ (!) w en o IZ I- w en Ll. Ll. o co E E 0') o 0. o SEGMENTS Figure 1-3. Two-Dimensional Address Space 1-8 AG90-03 create initiate; per process (activate) I Lage has segment number exists 1 in memory has page table pages 2 and 4 in memory (deactivate) terminate delete Figure 1-4. The Life of a Segment Note 1. Events in parentheses are not user visible. Note 2. Segments are automatically divided by the hardware into storage units known as pa ges with a fixed size of 1024 words. (One word is equal to 36 bits or 9-bit bytes.) 4 1-9 AG90-03 Dynamic linking is accomplished by having the compiler leave in the object code of a compiled program an indirect word with a "fault tag" which, if used in an indirect address reference, causes a linkage fault to the dynamic linker. The linker inspects the location causing the fa~ and from pOinters found there, locates the symbolic name of the program being called or the data segment being referenced. It then locates the appropriate segment, maps it into the current address space, and replaces the indirect word with a new one containing the address of the progr~m or data entry point, so that future references will not cause a linkage fault. When the system comes across an unresolved reference, it uses what are known as search rules (described in Section 3) to find the needed segment and establish the necessary link. This process is known as snapping a link. To see how the linkage fault caused by the ALM instruction mentioned previously would be resolved, refer to Figure 1-5. With dynamic linking, you don't pay the cost of resolving references (for example, calls to error routines) unless they are actually needed. If a subroutine is never called, it doesn't even have to exist, and the main program will still run correctly. An item in the file system has to be in your address space for you to use it, but it doesn't have to be copied and brought into memory before execution. The virtual memory guarantees that any item you reference is where the processor can address it directly. Dynamic linking simplifies your programming by totally eliminating the loading step. It also eliminates the need for a complicated job control language for retrieving, prelinking, and executing programs, and for defining and locating input/output files. For more information on dynamic linking, see the MPM Reference Guide. CONTROLLED SHARING AND SECURITY Mul tics permits controlled sharing of the operating system software and libraries, the language compilers, the data bases, and all user code and data. You can create links to other programs and data, give and revoke access, directly access any information in the system to which you have access, and share a single copy in core. 1-10 AG90-03 ALM program Ida data$x linkage (before) "data" compilation L linkage (after) execution new indirect word Figure 1-5. Resolving a Linkage Fault (Snapping a Link) 1-11 AG90-03 Access Control Lists One way of controlling the sharing and security of information is by using access control lists. ACLs, as you have already learned in the New Users' Introduction to Multics, define the access rights for each segment and directory. You can grant permission to use your segments and directories by individual user, by project, by instance (interactive/absentee), or by combinations of these. You can also grant different access to different users of the same segment. A good example of using ACLs is a compiler which resides in a segment that can be executed but not written. For more details on access control, see the MPM Reference Guide. Administrative Control Another kind of information control is administrative. Mul tics administration defines three levels of responsibility: system, project, and user. A system administrator allocates system resources among the proj ects on his system; a project administrator allocates project resources among the users on his project; a user can manage his own data through storage management and access controls. Your project administrator can define the environment of the users under his project. He can give you complete control in creating your own process, or he can limit the requests and commands available to you. He can determine the dollar limit that you may incur in a single month (or other period of time), and arrange things so you'll be automatically logged out if you exceed this limit. You won't be able to log in again until the next month begins or the limit is changed. He can also determine several other items, including whether a user can preempt others, specify his own directory, or have primary or standby status when logging in. You yourself also have flexibility in shaping your programming environment on Mul tics. A good example of this is the special command processor which allows you to make abbreviations for your frequently used commands (abbrev). For more information on Multics administrative features, the manuals in the Multics Administrators' Manual (MAM) set: Project Administrator Registration and Accounting Administrator System Administrator 1-12 refer to one of Order No. AK51 Order No. AS68 Order No. AK50 AG90-03 SECTION 2 PROGRAMMING ON MULTICS Programming on Multics is very different from programming on other systems. Many of the constraints and restrictions you may be used to are simply removed. 'The system provides high-level terminal control, data base management, 1/0 interfaces, and data securi ty. There is no need for overlays, chaining or parti tions. This section explains how to write, compile and execute programs in the Multics environment. It also offers advice on revising and documenting programs, manipulating segments, and creating storage system links. DESIGNING AND WRITING PROGRAMS Let's say you've been given specifications for a program which will compute the sum of three numbers. Obviously, this is not a realistic task for a computer, but it will provide us with a very simple example. Of course, the first thing you need to do is to develop a design for your program, be i t a flow chart, a functional diagram, a hierarchy, or whatever. Once you have a good design, the next step is to decide which language you will write your program in. The following programming languages are available on Multics: • APL: A terse, capabilities. powerful language, with strong data manipulation • BASIC: A simple language for beginners, which can perform string and arithmetic operations without much difficulty. • COBOL: A business oriented, high-level, English-like language with many string and arithmetic capabilities. • FORTRAN: A high-level, scientific language designed mostly for arithmetic applications, with very limited character manipulation capabilities. • PL/I: A very powerful, high-level language that offers almost total control over the operations of the program, and has many capabilities to manipulate characters and perform arithmetic operations. (ALM, the assembly language on Multics, is also available, but is not recommended for general use.) For this program, let's say you choose PL/I. The code for your program might look like this: 2-1 AG90-03 simple_sum: proc options (main); 1* this program computes the sum of three numbers set in the program, then prints the answer at the terminal *1 declare sysprint first no second- no third - no the sum - file, fixed fixed fixed fixed binary binary binary binary 1* 1* 1* 1* 1* ( 17) , ( 17) , ( 17) , ( 17) ; the the the the the terminal output *1 first number *1 second number *1 third number *1 answer *1 1* set the three numbers *1 first no = 123; second no = 456; third no = 789; 1* add them up *1 the sum = first no + second no + third_no; 1* print the answer *1 put skip list ("The sum of the three numbers is:", the_sum); put skip; Notice the use of sysprint for the terminal output. this, see "Using the Terminal for 1/0" in Section 4. For more information on Source Segments The next step is to create a segment containing your code. You can input your code by using anyone of several text editors. Two editors you are already familiar with are Qedx and Emacs. Detailed information on these edi tors is available in the Qedx Users' Guide (Order No. CG40) and the Emacs Users' Guide (Order No. CH27)respective~ Of special interest to programmer5are the programming language modes available in Emacs. The FORTRAN, PL/I and ALM modes provide editing environments which facilitate the creation, formatting and debugging of programs written in these languages. Two more editors will be introduced here. One is Edm. This is the most basic Multics editor and is described in Appendix D of this manual. The other is Ted. Ted is a more advanced version of Qedx, which offers many advantages. These include more flexibility in addressing characters within a line, two types of input mode, regular and bulk, and more ways of manipulating buffers. Ted is a programmable editor, which means that you can write character manipulation programs in the Ted editor language. Other Ted features include sorting and tabbing capabilities, the ability to translate letters from upper to lower case and vice versa, and the ability to have lines fill and adjust. For more information on Ted, use the help command. The segment that your source code is stored in is called a source segment. Once your source segment is created, you should give it an entryname which follows the Multics convention for such names. This convention is to add a dot suffix to the end of the name indicating which language the program is written in~ Thus, the form for a source segment entryname is: 2-2 AG90-03 A good name for your program would therefore be: simple_sum.pI1 Some other examples of program names are: ran num gen. basic payroll-:-cobol square_root.fortran (Remember that upper and lower case characters are not interchangeable on Multics. Thus, "payroll.cobol" and "Payroll.cobol" are two different names. See the MPM Reference Guide for more information on naming conventions.) You will probably find it useful to create several different directories for yourself, each containing a different sort of segment. For example, you could have one directory for the final (debugged) versions of your programs, one directory for the programs you are writing or revising, another directory for test data, etc. If you write programs in several different languages, you could also have directories for programs in each language. (Remember that your segments are not physically located in directories any more than you are physically in the phone book. When a segment is said to be "in" a directory, it means that the directory contains an entry for the segment.) COMPILING PROGRAMS Mul tics provides a compiler for each higher level language it supports. Compilers are system programs which translate source code into obj ect code, machine level language that is executable by the hardware. The input to a compiler is a source segment. The output of a compiler is a corresponding object segment. (This discussion does not apply to APL, which is an interpreted language. There is no APL compiler and no APL obj ect segment.) Your working directory is always assumed to be the location of the source segment you want to compile, and the intended location of the object segment you want to create, unless you say otherwise. To execute a compiler, you invoke it as a command, with a command line which looks like this: language_name path {-control_arguments} where language name is the name of the language your program is written in, path is the entry name of your source segment, and {-control arguments} are any of a number of optional control arguments you can supply to the compiler. Several of these control arguments instruct the compiler to create a listing segment in your directory. (No compile listing is produced by default.) This segment has the same entryname as your source segment, but with a suffix of "list" instead of "pI1" or whatever. A listing segment contains a line-numbered list of your source program, plus information that is useful for understanding, debugging, and improving the performance of your program. The control arguments which produce a listing segment are: -list produces a complete source program listing including an assembly-like listing of the compiled program. Use of this control argument significantly increases compilation time and should be avoided whenever possible by using -map. 2-3 AG90-03 -map produces a partial source program listing of the compiled program which should contain sufficient information for most online debugging needs. Another useful control argument is: -table generates a full symbol table for use by symbolic debuggers. The symbol table is part of the symbol section of the object program (discussed later in this section) and consists of two parts: a statement table that gives the correspondence between source line numbers and object locations, and a name table that contains information about names actually referenced by the source program. This control argument usually causes the object segment to become significantly longer, so when the program is thoroughly debugged, it should be recompiled without -table. See the MPM Commands under the specific compiler for detailed information on all of the control arguments and the information they provide. Also see the various Language Users' Guides. So, your command line for compiling your program might look like this: ! pl1 simple_sum.pI1 -map In this and all interactive examples in this manual, an exclamation point is used to indicate a line that you type at the terminal. You do not type the exclamation point, nor does Multics type it as a way of prompting you. It is strictly a typographical convention, to distinguish between typing done by you and typing done by Multics. In reality, you don't have to type the dot suffix component of your entryname. The compiler assumes that the input is a source segment, and will search your working directory (or whatever directory you're using) for the segment with the appropriate suffix. Thus: ! pl1 simple_sum.pI1 means exactly the same to the compiler as: ! pl1 simple_sum If your source code is clean and the compile is successful, an object segment is placed in the directory you're using, with the same entryname as your source segment, but stripped of the language name suffix: ran num gen. basic payroll:-cobol square_root.fortran ---------> ---------> ---------> ran num gen payrollsquare_root So, if you execute this command line: pl1 simple_sum -map then you list your working directory, you'll see: simple sum simple-sum.pI1 simple=sum.list Your listing segment, simple sum.list, can be printed on your terminal with the print command, or printed on paper with the dprint command. Since listing segments take up a large amount of space, the sensible thing to do is to dprint the segment, then delete it: ! dprint -delete simple_sum. list 2-4 AG90-03 If there are problems with your source code, the compiler will produce error messages. The compiler can detect errors according to the definitions of the language involved. These include typing errors, syntax errors, and semantic errors. These messages are printed for you at your terminal. The format and details of error messages vary from compiler to compiler. The following is a sample PLII error message: ERROR 158, SEVERITY 2 ONLINE 30 A constant immediately follows the identifier "zilch" SOURCE: a = zilch 4; If your compile is taking a long time, you can issue a QUIT signal and take a look at your ready message. Since a ready message contains the amount of CPU time used since the last ready message, if the CPU times on your last two messages are different, you know your compilation is working. To resume it, type start. You can also use the progress (pg) command to get information on how a command's execution is going. To check on your compile of simple sum.pl1 with the -map control argument, you would type: ! progress pl1 simple_sum -map The system would periodically type information about the pl1 command's progress in terms of CPU time, real time, and page faults. (A page fault occurs when a page of a referenced segment is not in memory.) See the MPM Commands for a detailed explanation. Object Segments As you may remember from the discussion of dynamic linking in Section 1, an object segment is an executable module. This is quite different from other systems, where the object module which is the output of the compiler cannot be executed until it has been through some kind of linkage editing to become a load module. On Multics, there is no such distinction between an object module and a load module. Thus, there is no need for you to determine in advance the absolute addresses of programs in memory, or give instructions for linking and calling programs or loading them. All compiled programs are ready to run. Most higher level languages supported by Multics compile into Multics standard object segments. These are divided into several sections. The first section is called the text section and contains the binary machine instructions that were translated from the source code and are executed by the processor. The next section is the definition section, which defines the names and locations of entry points present in the segment, and the names of external entry points used by the segment. An entry point is a symbolic offset within a segment. (See "A Naming Convention" in Section 3.) After the definition section comes the linkage section, which serves as a template of all virtual addresses for all external entry points used by the program. It contains per-process information used by the dynamic linker to resolve these external references. The next section is the static section, which contains data items to be allocated on a per-process basis. (This section may be included in the linkage section, and not exist as a separate section.) Then there is the symbol section, which contains information on all the variables declared in the program. The symbol section is always present in the object segment. If -table is specified when the program is compiled, then a symbol table is included in this section. Some compilers (e.g., p11) support the -brief table control argument, which produces a shorter symbol section. Finally there1s the object map, which contains the lengths and offsets for each section of the object segment. Details about the format of object segments and what each section contains may be found in the MPM Subsystem Writers' Guide. 2-5 AG90-03 Where the standards for the source produced by Multics are: • language permit, all obj ect segments pure: the object segment contains no code that modifies itself during execution. Information about calls outside the segment is copied into a special segment, and all modifications are made to the copy. The same segment can be executed by more than one user. No copies of object segments are made on a per-user basis; there is one shared segment in the address space of all who use it. For example, even when multiple users are simultaneously compiling COBOL programs, only one copy of the COBOL compiler is in use. • recursive: the object segment can call itself. • in standard format: the calling protocols for object segments are the same irrespective of the higher-level language of origin. This means that a program in one language can call a program in another language. Programs can also access any data or file which can be described by data types supported by the particular language. EXECUTING PROGRAMS Now that you have an object segment, you are ready to try executing your program. To do this, all you have to do is type the name of your program from command level. The entryname is understood as a command--the system is instructed to find your program and execute it, just as when you type the name of a command (like list), the system is instructed to find the program by that name and execute it. Source and object segments are both permanent (they don't have to be copied to a special directory to be saved), so your program can be run over and over until you choose to delete it. Some Results of Execution • The program runs to normal termination and you get a ready message, indicating that execution was successful. r 10:29 3.0 350 • The program pauses for input from your terminal. • The program halts because of a breakpoint you've put in it for debugging purposes. • The program runs to normal wrong. • The program halts because you issue a QUIT signal, and the system responds with a ready message indicating a new command level: termination, but the output you get is QUIT r 10:40 0.1 497 level 2 • The program halts because of an execution error. Examples of such errors are overflows, underflows, data conversions, and undefined references. The system prints an error message, then gives you a ready message indicating a new command level: Error: Exponent overflow by >udd>ProjA>MacSissle>bad_pgmI143 (line 33) System handler for condition returns to command level r 10:38 0.185 98 level 2 2-6 AG90-03 The new command level means that you are again in a position to invoke commands. There are some special commands that can be put to appropriate use here, such as the release, start, program interrupt, or probe commands. The release command ret urns you to the original command 1 evel--the work you were doinp at the time of the interrupt is simply discarded. The start command resumes execut ion where it 1 e ft 0 ff. The program int errupt command ret urns execut ion to a predetermined point from v;hich to resume execution. For the use of the probe command see Section 5, "Debugging Tools." ~ultics will provide you with as specific an error message as possible. One common error that happens to almost everyone at some time or other is the following: Error: record_quota_overflow condition by This message means that you have run out of storage space in the system. The best way to fix this situation is to delete unneeded segments and type start. (For descriptions of other common error messages, see Nultics Error Messages: Primer and Reference Manual, Order No. CH26.) REVISING AND DOCUMENTING PROGRAMS If you edit your program and recompile it, you may want to save the old object segment instead of replacing it with the new one. In the process of developing and testing new versions of a program, you may in fact end up with several versions, all of which you want to keep. Here are some ways you can do it: • You can move the old object to another directory, using the move command: ! move simple_sum obsolete_p11_obj>simple_sum • You can copy the faulty source (should you wish to save it as well) and give a new name to the edited version using the copy and rename commands: copy simple sum.p11 obsolete p11 source>simple sum.p11 rename simple_sum.p11 new_simple=sum.p11 - • You can change the name of the old object: You need to be aware of certain dangers involved in renaming segments which are already known to your process. Renaming a segment doesn't change the association between the segment name and the segment number. So, if pgma calls pgmb, then you rename pgmb as badb, create a new pgmb, and run pgma again, when pgma calls pgmb, it will end up with the old badb instead of the new pgmb. For more information on the association between segment names and segment numbers, see "A Note on Initiated Segments" in Section 3. If you ever get confused as to wnlcn version of your source program is which, you can use the compare ascii (cpa) command, which compares ASCII segments and prints any differences. Remember that final versions of your programs should be correctly formatted to improve their readability. There are several Multics commands which can help you do this. For example, the indent (ind) command indents free-form PL/I source code according to a set of standard conventions. For another example, the format cobol source (fcs) command converts free-form COBOL source programs to a fixed format-: These commands also detect and report certain types of syntax errors, and can be used for pre-compile examinations. 2-7 AG90-03 Your final versions should also be well-documented. There are two kinds of documentation for programs. One is internal, and consists of a step-by-step description of what the program does. This sort of documentation is best created by the generous use of comments throughout your code. The other kind of documentation is external, and consists of a more general description of the programs purpose, design, and use. ".jriting info sep;ments is an excellent \-lay of creating this sort of documentation. (Remember that the information in an info segment is printed using the help command). Fin.:.3.11y, all of your source a.nd object segments should access set, so only the appropriate people can use them. have the proper SAMPLE TERMINAL SESSIONS Figure 2-1 displays the interaction -between Multics and the user Karen f'l:acSissle as she logs in and writes, compiles, and executes the simple sum program. MacSissle uses the Qedx editor to put the program online, the pll command to compile it, and the program name (without the language suffix) to execute it. Note that MacSissle does not have the usual ready message. She sets her message to "Karen is here" by using the general ready (gr) command in her start up.ec, the special exec com that runs each time-she logs in. (See the ~~PM Commands for information on the use of general_ready.) In Figure 2-2, user Tom Smith is shown writing a program called times 2, which accepts an integer and prints the value of 2 times that integer. SmIth takes advantage of the terminal for both input to and output from his program. A Note on Examples Because ~ultics is written mainly in PLII, you may find that its runtime environment is somewhat oriented towards the convenience of PLII programmers. Ways to take advantafe of this orientation are presented in Appendix A, "Using Multics to Best Advantage". However, as mentioned in the preface, this manual is intended to be useful for all programmers. Although the majority of the examples are given in PLII, t here is no need to be discouraged if you aren't familiar with this language. ~ost of the examples are extremely simple. To see how you could write the same program in either PLII, FORTRA~:, or COBOL, see Section 4, "Using the Terminal for 110". ARCHIVING SEGMENTS Segments in Mul tics are assigned space in increments of pages (4096 characters) • This can be very wasteful if you have many short files stored in the system. The archive (ac) command allows you to combine several segments into a single segment called an archive. Once in an archive, the individual segments are called components of the archive segment. Packing segments together in this way can produce significant savings in storage allocation and cost. By invoking the archive command with different arguments, you can manipulate the archive segment in a variety of ways. For example, in addition to creating your archive, you can also get a table of contents that names each component in the archive, extract one or more components from the archive, update and replace one or more components, and delete individual components. 2-8 AG90-03 lop:in KacSissle Password: MacSissle ProjA logged in 03/18/81 0921.4 mst Wed from VIP7801 terminal "none". Last login 03/18/81 0726.2 mst Wed from VIP7801 terminal "none". Karen is here qed x a simple_sum; proc options (main); 1* this program computes the sum of three numbers set in the program, then prints the answer at the terminal *1 declCl.re sysprint first no second no third no the sum file, fixed fixed fixed fixed binary binary binary binary 1* 1* 1* 1* 1* (17), (17), (17), (17); the the the the the terminal output *1 first number *1 second number *1 third number *1 answer *1 1* set the three numbers *1 first no = 123; second no = 456; third_no = 789; 1* add them up *1 the sum = first no + second no + third_no; 1* print the answer *1 put skip list ("The sum of the three numbers is:", the_sum); put skip; end simple_sum; \f w simple_sum.pl1 q Karen is here pl1 simple sum PL/I Karen is here simple sum The sum of the three numbers is: Karen is here Figure 2-1. 1368 Sample Terminal Session Hi 2-9 AG90-03 login TSmith Password: TSmith ProjA logped in 06/07/79 0937.5 ~st Tue from ASCII terminal "234". Last login 06/06/79 1359.8 mst Mon from ASCII terminal "234". A new PLII compiler was installed; type: help pl1 new Rates for CPU usaRe have changed; type: help prices r 9:37 1.314 30 qedx a times 2: decla~e proc; (n~m,product) fixed bin(17); declare (sysin input, sysprint output) file; put list ("Enter integer"); put skip; p-et list (num); product = num*?; put skip list ("2 times your integer is:", product); put skip; close file (sysin), file (sysprint); end; \f w times 2.p11 q r 9:40 4.875 62 pl1 times 2 PLII r 9: 41 2.906 272 times 2 Enter- integer 19 2 times your integer is: r 9:43 0.231 50 Figure 2-2. 38 Sample Terminal Session "2 2-10 AG90-03 For more information about the archive command and its use, Corr,manos. refer to the MPH BINDING SEGMENTS The !':ultics bind (be) command is used to merge several separately compiled object segments into a single executable object segment called a bound segment. The binder is primarily an optimizer, which saves search time and link snapping. It resolves as many external references as it can in order to avoid the necessity of resolving them at run time. These references are resolved without recourse to the search rules--the binder looks only in the programs that are being bound. ane rejects any progra~s in which there are ambiguous external references. Binding offers the advantages of taking up less storag:e for the object code, decreasinR execution time, and avoiding many linkage faults that would otherwise occur if the bound programs referenced each other frorr separate segments. Those programs that you call frequently and that are interrelated (ie, reference one another) should be bound to improve program efficiency. The segments must be archived before they are bound. For more information about the bind command, refer to the -MPH Commands. Also, the MPM Subsystem Writers' Guide provides information on the structure of bound segments. LINKS The word "link" is used for two separate things in Hultics: an intersegment link and a storage system link. This can be confusing for beginners, but once you know the system, things are usually clear from their context. An intersegment link is an interprocedure reference, resolved by the linker. This kind of link is described in Section 3, "Dynamic Linking". A storage system link is essentially a "pointer" to a "target". This kind of link is described here. A storage system link is catalogued in a directory like a segment, but just gives the pathname of some other place in the directory hierarchy. The target of such a link is usually a segment, but it can also be a directory, or even another link. A storage system link enables you to access a segment located in some other portion of the directory hierarchy without actually making a copy of it, just as if it were catalogued in your own working directory. This is one of the ways in which Hultics facilitates sharing. Multics allows you to create a link anywhere in the storage system as long as you have the proper access to the directory in which the link is to be placed. You invoke the link (lk) command to create a link and the unlink (ul) command to delete a link. (Refer to the HPM Commands.) To see a list of the linkq you have in your working directory, you can use the list command with the -link control argument. 2-11 AG90-03 SECTION 3 DYNAHIC LINKING As the discussion of dynamic linking in Section 1 indicated, external references 1.-'hen the system comes on Multics are resolved when a program is executed. across an unresolved reference, it uses what are known as search rules to find the necessary segment and establish the link. The purpose of this section is to explain hoVl the search rules operate, then to show you some of the uses of dynamic linking. A NA~ING CONVENTION Due to a PIlI extension which is local to t-:ultics, the "$" character is understood when it appears as part of an external name. a$b is interpreted to mean segment a, entry point b. (Remember that an entry point is a symbolic offset within the segment. Refer to the discussion of two-dimensional addressing in Section 1.) Thus, hcs_$initiate, which will be discussed later in this section, is interpreted to mean segment hcs_, entry point initiate. SEARCH RULES Let's suppose that you are writing a new version of the Qedx Text Editor, and have a segment in your working directory named "qedx". If you type "qedx" on your terminal, you are instructing Multics to find the program named qedx and execute it. But which qedx do you want--yours or the system's? To make the situation a little bit more complicated, let's suppose that one of your coworkers is also writing a new version of Qedx, and has a segment in one of his directories named "qedx", to which you have access. You might want to run his prograrr sometimes instead of yours or the system's. In each case, it's up to Multics to figure out which segment you want. The way Multics does this is by searching. To understand why Multics searches the way it does, you first need to know some of the assumptions it works under. Once you have invoked some program or accessed some data base, r1ul tics assumes there is a good chance you will do so again. If the item is in your address space, that cuts down on the system overhead required to make a complete search for it a second or third time. So Multics keeps track of all the work you do after you login. It records your movement through the file system, noting each item it has located for you and putting these items in your address space. Multics also assumes that any time you use a reference name which you have already used, you mean the same item you meant the first time. (A reference name is a name used to identify a segment that has been made known by the user.) The name of the item and the information the system needs to find it are recorded in a table called the reference name table. Segments in this table are referred to as initiated segments. 3-1 AG90-03 The search rules are a list of directories which are searched until the desired segment is found. The standard search rules are: 1. in order initiated_segments Reference names for segments that have already been made known to a specific process are maintained by the system. A reference name is associated with a segment in one of four ways: 2. a. use in a dynamically linked external program reference. b. use in an invocation of the initiate command. c. a call to hcs $initiate, hcs $initiate count, or hcs $make seg with a nonnull character string supplied as-the ref name-areum-ent. These hcs entry points are described in the ~~PM Subroutines. d. a call to hcs $make ptr Subroutines). - or hcs_$make_entry (described in the t-:PM referencing_dir The referencing directory contains the segment \-lhose call or reference initiated the search. So, if pgma calls pgmb, and pgmb isn't in the reference name table, the system looks for pgmb in the directory where pgma resides. 3. lrTOrking_ dir The working directory is the one associated with you at the time of the search. This may be any directory established as the working directory by either the change wdir command or the change wdir subroutine (described in the ~1PP Commands-and MPt~ Subroutines respectively). The initial working directory is your home directory. 4. system libraries The system libraries are searched in the following order: >system library standard ThIs library contains standard system service modules, i.e., most system commands and subroutines. >system library unbundled ThIs library contains Multics Separately Priced Software. >system library 1 ThIs library contains a small set of subroutines each time the system is reinitialized. >system library tools ThIs library contains programmers. software >system library auth maintained ThIs library c()ntains user programs. You can see what your process's print_search_rules (psr) command: primarily maintained current 3-2 of and search that are reloaded interest installation rules are by to system maintained using the AG90-03 psr initiated segments referencinr: dir working dir)system-library standard )system-library-unbundled )system-library-1 )system-library-tools )system=library=auth_maint Note that, according to these search rules, if you have in your working directory a program with the sa~e name as a system co~mand or subroutine, your program will be used rather than the system's. Don't give your programs the same names as those of system programs, unless you really are trying to replace them. Here is an example of the trouble you can fet into when you duplicate the name of a system program. Suppose you have a program of your own which creates an output file and you name the file "list." If you run your program, then try to list your working directory usinf the list command, you will get a message like this: command_processor_: Linkage section not found. list The system thinks you are trying to run your output file, list, as a program! You can modify your search rules by using the add search rules (asr), delete search rules (dsr), and set search rules (ssr) commands, described in the MPM Commands. In addition, your system administrator can modify the default search rules described above for all users at your site. Thus, the first time you invoke a program after login, the system begins its search for the segment by looking in the reference name table. The search fails there, so it continues through the list of directories in the search rules until the segment is found or all the directories have been searched. Subsequent invocations of the sarle program are much faster, because the system finds the program right away in the reference name table. A Note on Initiated Segments If your program named x references a program named y by means of a call or function reference, a dynamic link is established between x and y so that all subsequent references to y by x are accomplished by using the segment number (the alias for the segment name discussed in Section 1). If you change to a new working directory, and execute a program named z that calls a program in this new directory named y, the system will establish a dynamic link to the original segment y because the reference name y is still associated with the original segment and segment number. The system maintains this association until the reference is terminated. See Figure 3-1 for an illustration of initiated segments working in this way. 3-3 AG90-03 workin9_dir _1 , \,---------",,/ '--- ------ ------------..",~ x call y I z calls y Figure 3-1. Initiated Segments 3-4 AG90-03 Segments can be mace known to your process by using the initiate (in) commc_nd. You can list your initiated segments with the list ref names (lrn) command. References can be terminated by using one of the ter~inate commands, either terminate (tm), terminate refname (tmr), terminate serno (tms) or terminate single refname (tmsr), whlch allmV' you to remove segments from the list of segments- known to your process. (The new proc command also erases all previous associat ion between segment names and segment numbers, by sT,{eeping out your entire address space.) For more detailed information on these commands, see the MPM Commands. Deleting a segment also terminates it. Recompiling a program unsnaps all links in the current process which point to the program, since the location of symbolic entry points may be changed by recompilation. Both of these actions affect only the process performing the operation. Recompiling or deleting a segment in one process may cause other processes using the segment to malfunction. USES OF DYNAMIC LINKING There are many ways in which dynamic linking can be used, but the following three are probahly the most significant: • to permit initial debup-ging of collections of programs before the entire collection is completely coded. • to permit a program to include a conditional call to an elaborate error handling or other special-case handling program, without invoking a search for or mapping of that program unless the condition arises in which it is actually needed. • to permit a group of programmers to work on a collection of related programs, such that each one obtains the latest copy of each subroutine as soon as it hecomes available. The use of dynamic linking in program development is shown by the following script. When the script starts, the program "k" and subprogram "y" have already been written and compiled by our user MacSissle. k: procedure; declare (x, y, z) declare i declare (sysprint, sysin) put list ("Which option?"); get list (i); if i = 1 then call x; else if i = 2 then call y; else if i = 3 then call Z; else put list ("Bad option return; end k; entry; fixed binary; file; II ) ; y: procedure; file; declare sysprint put list (lly has been called. II); put skip; end y; In this example and all others like it in this manual, script are distributed throughout the script itself. 3-5 comments on the AG90-03 k Which option? ! 2 Y has been called. r 17:11 0.123 11 The program "k" is invoked by typing its name. MacSissle calls for option 2, and the program "y" is called. "k" runs successfully even though two of the three subroutines it could call do not exist, because the subroutine it does call is available. Since linking is done on demand, and no demand for "x" or "z" occurs, their nonexistence does not keep the program from running. In the next use of "k", MacSissle asks for an option corresponding to the program iiZ,ii which doesn1t exist. k Which option? ! 3 Error: Linkage error by )udd)ProjA)MacSissle)k1152 (line 11) referencing zlz Segment not found. r 17:11 0.283 90 level 2 The attempt to call the nonexistent subroutine "z" fails. The linkage error handler invokes a second command level, as indicated by the field "Level ?" in the ready messafe. The error message shoHs the full pathname of the program attempting to locate "z," and rives the name of the program that could not be found. The notation "zlz" means entry point "z" in segrnent "z." It is necessary to separate entry pojnt name from segment name, since a PL/I program in a segment could have several entry points with different names. Execution of "k" is suspended, since it cannot continue with the call. has the c h 0 j C € 0 f g i v in g up, 0 r c rea tin g " z . " She in v 0 k est h e qed x editor and creates the segment. f'! a c Sis s I e qed x ! a z: procedure; declare sysprint file; put list ("This is Z") put skip; end z; \f w z.p11 q r 17:12 0.382 48 level 2 Now the segment must be compiled to create a callable object segment. p11 z -table PL/I r 17:12 0.234 65 level 2 With the object segment "z" created, the call from "k" can be restarted. MacSissle does this with the start command. 3-6 AG90-03 start This is Z r 17: 12 0.166 27 The program finishes successfully. any additional intervention. It can now be run with option 3 without k Which option? ! 3 This is Z r 17: 13 0.075 18 For more information on the details of dynamic linking, see the MPH Reference Guide sections on object segments, system libraries and search rules. You might also want to learn about the resolve linkage error (rle) command, which can be used to satisfy the linkage fault after your process encounters a linkage error. This command is described in the MPM Commands. SEARCH PATHS . Searching is something that Multics has to do all the time. So far we've only talked about searching for object serments--what Multics has to do when you type the name of a program you want to execute, or your program references an external procedure. Hultics has to searcr. for other things, too, notably input of some kind. For example, the help co~mand requires as input an info segment. You can tell the system to look in specific places for the input by creating search paths. Search paths have the same basic function as search rules, but are used for things like subsystems and language compilers. A set of commands similar to those available for modifying search rules are available for modifying search paths. These commands are add search paths (asp), delete search paths (dsp), print search paths (psp), set search paths (ssp), and where-search-paths (wsp). All are documented in the HP~:r Commands. -- 3-7 AG90-03 SECTION 4 INPUT/OUTPUT PROCESSING Input/output (I/O) processing on Multics can be handled in many different ways. The intent of this section is to show you how to do simple kinds of I/O on Multics, and to introduce you to the basics of doing more complex I/O. The rultics I/O system handles logical rather than hardware I/O. This means that I/O on Multics is essentially device independent. In other 1rlOrds, you don't have to write your program with a specific device in mind. Most I/O operations refer only to logical properties (e.g., the next record, the number of characters in a line) rather than to particular device characteristics or file formats. To understand how I/O processing on Multics works, you must first be familiar with two important terms. (1) I/O switch: a software construct through which the file name in your program is associated with an actual device. The I/O switch is like a channel, in that it controls the flow of data between your program and a device. It keeps track of the association between itself and the device and the I/O module. (2) I/O module: a system or user-written program that controls a physical device and acts as an intermed iary bet'Voleen it and your program. The I/O modul e knows what the attributes of the device are, and "hides" them from you so you don't have to worry about them. It processes the I/O requests that are directed to the switch attached to it. The ~1ultics system offers the following I/O modules: discard provIdes a "sink" for unwanted output. rdisk supports I/O directly from/to removable disk packs. (These are packs which are allocated in their entirety to a process; they do not contain files in the Multics storage system.) record stream provides a-means of doing record I/O on a stream file or vice-versa. syn establishes one switch as a synonym of another. tape ansi supports I/O from/to magnetic tapes according to standards proposed by the American National Standards Institute (ANSI). 4-1 AG90-03 tape ibm supports I/O from/to magnetic tapes according to IEr1 standards. tape r.1ult supporIs I/O from/to marnetic tapes in Multics standard tape format. tape_nstd supports I/O from/to magnetic tapes in nonstandard or unknown format. tty supports I/O from/to terminals. vfile supports I/O from/to files in the storage system. ~lgure 4-1 illustrates the flow of data between a module, and a device. nY'''''o"Y'~m t-' ... - C','" .......... ~ ; an 1/0 S~!itCh7 an 1/0 THE FIVE BASIC STEPS OF INPUT/OUTPUT For every input/output data stream you are using, you must follow the 5 basic steps of ~ultics I/O processing, which involve attaching en I/O switch to an I/O module, opening the switch, performing the data transfer, closing the switch, and detaching it from the I/O module. These steps may be accomplished outside of your program by means of commands input before and after your program runs, or inside your program by means of subroutine calls or language I/O statements. (Defaults are arranged so you can often appear to skip these steps, and they will be done correctly anyway.) (1) Attach the Switch This step associates your data with a file in your program. The switch is the program's name for each data stream. (In FORTRAN, switches are called file05, file10, etc.) An attachment statement in ~ultics is comparable to a JCL data definition (DD) statement in IBf'1 systems. A switch remains attached until you detach it or you issue a new_proc or lo~out command. A switch may be attached by: • invoking the io_call command • issuing a call to the iox subroutine • using a language open statement (if the switch hasn't been previously attached) • using the default attachments associated with PL/I gets and puts, FORTRAN reads and writes, or COBOL reads and writes 4-2 AG90-03 00 TAPE Figure 4-1. 4-3 Flow of Data AG90-03 (2) Open the Switch This step describes the data you're going to use. It tells the system how the data is organized (its file type) and how it is to be accessed (its mode). Data sets can be organized in four fundamental 1-lays: stream, sequential, blocked, and keyed. Only the first two ways will be discussed here. A stream file is a collection of data that is like free-form text. The data is a continuous flow of information, with individual items separated by blanks, commas, or newline characters. A stream file can be created, examined, and updated via a text editor, and can be meaningfully printed on a terminal or line printer, because it contains only ASCII characters. It's size is arbitrary. A sequential file is a collection of data that is broken into discrete units called re-cords, \-lhich have a fixed form. A sequential file is created by a program, and is used for information which is meant to be read and processed by another program. The data are in the same coded form as data stored internally in the computer and can't be printed meaningfully. ~ost tape files are sequential. Disk files may be either stream or sequential. Terminal I/O is stream-oriented. Data sets can be operated on in three fundamental ways: input only, output only, or both input and output. Some of the opening modes of a switch are therefore: sqi - sequential input sqo - sequential output sqio - sequential input/output si - stream input so - stream output sio - stream input/output A switch may be opened by: • invoking the io call command • issuing a call to the iox • using a language open statement • using PL/I gets, puts, reads, and writes, FORTRAN reads and writes, or COBOL reads and writes--the switch is opened by default subroutine (3) Perform I/O Operations This step is where the data transfer actually occurs. Data transfer may be performed by: • invoking the io_call command • issuing a call to the iox • using language defined I/O statements (gets, puts, reads, writes, etc.) subroutine (4) Close the Switch This step tells the system you are through (at least temporarily) with the I/O switch. It prevents further access to the data through that switch, enables you to re-open the switch la':.er with a different mode, and with output disk files and tapes, sets the length of the file. 4-4 AGgo-o3 A switch may be closed by: • invoking the io call command • issuing a call to the iox • using a language close statement • default (on your program's return), if and only if the switch was opened by default subroutine (5) Detach the Switch This step disconnects your program from your data. A switch may be detached by: • invoking the io_call command • issuing a call to the iox • using a language close statement • default (on your program's return), if and only if the switch was attached by default subroutine USING THE TERMINAL FOR 1/0 The simplest way to do 1/0 on Multics is to use the terminal. There are four standard switches which are attached when your process is created. (1) user i/o: this switch acts as a common collecting point for all terminal 1/0. It's attached to your terminal through the 1/0 module tty and opened for stream input and output. - (2) user input: this switch controls command and data input at the terminal. It's-attached to user ilo through the 1/0 module syn , and through that to your terminal. It's opened for stream input. - (3) user output: this switch controls command and data output at the terminal. It's attached to user ilo through the 1/0 module syn_, and through that to your terminal. It's opened for stream output. (4) error output: this switch controls output of error messages at the terminal. It's attached to user ilo through the 1/0 module syn_, and through that to your terminal. It's opened for stream output. Figure 4-2 illustrates these standard attachments. 4-5 AG90-03 PROCESS Figure 4-2. Standard Attachments 4-6 AG90-03 If you don't specify switch names and 1/0 ~odules when you run your program, the system uses these defaults. So, it's possible to write your program using the terminal for input and output and not worry about files. For example, here is a revised version of our sample program from Section 2, simple sum. It has been renamed any sum, and changed to accept input typed by the-user at the terminal in response to a prompting message. The output is typed back on the terminal. Notice the use of sysin and sysprint for the terminal input and output. any_sum: proc options (main); 1* this program computes the sum of any three 1 to 6 digit numbers typed at the terminal, then prints the answer at the terminal *1 declare sysin sysprint first no second no third -no the sum file, file, fixed fixed fixed fixed binary binary binary binary (20) (20) (20) ( 24) 1* 1* 1* 1* 1* 1* , , , ; the the the the the the terminal input *1 terminal output *l first number *1 second number *1 third number *1 answer *1 1* get the three numbers *1 put skip list ("please type three 1 to 6 digit numbers:"); get list (first_no, second_no, third_no); 1* add them up *1 the sum = first no + second no + third_no; 1* print the answer *1 put skip list (lithe sum of the three numbers is:", the_sum); put skip; Here are FORTRAN and COBOL versions of the same program. c c This program computes the sum of any three numbers typed at the terminal, then prints the answer at the terminal. integer first no, second_no, third no integer the sum c the 3 numbers the answer Get the three numbers print, "please type three numbers:" input, first_no, second_no, third no c Add them up the sum c = first no + second no + third no Print the answer print, "the sum of the three numbers is:", the sum stop end 4-7 AG90-03 Detailed information about how the command utility and active function error subroutines can be used from an active function procedure is provided in the MPM Subroutines and the MPM Subsystem Writers' Guide respectively. I The same procedure can be programmed to operate both as an active function and as a command procedure. Typically when such procedures are called as a command, they print on the user's terminal the value of the string they would return as an active function. These command/active function procedures are coded as active functions and should call cu $af return arg instead of cu $af arg count. If cu $af return arg returns the error-code error-table $not act friC, trieyoperate as cOmmar1ds. If the code returned is zero, they use the -returned pointer and length to base the return value. Any other nonzero error code should be fatal. Note that eu $af return arg always returns a correct argument count even if the active functIOn was invoked as a command, so the user can go on to use cu_$arg_ptr with no further checking. ADDRESS SPACE MANAGEMENT When a user logs in, he or she is assigned a newly created process. Associated with the process is a collection of segments that can be referenced directly by system hardware. This collection of segments, called the address space, expands and contracts during process execution, depending on which segments are used by the running programs. Address space management consists of constructing and maintaining a correspondence between segments and segment numbers, segment numbers being the means by which the system hardware references segments. Segment numbers are assigned on a per-process basis (i.e., for the life of the process), by supplying the pathname of the segment to the supervisor. This assignment is referred to as "making a segment known." Segments are made known automatically by the dynamic linker when a program makes an external reference; making a segment known can also be accomplished by explicit calls to address management subroutines. In addi t ion, when a segment is made known, a correspondence can be established between the segment and one or more reference names (used by the dynamic linker to resolve external references); this is referred to as "initiating a reference name." When dynamic linking is the means used to make a segment known, the initiation of at least one reference name is performed automatically. (For more information on reference names, see "Reference Names" in Section 3 and "Making a Segment Known" below.) A general overview of dynamic linking is given below. Dynamic Linking The primary responsibility of the dynamic linker is to transform a symbolic reference to a procedure or data into an actual address in some procedure or data segment. In general, this transformation involves the searching of selected directories in the Multics storage system and the use of other system resources to make the appropriate segment known. The search for a referenced segment is undertaken after program execution has begun and is generally required only the first time a program references the address. The dynamic linker is activated by traps originally set by the translator in the linkage section of the object segment. These traps are used by instructions making external references. When such an instruction is encountered during execution, a fault (trap) occurs and the dynamic linker is invoked. 9/81 4-7. 1 AG91C The dynamic linker uses information contained in' the object segment's d efin i t ion and 1 inkage sec t ion s to fi nd the symbol ic reference name. (For a detailed description of these sections, see "Multics Standard Object Segment" in Section 1 in the MPM Subsystem Writers' Guide.) Using the search rules currently in effect, the dynamic linker determines the pathname of the segment being referenced and makes that segment known. The linkage trap is modified so that the fault does not occur on subsequent references; this is referred to as snapping the link. 8/80 4-7.2 AG91B identification division. program-ide anysum. author. KMacSissle. date-written. February 1981. date-compiled. remarks. This pro~ra~ computes the sum of any three 1 to 6 digit numbers typed at the terminal, then prints the answer at the terMinal. environment division. configuration section. source-computer. Multics. object-computer. Multics. data division. working-storage section. 01 01 01 01 first-no second-no third-no the-sum pic pic pic pic 9(6) 9(6) 9(6) 9(7) value value value value zeroes. zeroes. zeroes. zeroes. procedure division. 100-get-three-numbers. display "please type three 1 to 6 digit numbers". display "(numbers less than 6 digits long must be zero-filled,". display" and each number must be typed on a neH line):". accept first-no. accept second-no. accept third-no. 200-add-the£T1-up. compute the-sum = first-no + second-no + third-no. 300-print-the-answer. display "the sum of the three numbers is:" stop run. the-sum. USING SEGMENTS AS STORAGE FILES v] hen you rap pI i cat ion r e qui res the use 0 f a s tor age f i 1 e for I/O, the easiest thing to do is to use a segment in your working directory (or a segment in another directory to which you have created a link). In your program, you must do the following: (1) Give the file a name and declare it as a file; (2) Open it (connect it to your program, prepare it for processing, and position it at the beginning); (3) Do data transfer via one or more get, put, 'read or write statements (depending on the language you're using); (4) Close it (disconnect it from your program). 4-8 AG90-03 Here is a revised version of the any sum program. It's been renamed compute sum, and changed so that it gets its input from a segment in your working directory called in file. The output goes to another segment in your working directory called out file. compute_sum: proc options (main); 1* this program computes the sum of three 1 to 6 digit numbers read from an input file, then writes the answer to an output file *1 declare in file out file first no second-no third no the sum 1* 1* 1* 1* 1* the the the the the 1* the stream file, stream file, fixed binary (20), fixed binary (20), fixed binary (20), fixed binary (24); input file *1 output file *1 first number *1 second number *1 third number *1 anSvler * I 1* open the files *1 open file (in file) input, file (out_file) output; 1* get the three numbers from the input file *1 1* add them up *1 the sum = first no + second no + third_no; 1* put the answer in the output file *1 put file (out file) list (the_sum); 1* close the files *1 close file (in file), file (out=file); end compute_sum; Doing 1/0 this way also takes advantage of the default switches and modules. The open statement attaches and opens the switch, the close statement closes and detaches the switch. What if the files you need to use are not segments in your working directory? One thing you can do, if you're a PL/I programmer, is to use the title option on your open statement. For example: open file (in file) title ("vfile_ >udd>ProjA>MacSissle>data_files>test file 1") input; where vfile >udd>ProjA>MacSissle>data_files>test_file_1 is an example of an attach description. An attach description is a string of characters which identify the name of an 1/0 module and options to control its operation. In this case, the only option given is the source/target of the attachment (i.e., the name of the device or file). 4-9 AG90-03 Other languages have constructs which are somewhat similar to the PL/I title option. In FORTRAN, there is the attach specifier, which is used on an open statement. In COBOL, there is the catalog-name clause. See the Language Users' Guides for information on how to use these constructs. USING 110 COMMANDS AND SUBROUTINES The use of 1/0 commands and subroutines is where 1/0 processing may become more complex. The following discussion is not intended to fully explain their use, but rather, to introduce the basic concepts involved. For more information, refer to the MPM Reference Guide, Section 5. Information is also available in the Language Users' Guides. (io). The command for performing operations on designated 1/0 switches is io call Its syntax is: io opname switchname {args} It is used as follows: (1) To attach a switch: syntax: io attach switchname modulename {args} example: io attach my_switch vfile_ >udd>ProjA>MacSissle>my_file (vfile >udd>ProjA>MacSissle>my file description.) (2) is another example of an attach To open a switch: syntax: io open switchname mode example: io open mY_SWitch sequential_input (3) To close a switch: syntax: (4) io close switchname example: io close my_switch To detach a switch: syntax: io detach switchname example: io detach mY_SWitch The io call command is used outside of your program. A typical sequence at command level would involve attaching and opening the switches, running your program, then closing and detaching the switches. (Switches that are attached and opened at command level should usually be closed and detached at command level. However, they can also be closed explicitly by the program using language close statements.) Other I/O-related commands include: close file (cf) closes specified FORTRAN and PL/I files. This command is very useful if your program opens a file, then terminates unexpectedly before closing it. You must close the file before you run the program again, or you'll get an end-of-file error. 4-10 AG90-03 copy cards (ccd) copies specified card image segments from the system pool storage into your directory. The segments to be copied must have been created using the Multics card image facility. copy file (cpf) copies records or lines from an input file to an output file. display pl1io error (dpe) describes the most recent file on which a PL/I I/O error was raised and displays diagnostic information associated with that errore file_output (fa) directs all subsequent output over user_output to a specified segment. print attach table (pat) prInts information about I/O switch attachments. revert output (ro) restores all subsequent output to the previous device. stop cobol run (scr) causes the termination of the current COBOL run unit. terminal output (to) directs all subsequent output over user_output to a terminal. Three of these commands can show you a little about how switches work. "pat" on your terminal and the system will print this: Type user i/o tty -login channel - stream input output user input syn user i/o syn- user-i/o user-output error_output syn:= user:=i/o You can see from this that user i/o is attached via the module tty to the login channel, and user input, user output, and error output are attached-Via the module syn_ to user i/o.Type "fo my file; pat; ro; print something like this: pr my_file" on your terminal and 03/10/81 the system will 1124.0 est Mon user i/o tty -login channel stream input output user_input syn_ user i/o user output syn_ fo !BBBJKqdcZHXHFf error output syn user i/o ' fo save !BBBJKqdcZJXgxW- syn user i/o fo !BBBJKqdcZHXHFf vfile >udd>ProjA>MacSissle>my_file -extend stream_output You can see from this that user output was attached via vfile instead of syn • (Refer to Figure 4-3.) For complete information on all of these commands, see the MPM Commands. 4-11 AG90-03 The most important subroutine for doing 1/0 is iox. It is called from vlithin your program just like any other subroutine, and can be used to attach, open, close and detach switches, as ,..reI 1 as to read and write records, and perform various other 1/0 operations. Another subroutine for doing 1/0 is ioa , which is used for producing formatted output; it can be very handy. The use of these subroutines is beyond the scope of this manual. Detailed information is available in the MPH Subroutines. CARD INPUT AND CONVERSION ---You may have programs punched on cards that you would like to compile and run under r~ultics. The standard way of handling a card deck on ~'lultics is to place the deck in a card reader and read it into a system pool. Once this is done, you log in on a terminal, and transfer the card file from the system pool to your working directory using the copy_cards command already mentioned. A minimum cards identify are submitting. input, which is bulk data input of three control cards must accompany your deck. These control you to the system, and specify the format of the card input you There are two kinds of card input on Multics. One is bulk data usually a progra~ or a data file. The format of a card deck for is shown belovl: ++DATA DECK NAME PERSON ID PROJECT ID ++PASST,.]OR D PA SSWOR D ++CONTROL OVERWRITE ++AIM ACCESS CLASS OF UAlA CARDS ++FORMAT PUNCH FORMAT MODES ++INPUT (user data cards) The three cards required as a minimum are the first, which is an identifier card, the second, which is a password card, and the last, which signals the end of control input. The other kind t-1ultics commands to jobs, and the format complete explanation Reference Guide. of be of of card input is remote job entry, which is a series of run as an absentee jOb':'""" ~information on absentee a card deck for remote job entry, see Section 7. For a all the ~ultics control cards, see Appendix C of the MPM 4-12 AG90-03 Figure 4-3. Attachments After Execution of file_output Command 4-13 AG90-03 SECTION 5 A DEBUGGING TOOL A variety of debugging tools are available on Multics. They allow you to look at your program piece by piece, in a vlaY that is closer to the way the machine sees it. The most powerful of these tools is an interactive program naDed probe, which permits source-language breakpoint debugging of PL/I, FORTRAN, and COBOL programs. To understand the discussion of probe given later in this section, you must first know a little about the Nultics stack. THE STACK Each process has associated with it a stack segment (called the stack) that contains a history of the environment. The stack is essentially a push down list which contains the return points from a series of outstanding interprocedure calls. It also holds storage for automatic variables. If you were to stop a running process and trace its stack, you would find, starting at the oldest entry in the stack, a record of the procedures used to initialize the process, followed by the command language processor, followed by the procedure most recently called at command level and any procedures it has called. Your stack can be visualized as follows: The lines in the illustration above define stack frames. As control passes from program to program within the system, your stack ::grows ii new stack frames: 5-1 AG90-03 D Fi gure 5-1 gives a pictorial v ievJ 0 f what t he diffecent times during the execution of a program. frame of the stack can type commands called and a stack 5-1b). The stack program. stack rr.ight look 1 ike at In Figure 5-1a, the last. is for the command level programs. From command level, you at the terminal. Once a command is typed, that program is frame immediately allocated for it. (This is shown in Figure remains in this state for the duration of execution of the Header Header Header initial program initial program initial program first comrr:and level first command level first command level program program a QUIT information b (signal overhead) second command level c Figure 5-1. (a) (b) (c) State of Stack State of Stack after Login State of Stack after Command is invoked State of Stack after QUIT 5-2 AG90-03 Figure 5-1c depicts the stack after a QUIT is signalled. Here a second command level is established. The first command level, and the program itself, have been suspended, but nothing has been thrown out. At this point further commands could be issued. The start command vlould cause the program to resume execution, and the stack to revert to the state illustrated in Figure 5-1b. The release command '.-lould cause the stack frame (and hence the execution state) of the program to be discarded, and the stack to revert to the state depicted in 5-1a. Note that it would be possible at the second command level (Figure 5-1c) to invoke the same program called at the first command level. Figure 5-2 illustrates several of the states of the stack during execution of a program consisting of several subprograms. The call/return sequence depicted is: ProGram Program Program Program Program Program Program A B C B D B A calls program B calls program C returns to B calls program D returns to B returns to A returns to command processor These diagrams illustrate the behavior of four separately compiled programs, each allocated a new stack frame every time it is called: 5-3 AG90-03 Header Header Header initial program initial program initial program first command level first command level first command level Program A Program A a b Program B c Header Header initial program initial program initial program first command level first command level first command level Header Program A Program A Program A Program B Program B Program B e Program C Program D d f Header Header Header initial program initial program initial program first command level first command level first command level 1 Program A Program A h Program B g Figure 5-2. Allocation of Stack Frames 5-4 AG90-03 (a) (b) (c ) (d) (e) (f) (g) (h) (i) User at command Jevel. A is invoked and gets stack frame, in which automatic variables are allocated and initialized. A call s B. B get sst a c k f r am e, i n '>-1 h i c h aut 0 mat i c va ria b 1 e s are a 11 0 cat e d and initialized. B calls C, C gets stack frame, in which automatic variables are allocated and initialized. C returns to S, the stack frame for C is discarded, and storage is released. B calls D, D gets stack frame, in which automatic variables are aJlocated and initialized. D returns to B, the stack frame for D is discarded, and storage is released. B returns to A, the stack frame for B is discarded, and storage is released. A returns to command level. All program-specific automatic storage has been released. Automatic storage is storage "Ihich stays around only for the life of a program. Static storage is storafe which stays around for the life of a process, or is retained across processes. If an unexpected error occurs (or you press the QUIT button), the syster.1 will save the current environment, mark the stack at its current level, and push a frame onto the stack for a new activation of the command processor. The new activation of the command processor accepts commands just as the original one did. It is possible to restart the suspended program, or to discard the saved environment, or to use one of the Multics debugging tools to examine the saved environment. The release command causes the command processor to return to its own previous activation, and discard the intervening stack contents. The programs whose stack contents have been discarded cannot be resumed or examined after the stack has been released. The start command causes the command processor to attempt to continue execution of the suspended program at the point of interruption. Depending on the nature of the error, and what has been done since the error occurred, the restart attempt mayor may not succeed. Programs may always be restarted after a QUIT, but only seldom after an error. If the program cannot be restarted, the error message will usually be repeated. An unsuccessful attempt to restart a program is usually harmless. If you would like to examine the stack history of your process in detail, try using the trace stack (ts) command, described in the MPM Commands. PROBE The probe (pb) command can be used to examine the saved stack and the current state of suspended programs. (Remember that a program which makes a call to another program is suspended just as a program which makes an error is suspended, except that a program which makes a call can always be resumed.) Probe can print the values of program variables and arguments, as well as reporting the last program location to be executed. The use of probe is shown here in a series of examples, which make use of the following program, blowup.pI1. This program has an illegal reference to the array "a", and the subscriptrange condition occurs when it is run. Since 5-5 AG90-03 suhscriptrange checking is disabled by default in PL/I, the error manifests itself as an out of bounds condition instead of a subscriptrange. (In practice, it is recommended-that PL/I programmers' enable such conditions as subscriptrange.) Althougr. this error is easy to spot, the behavior of the program is typical of other, harder to spot errors. print blowup.pl1 b I 01rlU P • P I 1 04/17/80 1332.0 mst Thu blowup: procedure; dcl dcl del j a (10) sum f xed b nary f xed b nary f xed b nary a (*) = 1; do j = -1 to -100000 by -1; sum = a (j); end; end blowup; r 13:320.11020 pl1 blowup -table PL/I r 13:32 0.675 174 The program is compiled with the -table control argument. This action causes a symbol table to be created, and stored with the program in the executable object segment. The information it contains can be used by the Multics debugging aids. A symbol table should always be created while debugging, so that errors may be found more easily. blowup Error: out of bounds at )udd)ProjA)MacSissle)blowupl24 (line 9) referencing stack 41777777 (in process dir) Attempt to access-beyond end of segment. r 13:32 0.228 32 level 2 The program is invoked by typing its name. It takes an 'out of bounds' fault, because the subscript used in the reference to array "a" is inialid. The program does not use PL/I subscriptrange checking, so it attempts to calculate the address of the (nonexistent) element of "a" referenced. The resulting address does not exist, so the fault occurs. This message shows the name of the error condition, the pathname of the program, the octal location in the object segment where the error occurred, the line number, and an additional message about the error. If blowup was a FORTRAN program, the pathname would look like this: )udd)ProjA)MacSissle)blowup$main, blowup being the name of the segment and main the name of the program entry point. This is because every FORTRAN program has a "main" program entry point and fvlultics uses this as part of its name. If the program had not included a symbol table, the line number would not have been part of the message. probe Condition out of bounds raised at line 9 of blowup (level 7). 5-6 AG90-03 t1acSissl e invokes t he probe command. Probe looks for the program wh ich caused the trouble, and prints a messa£"e about the most recent error found in HacSissle's process. The word "level" here refers not to command processor level, but to the number of programs saved on the stack. The error occurred in blowup, which was the seventh program on the stack. stack read listl13400 command processor 110301 abbrev T1501 release stackl1355 unclaimed signall24512 wall14410blowup (line 9) read listl 13400 command processor 110301 abbrev T1507 listen-17355 process overseer 135503 user inlt admin T40100 - 13 12 11 10 9 8 7 6 5 4 3 2 1 out of bounds The stack is displayed by the "stack" request. This request shows every program on the stack, in the order invoked. There i.,rill alt.·lays be unfamiliar programs on your stack. You can just ignore them--they are for handling errors, processing command, etc. The numbers on the left show the order of activation. The entry for blowup ShOltlS the source line number corresponding to the last location executed, and the name of the error that occurred. The line number can be determinerl because blowup was compiled with a symbol table. The other programs have no symbol table, so the display shows the octal offset of the last instruction executed. source sum = a (j); Using the "source" request, the source statement for line 9 is displayed. This is the line that was being executed when the error occurred. More precisely, the error occurred executing the object code corresponding to this source line. value j j = -2689 symbol a fixed bin (17) automatic Declared in blowup dimension (10) The value of the variable "j" is displayed v-lith the "value" request. This request takes as its argument the name of a variable; and prints the value of the variable. (Note that a program must be suspended for you to look at its automatic variables.) Next, the "symbol" request is used, to show the attributes of !l a ." position 8 do j = -1 to -100000 by -1; 5-7 AG90-03 The "position" request is used to examine different lines of the program, in this case the line before the one that caused the hang. This request can also be used to examine different programs on the stack. For example, to look at the abbrev program on level 4, MacSissle could type "position level 4". However, she would most likely get the answer "probe (position): Cannot get statement map for this procedure," which means that the program was not compiled with the -table option. (Most systerr. commands have -table omitted, to save space.) quit r 13:33 1.080 129 level 2 The last probe request used is "quit," which exits probe, and returns to command level. riacSissle is still at command level two, and the program 23 still intact. The next command typed is the release command, which discards the saved frames, returning to level one. release 13:33 0.057 16 r Unlike interactive programs like read mail, probe doesn't prompt you for requests. If you're not sure whether probe-is listening, type a dot, and probe will respond with "probe 5.2" (or \vhatever the version number is) if it is there. Probe has many more features than there is room to present here. It should still be useful to you even if you don't use the other features, but to learn about them you can use the "list requests" request, which tells you the name of every probe request, and the "help" request, which tells you about probe requests and also about probe itself. For example, you can type "help value" to find out about the "value" request, or "help help" to find out about "help". Another debugging tool which you may find useful is the trace command, which allows you to monitor all calls to a specified set of external procedures. Full descriptions of the probe and trace commands are available in the r~pr~ Commands. 5-8 AG90-03 SECTION 6 A PERFORMANCE MEASUREMENT TOOL After a program is written and debugged; it is often desirable to increase its efficiency. Multics provides performance measurement tools which identify the most expensive and most frequently executed programs in a given collection. Within these crucial programs, the most costly lines are found by using the profile facility. To use the profile facility, the first thing you have to do is compile your program with the -profile control argument. This control argument causes the compiler to generate special code for each statement, recording the cost of execution on a statement-by-statement basis. Then, after executing your program many times, you can use the profile command to look at its performance statistics. The example that follows shows the use of profile with a very small sample program to be used as a subroutine: procedure (trial prime) returns (bit (1) aligned); declare trial prime fixed binary (35) parameter; declare trial-factor fixed binary, last factor fixed binary; declare (mod~ sqrt) builtin; last factor = sqrt (trial prime); do trial factor = 2 to last factor; if mod (trial prime, trial factor) = 0 then return (~O"b); end; return ("1"b); end prime_; This subrout ine cannot be called directly from command level, since only programs whose arguments are nonvarying character strings may be called directly. It is to be used with other programs. To test it, a simple command is written which accepts one argument, converts it to binary; and calls the prime subrout ine. The testing command is called test_prime. It is not shown here. - pl1 prime -profile PL/I r 17:44 0.699 140 test prime 3 3 is a prime. r 17:44 .110 23 6-1 AG90-03 First, the prime subroutine is compiled using the -profile control argument. Next, the test_prime command is invoked with the argument "3". Test prime converts the 3 to binary, and calls the prime_ subroutine with it. discard output "test_prime ([index set 500J)" 17:lj5-5.103 5lj r To evaluate the performance of the subroutine, several hundred calls to it should be made, over a wide range of values. The next command line invokes test prime 500 times, witt values from 1 to 5eO. The index set active function returns the numbers from 1 to 500, and the parentheses invoke test prime once for each value. The output from the program is not interesting, so the discard output (dco) command is used. This command causes output from the program to be discarded, instead of printed on the terminal. profile prime - Program: prime COUNT LINE STMT 7 6 1000 1000 7 8 9 10 11 4218 800 3418 200 4lj18 ------Totals: 15054 r 17:46 0.368 51 COST STARS 34000 **** 3000 13254 ~H* 59052 **** 8800 ** 6836 ** 2600 OPEBATORS mod fx 1 return return 127542 \.Jhile the program was run, performance statistics were saved. tJow the profile command is used to display those statistics. For each line, it displays the total times executed, an estimate of the cost, and the PL/I operators used. Note that some statements (those in the loop) were executed more than others. The COST for a statement is the product of the number of instructions for the statement and the number of times the statement was executed. This cost does not take into account the fact that some instructions are faster than others, or the time spent waiting for missing pages (page faults). The STARS column gives a rough indication of the relative cost of each statement. The names of the PL/I operators used are also given. The operator fx1_to_f12 is used to convert the fixed point number to float, so that its root may be taken. The dsqrt operator takes the square root. Finally, the operator f12 to fxl converts the result back to integer. The PL/I mod builtin is implemented-by-the mod fxl operator. These operators are the most expensive things in the program. Occasionally a program can be rewritten to not require expensive operators. 6-2 AG90-03 profile prime_ -sort cost -first 5 Program: prine LINE STMT CTIUNT 8 4?18 6 1000 7 4418 9 800 3418 10 Totals: r 15054 COST STARS 59052 **** 34000 ***~ 132S4 8800 683E *** ** ** OPERA TOPS mod fx 1 fx1=to_f12, dsqrt, f12 to fx1 return 127542 17:46 0.205 49 When profiling large proframs, it is usually desirable to look only at the most expensive lines, since they are the only ones of interest. The profile command can be instructed to sort the lines by cost, and display the five most costly lines in order. The profile command can a1so be instructed to produce a source language type of listing with performance statistics adjacent to each source line. Figure 6-1 shows MacSissle using the profile command with the -list control argument to produce such a listing for the compute sum prograM. rlote that t..rhen -list is used, the profile command produces a seement with the sane nace as the progr2m, but with a suffix of "pfl". (Note also that MacSissle has again set her ready message to read "Karen is here".) More detailed records of execution are available if you compile your program \-lith the -long_profile control argument. Hhen this is done, the program samples the Multics clock before every instruction, so the total time per statement is available to the profile command. The performance data from a program compiled "v.rith -long profile is displayed with the profile command. For further information, see the HPM Commands description of profile. 6-3 AG90-03 ! ~11 eomput~_~u~ -profile 'PL./I I(arefl is here compute_sum Karen is here ~rof;lp. eo~pute_~um -list Karen is h"!'re Profile listin~ of >ud~>ProjA>~acSfssle>co~pute_qu~.o11 Date: ~5/01/~1 11?4.7 edt fr; Tota' count: 7 Total cost: 1°7 COltNT :? 3 1* G oro~"a~ eo~putes t~e su~ of three 1 to b digit numbers read input fii~, then wr~tes t~~ answer to an out out file *1 t~;~ fro~ a~ c; 20 *** ~5 *** c:;9 **** 6 ~ecll'lrp. in_file strea~ file, out_file streAm ffle, first_no f;xe rl ~inary (?O', sec~n~_"o fixed binary (20), t~i"d_n~ f;xe~ ~;ne"y (?O), t~e_sUM fixed binarY (2q): 7 the the the the first number *1 •• cond number *J third nymber *1 anlw.r *1 Ooen fije (in_file) inout, file (out_file) outout; 1* arl~ the~ UP *1 2/J 2~ 4 1* the input f f1 e *1 the outout file *1 1* 1* 1* 1* 1* thP._su~ = flrst_"O + s"!'cond_"o + third_no; 2~ 27 1* put 2f:l t~e 2Q answer in the output file *1 Put fne Cout_f;1e) list (the_Sum)J 30 31 1* close t~e files *1 3;> ~b 10 *** .oIr 3~ cl~sp. 311 file (;n_filA), f;j,. (out_file): 35 3~ erd c~m~ute_sum~ 37 Figure 6-1. Use of profile Command With -list Control Argument 6-4 AG90-03 SECTION 7 ABSENTEE FACILITY A common programming pattern is to develop a program online, using debugging tools and trying a variety of test cases interactively to check on a program's correctness. After the program is working, you may wish to do a large "production" run. Since the production run may produce a large amount of output or take a long time, you may not wish to wait at your terminal for the results. Production runs on Multics are best done using absentee jobs, which are somewhat analogous to batch jobs on other systems. ---An absentee job runs in an environment similar to that of an interactive user. In other words, an absentee job uses Multics in much the same way that a person does. It logs in to your home directory, and runs your start up.ec, if any. This must be kept in mind, both when writing a start_up.ec and when submitting an absentee job. If you forget that your absentee job will run your start up.ec, you may discover that it has stolen your messages or tried to read your mail. If you assume that your absentee job will log in to the directory from which you submitted it, you may discover that it has run the wrong version of your program. A big difference between an absentee job and an interactive user is that an absentee job is not associated with a terminal. Its input comes from a file, and its output goes to a file. (In an absentee process, the I/O switches are attached to the input and output segments, instead of the terminal.) An absentee input file, or control file, is a segment with the suffix "absin". At its simplest, it is just a collection of commands to be executed. The language used in an absentee job is the same as that used in exec coms. It is a superset of the command language. You must anticipate any responses or commands you must give ahead of time, and put all of this data into your control file. An absentee job is submitted by supplying the name of the absin file to the enter abs request (ear) command. The absin file is not copied. It stays absentee job. You must not, for example, edit a file it is using, or recompile a program it is running. The absentee job is placed in a queue and run as "background" to the normal interactive work of the system. This technique allows the system to utilize its resources most effectively, by keeping a queue of jobs that can always be run, and delayed for serving interactive users. For these reasons, the charging rate for absentee jobs is normally substantially lower than for interactive work. Output from an absentee job goes into a file whose name is the same as the absin segment, but with the suffix "absout" instead of "absin". When the job completes, you may print this absout segment. Figure 7 -1 illustrates the differences between interactive usage and absentee usage. 7-1 AG90-03 COMMANDS RESPONSES I ~~~A I ~ COMMANDS ABSIN FILE RESPONSES DATA FILE Figure 7-1. ABSOUT FILE Interactive vs Absentee Usage 7-2 AG90-03 Suppose MacSissle has written a FORTRAN program which figures square roots. The program resides in her directory of FORTRAN programs, and she would like to compile and run it absentee. The first thing she does is create a segment called compile_run.absin. cwd )udd)ProjA)MacSissle)fort progs fortran square root.fortran -list dprint -dl square root.list square root dprint-file10 logout Then she types this command line: Her absentee job is submitted. When it runs, it changes to the proper working directory, compiles the program and produces a listing segment, prints the listing segment on the line printer and deletes it, runs the program, prints the output file "file10" on the line printer, and finally, logs out. To run this same absentee job via remote job entry, MacSissle would put the statements shown above on cards instead of in a segment. Then she would surround her cards with control cards and put the deck in a card reader. Her absentee job would be executed automatically. The format of a card deck for remote job entry is shown below: ++RJE DECK NAME PERSON ID PROJECT ID ++PASSWORD -PASSWORD ++AIM ACCESS CLASS OF ABSENTEE PROCESS ++RJECONTROL CONTROL ARGS TO THE EAR COMMAND ++RJEARGS ARGUMENTS FOR THE ABSENTEE PROCESS ++EPILOGUE COMMAND ++FORMAT PUNCH FORMAT MODES ++INPUT (user absentee file) The three cards required as a minimum are the first, which is an identifier card, the second, which is a password card, and the last, which signals the end of control input For another example, suppose MacSissle wants to use the prime subroutine discussed in Section 6 to check the prime-ness of the first five integers, and she wants to use the absentee facility to do it. Remember that prime is called by test prime~ and that the index set active function can be used to return a set of numbers. 7-3 AG90-03 qedx a test_prime ([index_set 5]) \f w test5.absin q r 16:40 0.218 39 MacSissle uses the Qedx editor to create her absin file. enter abs request test5 -notify ID 210805~1; 5 already requested r 16:41 0.450 63 Multics confirms her submission, g1v1ng the request id and the number of previously submitted jobs in the absentee queue. Often, many of these jobs may be "deferred", which is to say, they will not be run until a later time. Thus, "5 already requested" doesn't necessarily mean that five jobs must be run before MacSissle's job will run. From Initializer.SysDaemon (absentee) 04/21/80 1641.4 mst Mon: Absentee job )udd)ProjA)MacSissle)test5.absin 2i0805.i logged in. MacSissle used the -notify control argument on her ear command, system sends her a message when her job logs in. so the who -absentee Absentee users 3/9 JQUser.ProjB* TSmith.ProjA* MacSissle.ProjA* r 16:42 0.272 22 MacSissle uses the who command to print a list of all absentee jous. It shows that there are three already running, and that a total of nine can run at one time. Absentee users are identified by the asterisk after their project. From Initializer.SysDaemon (absentee) 04/21/80 1643.1 mst Mon: Absentee job )udd)ProjA)MacSissle)test5.absin 210805.1 logged out. The system also sends her a message when her job logs out. 7-4 AG90-03 print test5.absout test5.absout 04/21/80 1643.6 mst Mon Absentee user MacSissle ProjA logged in: r 16:41 2.364 55 04/21/80 1641.4 mst Mon test prime ([index set 5J) 1 is-a prime 2 is a prime 3 is a prime 4 is not a prime 5 is a prime r 16:42 0.198 20 abs io: Input Stream exhausted. Absentee user MacSissle ProjA logged out 04/21/80 1643.1 mst Mon CPU usage 3 sec, memory usage 1.0 units MacSissle's job is done, so she prints the absout segment. With more advanced use of the absentee facility, you can also supply arguments to be substituted inside the absentee control segment, make absentee job steps conditional, delay absentee work until a chosen time, and develop a periodic absentee job which is run, say, once every two days. The next example shows how absentee jobs can accept arguments. print prime.absin prime.absin 04/21/80 1655.7 mst Mon test_prime ([index_set &1]) r 16: 55 • 110 19 This absin segment accepts one argument. The character string "& 1" is replaced by the argument wherever it occurs. MacSissle tests it by invoking it as an exec com. In order to use the absin segment as an exec com, it must have a name wit~ the suffix "ec" added to it. - add name prime.absin prime.ec r 10:56 0.100 5 exec com orime.ec 2 test-prime ([index set 2]) 1 is a prime 2 is a prime r 17:00 0.210 30 MacSissle invokes the exec com with the argument 2. As it runs, it prints the commands in the file. The argument mechanism seems to work, so she submits an absentee job. 7-5 AG90-03 ! enter abs request prime.absin -arguments 100 ID: 22T023~4; 6 already requested. 17:05 0.273 50 r Here, the argument 100 is passed to the absentee job. other business while the request runs. MacSissle goes about A common problem for many users is an absentee job that blows up unexpectedly because it is asked an unanticipated question, and the user has not provided an appropriate answer. For example, a job may be asked, "Do you wish to quit?" It can try to use its next command for an answer, but it will be told to "Please answer yes or no." At this point, the job will probably die. Suppose MacSissle has set up a daily absentee job that reads her mail. absin segment, called mail.absin, looks like this: enter abs request mail -time read mailprint all quit dprint -delete mail.absout "07:00" Her -notify MacSissle types the command line enter_abs_request mail -time "07:00" -notify once. Her absentee job submits a request for the next absentee job, then reads her mail. Once in the read mail request loop, it asks that all of her mail be printed, then quits out of the loop. Finally, it dprints her absout segment. This job seems like it should work fine. But what will happen if MacSissle doesn't have any mail? The request to read her mail will return the answer, "You have no mail". Then the request to print all of her mail will return the answer, "Segment all not found". The request to quit will return a similar answer. So, the job may not die in this case; but it will give MacSissle some unexpected results. To avoid this problem; MacSissle can change her absin segment to look like this: enter abs request mail -time "07:00" read mail--request "print all; quit" dprint -delete mail.absout -notify Now, if she has no mail, she'll just get the answer, "You have no mail", which is what she wants. For further information on absentee jobs, see the MPM Commands manual descriptions of the enter abs request and exec com commands. See also the descriptions of the p11 abs, cobol abs, and fortran abs commands, which invoke language compilers in abSentee jobs~ 7-6 AG90-03 SECTION 8 REFERENCE TO COMMANDS BY FUNCTION All of the Multics commands described in the MPM Commands are arranged here according to function and are briefly described. The Multics command repertoire is divided into the following 17 groups: Access to the System Storage System, Creating and Editing Segments Storage System, Segment Manipulation Storage System, Directory Manipulation Storage System, Access Control Storage System, Address Space Control Formatted Output Facilities Language Translators, Compilers, and Interpreters Object Segment Manipulation Debugging and Performance Monitoring Facilities Input/Output System Control Command Level Environment Communication Among Users Communication with the System Accounting Control of Absentee Computations Miscellaneous Tools Many commands can perform more than one function, so they are listed in more than one group. Detailed descriptions of these commands~ arranged alphabetically rather than functionally, are given in the MPM Commands. In addition, many of the commands have online descriptions, which you may obtain by invoking the help command. ACCESS TO THE ------- --dial echo enter enterp hangup hello login logout modes slave SYSTEM connects an additional terminal to an existing process sets terminal into echoplex mode before login connects an anonymous user to the system (used at dialup only) terminates communication between terminal and Multics repeats greeting message printed when terminal is first connected connects registered user to the system (used at dialup only) disconnects user from the system sets terminal modes before login changes service type of channel from login to slave for duration of connection 8-1 AG90-03 terminal type MAP 029 and 963 sets terminal type before login tells system user is attempting to gain access from terminal whose keyboard generates only uppercase characters tells system whether user is attempting to gain access from device similar to EBCDIC or Correspondence code IBM Model 2741 STORAGE SYSTEM, CREATING AND EDITING SEGMENTS adjust bit count canonicalize compare_ascii compose edm emacs indent merge ascii qedx set bit count ted sets bit count of a segment to last nonzero word or character ensures that contents of a segment are in canonical form compares ASCII segments, reporting differences composes forma.tted documents for production on various devices, including terminals and line printers allows inexpensive, easy editing of ASCII segments enters the Emacs text editor, which has a large repertoire of requests for editing and formatting text and programs indents a PLII source segment to make it more readable merges two or more related ASCII text segments allows sophisticated editing, including macro capabilities sets the bit count of a segment to a specified value used to create and edit ASCII segments; can do many kinds of text processing STORAGE SYSTEM, SEGMENT MANIPULATION adjust_bit count archive archive table compare compare_ascii copy copy_file create damaged sw off damaged-sw-on delete - link merge_ascii sets bit count of a segment to last nonzero word or character packs segments together to save physical storage returns the names of specified archive components in specified archive segment compares segments word by word, reporting differences compares ASCII segments, reporting differences copies a segment or multisegment file and its storage system attributes copies records from an input file to an output file creates an empty segment resets damaged switch off for segments sets damaged switch on for segments deletes a segment or multisegment file and questions user if it is protected creates a storage system link to another segment~ directory, link, or multisegment file merges two or more related ASCII text segments 8-2 AG90-03 move set bit count tape_archive truncate unlink vfile adjust volume_dump_switch_off moves segment or mul tisegment file and its storage system attributes to another directory sets the bit count of a segment to a specified value sorts ASCII segments according to ASCII collating sequence performs a variety of operations to create and maintain a set of files on magnetic tape truncates a segment to a specified length removes a storage system link adjusts structured and unstructured files turns off the specified volume dump switch of a segment turns on the specified volume dump switch of a segment STORAGE SYSTEM, DIRECTORY MANIPULATION add name cancel retrieval_request copy_dir create dir delete-dir delete name enter retrieval_request link list move dir rename safety_sw_off status unlink vfile status adds a name to a segment, directory, link, or multisegment file deletes request for a volume retrieval that is no longer needed copies a directory and its subtree to another point in the hierarchy creates a directory destroys a directory and its contents after questioning user removes a name from a segment, directory, link, or multisegment file queues volume retrieval requests for specific segments, directories, multisegment files, and subtrees creates a storage system link to another segment, directory, link, or multisegment file lists retrieval requests in the retrieval daemon queues prints directory contents moves a directory and its subtree to another point in the hierarchy renames a segment, directory, link, or multisegment file turns safety switch off for a segment, directory, or multisegment file t urns safety swi tch on for a segment, directory, or multisegment file prints all the attributes of an entry in a directory performs a variety of operations to create and maintain a set of files on magnetic tape removes a storage system link prints the apparent type and length of storage system files turns off the specified volume dump switch of a segment turns on the specified volume dump switch of a segment 8-3 AG90-03 STORAGE SYSTEM, ACCESS CONTROL check iacl copy acl copy-iacl dir copy-iacl-seg delete acT' delete-iacl dir delete-iacl-seg list accessIble list acl list-not accessible list iacl dir list-iacl-seg print_auth_names set acl set-iacl dir - - compares segment ACLs with the initial ACL copies ACL from segment or directory copies a directory initial ACL copies a segment initial ACL removes an ACL entry removes an initial ACL for new directories removes an initial ACL for new segments lists segments and directories with a given access condition prints an ACL entry lists segments and directories to which user does not have a given access condition prints an initial ACL for new directories ""'~~"'"' .... " ,}.Jl. -LJ.I'-'s.J ..",.... GLll ~1"'\a; .... ;~' ..L.ll..L.""..L.Q.J- I\(,T .n.'V'.&...-' ~n,.... .L V.L 1"'\OT..T ...... '- ... C!orrmoni-C! ....,"""'OLU""" ...... ..,...., prints names of sensitivity levels and access categories for an installation adds (or changes) an ACL entry adds (or changes) an initial ACL for new directories adds (or changes) an initial ACL for new segments STORAGE SYSTEM, ADDRESS SPACE CONTROL add search_paths add search rules attach Iv change default wdir change-wdir delete=search_paths delete search rules detach-Iv - initiate list ref names new proc print default wdir print=proc_auth print_search_paths print_search_rules print wdir set_search_paths set search rules terminate walk subtree where adds one or more search paths to the specified search list allows users to change (insert) search rules dynamically calls the resource control package to attach a logical volume sets the default working directory changes the working directory allows user to delete one or more search paths from specified search list allows users to delete current search rules detaches logical volumes attached by the resource control package prints definitions of site-defined search rule keywords adds a segment to the address space of a process prints all names by which a segment is known to a process creates a new process with a new address space prints name of default working directory prints access authorization of the current process and current system privileges prints the search paths in the specified search list prints names of directories searched for segments referenced dynamically prints name of current working directory allows user to replace search paths contained in specified search list allows users to modify search rules removes a segment from the address space of a process executes a command line in all directories below a specified directory uses current search rules to locate and print pathname of a segment 8-4 AG90-03 returns absolute pathname(s) of entryname when search list name and entryname are specified FORMATTED OUTPUT FACILITIES cancel_daemon_request compose dprint dpunch overlay print cancels a previously submitted daemon request composes formatted documents for production on various devices, including terminals and line printers queues a segment or multisegment file for printing on the high-speed printer queues a segment or multisegment file for card punching prints segment contents in octal, ASCII, or EBCDIC prints list of print and punch requests currently queued moves a request from one 1/0 daemon queue to another reads several ASCII segments and writes on user output 1/0 switch output that is the result of superimposing print - positions from each segment prints an ASCII segment LANGUAGE TRANSLATORS, COMPILERS, AND INTERPRETERS apl basic bind cobol cobol abs create data_segment display cobol run unit expand_cobol_source fast format cobol source fortran fortran abs indent lisp pl1 pl1 abs profile run cobol invokes the APL interpreter compiles BASIC programs packs two or more object segments into a single executable segment cancels one or more programs in the current COBOL run unit compiles COBOL programs submits an absentee request to perform COBOL compilations translates a create data segment source program into an object-segment displays the current state of a COBOL run unit translates COBOL source program containing COPY and REPLACE statements to equivalent source program not containing these statements allows user to enter FAST subsystem converts free-form COBOL source to fixed-format COBOL source invokes the site's "standard" FORTRAN compiler invokes the site's "standard" FORTRAN compiler in an absentee job indents a PLII source segment to make it more readable enters interactive Lisp subsystem, where Lisp forms can be typed at user's terminal and evaluated compiles PLII programs invokes the PLII compiler in an absentee job prints information about execution of individual statements within program executes a COBOL run unit in a main program 8-5 AG90-03 set cc set fortran common stop_cobol_run sets carriage control transformation for FORTRAN files initializes common storage for a FORTRAN run terminates the current COBOL run unit OBJECT SEGMENT MANIPULATION archive archive table bind date_compiled packs segments together to save physical storage returns the names of specified archive components in specified archive segment packs two or more object segments into a single executable segment prints date and time compiled and compiler identifier for object segments DEBUGGING AND PERFORMANCE MONITORING FACILITIES attach audit cumulative page trace debug display_audit_file dump_segment general ready page_trace probe profile progress ready ready off ready=on reprint error resolve=linkage_error trace trace stack sets up specified I/O switch to be audited by the audit I/O module adjusts length and content of system condition messages accumulates page trace data permits symbolic source language debugging displays the file produced by the audit I/O module displays diagnostic information about PL/I I/O errors prints segment contents in octal, ASCII, or EBCDIC allows user to format ready messages prints a history of system events within calling process permits program debugging online prints information about execution of individual statements within program prints information about the progress of a command as it is being executed prints the ready message: a summary of CPU time, paging activity, and memory usage suppresses the printing of the ready message restores the printing of the ready message reprints an earlier system condition message satisfies linkage fault after a process encounters a linkage error permits the user to monitor all calls to a specified set of external procedures prints stack history INPUT/OUTPUT SYSTEM CONTROL assign resource cancel-resource close file copy cards copy=file assigns peripheral equipment to user cancels reservations made with the reserve command cancels a previously submitted print or punch request closes open PLII and FORTRAN files copies card decks read by 110 Daemon copies records from an input file to an output file 8-6 AG90-03 discard_output dprint dpunch file output io call line_length list daemon_requests list resources print print_at tach_table print_request_types reserve resource tape_archive unassign resource vfile adJust vfile-status executes a command line while temporarily suppressing output on specified 110 switches displays diagnostic information about PL/I 110 errors queues a segment or multisegment file for printing on the high-speed line printer queues a segment or multisegment file for card punching directs terminal output to a file allows direct calls to inputloutput system entries allows users to control maximum length of output lines prints list of print and punch requests currently queued prints a list of all resource types described in a resource type description table (RTDT) lists peripheral equipment assigned to user prints an ASCII segment prints list of current inputloutput system switch attachments prints available 110 Daemon request types reserves resource (s) for use by the. calling process performs a variety of operations to create and maintain a set of files on magnetic tape unassigns peripheral equipment assigned to user adjusts structured and unstructured files prints the apparent type and length of storage system files COMMAND LEVEL ENVIRONMENT abbrev add search_paths add search rules answer attach audit change default wdir change=error_mode change wdir delete=search paths delete search rules detach-audit display_audit_file do exec com fast file_output allows user-specified abbreviations for command lines or parts of command lines adds one or more search paths to the specified search list allows users to change (insert) search rules dynamically answers questions normally asked of the user sets up specified 110 switch to be audited by the audit 110 module sets the default working directory adjusts length and content or system condition messages changes the working directory allows user to delete one or more search paths from specified search list allows users to delete current search rules removes audit from specified switch displays the file produced by the audit 110 module expands a command line with argument substitution allows a segment to be treated as a list of executable commands allows user to enter FAST subsystem directs terminal output to a file 8-7 AG90-03 gcos general ready get_system_search_rules if line_length memo new_proc on print default wdir print=search_paths print wdir program_interrupt ready ready off ready-on release reprint error resolve=linkage~error run set_search_paths set search rules set=tty start where search_paths invokes GCOS environment simulator to run single GCOS job in user's process allows user to format ready messages prints definitions of site-defined search rule keywords conditionally executes a command line allows users to control maximum length of output lines allows users to set reminders for later printout creates a new process with a new address space establishes handler for specified set of conditions, executes imbedded command line with handler in effect, reverts handler prints name of default working directory prints the search paths in the specified search list prints names of directories searched for segments referenced dynamically prints name of current working directory provides for command reentry following a quit or an unexpected signal prints the ready message: a summary of CPU time, paging activity, and memory usage suppresses the printing of the ready message restores the printing of the ready message discards process history retained by a quit or an unexpected signal interruption repeats the last query by the command query subroutine reprints an earlier system condition message satisfies linkage fault after a process encounters a linkage error provides user with temporary, somewhat isolated, environment for execution of programs allows user to replace search paths contained in specified search list allows users to modify search rules prints and sets modes associated with user's terminal continues process at point of a quit or an unexpected signal interruption effects abnormal termination of run-unit created by run command returns absolute pathname(s) of entryname when search list name and entryname are specified COMMUNICATION AMONG USERS accept_messages defer_messages delete message immediate messages print mail print-messages read mail initializes the process to accept me.::sages immediately inhibits the normal printing of received messages deletes messages saved in user's mailbox restores immediate printing of messages prints all messages in a mailbox prints any pending messages provides a facility for examining and manipulating messages 8-8 AG90-03 send mail send message send-message acknowledge send=message=express send_message_silent who transmits a message to one or more recipients sends message to specified user sends message and acknowledges its receipt sends message only if user will receive it immediately sends message but does not acknowledge its receipt prints list of users and absentee jobs currently logg~d in ---- COMMUNICATION WITH --THE SYSTEM ~~~~~---- check_info_segs damaged sw off damaged-sw-on help -how many users enter retrieval_request list retrieval_requests no save on disconnect print_motd save on disconnect who deletes request for a volume retrieval that is no longer needed checks information (and other) segments for changes resets damaged switch off for segments sets damaged switch on for segments prints special information segments prints the number of logged-in users queues volume retrieval requests for specific segments, directories, multisegment files, and subtrees displays names of all info segments pertaining to a given topic lists retrieval requests in the retrieval daemon queues moves a request from one absentee queue to another disables process preservation across hangups in user's process prints the portion of the message of the day that changed since last printed reverses effect of no save on disconnect command turns off the specified volume dump switch of a segment turns on the specified volume dump switch of a segment prints list of users and absentee jobs currently logged in ACCOUNTING get quota move_quota resource_usage prints secondary storage quota and usage moves secondary storage quota to another directory prints resource consumption for the month 8-9 AG90-03 CONTROL OF ABSENTEE COMPUTATIONS cobol abs enter abs request fortran abs how many users list_abs=requests pl1 abs runoff abs who cancels a previously submitted absentee job request submits an absentee request to perform COBOL compilations adds a request to the absentee job queue invokes the site's "standard" FORTRAN compiler in an absentee job prints the number of logged-in users prints list of absentee job requests currently queued moves a request from one absentee queue to another invokes the PL/I compiler in an absentee job invokes the runoff command in an absentee job prints list of users and absentee jobs currently logged in MISCELLANEOUS TOOLS calc calendar canonicalize decode encode manage_volume pool memo merge progress sort performs specified calculations prints a calendar page for one month ensures that contents of a segment are in canonical form deciphers segment, given proper coding key enciphers segment, given a coding key allows users to regulate use of a predefined set of volumes allows users to set reminders for later printout provides generalized file merging capability prints information about the progress of a command as it is being executed provides generalized file sorting capability 8-10 AG90-03 APPENDIX A USING MULTICS TO BEST ADVANTAGE You may, if you wish, treat Multics as simply a PL/I, FORTRAN, APL, BASIC, or COBOL machine, and contain your activities to just the features provided in your preferred programming language. On the other hand, much of the richness of the Multics programming environment involves use of system facilities for which there are no available constructs in the usual languages. To use these features, it is generally necessary to call upon library and supervisor subroutines. Unfortunately, a simple description of how to call a subroutine may give little clue as to how it is intended to be used. The purpose of this appendix is to illustrate typical ways in which many of the properties of the Multics programming environment may be utilized. When you choose a language for your implementation, you should carefully consider the extent to which you will want to go beyond your language and use system facilities of Mul tics which are missing from your language. As a well-known standard for completeness of that language (e.g., ANSI or IBM). However, in going beyond the standard languages, you will find that Multics supervisor and library routines are designed primarily for use from PL/I programs. This results from the fact that most of these routines are themselves implemented in PL/I. For example, if you plan to write programs which directly call the Multics storage system privacy and protection entries, in FORTRAN or BASIC, you have no convenient way to express such structures. Note that the sit uation is not hopeless, however. Programs which stay within the original language can be written with no trouble. Al so, in many cases, a trivial PL/I interface sub rout ine can be constructed, which is callable from, say, a FORTRAN program, and goes on to reinterpret arguments and invoke the Mul tics facility desired. This is made possible by the Multics conventions which ensure that FORTRAN and PL/I programs can communicate. (For more information, see the MPM Subsystems Writers' Guide.) Using such techniques, almost any program a standard call is performed, the argument pointer is set to point at the originally prepared for another system can be moved into the Multics environment. The examples which follow show that the effect of the mapping together of the main memory and secondary storage environments can range from the negligible (programs can be written as though there was a traditional two-environment system) to a significant simplification of programs which make extensive use of the storage system. Here are seven brief examples of programs which are generally simpler than those encountered in practice, but which illustrate ways in which online storage is accessed in Multics. A-1 AG90-03 1. Internal Automatic Variables. The following program types the word "Hello" on four successive lines of terminal output: a: procedure; declare i fixed binary; do i = 1 to 4; put list ("Hello"); put skip; end; return; end a; The variable i is by default of PL/I storage class internal automatic: in Multics it is stored in the stack of the current process and is available by name only to program a and only until a returns to its caller. It is declared binary for clarity : although the defaul t base for the representation of arithmetic data is binary according to the PL/I standard, as well as in Mul tics PL/I, some other popular implementations have a decimal default. There is no need for decimal arithmetic in this program, and binary arithmetic is faster. 2. Internal Static Variables. The following program, each time it is called, types out the number of times it has been called since its user has logged in: b: procedure; declare j fixed binary internal static intial(O); j =j + 1; put list (j, "calls to b."); put skip; return; end b; The variable is stored in bls by name only to process, or until etc.), whichever value of j to be process. j is of PL/I storage class internal static; in Multics it static section (discussed in Section 2) and is available program b. Its value is preserved for the life of the b is terminated (by the terminate command, recompilation, time is shorter. The "initial" declaration causes the initialized at the time this procedure is first used in a A-2 AG90-03 3-4. External Static. Suppose you wish to set a value in one program and have it printed by some other program in the same process: c: procedure; declare z fixed binary external static; z = 4; return; end c; d: procedure; declare z fixed binary external static; put list (z); put skip; return; end d; In both programs, the variable z is of PL/I storage class external static; in Mul tics it is stored in a particular segment where all such variables are stored, and is available to all procedures in a particular process, until the process is destroyed. External static is analogous to common in FORTRAN, but with the important difference that data items are accessed by name rather than by relative position in a declaration. Program d above could be replaced by the following FORTRAN program: integer n common /z/ n print, n end Multics calls such data items external variables. There are commands (for example, list_external_variables) to list, reinitialize, and otherwise deal with all the external variables used by a process. Each variable which is accessed in this form generates a linkage fault the first time it is used. Later references to the variable by the same procedure in that or subsequent calls do not generate the fault. 5. Direct Intersegment References. The following program prints the sum of the 1000 integers stored in the segment w: e: procedure; declare w$(1000) fixed binary external static; declare (i, sum) fixed binary; sum = 0; do i = 1 to hbound (w$,1); sum = sum + w$(i); end; put list (sum); put skip; return; end e; A-3 AG90-03 The dollar sign in the PL/I identifier "w$" is recognized as a special symbol by the PL/I compiler, and code for statement 6 is constructed which anticipates dynamic linking to the segment named w. Upon first execution, a linkage fault is triggered, and a search undertaken for a segment named w. If one is found, the 1 ink is snapped, and all fut ure references will occur with a single machine instruction. The storage for array "w$" is the segment w. If no segment named w is found, the dynamic linker will report an error to the user and return to command level. At this point, it is possible to create an appropriate segment named w, and then continue execution of the interrupted program, if such action is appropriate. 6. Reference to Named Offsets. The following procedure calculates the sum of 1000 integers stored in segment x starting at the named offset u: f: procedure; declare x$u(1000) fixed binary external static; declare (i, sum) fixed binary; sum = 0; do i = 1 to 1000; sum = sum + x$u(i); end; put list (sum); put skip; return; end f; The difference between this example and the previous one is that segment x is presumed to have some substructure, wi th named internal locations (entry points). To initially create a segment with such a substructure, the compilers and assemblers are used, since information must be placed in the segment to indicate where within it the entry points may be found. Unfortunately, the PL/I language permits specification of such structured segments only for procedures, not for data. The create data segment subroutine can be used in conjunction wi th the create data -segment (cds T command to create such data segments from PL/I data structures passed to it as parameters. The create data segment command translates a CDS source program into a data segment ~actually a standard object segment). A sample CDS source program~ x.cds, is shown below: x: procedure; declare 1 x aligned, 2 u(1000) fixed binary; declare create_data_segment_ entry (ptr, fixed binary (35)); (overhead required to utilize create_data_segment_) call create data segment ", and the entry name, since if the dir name were ">,, (the-root directory), this would result in an invalid pathname containing the sequence "»". 149 A pool of segments in a process directory is maintained by the get temp segments and release temp segments subroutines. These segments-are doled out to commands and subsystems which request them (via get temp segments ) and it is expected that they will be returned to the pool when there is no further use for them. This facility avoids the need for user programs to create and delete (or attempt to manage or share) segments needed on a "scratch" or "temporary" basis (for work areas, buffers, etc). Segments obtained from this facility are guaranteed to contain all zeros (truncated) when obtained. B-6 AG90-03 The number of segments to be obtained is determined by get temp segments from the extent of the pointer array parameter. The name of the-subsystem is passed to get temp segments both to facilitate additional checking by release temp segments, and to support the list temp segments command, which describes which subsystems in a process are using temporary segments. 161 If the segment specified on the command line does not exist, the editor is to assume that it is creating a new segment, and go into input mode. The value of the variable "source otr" will be null if this is the case. -- 162 The ioa subroutine is a handy library output package. It provides a format ?acility similar to PL/I and FORTRAN "format" statements, and it automatically writes onto the liD stream named user output, which is normally attached to the interactive user's terminal.- When used as shown, it appends a newline character to the end of the string given. Programmers who are more concerned about speed and convenience than about compatibility with other operating systems use ioa in preference to PL/I "put" statements, because ioa is cheaper, easier to use, and far more powerful. The formatting facilities of ioa are used in a simple way in this example. The circumflex (""''') in-the format string indicates where a converted variable is to be inserted; the character following the circumflex indicates the form (in this case, a character string) to which the variable should be converted. The first argument is the format string, remaining arguments are variables to be converted and inserted in the output line. 165 The storage system provides for every segment a variable named the "bit count". For a text segment, by convention, the bit count contains the number of information bits currently stored in the segment. The bit count of the segment being edited was returned by hcs $initiate count (hence its name) on line 139. - This statement converts the bit count to a character count. Note that we have here embedded knowledge of the number of hardware bits per character in this program. 165 The PL/I language specifies that the result of a divide operation using the division sign is to be a scaled fixed point number. To get integer division, the divide builtin function is used instead. Note that the precision of the quotient is specified to match its size. 166 Here, we invoke some of the most powerful features of the Mul tics virtual memory. This simple assignment statement copies the entire source segment to be edited into the temporary buffer named "from seg". A single hardware string-copy instruction is generated for this-code, copying data at processor speed. The string-copy instruction may be interrupted by page faults on either "source seg" or "from seg" several times; after allocating or reading the required page, the instruction is restarted where it left off. Note that we are regarding the entire text segment as a simple character string of length "size". We may regard it this way because the storage representation for permanent text segments is, by convention, identical to that of a PL/I nonvarying character string. 167 Be sure to read the comments embedded in the program, too. B-7 AG90-03 115 The standard lID system is being invoked to read a line from the user's terminal. The line is read from the lID switch identified by the external pointer iox $user input. Although passing the buffer to be used as a character string-would be more convenient, this set of interfaces was designed with maximal efficiency in mind, and this form of call is more efficient. Note that it would also be safer than passing a pointer to the character string, since that would allow PL/I to check that an appropriate character string was being passed, as opposed to a pointer, which can point to any data type. This design demonstrates the frequent tradeoff between efficiency and convenience. 115 Subroutine iox $get line is often used for input rather than the PL/I statement "read file (sysin) into ... ", again because of efficiency and error-handling considerations. The PL/I facility ultimately calls on the Multics iox package anyway. (Again, if you wished to write a program which would also work on other PL/I systems, you would be better advised to use the PLiI IiO statements instead.) 116 It is highly unlikely that a call to read a line from the terminal will fail. Nevertheless, in cases of people debugging their own extensions to the Multics 110 system (a practice intended by the designers of the 110 system), it can occur. It is reasonable to abort the entire editor in this unlikely case rather than repeating the call: presumably that would repeat the error too. 180 For the sake of human engineering, the editor ignores blank command lines. Since complete input lines from the typewriter end with a new line character, the length of a blank line is one, not zero. 182 The code to isolate a string of characters on the typed input line is needed in four places, so an internal subroutine is used. This subroutine is not recursive, which makes it possible for the compiler to construct a one-instruction calling sequence to the internal procedure. Certain constructs (e. g., variables of adjustable size declared within the subroutine) will force a more complex calling sequence. For details, you should review the documentation on the Multics PL/I implementation, contained in the Multics PIlI Language Specification, Order No. AG94. 184 Al though the dispatching technique used here appears costly, it is really compiled into very quick and effective code 2 machine instructions for each line of PL/I. For such a short dispatching table, there is really no point in developing anything more elaborate. If the table were larger, one might use subscripted label constants for greater dispatching speed. 189 Human engineering: the typist is forced to type out the full name of the one "powerful" editing request which, if typed by mistake, could cause overwriting of the original segment before that overwriting was intended. 200 Whenever a message is typed which the typist is probably not expecting, it is good practice to discard any type-ahead, so that he may pxamine the error message, and redo the typed lines in the light of tnis new information. 201 The general strategy of the editor is as follows: lines from the typewriter go into the variable named "buffer" (accessed as "commands") until they can be examined. Another buffer, named" line buffer" (accessed as "line") holds the current line being "pointed at II by the eds conceptual pointer. Subroutine "put" copies the current line onto the end of to seg, while subroutine "get" copies the next line in from seg into the current line buffer. - 225 The procedure get num sets up the variable "n" to contain the value of the next typed integer on the request line. Such side-effect communication is not an especially good programming practice. B-8 AG90-03 226 The delete request is accomplished by reading lines from from seg, but failing to copy them into to seg. If deletion were a common operation, it might be worthwhile to use more complex code to directly push ahead the pointer in from_seg, and thus avoid a wasted copy operation. 237 More side-effect communication: the variable "edct" is always pointing at the last character so far examined in the typed request line. 254,265 All movement of parts of the material being edited is accomplished by a simple string substitution, using appropriate indexes. 284 The locate request is accomplished by use of the index builtin function, used on whatever is still unedited in from_seg. 422 A negative number in the next request results in moving the conceptual pointer backward. The resulting code is quite complex because the eds editing strategy requires interchanging the input and output segments before backward scanning, so that the backward scan is with regard to the latest edited version of the segment. 427 This code to search a character string backward is recognized by the compiler as such. Extremely efficient object code to search the substring backward is generated, using a single hardware instruction. No copies are made in this fairly expensive-looking statement: it is, in fact, cheap. Combinations of reverse, index, substr, search, verify, etc. that seem like they ought to generate efficient code in fa~t usually do. The -profile control argument and the profile command are useful tools for discovering where inefficient code is causing performance problems. 456 Before exiting from the editor, the temporary segments should be returned to the temporary segment manager, and the segment that was initiated terminated. 468 Another human engineering point: since the user may have typed several lines ahead, the error message includes the offending request, so that he can tell which one ran into trouble and where to start retyping. 469 Note a small "window" in this sequence of code. If the editor is delayed (by "time-sharing") between lines 468 and 469, it is possible that the message on line 468 will be completed, and the user will have responded by typing one or more revised input lines, all before line 469 discards all pending input. Al though in principle fixable by a reset option on the write call, Multics currently provides no way to cover this timing window. Fortunately, the window is small enough that most interactive users will go literally for years without encountering an example of a timing failure on input read reset. 500 Note the practice of copying data into the original segment, setting its bit count, and truncating it in that order. This provides for maximal data being saved should there be a system failure between any two lines. Common sense seems to indicate this order as "maximally safe", and analysis of the data involved will demonstrate this as well. 538-540 The input and output editing three statements. Here is an variables to make clear that interchange of the meaning of 551 The IIO system provides this entry point to perform control operations (e.g., "resetread") upon the objects represented by IIO switches. buffer areas are interchanged by these example of localizing the use of pointer they are being used as escapes to allow PL/I identifiers. B-9 AG90-03 563 This editor considers typed-in tab characters to be just as suitable for token delimiters as are blanks. Ideally, tab characters would never reach the editor, having been replaced by blanks by the typewriter input routines. Such complete canonicalization of the input stream would result in some greater simplicity, but would require a more sophisticated strategy to handle editing of text typed in columns. 563, 566 The PLfI search and verify builtins, which are quite useful in circumstances like this (parsing lines), are compiled into very effic ient single-instruction hardware operations by the Multics PLfI compiler. 580 The cv dec library routine is used here rather than a PLfI language feature, because cv dec will always return a value, even if the number to be converted is-ill~formed (in which case it returns zero). Thus, the editor chooses not to handle ill-formed numbers. Had it wished to check for them, it could have used the cv dec check subroutine. PLfI language conversion would cause an error-signal whIch must be caught and interpreted lest PLfI' s runtime diagnostic appear on the user's console. Thus, eds retains complete control over the error comments and messages which will be presented to the user. Such control is essential if one is to construct a well-engineered interface which uses consistent and relevant error messages. 589 The cleanup procedure calls the release temp segments subroutine to release the temporary segments acquired- earlier. A -binary zero is passed to release temp segments by value (by enclosing it in parentheses) because the cleanup 'handler has no use for an error code. Cleanup procedures should never print messages, even error messages, because they are only invoked when exiting a procedure. There is no corrective action the user can take. 590 If the segment edited was not known before editing it, it should be unknown after the editor finishes as well. The supervisor maintains a reference count for each segment in the process. This count is incremented by the call to hcs $initiate and decremented by the call to hcs $terminate noname. - If the count goes to zero (i. e. the segment was-made known-by the editor), then the segment is made unknown. B-10 AG90-03 !j:.~}JT '- 'T T'-i t- 'I ~i T •• G r~F ·:::~C,J·~t, '.:" e..ools t'v; [YD"'r;II''''nta 1 '"'LIT L",~;r:i't::r r';f Tt-urs'iaY, Feo"uerv 2b, 19B1 at 18:23 ;J"'o;joc o·p41 .. C a~: ro"'c.;i1!"o c.n: no~inns; ~0n~y~el 1 LT~~ Jf,/11/6~ o?timize Phne~iwr it" .. :-'.1 "'ut ~ys~e~ ~ ~~o'" ~a~ 1 .. ~~: ? pcitnr -- examnie , 11< ~j~cle !.l 11< "r; ttcl"! .Tu 1 '1' 117'1, kif "orlif;pd 1''1''1, for)~q.(I <; lie text ,''''1, nrD9r~~ """,,"one 0. */ Vn"", Id suhrClutines, ov Someone Else *1 f., 7 lie q dec]p!'" l~ -:-Ier:]",r<> 11 ,-let:' 1"1 r l ' ~erl"'ro D fj)fe rl binary: character (1), a"'g_c"'u"'t nr-~"'k fil(e,; hinary: 0'" -{, :)l.If~e .. ch?rade" (210), 13 decla"'~ 1" "'erl-"lr" c '" ~!""!~.J ~ S _0 (" cur r- ~ ,--! .... i cf"'l·. j~ . fi~e,; 1<:: lt-- C:":;if"'l .-I?~l",r'" 17 de~l-"Ir"" 11\ c'ec:- 'j '" r o t Number of command line arguments bre8~ char for change *1 1* 1* ~o'ds 1* Ty~ewriter input buffer. *1 (l) 1 ~;'"!ary (~S); character (c"'vnt) hased (ario,. (t/uffer»; dl'"'l·.;~ C"'U""':t fjve~ h;nary (~1); csi?e ~;~erl .... i"a,.v (~l); 1* 1* Va'i~ Valid oortion of buffer *1 length of data in "buffer" *1 10 "'~rl",r" er'c~ fp:e.-! I,;nary; 21) rle~l",r Oirectory containing segment *1 rler:l",r~ char"'cte!" (If.b); eharactel" O?)! 1* 2t d; r_1"1'1"'" e!"l t .. y _n '" cr, <> [')o;r,~er; 1* 1* Temporary pointer holder. *1 Pointer to current from_se9. *1 .. 2~ rle("l;::.r", 2' '"'er:l"'I"" frou",_ ... t'"' 2'l ':leel!!!r .. 20::; 21, r:!ec:-Iar" frc·''''_~~'"'J 27 "'E!cl-"lr'" i :'"lo;nte"; Character- (1~4~~76) flxet'l ':">ina!"y (~1), ~;eCl?r'" 1 i -f;Yer! I- ; ~a"'y (? 1) ; ~q '~e~i"'!'''' ; ,"!,j~ fiyer' !-. i r-·ar-y C;:'l); -fixe'" '"'inal"v (71) ; 3? 3" sa ; '''I\J t ~i)(e~ rle~l"'r" r'e~l",r'" h;""ary f;xe rl ""ina"y (1); (? 1); fjYe.-l (~l); bi~a~y 'ier:i",ro 3': "er-I",rp ~ .. rlecl~r .. 1 ; r,e' 1 1 "., •• >-l,.. f f'" r ~har~cter (l;n~l) c~ar~cte~ (210); 1;N'] f;Ye'"' t.i"'ar.,,~ :'7 l""c::>t ,.,; fll .-fe"'l3re ~;no~Y (~l); ~iYe~ ri""al"y C?l~; ,:jc:. 0ecl-'\r~ 51' :51 hase~ t five-l h;l"\ori (?~); s"u"cp_t:'tl" s"':.J"'c!'_se" !"·ointe r , char~c~el" rl~4~~7o) (2) t"'1r'''_se''ls ,..J; 'T"e"s; C'" 1;1 i'" cr· a rae tel" (210); tlrn chi'lr~ete" ((' cr·~raC~E'r- (10!.!P5 7 t» reCl!H'p (arior fline_buffer))J 1* Holds li~e currently being edited •. 1* lenot'" of "l;ne" *1 ~aserl l"Io;nte~, 1* 1* ; I.,a~ery ~" ronstQ~t~ Ruffer to no'd outout of cnange. HOld& next item on typed line *1 (t ",_ot r) : ,* 1* sa 1* .1 (s~a~e_ptr); 1* Source name *1 1* Length of ~ouree segment name. *1 1* Pointer to source segment name. *1 1* Holos seament bit length. *1 1* Pointer to source seQ. *1 hase1 (s(')ul"ce_otr): 1* ~utside seament for read or write. *1 (sna~e_l~h) fiYe-l hi~ary (?1); '"'ointe ro ; 4!'- 47 ryer:]",r" 4R rleel?r .. 4Q .-feel"'r" fdit1no is from this segment. ;I"\i::lrv~ ~ixe~ cn?rac~e" :.ina""p._i+-~ iJ? ii, (fro~_ptr)1 0"5'-! cR 31' ~ecl",rp 51 "'er: I i'\ r'" haserl 1* 'J' *1 cditina is to this Pointer to to_sea. seg~ent. *1 +/ B-11 AG90-03 *1 *1 55 56 57 58 5q 60 61 62 63 6lJ Nt eharacter' (1) static ootio"'s (eonstant' initial (II charecte" (3) st"Hic (co!"lsta"'tl initial (II ")J deelare ~HJTESPACF II); deelArl"! /* dee leN! 6'5 declare b6 declare b7 declare bPo declare 69 rleclere 70 deelare 71 72 declare ~IL 1* TAB character' (3) stAtic o"'tio"'s (constant' initial ("eds"); MVfljll!·iF. ~xtep'nal sUbr'outine declarations. com_er'r_ cu_$arQ_count cu_~a,.g_ptr cv_dee_ entry pntrY entry Fi!ntrY expand_oathna~e_ ~ntrY get_temo_se~ments_ 7U declare hcs_$set_bc_seg 75 declare 76 neelAre hes_$te,.minate_nona~e 77 .... eclere i08_ ir.>x_$eontr'o' iox_$oet_line pntrY entry fixer! entry fixe(l entry pntrv entry Fi!ntrv E'ntrv pntrY io~_$eut_ehars ~ntrv n 78 declare 1Q rlecl~re 8~ daels;-~ 81 rleelere 62 deell!1re 83 84 rleelare hcs_$initiate_cnunt hes_~truncate_seg patl-namE'_ ~ntrv relI"!9se_temo_seo ments_ entrY cleanup o~tions SPACE 1", 0, s,.,a"'e_otr, sna'l,E'_'tl-:, (I))); "': 0 t~e" ric; ci'lll co"'_orr_ (co,-le, ")~'M~Cl, "lJsaoe! "a ", rl'!t u r"'; MYN4ho\F): cl)_"'a~,.!_;'.'tr CI")Q~ llc 12 r MY~JA"'f.); 121 12;:> 12' 1 .,., I' ~ ," " ,. ~ t p" ; "1 t "! r 1: n t no", e ') ~,1 '" n t t () t' P e d ; ted .,., I ~ 211 12C:: ca'1 126 127 if eX0~n~_nath~a·@_ c~0~ A; 0 then ca1' t::'o .... _ .. rl"_ r'!turn; 1t!.P rs~a~e, ~ir_na~e, code); 1* Bad P8t~n8me *1 ~ntrv_na~e, ~o: (corle, ',:., "IAf'E, ""a", 12 c 13(1 l.5t 132 U"t. i 30. '* SO,,'r~e_.:tr::: l:e"'~_s!"(;t:; ne:: On n'Jl1 = (*' con~iti~n ()~ nulj 1* Make- SUl"8 handler h8S valid d8ta *1 l), (cl'!a~ucJ eail cl~an_ug; Uf- '37 /k th", sourCe se9 M e"'t. *1 !nitiat~ raJ] ncs_~initiate_c~unt entry_name, "", 1* = ;f s!11,..rc'!_ntl" "1,..11 t~en if c~o~ A; ~al1 (rlir_"a~e, souree_cnunt, 0, source_Dtr, codel, Initiate the segment *1 () el"r~r_table_$noentrY c~~_err_ (ende, ijy~a~~, th~n d~;I* "rannot acceSS Pl"ohlem 01" Just new seg? *1 A a ", D8thname_ (dil"_name, entry_name»)' r-eturn: 14l1~7 /" <:et '_';::' '~lJt"el" ,.",11 ;f Se.,r,lPnts. 1<1 (,.Vl,t.r,:F, te:nr"_sees, ~orle); v t~en ~c: c"'ll co"_""r"_ (ro'"'e, "'tt'A"t, "Can!'lot (Jet: telllPl:'rarY segments.")' c<"l' clpa"_l.lo; rptur"li ~;et_ter1::-_~e""rH"l"Its_ C~~e A; 8-13 AG90-03 = = t·mn_~e~s ~~"~_D~~ to_Dtr ISO temr_~€cs (1); ('): 1ul' 161 CS;ZP, ina f , inot = if Snu~cp_"t~ = null lto? c"Il' ;0"'_ ~; 1* then In;tial1z~ buffer control vars. *1 ~o~ ("!)I;'c·"'e"t"~ "ot fou"ri.", e1"lt .. y_nam~)J qc tc, ;::.;rmut; 16"1: loll loS , 0'" jC:In~; = ~;virie rS;ZF C;J~str (~ourr.e_count, (fr"T'l_s .. \.', 1 (f, c:: 1, ~u~str C"11e) 1* change v); (source_seg, 1, , 07 1* ~;t count to c~ar count *1 csize)~ Move S1"lu"Cp. segm~nt into buffer. *1 loP '0" 1* "",;f) l(\o~ e.-l;tl"C:; *1 ••••• 171l 1.71 7," "'e ~ t 1 7 c; 1 ! '-a'i 10._~"~et_'i"e (;vY_~u·:H.~_;f)l"lJ~, anal" (ouffe!"), 'el"lgtll (l'Iuffer), COUl"lt, code)J if cndp 0 the~ ,.Ie; c"l' c"~_~r~_ (role, ~··l·""~, nt"ror r ... ad;r'lg il"lput line"'; -= 171, 177 :71':. ",n ,7 0 e-n~; ldr. LlI f;"is~, to = cnunt i then 00 tn ~ JI'" t = 1~ .. a' 1 U!!t_tC'<.en: ; f II'? 1* if l"Iull line then get another line, don't print error *1 1* Set up counter to scan this '1ne. *1 1* Tcentify next tokel"l. *1 r.ext~ 1-::"1: ; f t"n '8<0 ; t ti.on ld~ ; f tv" 1l\ .., if if t '" 14/1 1~" "nil t''1 ; f t "n 10Q t "" if t L n ; f ; f ; f '9<:; 190- 1* Tf "11"1..,- ~f ?Cl ?P '0' I.", ~o t'"' t"l r>r;nt; (']0 to "'exii,,: ...,n "'\...,11. 1'1': II "h" t In-, call cll'l "'0 11 t J..., t i< r) if t <'l 1 Ct; ~e"', ",..," t"e" t t:> HIe; cn'ln'Je1 t'"' rie' i in: tn "'SPlv~; "Cj'dve " thp'" ;;" II C 'I r"-le .... "0 tn ; f 19" 1~ 1 1. '/? 197 ,q" ";" t'er- roo tr inse~t: ",..1' t"e" ~o tl"l retyr>e' n 1 II t!-.e~ "'0 to locate: ., n t~e t"Er t;'e.- '':''IrJ ",., t ~ f; ~ "'0 to to,.,; t"e" ""0 tl' f',ot"tOfTI: t"er- co to C'i"'plJt: a~ove tke" I"Int i1"l8_ r~'·PI' res'!tr'eaC1: ~(\t d" ~ re"u~st P~;t */ ~eque~t", sub9tr (cnmmands, 1, length (commends) - 1»; "'e~t: *+>:**".** i'-Ollt [',n'll;' *******~* *1 ?JG 1* print worrl input *1 ?JQ 'v Q '10 ?11 '1' ?l' :? 111 ca'l inx_~oet_'i"e (;:>v_~use'-_!nput, arij~ (Duffer), length (buffer), count, code" if coo- -= v t~er ~o: cal' co"'_-r~_ (cc,.le, "tfIA,,'t, "E:,!"ror rl"sriir'lg i..,out-mode l;ne."); ~o to ti"isk; ~",.I; r C<"l,r."'8"C!!, j" ') B-14 AG90-03 ?Ie:: 1* ?1!-. ~a' 217 1,ne1 ':: cheek for mod~ chenoe *1 1 V'Jt; len~th l~o~r~n~s'; 1* mov~ l;~e inputted into 1* repeat "til "." *1 ':>1" ?lq inter~edi8te storage *1 ::>2 !'I ':>21 '2; 1* **~*~*.** opl~tP *' *~*.***** ;>23 ?2ll ,.Ie 11; rl ~ ::>2'5 '??f:o.. rio ; 227 n 1* do for eaeh line to be de1eted *1 1; - <"let; t?f!,.J; ?2<':l ':>30 2,51 23? 1* ?3£! ?30::; to c .. 11 '?2P 'B =1 Ix nullify lest 1ine *1 1; !"Ie 1 ':: (); 00 ~***~**** tr) nelCt; ins~rt *1 ***.***~k in<::er-t: 1* 1* ?36 ret'yl"e! '37 , i n e 1 ':: 1 e'" q t h ( c 0 '?3~ ':>3 0 'i~e ~o = substr- ~,n i'! n 'i s) rcom~ancs, Add current line to output segment *1 This;s also the retype request. *1 e ci c t ; - erlct + 1); 1* ado replaeed l;~e *1 to neltt; ?1.i.'1 '41 1* ****~*.** "~,t **+**~*~* *i '?4? ?i4'J cal 1 q~t_nur:;~ ; f n < 0 t ~en "4"' "', ?4f. ca'l J:,ut: 247 ""-0 i :; 2 4 't "'e" 1 ; n = j '4 A ; if ?~q K ?sn ?51 if ;>5? ,~o to h de" ~J 0 : 1* save Where ; ""J ~; ~ "'_I'!()~~ ?53 are */ 1* once for eaeh nl *1 1 to .. ; j >= c~i2e then '0 tn n_l'!of; (suhstr (fro~_se~, I + 1, cc;i7.e = i"a~x YOU :: 0 th~r c~~ if ;nc f >:: c~ize 1, roe1 :: !'Ii ?'::ll 251:; su~str (to_3e~, ?5~ in";f :: csi7e~ ':>57 in~t ::>5~ "0 t.., ecfi = ;ret t~en 00 - 1* cheek for eof *1 j), \ILl; to eofi inrlt + 1, csizp - m) 1* locate end of line */ 1* no nl (~of) print eof *1 1* set to no Ifne */ (from_geo, m + 1, esize - m)' 1* move in top of file *1 = substr + csizp - m; 1* set pointers *1 ?sq 1* increment ';>(1) j by length of line *1 ?Q~ ?6? i r>c1f ?b't '?ell , i!"le' :: P :: f(i li~e :; substr ?6"' suhstr 1* set Dointers end move in too of file *1 (fro~_se~, (tc_se~, in1t ~ j 1, - k t i~rlf - 1, linel)~ linel - m) ?66 ';>67 ?6P tnrlt :: i~ot • to revt: ;~rif - lin~l 1* put working line in line *1 (from_seg, m + 1, indf - line1 - m)1 1* fil1 rest of file *1 = su~str - m; "'0 ::>:'0 27(1 1* '71 ?P if erlct 2B ?71J P¢<"t:: = lenqtr. e:-:!ct tnen qo to cad_svntax; + 1; 1* check for Dlein "1 NLR *1 Skip delimiter. *1 1* initialize nointers for index type search *1 I~ , :: i w"t! B-15 AG90-03 275 276 '" = ; nelf ; 277 ea'l put: ?7e. 2H if ~ = csize 292 ?99 300 301 I (n <= 0) then do; call switr:h; ;f ! > (\ th~n n else n : (\i J m, = j .. 1: = n; enl'f; = index (substr- (fl'o"'_':Ie", indf + 1, n), subst" (com'l'ands, e-ict, length (comma"ds) .. erict»); if ; A: 0 then do; 1* ;f founrl then do *1 k index ("eve"s~ (SUQstl' (fl'o~_se"l' 1, inrlf + il), NL)i ;f ~ -: 0 t~en k = in~f + i - ~ + 1; 1* k index of NL *1 j = index (su~str (fr~m_seQ, k + 1, esize - k), NL)7 1* find end of line *1 if J n thpr inof = csizei else indf = j + k~ sub~tl' (to_~et'!, l!"1ot + 1, I( 'Il) = suhs t " (from_seg, m + t, k - 01); 1* mOve in top of file *1 i = = = 293 294 29r; 296 297 298 = 0) (cs;ze ?8() 2iH ?8? 283 28£1 285 286 287 28P ?8Q 290 291 .. indf; 1;ne1 indt line = ;!"I 1 ) ; n U go to pl';nt1i 1* put found line in line *1 1* print found line if want en *1 p.nrli cali copv; ca'l switch; "'0 tr) next; 1* get next command *1 ';02 303 30 11 305 orint: 306 307 ea'l get_nurli: if linel = 0 t"en eel' ioa_ 30A go to ';0= ("~D l1 n 1* print indication of no lines *1 e."); nolin~; 309 310 311 orint1: 312 313 314 ~ 1'; ~16 call ;ox_$out_ch".rs Ciox_$user_outr'lu t , arid" Cline), length (line), codl'!)J ~f code ~= 0 then ~o: cal' eOr'l_erl'_ (code, r·i"A'~E, "P"'cblp,." .. ,,;t;!"Ig edito" output"); QO = to finis,",; 1* 317 !"I 0 1 ; ne: n n - 1; 318 if n 0 then 00 to !"Ieyt~ cail put; 31 Q call get; 320 321 00 to C'rintP 322 323 1* ********* cha!"lg~ ****+*+** *1 324 325 ehanoe: located n; 326 if count 2 then do; 327 328 count count - 1: 329 cal' 109_ ("I~D"ooel': 330 call reset reao:i; go to next; 331 = ~r-ite the l;n!'! *1 1* any mOre to b~ printed? *1 = = = 332 333 334 end; brkl break = erlct ... = substr 1* Strip NL off "commands" *1 -a", eo~"'ands)~ ?; (co~manrls, eoct + 1, 1): B-16 1* Pick ur'l the delimiting char-acter. AG90-03 *1 'l;)r; t :: 0 then (c"~~a~~~1 tn ~o :: inrfex f 'l3Q rl j ~~~')' hr~ak): ha1_st~t~x~ = 0 then :: br~alr)~ - ~r~1 + 1; 1* "n"~; O]ODSW :: "1 :: 1; ~41 3 .. ;> i (su[:.Str (eor"",';;l"\ds, i + t,ri(1), i '~~~th leo"'m~n~$) - i eq!"t :: e"'ct of. i + I ~ 1; ~37 33? 'Z.4 (su~~t~ :: inrle Y 3.36 1* Contfnue seannfnq edft line. */ Assume onlY one change. */ Assume only one )ine c~anged. */ /* /* If token there. Drocess ft. Change ell occurrences. *1 1* Try for another erqument. /* n)l.~I"(": ~i), 34(0, ca'l '.:let tn;'; .. n; if tk~ . ; " " thPn d~; if tk"1 :: "q" then e'sp. call CV_l"Iu'"" 31:.7 go to r\ltar,-': '7j4{J ~4C:; :: ala?: ~lo~sw *1 */ '!-:.lP ~I.iQ *1 351' 351 cn~n~e~_oc~u~r~? 'Z.5~ "', 3':>3 35/) 3sr; ;f ; :: 1 :: H""~; /* ind~xe8 to strings *1 /* add to beQinninq of line 1 :: 1: ij, t~en ~o: C~anges_onCurre~ l.,cateu :: l~ 35(· 'l57 SUbst ... (t'in, 1, 'Z.SFI ... rt'i~, j, 'e~9tn (1;ne)) :: line; ;i :: 1 ... 'i"e' - 1; 1 :: j + Ii nf' I + 1; go to cnrt; • 1) ; S'Ib'Oltr CCt:lrn'l'lar"lds, + i, j - 1); 1* COpy nal't to ~e added */ 1* copy 01'" line *1 ol'kl suo~t '2.59 3bf! ,61 *1 "l~u; :: "r-r'; 'b2 v = inciell' "iG, C'n:>; (lin~,,,), 'SIJj,'';tr'' suestr (Ct'l'n"lanUS, 30ll ,::,<:: if ~ th~n -; " S'!b~tr '6f.. C~; ii, (tlir-, .<. J.J :: - sl.J~str ~i;.7 SUrc~tr 36" bl'k,l, i - 1»): /* locat-. what ;s to be changed */ (t'i"'l 11 ~ I( - 1, j - U (line, m, = suhstr ffi m :: iJ t ~p. c: - - c; .::: ~ ij + k t J :; 1 + IC + j ~7'? - Clo,a"91"S_OCC'Jr r e'" :; 1 oc~te0 ; 1: if ~lOb~W t~e~ 00 371! 7.7'" 3H - Pi cOPV line UD to cnang~ (cO'l1ma",ds, brkl + i, J - 1), 1* /* put in ehanQe */ /* ir"lcl'ement inaexes 'Z,o'7 37f' 371 I( "l"p~ /* *1 *1 indicate tnat you did sometinq *1 cn~; to "'n r , -;n sui-str (tlin, le'"'~;t:; ij, (',"1e) -",,'''' 1):: suoSt~ ,7~ 7..7° -;a!'l ij :; ii ... 'e~(;tr, , :; 1 ... lel"lqtn (';r-e) - '2.81 c;>rt: 36;> i f (1;"'e 1 vn i~ "'; ~i c"'a""~",s_OCC\lr"e'" tll~n cal' ;ox_'Dut_c~al's ;;'0, 1* liox_~u~er_Outout, 38<:: -:: ~ then ~Oi cal] cf'\flJ_e~r_ (::oJe, 36~ "'0 364 (l;ne, /TIl; 1* COpy rest of line */ ad~r ~rite (tlin), 1, cna",g~s co~e); */ co~e to ,y;.~.:,r:, "Fr~or writino chanQe line"); -F;r'I;~n: 307 ,;)R ,8C' ~.,,...;; ,9(1 line : , il'el 39'. ,q;> S i< ; ,93 ,~l! I' ~ h~ i f :: ; p su~~t~ (t'in, = 1. t: to ~ n ,~ ..... if 'ocaterl :: i, ij)i n <. count :: ~ ur; t:'~n CC'Jl1t - 1* Get 1; B-17 rid of NL "commends" *1 AG90-03 cal' ina_ ("Mothtna chanaed by: 39'5 396 397 39e. 399 ca' 1 AS", co~mands); 1* if not located *1 rp.sp.t"e~;H end~ go to next; = ,., - lIOt " 402 403 ca1l put; eall g~t~ ao to cn1; aoa 1; a05 aOb IJ07 ao~ 1* ********* top ********* *1 too: 1* ********* bottom: 1* call COpy; call swl tch; 00 to next: *1 ca'l COpY; line' = n; r'l0 to "input: ********* backup: ********* botto~ 1* i = indt; eal i COPy; call switCh; indf + 1: do n :; n to 0; 1* save otrs *1 =; = if J 1; ne buffer *1 *********P*I backuo j ;~" il"id~x A:; 0 1* restore ot,., *1 Note that "n" 8ta,.ts ("evers~ t~en indf u else if n :; else ~o~ t~en 1* rSUQstr Uro.,,_sp.::'I. :; ind f indf :; C: 1, neg~tive. in';f - l), NUi 1* ~~nt off ton of file *1 I; , ; ne' :; n; 1;. ;nrlt, ;n~f :; 0; 00 t" ~of; n :; nci r-in"'t :; ;ndfj substr (to_seg, do inaf 1" ;not) :; sucstr = inrlt substr t 1 by 1 to csize~ (l;np., inOf - ;nrit, 1.) :; ;f suns!:r (frnn_se>J' inrif, then r'lO to ';ne_en~: 046 indf :; 1ine_e.,d: 1148 I" 450 451 00 453 sub~tr :; i;t 1* search for end of line *1 1* ********** Dsa file! csize~ 1;nel = incf - indt; = 1; 1I4Q liS? 1) 1* line starts 8S indt *1 1, inrlt)i 1* move in top of file ~I 1* find en rl of lfne *1 (f"o"'_~eo, indf, 1); 1* move into line *1 end; 1145 {J~7 Cfro"'_seCl, t~ printl~ "fileR re~up.st ********** _I call COpy; 8-18 AG90-03 *1 ~.el 1* 1* i SAve; call c1e3n_Ul"; '"'etul"n; Ca 1 I CO;;'11 cal I savp.; ""0 to ne'(t: = cc.vnt: co'mt iaa_ rps~t ~e"o; "0 (Hfn~ 1* source and release temp segs *1 RetuFn to eomm8nd Droc~ssor *i 1* 1* 1* Finish COPY. *1 Save it. *1 Continue aecepting requests. *1 1* Rem/')ve NL *1 1 of Fi1 0 *1 ~e~che~ ~y:·I·a", co~mands); to P'1ext: ~i-~L~:;; /*********kI··.Tt., ~cny! - cal1 <':a11 Save it. Te~minate l"r~c~aur~; Svhstr (to_seq, in"';t + 1, 'e.,;;th (line)) inrlt = linp.; 1* = in;:;t = (1; if cS;2'e ;:; u + le n qtt'l - c~i2'e ;:; 11"'!'I sUbst~ ;n"';t ;:; ;n,",f = ;"1:;t + 1, ;1) = SlJb"'tl" (f~om_seo, 1* *1 indf + i, i l l ' counters *1 s~t c~ize; ...·r"c .. ot'r ... i if sou",ce_rtr cel' if 1* If new input, then no cooy needed. 1* do rest of file *1 i~cf. (to_seo, ;nct + i j , thon *1 1* No more line *1 ._'1"" rptur,,; q CODY current line. (line); 1; ne1 i) 1* COoy rest of file into to file *1 ~ null t~e" hCS_S~8~p_qen cc~e A: (1 then call c!')~i'_e~r_ ret u ron ~ ( ~o: ir_na~p., entl"y_na~e, 1* Proceour~ to write out all 1* Must be a new seg~ent *1 "", 010tOb, source_Dtr, code)1 o~ Dart 01 "to" buffer. ~" "(.;P., J', v,,~-',F, "r.al'1not lDr'ln, $w!--str (~ource_seq, 1, II"'(.:tJ :::: SlJO$lr (to_!'leo, 1, indt); ~a' 1 hcs_J,!':et_rc_s"'c;: ('3o'Jrce_~'tr, ;n~t * 4, co~e); if c(')d~ I') tnpn cell hc!,:_Ttr~"'C9tP_!':e~ (s~urc~_~t~, divid~ (i"dt + 3, 4, 19. 0), ;f C~UP 0 t~en ~o~ cill1 cc~,_prr_ (corle, • i"A"E., "CPlnnot t:runcate/sp.t bit COUl'lt (Aa) ;n~t * ~, nathnaMe_ (~ir_n<'lm~, e"'try_name); = A= code); on "'a", pr.rii "'eturn: B-19 AG90-03 *1 151'5 "ut: 516 517 croeer'ure: sukstr 4n~t 51~ 51~ , ; ne1 ;ndt t 1, ler"!qth (line)) length (l;ne); (to_S~g, = indt = n; + = Hne; 1* do !!love *1 1* set counters *1 1* O;scard old line. ~20 er-d: 52' &:;22 523 521.1 oet: 525 526 527 528 52q proeerlure; l;nel = n; if ;ndf ~= c~;7e t~en no to ~Cf; 11nel = index (substl" (fro"'_!;eo, ;ntiof' 1* Reset. eUl"rent line lenotk. *1 1* If no inout left, give UP. c9ile - ; ndf), NU; 1* Fir-o the next new 'ine. *1 1* If no I'll found, treat end of segment as one. *1 ff lfn!'!l = 0 t"'er'l linel = es;z~ - inrlf; l;ne substl" (fro",_seo, indf + 1, linel); 1* Return the lfne to caller. *1 fndf = linel + ;nd f ; 1* ~ove the "from" I'ofnter ahead one line. *1 I"eturn: 530 531 153? 533 531.1 535 536 + 1, = end; switch~ 537 orocedure' S3~ ~x~tr 1* maKe = from_ptr: from_ptr = to_rtr; to_pt.r = 539 54{\ fro~-ffle to file, and v.v. *1 exptr~ es;ze = ir'lr'!t: i n('jt, i nd f = 0 ~ 11,.,e1 = OJ return; 51.11 542 543 54D 545 546 547 ena Switch; 548 resetreerl: 541:1 1* Call ;/0 system reset read entry. *1 1* In nne Dlac~ to centralize error handling *1 ea 1 1 fox_5eor'ltrol (;ox_:'lJser_;nput, "rt"sf!troel!ld", null (), code); 'f code ~= 0 the~ ea 1 ] c~~_el"r_ (COj~, kY~~~E, n[ann~t r~setl"el!ld user'_1n~ut"'J return; procerlul"e; 550 551 552 553 551.1 sse; 556 557 ! 55~ I:)sq 560 561 562 563 564 565 566 t;67 56~ 1:)69 570 571 ~et_token: procedure~ tkn =n "; wh;t~_'th = ver;fy (su~str (co~mAn~s, p.dct), 1* Set for easy fa1lur~ *1 - lJ 1* unly whftesoace left *1 ~HITE~PAC~) if wh;te_lth < 0 then return: edet edet • ~hit~_lth; to~en_lth seereh (9u~str (eo~~anrls. edetl, ~~ITESPAC~) - l' if to~en_lth < 0 the~ tov.e~_'th length (eO~m8n~s'- edct; ~ tkn substr (commands. ~dct, toke~_'th): 1* Extract token *1 edct edct + token_lt~; return; = = = = = &:;72 573 57" B-20 AG90-03 :7r::. oet _"ll--: :71-~I-o~e~~re; :7'7 ~a' 1 ~i~t_to"pn~ :7 Pelt' _n 'H. ~ ,7C! e.,try: 5" ~ = cv_dpc_ (t~n); 81. ifn=Qtr-e"",::'i 8~ Pout~ne Deli~;t 1* 1* 1* Enter here if token already avai1abl@. Co"vert it. *1 nefault count is 1. *1 to eonvept token to the tokel"l. *1 bi~8fY "p.tu"n~ .s:t 8a 1* 1* e!"lo gP t_nu.r ~ dr::. 6~ 07 8P rloil"_l.IP: D .. oc~~~~e: 8" Ci'l11 9('1 ;~ "fo"e<3S~_te"'L'_sP9"'ent"!_ ~OIJrCp_r;~r "= ... »11 t"'e" ~~",'... ",t., r:~11 te'!'H;)_segs, (('I)); hcs_;ilterrrdnate_rlol"lalTle (source_otr, CO)), 91 9? enc c'ei'l"_~"'; B-21 AG90-03 i"teger. *1 *1 LI~E ~U~BFR o "ATE MnDIFIEn Ob101/~1 'b a3.1 ~~~E PATH~lAME. ~os.oll >udd>Pubs>userd>AG90-02>eds.ol1 B-22 AG90-03 ATTRI8UTES ANO REFERENCES OFF~ET IOENTIFIER (* indicates NAMES DECLARFD MYNA"'E flY nECLARF.: 5TAHI"lENT. NL WHITESPACE oo%n 0 consta~t cl,a .. (~) 1l0 0 0'l1 constant 001110<: constant cha" (1) c kar(3) ou;ltfn function arg_count break brkl buffer OOl}100 nOl)101 000102 0(i Ol1\3 fixed bin(17,O) cl,a .. (1) fixed bin(17,O) cka .. C:?l 0) A~anC!es_o¢curred non170 automatic bit(!) OOi'l472 stac\( refeN'nce conci; t i on 1"0"171 automatic fixed binC3r;,O) addr 'anup Ie cOIII_err_ autolTll!tic automatic at1t"."at; c auto'!1at;c nOOO1O c(')nstant cOlllmands b"lseo entry char- count nOO172 al.ltomat; c fixea 0;n(21,0) csize 00()173 aut(')matic 1;xeo b;n(21,0) cu_Sar!1_co unt eu_Sarc:l_ptr ev_dec_ dir_name 1')00012 OOtlO14 00 0 0'6 000175 entr-y eP'1t .. y ent .. y char(16P) divide edet (\00174 aut"matic bui 1 t; n funetion fixed bin(17,O) entry_name 00°247 automatic c k ar-02) error_table_'noa .. g 001')0% i'lOOOI'O nOO062 (l000?0 0002"0 tlO"'2f.2 error_table_~n(')entry error_table_~too_many_args expand_pathname_ eXDtr from_ptr con'>tl!nt constant constant: automatic e)'ternal stat c f;xeo bin(35,O) el(ternal stat c fixed bin(3'5,O) el(terna l !'Itat c fixed bin(3r;i O) entry e~nstant pointer automatic pointer aut"mat;c B-23 II set context) initial unaligned del bO set ref 104* Ill* 113* 119* 119. 127* 143* 149* 151* 177* 210* 313* 385* 498* 507* 552* 589* initial unaligned del 5& ref 249 286 288 427 443 528 initial unaligne~ del 58 ref 563 566 dcl 85 ref 174 174 199 199 199 199 207 207 214 217 ?1~ 218 236 238 23S 264 272 284 284 295 311 311 311 311 311 311 329 334 335 337 338 356 358 358 363 363 366 36A 377 377 379 380 383 383 390 195 441 40A 476 478 480 517 517 518 531 5&3 566 567 !:i68 del q set ref 10?* 108 109 unaligned del 10 set ref 334* 335 337 del 11 set ref 333* 335 337 338 356 363 368 unaligned del 12 set ref 174 174 174 174 199 199 199 199 207 207 207 207 214 217 218 236 238 ~72 284 284 329 334 335 J37 338 356 363 368 395 46A 5&3 56" 567 568 unaligned dcl 13 set ref 351* 354* 373* 381 del A4 ref 135 dcl 14 set ref 102* 103 104* 108* 109* 110* 112 113* 118 119* 125* 12b 127* 139* 14' 143. 149* 150 151* 174* 176 177* ?07* 209 210* 311* 312 313* 383* 384 ~85* 496* 497 49A* 503* 504 504* 506 507* 551* 552 552* external del 64 ,.ef 104 113 119 127 143 151 177 210 313 385 498 507 552 unaligned del 15 set ref 199 199 199 199 214 2t7 218 236 238 272 284 ?84 329* 334 335 337 338 356 363 36~ 395* 468* 563 566 567 568 rle l 17 set ref 174* 180 199 199 199 199 207* 214 214 217 218 236 238 272 284 284 326 327* 327 329 329 J34 335 337 33~ 356 363 368 394* 394 3Q5 395 467* 467 468 46~ 563 ~66 ~67 568 del 18 set ref 160* 165* 166 Ib6 248 249 252 254 254 25~ 257 276 27~ 288 ~89 440 446 482 484 488 527 52~ 531) ':;41* @)(ternal del 65 ref 102 ~xte"nal del 66 ref 117 p)(ternal del 67 re~ 58n unsligned del 20 set ref 125* 139. 143* 143* 4Q6* 498* 498* 507* 507* del ~5 ref Ib5 504 504 ~el 19 set rpf 181* 236 23~ 272 273* 273 284 284 333 334 339* 339 5~3 565* 565 566 567 568 56Q* 569 unaligned del 21 set ref 125* 139* 143* 143* 162* 496* 498* 498* 507* 507* del 91 ref 109 del n ref 141 de' Q3 r@f liO external del 68 ref 125 del 22 set ref 5J8* 540 del 23 set ref 155* 166 249 254 264 265 284 286 288 291 295 427 438 441 443 485 528 531 538 539* AG90-03 bas"o char(10ll8~7f.,) (\O('lv~ .. entry bi t (1) e"try ~cs_~t"'rm;nate_n~na~~ constant I'IQ(l2fJ Clut"rrat; c 1'1(,1'10::'4 c,>n,:;t?lilt 11(1'10::'0 c""'st",nt 11\; ('''J:t (i cnnst a,rt 1'I\j"()~2 COf"lst"nt hC5_~tr~"catp_~e~ 1'I(;'l0~4 C"lnst",nt ent ry entry e'"lt,..v ; Ov~2"5 automatic fixpd bin(21,O) i j "on21'-6 dtlt"linat i inoell inrlf r.onZ/.,i alIt ("rr>?lt i c oet_~e~._s~~~ent~_ .,lot!"'" "'cs_C;: i '"I; t i I't"'_r-Ollnt "'C5_ 'f~Ii!kp._se ... hcs_"'s"!t_b~_Se,. ent,.y c builtin fllnct;o,", fixed bin(21,O) fixed bin(21,0) io,,_ ; 0(,'" ox_~ CO!)fo ; 0 x_ ; 0 II _ p"'n 1 ,; .. t _ I ; n" <: C, II t _c I- drS ~ ;Ox_'t\JRe .... _;rH'''II,.j+ ; Oll_ ~user_("ut:::·"t I entry entry e"try e'"lt,.y O~O I' ij(\lilJ c">nst'!n t IJ C(""'5t'lnt '10"\ C IJ': niln (j!JI.! "0")00::" nOI1 iJc;.:: 'lv"i:'71 cnnstant cnnst :H'I~ e"t~rnal st;,tic ooint~r ext"r"al st'!!tic oo;ntPr a I.J tor;; ~ t ; c fixed bin(21,O) le"ot., fixe:] bin(21,O) ouiltin fU'"Iction 1; ne char cha"'(?'lO) 1; neo' locate,", n003~2 auto~~tic ron,Sf.·3 (lllt"!1'at;c fixed binC17,O) fixed t,;n(21,0) fixP.d bin(2t,tl) builtin function null nathna."e_ rOf\()!!!:; C~"stA'lt re'ease_te.u_spq~e'"'ts_ rvniJc;(j CO'i'3tAnt revers" se .. rc-h e"try e'"ltry built;" functio" builtin funetio" B-24 unaligned del 24 set ref 166* 249 254 264 265 284 286 288 291 295 421 438 441 443 485 528 531 @xternal del 69 ref 149 unaligned del 26 aet ref 340* 345* 315 external del 70 ref 139 external del 72 ref 496 ~xte~nal del 74 ref 503 ~xternal del 7~ ref 590 external dcl 76 ref ~04 riel 27 set ref 2?6* 247* 2~4* 285 286 281 335* 336 337 338 339 353 356 363 368 370 422* 425 del 28 set r~f 3~2* 359* 366 368 371* 371 377 379* 379 389 390 484* 4AS 485 485 487 del 85 ref 249 2~4 286 288 335 337 363 427 528 del 29 set ref 160* 245 252 256* 262* 265 265 267 ~7~ 276 284 286 287 289* 290* 293 425* 427 428* a2~ 429* 433* 437 440* 441 441 443* 446* 447 4e4 485 48~* 527 528 528 530 531 532* 532 542* del 30 set ref 160* 254 257* 257 265 267* 267 274 291 294* 294 422 433* 437* 438 43e 440 441 447 47e 480* 480 485 4 A7* 487 502 502 503 504 504 507 517 ~lA* 518 541 542* external del 77 ref 162 172 199 205 307 329 395 468 external dcl 7~ ref 551 fl'xtern&l dcl 79 ref 17ll 207 i!!xtel'nal dcl 80 I"ef 311 383 del 90 set ref 174* 201* 551* del 90 set ref 311* 383* dcl 31 set ref 245* 248 249 249 260* 260 262 264 27ll* 2AO 2~0 282* 288* 289 290 337* 338 338* 339 35~ 356 358 359 360 368 368 371 372 427* 428 428 del 32 set ref 249* 251 260 263 264 286* 287 287* 287 288 288 290 291 291 293 294 295 363* 365 366 366 368 370 371 372 del 33 set ref 3~2* 360* 372* 372 380* 380 383* del AS ref 174 174 199 199 207 207 217 236 27c 284 ~lt 311 338 358 377 379 380 47~ 480 517 51a 567 uneligned del 34 set ref 218* 238* 264* 295* 311 311 '11 311 35R 35~ 363 366 377 377 379 380 390* 441* 478 478 480 517 517 SlR 531* unaligned del 35 s@t ref 218 238 264 c95 311 311 311 311 35A 358 3b~ ~6~ 317 377 379 380 390 441 478 47~ 480 517 ~17 51a 531 del 36 set ref 217* 218 229* 236* 238 253* 263* 264 26ll 265 265 267 293* 295 295 306 311 311 311 311 349 35A 35~ 359 360 363 366 377 377 379 380 389* 390 417* 431* 44' 447* 478 478 480 481* 517 517 518 519* 526* 52A* 530 530* 531 531 532 543* dc' 37 aet ref 325* 35~* 374* 393 del 38 set ref 245* 254 254 254 257 265 265 265 267 275* 282* 291 291 291 294 352* 363 366 370* 370 377 377 379 3SO del 39 set ref c?6 244 2117 276* 278 280* 281* 284 296* 317* 317 318 341* 392 401* 401 426* 426* 429 432* 449* 580* 581 581* del 1145 ref 133 134 141 161 495 551 551 590 i!!xternel del 81 ref 143 143 498 498 507 507 ~xternel del 82 I"ef 58 Q del 85 ref 286 427 del 85 ref 566 AG90-03 .".me ."eme_lt~ .neme_Dtr source_count souree_ptr bas eO automatic. t')O(l36b autnmi"!tic 000370 automatie 00n372 automatic (l0"3~5 basI";) souree_seg substr e~ar f ixeo bin(21,O) :>o;nter Hxed bin(Z4,O) pn;nter c~ar (1 0/J8576) puilt;n function temp_seps tkn 1')0037L1 automi"!tic nOIlL/ A6 autol1at i c o<",;nter c"ar (I~) t lin nO l1 4 0 0 aut on,at; C c"a"(10) to_Dtr OOO/Po automatic to_seg c"arC1.0 1l 857t,) alltomatic fixed bln(21,0) built;n function f;XPd bi n (21,0) token_lt~ 000':1% ler! fy ~hite ...1tk 1'l()(\S"7 auto'nllt;c .MES DEr.LARED BY FXPL TCn C(l/~TEXT pointer cas~o • :prt :v_num Ie' I in 'ds 'of ile ; nish 'et et_nu" et_toke n nDut nsert !ne_e.,d ocate _eof eIClin eICt 110?u7/J constcont: 001775 consti"!nt nO?0+71 constar'lt /'IO?1~6 con!>tant nO?21'l3 cnnst"nt 001771 constanl: 11034,3 constant no?(;"O cnnstant IlO~3lJ5 constant OO~4r;o constant 0013t! 1 constant oon2~0 constant 00?6?1 constant 00?6 0 7 cnnstant 00;:>011 cOr1star'lt 0031 7 2 constl'l"lt 007;4 11 3 COrl!'ltant 00'B24 conlltant 0012"1 c"'1st;jnt 00'357 CO'1st9nt 0026 0 1 constar'!t 00 1 5;:>1 constant 1')01432 constant 001.H3 c~nstant "010;:>0 cI'Jr'!!;tant label label 1901"1 label lab"l label entry entry label e"try I aoel entry label label lab!!'! entry entry ent,.y laoel 1 aoel lahel 1 ebel lao!!l 1;joel label ol;ne Xl!lrq edit input rint !'intl Jt uetread 00171,2 const'llnt !'0?114 constant (lOtO I1 5 COr')stant 001.2'0 const'llr'lt 001.6 7 3 constant "01]12 cO"lstClnt 003157 eon!'ltant 007;2 D2 cl)nstant 1 abel I ao!!l aCi(UP lad_syntax lottOm :n 1 :n2 :henge :lean_up :o~y unaligned del 40 set ref 125* 127w del 41 set ref 117* 12C; 125 127 127 del 42 set rflf 117* 125 127 del 43 set rflf 139* 16C; del 44 set ref 133* 139* 141 161 166 495 496* 502 503* 504* '590 590* uneligned del LIS set ref 166 502* /'Icl 85 set ref 166* 166 199 199 214 238 249 2511* 254 2611 265* 265 2114 211\4 28& 2813 291* 291 295 334 '335 337 356* 356 3513* ,63 3&3 366* 366 3613* 368 377* 377 390 427 43~* 438 441* 441 443 478* 4~5* 485 502* 502 517* 52R 531 '563 566 568 arraY dcl 47 set ref 134* 149* 155 156 589* uMligned dcl 49 set ref 184 185 186 187 188 1M 190 191 192 193 19/J 19'5 344 345 562* 568* 5130* uneligned dcl 48 set ref 356* 358* 366* 368* 377* 383 383 390 dcl '52 set ref 1'56* 254 265 291 438 478 /J85 502 517 539 '540* un!!ligne('f dcl 50 set ref 254* 265* 291* 438* 478* 485* 502 517* dc' 56n set ref 56£0,* 567 567* 568 569 ('fe' 115 ref 563 de' '560 set ref 563* 56/.1 565 dc' IJ2;) ref 241J /'Iel 327 ref 272 336 ciel 416 ref 191J dcl 351 ref 404 de' ;63 ref 37C; dcl 325 ref 190 inte,.nsl dcl 586 ref 135 152 /.IS 6 fntern81 dcl 477 ref 2q9 410 416 423 454 461 de' 381 ref 361 inte,.nal del 578 ref 346 de' 224 ,..ef 191 I!!xte"n81 dcl 1 del 467 ref 252 251\ 434 527 del 454 ref 189 riel /lSI, ref 1711 :1Ilt 314 386 intern8l del 524 ref 227 3:110 403 internal del 575 ref 224 243 305 internal del 557 ref 182 3 11 2 577 del 207 ref 219 del 2311 ,.ef lB4 de' 1147 ,..ef 443 dc l 272 ,..ef 113£0, riel 252 ref 248 del 243 ref 18~ de' 174 ref 1M 201 230 239 2611 301 318 331 399 412 463 'HO del 317 ref 308 dcl 342 ref 347 del 172 !"ef 214 dcl 205 ,.ef 163 195 418 "'cl 305 ,..ef 187 del 311 ref 297 321 450 internal dcl 515 ref 21b 234 246 277 319 402 1r'1tern81 dcl 548 ref 200 330 397 469 Il!b~1 labei 1aoe1 lab'!l entry el'ltry B-25 AG90-03 retyr>e !;lave lAbel "01 V,O Cl:lnst<'li"lt "IJ '?"/ :'\6 cOr)<;t",,,t sk;p~h nu?i;~2 C"iist~nt lab~l ~w; flO)i:>5 CO'"lstant ent"'y to" '()?LI~,} 1 abel WSi\V'" "O:>td ,; tl':'l t:ln unit _; n'" '1e f s Static tJ4r:: oj '11 03 l!.F4 ':"'4 210 C!~1 "T ,:..rf< :;:'T ,e= ur'lit "" i"tern",l "I.I COpy ;r"\t:ern3i in+:e"'nal ;nt-e'"nai ;nte"nal ;n+:e"nal ;nte,""i'li save nut oet' switch !"esetrPd"" ~et_to' 71 POS ecJs 0'1t'P7:> ~IAMt:: "0<1 vf\u?~7 lr!"l(i17<:; proee~uI'e. • aro_I':OI.Jf't i):> extern~l '< eo'S 'j!j()n~ !"d"! 0"O~/~ 'i~e_buff~~ ",oJS u"03iJl ()"t01c.? eds !)l')iJ~6~ l;n~' 'o,,:ate'~ .., :;:'\fJ~1j11 ., '!OS ",oj! ~d"l 'J '1 (J <;;, c:: 0;: ;., P _ 1 t I, ",d!;l CI\\J<:~'t., :c;n",,::;p_rt~ eds 0('1,)'1:7') source_co\J"'t eos n ~ B-26 AG90-03 000372 000'374 QOOf.lO O 000466 0(10 11 7" OOO"'5A 0"0"57 TH~ FOLLO~IN~ ~XTEQNfL 81loc_cs enable UPE~ATQPS souree_ptr temp_sf!gs tlir; U:!"l to_ptr toi(en_'th eds eas ~d9 ",us A.CiS ..,et_toke n ne·_toke n ~lhHe_'th APE call_ext_out_d~sc sh~rten_stack U~En Ry TUl~ p~n~~~~. ea'l_ext_out c a 1 1 _ ; n t _0 the r set_cs_eis ca'l_;~t_t~;s int_~ntry ext_~ntry return (ndex_cs_eis cv_dec_ eO'TI_err_ cu_!i.aro_Collnt eu_:!iaro_otl" exoa~d_pat~n8me_ Qet_temD_seg~ent~_ ~c!'!_~;!"l;t;ate_count ~cs_!make_seg "cs_~set_bc_geo iox_~control hcs_~tprm;nate_ncn~me hcs_~trunC8te_seo 108_ iOlt_ltget_linp iox_4:out_c nars I'athna!!le_ rele8se_temp_seg~e!"lts_ 'HE FOLLOWING FXTEP~AL ~AHIARLFS error_tablp._$noarg iox_$usel"_OUtpllt LINE LnC 1 0002?7 110 (10031'10 120 001'1411 13" 000514 151 00(171'16 162 0007"'2 177 001045 186 001115 193 00'160 ?07 0012"'1 218 001335 230 OOn Ci 6 ?45 001376 253 ('01435 t I'!E fib? 1'10'4"" 21.3 ?73 00'524 280 (101542 ?8R 001613 296 001065 307 001676 31P 00'-1"4 329 001.777 337 002056 34c; 00?1?2 354 (l021llb ~6~ 0022(13 373 00231)4 383 (\023£!7 391; 1)0?4;:>5 a03 (\0~464 002473 l!2R (102524 1.13 7 OO:?5l14 a1F~ APE USE!"! ~y TYl~ PRnGnA~. error_tahle_~noentry LUr 000235 112 01'10303 1(')2 LnC L 1 "IE L JC LINE 1.03 1')()02'l5 11 , 'llln305 Lnc 1"\"1 O(\O2~7 In 105 117 12A 144 156 172 182 190 201'1 1'100264 000335 00(\47& 001"662 0007111 00101)5 001102 OOlllll LTI';~ 1?5 O!'l()Llp 12~ r)v04a~ 1~9 •q1 001'61'1(, 0OO53~ It::2 0OO73? If.3 01')077e; 178 00107 11 IP7 or'J 112' 1°4 00110'5 21'9 O!'lP7 11 219 001340 234 001'357 2Ub O(\1 IJ OI 20::4 001/136 (lnliJ6~ 274 (lOl')2Cj 21'\1 01'11547 2~9 001f,27 2 0 7 0011,07 3('b 0 0 1711 319 00176f, 31:0 002025 na 002076 3 11 6 002132 3')5 002'50 3~';> 002'227 374 002~O6 31'4 0(\2361, 3e~ 0021J27 un4 002465 4?2 OO2 11 7 11 42'1 0021:j(l 47,8 0°2"'41, error_tahl"'_~too_m8nY_8ros '5~ ()001'6 111..( Of'0334 OI'lC!l411 1113 O"Uf.ll'1 1"'5 01'10 7 37 160 01')1 0 01 16<:: I'Ivr)77l) 1(1) "\0 1 075 lAl 0(')1101'1 168 1'I011?? 19!) 1)(; 1172 lR9 001134 1°9 ()01177 211 0017;2;:> ?11'1 "012. 7 0 ?2!1 ?31:> ?47 ?5f, ;>6 /1 OOU!Jl 226 OOL~4;:> ouUb0 2~8 onl~63 0014(12 2uS 257 2"5 27 0 v01 Ll l! 0('111.:5" 2P.!.j vnl'5~? Ilv1ifO:;:.:> 1'I()1~7iJ ;>"15 'led 5'1 ?8? (')0150:;0 ;:>lfn 0Olo1:~ '99 "0t67() 1:11 1')0 1712 '32('\ nO'7b7 ~31 nO?Pb ('10;:>1-14 347 00;:>1'33 3';>6 OO?lt::c: ~6b 1'102230 ~75 Ou?31() ';3 Cl \lOlll77 0/')1"'3 1 2('11 0('11"3') ')1 f,71 ~OO (t 312 OOl73~ 3:'.1 001770 333 002027 3 t1 0 002111 3<'19 002134 3';8 002166 3~o O'l224{" 377 0021:12 39'" CQ?u'31 lJl!'\ 1'102460 3P.6 O!"l2lJ11J :'°7 on2457 411 on211&7 lJ2~ 424 O()2L177 360:: OO?,)7v 00?'476 l!3t 002534 l.f40 "\O'~53 Q02"'3r::; 4ill 01')2563 4~2 B-27 1)012~3 ?14 0013:='3 227 f')013"'2 ?39 001372 249 001414 ~5~ 001460 267 001514 ?77 001534 :='85 001571 293 0016':'1 301 001672 313 (101735 325 001771 334 002032 341 002112 351 0021'3& 359 I) Q2173 1:70 OO::?265 ';79 002335 389 002'115 399 (')02'160 lI12 0021.170 425 00;:>500 1133 002537 1143 002571 LINE 108 118 133 149 160 LOC 000265 OOO~55 Oooa77 000663 000743 174 001021'1 18a 001103 001146 001235 01'l1332 00BS3 2a3 001373 251 001431 260 001~&1 268 001520 278 0015315 2Ao 001'572 294 001651J 305 001673 314 001761 320 001772 335 002037 3£12 0(12114 352 002137 360 002177 371 002277 380 0"23'11 3QO 002417 191 201 210 228 401 0021161 410 0021171 :.l~6 0025Q3 434 002541 4~5 002-;75 AG90-03 LINE LOC 10q 000272 l1q 000357 131.1 150 1&1 176 185 192 000501 000704 00074& 001043 001110 001153 205 00123& 217 001333 22q 00135~ 2~4 001374 25? 001432 261 001462 272 001521 ~79 001541 287 00160& 295 f')01660 306 001074 317 001762 327 001775 336 002055 344 002115 353 002143 361 002202 372 002277 381 OOi?345 392 002422 402 002463 417 {l02"72 427 OQ2507 1I3b 002542 446 002577 '147 46 1, r;O'6i'11 00::»6 1 0 4l"~ 01'12601.1 45" !'l'G '01'1 0 4~4 002607 LIse; n02bl0 4f,i on2~17 I1b~ ~Pb?0 467 002~2', 46~ 002623 077 t'026t::() a87 nO?/01 1J9R !'l02-, C:;t.j 4'70 0026~1 tib"l ni,j"i'br:.7 "ili) 0I'1c7()~ CIjO ov 2'/"5 481 Ol)cF,bl 4 0 4 0(\27iJ~ L1Q", i')v'30~u 503 00.$036 50q 0030C;4 ';i1:> \)1'31'12 7 0 11 3157 "=(;' 1'10311::6 C::17 n(j3,i.f-iJ S2 R ....' ;.v "Z.. • "', "7, t::;;q I'\v323u 1:;51 "il1;2 u ,5 '::ita 01')3166 ell) 52f. (1031 7 3 r'032"S ~'11! (I O~~l! 1 f.\o; 1i(j"l:3 "7 e..7fl "1)341'12 r::.&f-. 003 .. 1:2 t:;36 f13i 7ii V7 (J 5"Z8 OI'l3?2'" S'!d ;'L.i.i 0"3' .. 1' ~,1. I.in3~"'~ <:6C:; "\J3,,1::2 575 0t'l3 11 (;) S~'1 On3 U4" S77 "i.J ".1'14 I'H,l'104 A 2 r::.'11'l a82 002&62 495 0027"7 ~30 on3? 1'~ C;lQ (103170 1:\31 OO'3~20 ~IIO 0 11 3'3' ~41 on3?7S 00.33S3 7 5 6 0"'3401:\ 5Q2 003501 '5~2 5k 6 B-28 0032"51.1 553 1'103323 t;b7 003372 Ci80 OO~4n7 456 002611 469 002646 484 002665 49b 002713 SOb 003075 520 003171 532 003223 542 003236 557 003324 568 003376 SAl 003426 AG90-03 457 002615 470 002647 1.185 002667 tJ97 002752 S07 003077 '524 003172 533 003224 543 003240 Sb2 003325 56Q 003401 C;S2 00'3431 APPENDIX C MULTICS SUBSYSTEMS The Mul tics system offers many special' subsystems, designed to serve a part icular set of users or perform a particular set of tasks. Some of these subsystems are already familiar to you--the Qedx and Emacs text editor systems, the input/output system. Various other subsystems are described briefly here. For detailed information on any of them, see individual manuals. DATA BASE MANAGER The Multics Data Base Manager (MDBM) supports the description and processing of data bases of widely varying sizes and organizations, and provides a large measure of data independence. It consists of an integrated set of functions which offer a full range of data base retrieval and update capabilities, and it is writ ten to interface with any programming language that supports a call statement. The MDBM offers a powerful, extremely flexible method of structuring and manipulating data bases: the Multics Relational Data Store (MRDS). MRDS supports the relational model of data base organization, in which data relationships are represented by means of formal algebraic entities. It allows you to structure and access data without concern for how or where it is actually stored. A special MDBM query language called LINUS (described later in this section) provides comprehensive query capabilities for MRDS data base users. Data bases reside wi thin the Mul tics storage system and are protected by all of the security features inherent in the Multics virtual memory environment. FAST The Multics FAST subsystem is a simple-to-use, low-cost user interface for creating and running BASIC and FORTRAN programs. The Mul tics FAST command language is a subset of Multics commands with additional commands for manipulating line-numbered text. GCOS ENVIRONMENT SIMULATOR The GCOS environment simulator, together with several Multics facilities, permits GCOS batch-processing jobs to be run under the control of Multics and provides some job-scheduling facilities. Invoked via the Multics gcos command, the simulator immediately runs one GCOS job in your process. Your terminal is treated as if it were the GCOS operator's console. C-1 AG90-03 It's also possible to simulate GCOS time-sharing usage, Multics gcos_tss (gtss) command. by invoking the GRAPHICS The Multics Graphics System provides a general purpose interface through which user or application programs can create, edit, store, display, and animate graphic material. It is a terminal-independent system, which means that a program writ ten for one type of graphic terminal is operable without modification on another terminal having similar capabilities. LOGICAL INQUIRY n 1IT1"'\ .t1nu nn1"'\/I'T'V UJ:Ul1.J.D The Logical Inquiry and Update System (LINUS) is a facility for accessing MRDS data bases. The complete data base management capability provided by LINUS includes both retrieval and update operations. LINUS makes use of a high-level nonprocedural language called LILA (LINUS Language) that can be understood by individuals who aren't necessarily computer specialists. REPORT PROGRAM GENERATOR The Multics Report Program Generator (MRPG) is a language translator used to generate a PL/I source program from an MRPG source program, with the purpose of generating formatted reports. SORT/MERGE The Sort/Merge subsystem provides generalized file sorting and merging capabilities, specialized for execution by user-supplied parameters. Sort orders an un ranked file according to the values of one or more specified key fields in the records you are using. Merge collates the contents of up to ten ordered files according to the value of one or more key fields. Input and output files associated with the Sort/Merge subsystem can have any file organization and be on any storage medium. Records can be either fixed or variable length. WORDPRO The Multics word processing system, WORDPRO, consists of a set of commands that assist you in the input, update, and maintenance of documents. The commands provide tools for text editing and formatting, Speedtype, dictionaries for hyphenation and spelling, list processing, and electronic mail. An important part of the WORDPRO system is the compose command, which is used for formatting manuscripts, and has programmable requests that make it a minor programming language. C-2 AG90-03 APPENDIX D THE EDM EDITOR The Edm editor is a simple Multics context editor which is used for creating and editing ASCII segments. Edm is less sophisticated than Qedx, and far less sophisticated than Emacs, so if you are already comfortable with one of these editors, this appendix will not be very useful to you. However, if you would like to learn how to use a simpler editor, this appendix will help. To invoke the Edm editor, you type: edm pathname when pathname identifies the segment to be either edited or created. The Edm editor operates in one of two principal modes: edit or input. If pathname identifies a segment that is already in existence, Edm begins in edit mode. If pathname identifies a segment that does not exist, or if pathname is not given, Edm begins in input mode. You can change from one mode to the other by issuing the mode change character: a period (followed by a carriage return) which is the only character on a line. For verification, Edm announces its mode by responding "Edit." or "Input." when the mode is entered. The Edm requests assume that the segment consists of a series of lines and has a conceptual pointer to indicate the current line. (The "top" and "bottom" lines of the segment are also meaningful.) Some requests explicitly or implicitly cause the pointer to be moved; other requests manipulate the line currently pointed to. Most requests are indicated by a single character, generally the first letter of the name of the request. REQUESTS Various Edm requests and their functions are listed below. Detailed descriptions of these requests are given later in this section. This list does not include all of the Edm requests; it identifies only those requests that you will need as you begin using this editor. For a complete listing and description of all the Edm requests, see the MPM Commands. backup = print current line number comment mode mode change b bottom d delete D-l AG90-03 f find i insert k kill 1 locate n next p print q quit r retype s substitute t top v verbose w write GUIDELINES The following list offers helpful suggestions about the use of Edm. 1. It is useful to remember that the editor makes all changes on a copy of the segment, not on the original. Only when you issue a w (write) request does the editor overwrite the original segment with the edited version. If you type a q (quit) without a preceding w, the editor warns you that editing will be lost and the original segment will be unchanged, and gives you the option of aborting the request. 2. You should not issue a QUIT signal (press ATTN, BRK, INTERRUPT, etc.) while in the editor unless you are prepared to lose all of the work you have done since the last w request. However, if a QUIT signal is issued, you may return to Edm request level without losing your work by issuing the program_interrupt command. 3. If you have a lot of typing or editing to do, it is wisest to occasionally issue the w request to ensure that all the work up to that time is permanently recorded. Then, if some problem should occur (with the system, the telephone line, or the terminal), you only lose the work done since your last w request. 4. You should be sure that you have before typing editing requests, you forget, the editing requests being acted upon. You then have 5. As you become more familiar with the use of Edm, you may conclude that it provides verification responses more often than necessary, thus slowing you down. You may use the k (kill) request to "kill" the verification response. However, once you feel confident enough to use the k request, you are probably ready to begin using the more sophisticated editor, Qedx. The Qedx editor provides you with a repertoire of more concise and powerful requests, permitting more rapid work. D-2 switched from input mode to edit mode including the wand q requests. If are stored in the segment, ins~ead of to locate and delete them. AG90-03 REQUEST DESCRIPTIONS The following Edm requests are the ones that you will find most useful as you begin working with this editor. Examples are included to help you see the practical use of each request. Backup (-) Request The backup request moves the pointer backward (toward the top of the segment) the number of lines specified, and prints the line to show the location of the pointer. For example, if the pointer is currently at the bottom line of the following: get list (n1, n2); sum = n1 + n2; put skip; put list ("The sum is:", sum); and you want the pointer at the line beginning with the word "sum," you type: -2 sum = n1 + n2; If you don't specify a number of lines with the backup request, the pointer is moved up one line. (Typing a space between the backup request and the integer is optional.) Print Current Line Number (=) Request The print current line number request tells you the number of the line the pointer is currently pointing to (all the lines in a segment are implicitly numbered by the system--1, 2, 3, ••• , n). Whenever you want to check the implicit line number of you issue this request and Edm responds with a line number. the current line, = 143 Comment Mode ~ Request When you invoke the comment mode request, Edm starts printing at the current line and continues printing all the lines in the segment in comment mode until it reaches the end of the segment, or until you type the mode change character (a period) as the only entry on a line. To print the lines in comment mode means that Edm prints a line without the carriage return, switches to input mode, and waits for your comment entry for that line. When you give your comment line and a carriage return, Edm repeats the process with the next line. If you have no comment for a particular line, you type only a carriage return and Edm prints the next line in comment mode. When you want to leave comment mode and return to edit mode, you type--as your comment--the mode change character (a period). D-3 AG90-03 Programmers will find that the comment mode request gives easy way to put comments in their programs. Mode Change ~ them a fast and Request The mode change request allows you to go from input mode to edit mode or vice versa simply by typing a period as the only character on a line. This request is also the means by which you leave the comment mode request and return to edit mode. For example, when you finish typing information into a segment, you must leave input mode and go to edit mode in order to issue the write (w) request and save the information. last line of segment Edit. w Bottom (b) Request The bottom request moves the pointer to the end of the segment (actually sets the pointer after the last line in the segment) and switches to input mode. This request is particularly helpful when you have a lot of information to type in input mode; if you see some mistakes in data previously typed, you can switch to edit mode, correct the error, then issue the bottom request and continue typing your information. red oramge yellow green . Edit. -2 oramge slmlnl orange b Input. blue Delete (d) Request This request deletes the number of lines specified. Deletion begins at the current line and continues according to your request. For example, to delete the current line plus the next five lines, you type: d6 If you issue the delete request without specifying a number, only the current line is deleted. (That is, you may type either d or d1 to delete the current line.) After a deletion, the pointer is set to an imaginary line following the last deleted line but preceding the next nondeleted line. Thus, a change to input mode would take effect before the next nondeleted line. D-4 AG90-03 Find (f) Request The find request searches the segment for a line beginning with the character string you designate. The search begins at the line following the current line and continues, wrapping around the segment from bottom to top, until the string is found or until the pointer returns to the current line; however, the current line itself is not searched. If the string is not found, Edm responds with the following error message: Edm: Search failed. If the string is found and you are in verbose mode, Edm responds by printing the first line it finds that begins with the specified string. f If If the string is found and you are in verbose mode, Edm responds by When you type the string, you must be careful with the spacing. A single space following the find request is not significant; however, further leading and embedded spaces are considered part of the specified string and are used in the search. In the find request, the pointer is either set to the line found in the search or remains at the current line if the search fails. Also, if you issue the find request without specifying a character string, Edm searches for the string requested by the last find or Yocate (1) request. Insert (i) Request The insert request allows you to place current line. a new line of information after the If you invoke the insert request without specifying any new text, a blank line is inserted after the current line. If you type text after the inse~t request, you must be careful with the spacing. One space following the insert request is not significant, but all other leading and embedded spaces become part of the text of the new line. For example, if the pointer is at the top line of the following: sum = n1 + n2; put list ("The sum is:", sum); and you issue the following insert request: i put skip; the result is: sum = n1 + n2; put skip; put list ("The sum is:",sum); If you want to insert a new line at the beginning of the segment, you first issue a top (t) request and then an insert request. D-5 AG90-03 Kill (k) Request The kill request suppresses the Edm responses following the change (c), find (f), locate (1), next (n), and substitute (s) requests. To restore responses to these requests, you issue the verbose (v) request. It is recommended that as a new user you not use the kill request until you are thoroughly familiar with Edm. The responses given in verbose mode are helpful; they offer an immediate check for you by allowing you to see the results of your requests. Locate ill Request The locate request searches the segment for a line containing a user-specified string. The locate and find (f) requests are used in a similar manner and follow the same conventions. (Refer to the find request description for details.) With the find request, Edm searches for a line beginning with a specified string; with the locate request, Edm searches for a line containing--anywhere--the specified string. Next (n) Request The next request moves the pointer toward the bottom of the segment the number of lines specified. If you- invoke the next request without specifying a number, the pointer is moved down one line. When you do specify the number of lines you want the pointer to move, the pointer is set to the specified line. For example, if you type: n4 the pointer is set to the fourth line after the current line. responds, when in verbose mode, by typing you-specified line. The Edm editor Print (p) Request The print request prints the number of lines specified, beginning with the current line, and sets the pointer to the last printed line. If you do not specify a number of lines, only the current line is printed. If you want to see the current line and the next three lines, you type: p4 current line first line after current line second third In Edm, every segment has two imaginary null lines, one before the first text line and one after the last text line. When you print the entire segment, these lines are identified as "No line" and "EOF" respectively. D-6 AG90-03 Quit (q) Request The quit request is invoked when command level. you want to exit from Edm and return to For your convenience and protection, Edm prints a warning message if you do not issue a write (w) request to save your latest editing changes before you issue the quit request. The message reminds you that your changes will be lost and asks if you still wish to quit. q Edm: Changes to text since last "w" request will be lost if you quit; do you wish to quit? If you answer by typing no, you are still in edit mode and can then issue a write (w) request to save your work. If you instead answer by typing yes, you exit from Edm and return to command level. Retype i£l Request The retype request replaces the current line with a different line typed by you. One space between the retype request and the beginning of the new line is not significant; any other leading and embedded spaces become part of the new line. To replace the current line with a blank line, you type the retype request and a carriage return. Substitute ~ Request The substitute request allows you to change every occurrence of a particular character string with a new character string in the number of lines you indicate. If you are in verbose mode (in which Edm prints responses to certain requests), Edm responds by printing each changed line. If the original character string is not found in the lines you asked Edm to search, Edm responds: Edm: Substitution failed. For example, if the pointer is at the top line of the following: get list (n1, n2); sum = n1 + n2; put skip; put list ("The sum is:", sum); and you want to search the "total," you type: next three lines and change the word "sum" to s4/sum/totall total = n1 + n2; put list ("The total is:", total); D-7 AG90-03 The four lines searched by the editor are the current line plus the next three. (The search always begins at the current line.) If you do not specify the number of lines you want searched, Edm only searches the current line. If you do not specify an original string, the new string is inserted at the beginning of the specified line(s). Notice in the example that a slash (/) was used to delimit the strings. You may designate as the delimiter any character that does not appear in either the original or the new string. Top (t) Request The top request moves the pointer to an imaginary null line immediately above the first text line in the segment. (See the print request description concerning imaginary null lines in Edm.) An insert (i) request immediately following a top request allows you to put a new text line above the "original" first text line of the segment. Verbose ~ Request The verbose request causes Edm to print responses to (f), locate (1), next (n), and substitute (5) requests. the change (c), find Actually, you do not need to issue the verbose request to cause Edm to print the responses; when you invoke Edm, the verbose request is in effect. The only time you need to issue the verbose request is to cancel a previously issued kill (k) request. Write (w) Request The write request saves the most recent copy of a segment in a pathname you specify. (The pathname can be either absolute or relative.) If you do not specify a pathname, the segment is saved under the name used in the invocation of the edm command. When saving an edited segment without specifying a pathname, the original segment is overwritten (the previous contents are discarded) and the edited segment is saved under the original name. If you do not specify a pathname and you did not use a pathname when you invoked the edm command, an error message is printed and Edm waits for another request. If this happens, you should reissue the write request, specifying a pathname. D-8 AG90-03 INDEX MISCELLANEOUS address space 1-2, 1-10, 2-6, 3-1, 3-5, 8-4, 8-5, 8-8, B-6 -absentee control argument -all control argument 7-4 addressing online storage A-1 1-7, 3-2, 1-1 -arguments control argument -brief control argument 7-6 1-1 -brief_table control argument 2-5 -first control argument 6-3 -link control argument 2-11 -list control argument 7-3 2-3, 6-3, 6-4, 3-7, 8-4, add_search_rules command 3-3, 8-4 administrative control 1-12, 3-3 alignment of variables B-2 ALM programming language 2-2, A-4 apl command -long_profile control argument -map control argument add search_paths command - 8-7 6-3 1-10, 2-1, 8-5 APL programming language 8-5, A-1 2-1, 2-3, 2-4, 2-5, B-2 -notify control argument archive component 2-11, 8-2, 8-6 segment 2-8, 8-2, 8-6 7-4, 7-6 -optimize control argument B-2 archive command -profile control argument 6-4 -sort control argument attach description 6-3 -table control argument 5-8 2-8, 2-8, 8-2, 8-6 6-1, 6-2, attaching switch 2-4, 3-6, 5-6, 4-9, 4-10 4-2, 4-9, 4-10 automatic storage 5-5 B A background absentee facility 1-1, 4-12, 7-1, 7-3, 7-4, 7-5, 7-6, 8-5, 8-9, 8-10 accepting arguments 7-5 capabilities 7-5 control file 7-1, 7-3, 7-5, 7-6 enter abs request command 7-1, 7-3, £-4,-7-6 input file 7-1, 7-3, 7-5, 7-6 job 1-1, 4-12, 7-1, 7-4, 7-5, 7-6, 8-5, 8-10 output file 7-1, 7-5, 7-6 process 1-4, 7-1 production runs 7-1 1-4, 7-1 backup request see Edm editor requests basic command BASIC programming language C-1 batch binary 2-2, 2-5, 2-9, 4-7, B-2 2-11, 8-5 7-1, 7-3, 7-5, 7-6 absolute pathname absout segment 2-1, 8-5, 1-1, 7-1 bind command absin segment 4-10 binding bind command 2-11 binder 2-11 bound segment 2-11 A-6, B-5 7-1, 7-5, 7-6 access 1-5, 2-6, 2-8, 4-5, 8-4, 8-1, B-5, C-1 bit count access control list bottom request see Edm editor requests 1-12, 8-4 ACL see access control list add search rules command 1-9, 8-2, 8-3, A-6 builtin functions divide B-7 index B-9 reverse B-9 search B-10 8-7 i-1 AG90-03 builtin functions (cont) substr B-9 verify B-10 bulk data input byte size commands (cont) link 2-11, 3-3, 8-2, 8-3 list 2-11, 8-4, 8-3 list external variables A-3 list-ref names 3-5, 8-4 move 2-7, 8-3 new proc 1-4, 3-5, 4-2, 8-4 pl1 2-4, 2-5, 2-8, 2-9, 2-10, 3-6, 5-6, 6-1, 8-5 pl1 abs 7-6, 8-5 print 2-4, 4-11, 5-6, 7-4, 7-5, 7-6, 8-4, 8-5, 8-6, 8-7 print attach table 4-11, 8-7 print-search-paths 3-7, 8-4, 8-8 print-search-rules 3-2, 8-4, 8-8 probe- 2-7, 5-1, 5-5, 5-6, 5-8, 5-7, 8-6 profile 6-1, 6-2, 6-3, 8-6, B-9 program interrupt 2-7, 8-8, D-2 progress 2-5, 8-6, 8-10 release 2-7, 5-3, 5-5, 5-8, 8-8, B-5 rename 2-7, 8-3 resolve linkage error 3-7, 8-8 revert output 4-11 set search paths 3-7, 8-4, 8-8 set-search-rules 3-3, 8-4, 8-8 start 2-5~ 2-7, 3-7, 5-3, 5-5, 8-8 status 8-3 stop cobol run 4-11, 8-6 termTnaloutput 4-11 terminate 3-5, 8-4, A-2 terminate refname 3-5 terminate-segno 3-5 terminate-single refname 3-5 trace 5-1, 5-8,-8-6 trace stack 5-5, 8-6 unlink 2-11, 8-3 where search paths 3-7, 8-5, 8-8 who 7-4, 8-10 4-12 1-9 C cards bulk data input 4-12 control 4-12, 7-3 conversion 4-12 input 4-12, 7-3 remote job entry 4-12, 7-3 change_wdir command change_wdir subroutine character string D-5 B-5, B-6 close file command closing switch 3-2 3-2, 7-5, A-5, B-2, cleanup handler cobol command 3-2, 8-4 4-10, 8-6 4-4, 4-5, 4-9, 4-10 8-5 COBOL programming language 2-1, 2-6, 2-7, 2-8, 4-2, 4-4, 4-7, 4-10, 4-11, 5-1, 8-5, 8-10 cobol abs command 7-6. 8-5. 8-9 command level 2-6, 3-6, 4-10, 5-1, 5-3, 5-5, 5-8, 6-1, D-7 line 2-3, 6-2, 7-6, 8-4, 8-7, 8-8 name B-5 processor 5-3, 5-5, 5-7, B-5 comment mode request see Edm editor requests compare_ascii command 2-7, 8-2 compiler 1-10, 1-12, 2-3, 2-4, 2-5, 2-6, 2-10, 6-1, 8-5, 8-6, 8-10, B-1, B-2, B-4, B-3 commands add search paths 3-7 add"-search-rules 3-3, 8-4 apl- 8-5 archive 2-8, 2-8, 8-2, 8-6 basic 4-10 bind 2-11, 8-5 change wdir 3-2, 8-4 close file 4-10, 8-6 cobol- 8-5 cobol abs 7-6, 8-5, 8-9 compare ascii 2-7, 8-2 compose- 8-2, 8-5, C-2 copy 2-7, 8-2 copy cards 4-11, 4-12, 8-6 copy-file 4-11, 8-2, 8-6 create data segment 8-5, A-4 delete-search paths 8-7 delete-search paths 3-7, 8-4 delete-search-rules 3-3, 8-4, 8-7 discard output 6-2, 8-7 display-pl1io error 4-11, 8-6, 8-7 edm 8-~, D-1~ D-8 enter abs request 7-1, 7-3, 7-4, 7-6,-8-10 exec com 2-8, 7-5, 7-6, 8-7 fast- 8-5, 8-7 file output 4-11, 8-7 format cobol source 2-7, 8-5 fortran 7-3~ 8-5 fortran abs 7-6, 8-5, 8-10 gcos 8=8, C-1 gcos tss C-1 general ready 2-8, 8-6, 8-8 get system search rules 8-4, 8-8 indent 2-1, 8-2initiate 3-2, 3-5, 8-4 io call 4-2; 4-4; 4-5; 4-10; 8-7 compiling 1-1, 2-6, 3-5 compose command com err 8-2, 8-5, C-2 B-5 com err subroutine B-5, B-6 constant A-5, A-6, B-4, 2-5, B-3 control arguments -absentee 7-4 -all 1-1 -arguments 7-6 -brief 1-1 -brief table 2-5 -first- 6-3 -link 2-11 -list 2-3, 6-3, 7-3 -long profile 6-3 -map -2-3, 2-4, 2-5, B-2 -notify 7-4, 7-6 -optimize B-2 -profile 6-1, 6-2 -sort 6-3 -table 2-4, 3-6, 5-6, 5-8 control cards 4-12, 7-3 control characters controlled security C-1 i-2 B-3 1-1, 1-12, 2-1, AG90-03 controlled sharing 1-1, 1-4, 1-5, 1-10,1-12,2-11, B-3 dollar sign copy command dynamic linking 1-1, 1-10, 2-5, 3-1, 3-5, 3-7, A-4 usage 3-5 2-7, 8-2 copy_cards command 4-11, 4-12, 8-6 copy_file command 4-11, 8-2, 8-6 E core see memory core image editing 1-10, 2-2, 2-5, 8-2, B-3, C-2, D-2 1-2 create data_segment command A-=-5 subroutine cu_$arg_count edm command B-4 B-4 B-5 cu_$arg_ptr subroutine cv dec A-4, B-4 cu_$arg_count subroutine cu_$arg_ptr editor 2-2, 2-8, 3-6, 4-4, 7-4, B-3, B-5, D-1 Edm 2-2, 8-2, B-1, D-1 Emacs 2-2, 8-2 Qedx 2-2, 2-8, 2-9, 2-10, 3-1, 3-6, 7-4, 8-2 Ted 2-2, 8-2 8-5, A-4, create data segment subroutine A-=-5 cu subroutine B-5 B-4, B-10 D daemon 3-2, A-4, B-4 1-4, 8-3, 8-5, 8-9 data base manager subsystem C-1 debugging 1-1, 2-2, 2-3, 2-4, 2-6, 3-5, 5-1, 5-5, 5-6, 5-8, 6-1, 7-1, 8-6 debugging tools see probe 8-2, B-1, D-1, D-8 Edm editor 2-2, 8-2, B-1, D-1 requests D-1, D-2 backup D-3 bottom D-4 comment mode D-3 delete D-4 find D-5 insert D-5 kill D-6 locate D-6 mode change D-4 next D-6 print D-6 print current line number D-3 quit D-7 retype D-7 substitute D-7 top D-8 verbose D-8 write D-8 Emacs editor enter abs request command 7-4,-7-6, 8-10 default 2-3, 4-2, 4-4, 4-5, 4-9, 5-6, 8-4, 8-7, 8-8, A-2, B-2 definition section 2-2, 8-2 entry point 1-10, 3-2, 3-6, 5-6, A-5, B-4, B-6 2-5 delete request see Edm editor requests entryname A-6 delete search paths command 8-=-7 - 3-7, 8-4, delete search rules command 8-=-7 3-3, 8-4, 2-2, 2-3, 2-6, 8-5, 8-8, error handLing 1-4, 1-10, 2-5, 2-6, 2-7, 3-5, 3-6, 3-7, 4-5, 4-11, 5-5, 5-6, 5-7, 8-6, 8-8, A-5, A-6, B-2, B-3, B-4, B-5, D-4, D-5, D-8 error_output switch designing 4-5, 4-11 2-1 detaching switch execution 1-2, 1-4, 1-10, 2-1, 2-3, 2-5, 2-6, 4-12, 5-2, 5-3, 5-6, 6-3, 7-1, 7-3, 8-5, 8-6, 8-7, 8-8, A-4 4-2, 4-5, 4-10 device independence 4-1 direct inter segment references A-3 execution point 2-8, 7-5, 7-6, 8-7 external references A-4 discard_output command external static variables 6-2, 8-7 display pl1io error command 8-7 divide builtin function exec com command 1-4 directory 2-3, 2-4, 2-11, 3-2, 3-3, 7-1, 8-3, 8-4, 8-7, 8-8, 8-9, A-6, B-4, B-5 home 3-2, 7-1 working 2-3, 2-4, 2-11, 3-2, 3-3, 4-8, 8-4, 8-7, 8-8 expand_pathname_ subroutine A-6, B-5 1-10, 2-11, 3-1, B-4 4-11, 8-6, F B-7 fast command documenting 7-i, 7-3, 8-5, 8-7 2-1, 2-7 fast subsystem i-3 8-5, 8-7, C-1 AG90-03 1-10, 2-5, 2-11, 3-7, 5-6, 8-6, 8-8, B-7 linkage 1-10, 1-11, 2-11, 3-7, 8-6, 8-8 page 2-5, B-7 fault file I I/O see input/output processing 2-2, 2-9, 3-1, 3-3, 4-1, 4-4, 4-8, 4-9, 4-11, 7-1, 7-3, 7-4, 8-2, 8-3, 8-5, 8-7, 8-10, B-5, I/O module 4-1, 4-2, 8-6 vfile 4-9, 4-10, 4-11 4-1, 4-2, 4-4, 4-5, 4-9, 4-11, 7-1, 8-2, 8- 3, 8-5, 8-6, 8-7, 8-9, B-4, D-4 C-2 sequential 4-4 stream 4-1, 4-4, 4-9 I/O switch 4-11, 8-7 file_output command find request see Edm editor requests B-9 index builtin function info segment 2-7, 8-5 format cobol source command 2-8, 3-7, 8-9 3-2, 3-5, 8-4 initiate command 7-3, 8-5 fortran command 2-7, 8-2 indent command 1-1, 2-1, 2-2, 2-8, 4-2, 4-4, 4-7, 4-10, 5-1, 8-5, 8-6, 8-10, A-1 1-7, initiating segments A=6 3~5, FORTRAN programming language 7-6, 8-5, 8-10 fortran abs command G gates 8-4 gcos command 8-8, C-1 8-8, C-1, C-2 gcos subsystem gcos tss command C-1 general_ready command 2-8, 8-6, 8-8 - 8-8 - insert request see Edm editor requests 8-4, get system search rules command - interactive B-6 get_temp_segments 1-1, 1-4, 2-4, 5-8, 7-1, 8-5, B-1 get_temp_segments_ subroutine graphics subsystem 1-1, 2-2, 2-8, 2-9, 2-10, 4-5, 4-8, 4-9, 4-10, 4-11, 4-12, 7-1, 8-2, 8-5, 8-7, 8-8, B-2, B-3, B-4,. B-5 modules 4-1, 4-2, 4-5, 8-6 switches 4-1, 4-2, 4-4, 4-5, 4-9, 4-11, 7-1, 8-2, 8-3, 8-5, 8-6, 8-7, 8-9, B-4, D-4 attaching 4-2, 4-9, 4-10 closing 4-4, 4-5, 4-9, 4-10 detaching 4-2, 4-5, 4-10 error ouput 4-5 error-output 4-11 opening 4-2, 4-4, 4-9, 4-10 user input 4-5, 4-11 user-io 4-5, 4-11 user=output 4-5, ~-11, 8-5, B-7 input/output processing B-6 A-2 internal automatic variables C-2 internal static variables interpreted language A-2, B-3 2-3, 8-5 H inter segment link hardware hcs 1-5, 1-9, 2-3, 4-1, B-2, B-3 subroutine subroutine iox - subroutine B-8 hcs $initiate subroutine - A-6, B-6, B-10 3-1, 3-2, 4-2, 4-4, 4-5, 4-12, iox - $get line subroutine - hcs $initiate count subroutine 3-2, iox $user input iox $user - input - - A-6, B-6-;- B-7 hcs_$make_entry subroutine 3-2 io call command hcs_$make_ptr subroutine 3-2, A-5 hcs_$make_seg subroutine 3-2 hcs $terminate noname subroutine - B-10 B-4, B-7 3-1, 3-2, B-4 A-6 hcs_$initiate ioa 2-11 - B-8 B-8 subroutine B-8 4-2, 4-4, 4-5, 4-10 J A-6, JCL see job control language help request see probe requests higher level language home directory job control language 1-1, 1-7, 4-2 2-3, 2-6 3-2, 7-1 i-4 AG90-03 making a segment known 8-4, B-5 K kill request see Edm editor requests MDBM see data base manager subsystem memory 1-1, 1-2, 1-7, 1-10, 7-5, 8-6, 8-8, A-1, B-1, B-3, B-6, C-1 L language 1-1, 2-1, 2-2, 2-3, 2-5, 2-6, 3-7, 4-2, 8-6, A-1, B-2, B-3, C-1 higher level 2-3, 2-6 interpreted 2-3, 8-5 machine 2-3 programming 2-2, C-1 ALM 1-10, 2-1, 2-2, A-4 APL 2-1, 2-3, 8-5, A-1 BASIC 2-1, 8-5, C-1 COBOL 2-1, 2-6, 2-7, 2-8, 4-2, 4-4,4-7,4-10,4-11,5-1, 8-5, 8-10 FORTRAN 1-1, 2-1, 2-2, 2-8, 4-2, 4-4, 4-7, 4-10, 5-1, 8-5, 8-6, 8-10, A-1 PL/I 1-1, 2-1, 2-2, 2-5, 2-7, 2-8, 2-9, 3-6, 4-2, 4-4, 4-10, 4-11,5-1,6-2,8-5,8-6, 8-10, A-1, A-2, B-1, B-2, B-3, B-4, B-5, B-6, C-2 source 2-5, 6-3, 8-6 library 1-10, 3-2, 3-7, A-1, A-6, B-2, B-3, B-4, B-5 merge subsystem C-2 mode change request see Edm editor requests move command 2-7, 8-3 MRPG see report program generator subsystem N named offsets A-4 naming conventions new_proc command next request see Edm editor requests null string A-5 o 2-11, 3-3, 8-2, 8-3 object map linkage editor see loading 2-5 object name linkage fault 8-6, 8-8 2-3 1-4, 3-5, 4-2, 8-4 link intersegment 2-11 storage system 2-11, 8-2, 8-3 link command 1-5, 2-7, 3-1, 2-4 object program see object segment 1-10, 1-11, 2-11, 3-7, LINUS see logical inquiry and update subsystem object segment 2-3, 2-5, 2-6, 2-7, 2-11, 3-6, 5-6, 8-5, A-4, B-3 section definition 2-5 linkage 2-5 object map 2-5 static 2-5, A-2 symbol 2-5 text 2-5 list command online linkage section 2-5 linking 1-10, 2-5, 2-11, 3-1, 3-3, 3-6, 3-7, 8-2, 8-3, 8-6, 8-8, B-4 3-3, 8-3 listing segment B-2 2-3, 2-4, 6-3, 7-3, list external variables command list ref names command 2-4, 2-8, 7-1, 8-1, 8-6, A-1 opening modes opening switch A-3 4-2, 4-4, 4-9, 4-10 options (constant) B-3 options (variable) B-2 3-5, 8-4 list requests request see probe requests overlay defining load module see loading loading 4-4 B-3 p 1-10, 2-5 page locate request see Edm editor requests 1-9, 2-5, 8-6, 8-10, B-7 page fault logical inquiry and update subsystem C-2 2-5, B-7 pathname 3-6, 8-4, A-6, B-5, D-1, D-8 absolute A-6, B-5 relative A-6, B-5 pathname_ M B-6 pathname_ subroutine machine language B-6 2-3 i-5 AG90-03 performance measurement tools see profile facility Q PL/I programming language 1-1, 2-1, 2-2, 2-5, 2-7, 2-8, 2-9, 3-6, 4-2, 4-4, 4-10, 4-11, 5-1, 6-2, 8-2, 8-5, 8-6, 8-10, A-1, A-2, B-1, B-2, B-3, B-4, B-5, B-6, C-2 pl1 command 2-4, 2-5, 2-8, 2-9, 2-10, 3-6, 5-6, 6-1, 8-5 pl1 abs command Qedx editor 2-2, 2-8, 2-9, 2-10, 3-1, 3-6, 7-4, 8-2 quit request see Edm editor requests see probe requests QUIT signal D-2 2-5, 2-6, 5-2, 5-5, B-5, 7-6, 8-5 position request see probe requests R precision of variables B-2, B-3 ready message 8-6, 8-8 print command 2-4, 4-11, 5-5, 5-6, 7-4, 7-5, 7-6, 8-4, 8-5, 8-6, 8-7 2-5, 2-6, 2-8, 3-6, 6-3, record 1-5, 4-1, 4-11, 4-12, 5-1, 6- 3, 8-2, B-2, B-5, C-2 print current line number request see Edm editor requests recursive procedure print request see Edm editor requests reference name B-6 2-6 3-1, 3-2, 3-3, A-6, print_attach table command 4-11, 8-7 reference to named offsets print search paths command "8"-8 - 3-7, 8-4, references external print search rules command "8"-8 - 3-2, 8-4, probe command 8-6 release command 8-8, B-5 remote job entry rename command processor 1-2, 1-10, 1-12, 5-1, 5-3, 5-5, B-5 profile facility programming C-1 2-7, 5-3, 5-5, 5-8, B-6 release temp segments subroutine B-To - process 1-12, 3-2, 3-5, 4-5, 5-1, 7-1, 8-1, 8-4, 8-6, 8-7, 8-8, 8-9, B-2, B-3 profile command B-9 A-6, B-5 release_temp segments 2-7, 5-1, 5-5, 5-6, 5-8, production run 1-10, 2-11, 3-1, A-4 relative pathname probe 2-7, 5-1, 5-5, 5-6, 5-8 requests help 5-8 list requests 5-8 position 5-7 quit 5-8 source 5-7 stack 5-7 symbol 5-7 value 5-7 A-4 B-6, 4-12, 7-3 2-7, 8-3 report program generator subsystem C-2 resolve linkage error command 8-"8" - 3-7, restarting suspended programs 3-7, 5-5 2-7, retype request see Edm editor requests 7-1 reverse builtin function 6-1, 6-2, 6-3, 8-6, revert_output command 6-1, 6-3 ring structure B-9 4-11 B-4 1-12, 2-1, 2-2, 7-1, B-1, s programming environment 1-2, 1-4, 1-12, 2-1, 2-8, 4-8, 5-1, 5-5, 7-1, 8-8, C-1 search builtin function programming language search paths 2-2, C-1 program_interrup command program_interrupt command progress command pure procedure 8-8 B-10 8-4, 8-7, 8-8 search rules 3-1, 3-2, 3-3, 3-7, 8-4, 8-7, 8-8 2-7, D-2 segment absin 7-1, 7-3, 7-5, 7-6 absout 7-1, 7-5, 7-6 archive 2-8, 8-2, 8-6 bound 2-11 info 2-8, 3-7, 8-9 listing 2-3, 2-4, 6-3, 7-3, B-2 number 1-7, 2-7, 3-3, B-6 2-5, 8-6, 8-10 2-6, B-3 i-6 AG90-03 segment (cont) object 2-3, 2-5, 2-6, 2-7, 2-11, 3-6, 5-6, 8-5, A-4, B-3 size of B-3 source 2-2, 2-3, 2-7, 8-2, 8-5, B-2, C-2 stack 5-1 structured data substr builtin function B-3 4-4 sequential file set search- paths command 3-7, 8-4, set search rules command 3-3, 8-4, - 8-8 8-8 substitute request see Edm editor requests 1-7, 2-7, 3-3, B-6 segment number segments temporary A-5 - 1-10, 1-11, 2-11, 3-5, snapping a link subroutines (cont) hcs $make seg 3-2 hcs-$terminate noname A-6, B-10 ioa- B-4, B-7iox 4-2, 4-4, 4-5, 4-12, B-8 iox=$get_line B-8 A-4 subsystem data base manager C-1 fast 8-5, 8-7, C-1 gcos 8-8, C-1, C-2 graphics C-2 logical inquiry and update C-2 merge C-2 report program generator C-2 sort C-2 wordpro C-2 2-2, 2-3, 2-4, 6-3, 7-1, 7-5 suffix C-2 sort subsystem symbol request see probe requests 2-5, 6-3, 8-6 source language symbol section source program see source segment symbol table source request see probe requests system 2-5 2-4, 2-5, 5-6, 5-7 1-1, 1-12, 2-1, 2-11, 3-2, 3-3, 4-1, 4-4, 5-5, 5-7, 7-4, 8-2, 8-6, 8-7, 8-8, 8-1, A-5, B-1, B-3, B-4, C-1 2-2, 2-3, 2-7, 8-2, source segment B-9 B-2, C-2 5-1, 5-2, 5-3, 5-5, 5-7, 8-6, B-5 frame 5-2, 5-5, B-5 stack T Ted editor stack request see probe requests temporary segment 2-6 standard format 2-5, 2-7, 3-7, 5-3, 5-5, start command B-5 terminal session 1-1, 2-8, 2-9, 8-5 using for I/O 2-2, 2-6, 2-8, 2-9, 4-5, 7-1, 8-7, 8-8, B-4, B-5 8-8 start_up.ec 2-2, 8-2 2-8, 7-1 terminal_output command static section 2-5, A-2 terminate command static storage 5-5 terminate refname command status command 8-3 terminate_segno command stop_cobol_run command 4-11, 8-6 1-7, 1-12, 2-1, 2-11, 4-8, 5-5, 8-3, 8-6, 8-7, 8-9, A-1, A-2, B-1, B-2, B-3, B-5, C-1 automatic 5-5 static 5-5 stream file 2-11, 8-2, 8-3 4-1, 4-4, 4-9 structured data segment terminating segments 3-5 3-5 text section A-5 3-5 1-7, 3-3, A-2, A-6, B-5 2-5 top request see Edm editor requests trace command 5-1, 5-8, 8-6 5-5, 8-6 trace stack command subroutines change wdir 3-2 com err A=5, A-6, B~4, B-5, B-6 create data segment A-4 cu B=4 cv-dec B-4, B-10 expand-pathname A-6, B-5 hcs 3-1, 3-2,-B-4 hcs-$initiate 3-1, 3-2, B-6, B-10 hcs-$initiate count 3-2, A-6, B-6, - B-7 3-5, 8-4, A-2 terminate_single_refname command storage storage system link 4-11 u unlink command 2-11, 8-3 user_input switch user io switch - 4-5, 4-11 user output switch -B-7 hcs $make entry 3-2 hcs=$make=ptr 3-2, A-5 i-7 4-5, 4-11 4-5, 4-11, 8-5, AG90-03 v value request see probe requests variables alignment B-2 external static A-3, B-4 internal automatic A-2 internal static A-2, B-3 precision B-2, B-3, B-7 verbose request see Edm editor requests verify builtin function vfile I/O module B-10 4-9, 4-10, 4-11 virtual memory 1-4, 1-5, 1-7, 1-10, B-1, B-3, B-6, C-1 w where search paths command "8-8 who command word 3-7, 8-5, 7-4 1-9 word pro subsystem C-2 working directory 2-3, 2-4, 2-11, 3-2, 3-3, 8-4, 8-7, 8-8 write request see Edm editor requests writing 2-1, A-1, B-2 i-8 AG90-03 HONEYWELL INFORMATION SYSTEMS Technical Publications Remarks Form TITLE LEVEL 68 INTRODUCTION TO PROGRAMMING ON MULTICS ORDER No·1 DATED I ERRORS IN PUBLICATION SUGGESTIONS FOR IMPROVEMENT TO PUBLICATION r\ y Your comments will be investigated by appropriate technical personnel ::~n~:~~~:~~ ~~::~:~, ~~ ~::U~~~:ir::C~~:i~:da~~~~~~~h:~I~ ~:re. 0 FROM: NAME ------------------------------------------TITLE __________________________ ._____________ COMPANY - - - - - - - - ADDRESS _________________________________________ DATE AG90-03 JULY 1981 PLEASE FOLD AND TAPENOTE: U. S. Postal Service will not deliver stapled forms 111111 BUSINESS REPLY MAIL FIRST CLASS PERMIT NO. 39531 WALTHAM, MA02154 POSTAGE WILL BE PAID BY ADDRESSEE HONEYWELL INFORMATION SYSTEMS 200 SMITH STREET WALTHAM, MA 02154 ATTN: PUBLICATIONS, MS486 Honeywell NO POSTAGE NECESSARY IF MAILED IN THE UNITED STATES Honeywell Honeywell Information Systems In the U.S.A.: 200 Smith Street, MS 486, WaHham, Massachusetts 02154 In Canada: 155 Gordon Baker Road, Willowdale, Ontario M2H 3N7 In the U.K.: Great West. Road, Brentford, Middlesex TW8 9DH In Australia: 124 Walker Street, North Sydney, N.S.W. 2060 In Mexico: Avenida Nuevo Leon 250, Mexico 11, D.F. 32397, 5C981, Printed in U.S.A. AG90-03
Source Exif Data:
File Type : PDF File Type Extension : pdf MIME Type : application/pdf PDF Version : 1.3 Linearized : No XMP Toolkit : Adobe XMP Core 4.2.1-c043 52.372728, 2009/01/18-15:56:37 Create Date : 2003:03:24 17:39:48-08:00 Modify Date : 2014:11:12 18:38:32-08:00 Metadata Date : 2014:11:12 18:38:32-08:00 Producer : Adobe Acrobat 9.55 Paper Capture Plug-in Format : application/pdf Document ID : uuid:c48241cc-ecb6-6448-9115-af07e9e9c5a0 Instance ID : uuid:ffd50d05-8164-554a-aab3-badfe1f97b0c Page Layout : SinglePage Page Mode : UseOutlines Page Count : 140EXIF Metadata provided by EXIF.tools