|
|
HP C
|
Previous | Contents | Index |
Example 2-6 shows the function that deletes records. This function is called when ' d ' or ' D ' is entered in response to the menu.
Example 2-6 Utility Function: Deleting Records |
---|
/* This segment of RMSEXP.C contains the function that * * deletes a record from the file. */ void delete_employee(void) { int i; (1) do { printf("(DELETE) Enter Social Security Number "); gets(response); i = strlen(response); } while(i == 0); (2) while(i < SIZE_SSN) response[i++] = ' '; (3) rab.rab$b_krf = 0; rab.rab$l_kbf = response; rab.rab$b_ksz = SIZE_SSN; rab.rab$b_rac = RAB$C_KEY; (4) rms_status = sys$find(&rab); (5) if (rms_status != RMS$_NORMAL && rms_status != RMS$_RNF) error_exit("$FIND"); else if (rms_status == RMS$_RNF) printf("RMSEXP - specified employee does not \ exist.\n"); else { (6) rms_status = sys$delete(&rab); if (rms_status != RMS$_NORMAL) error_exit("$DELETE"); } } |
Key to Example 2-6:
Example 2-7 shows the function that displays the employee file at the terminal. This function is called from the main function when ' t ' or ' T ' is entered in response to the menu.
Example 2-7 Utility Function: Typing the File |
---|
/* This segment of RMSEXP.C contains the function that * * displays a single record at the terminal. */ void type_employees(void) { (1) int number_employees; (2) rab.rab$b_krf = 1; (3) rms_status = sys$rewind(&rab); if (rms_status != RMS$_NORMAL) error_exit("$REWIND"); (4) printf("\n\nEmployees (Sorted by Last Name)\n\n"); printf("Last Name First Name SSN \ Comments\n"); printf("--------- ---------- ---------\ --------\n\n"); (5) rab.rab$b_rac = RAB$C_SEQ; rab.rab$l_ubf = (char *) &record; rab.rab$w_usz = RECORD_SIZE; (6) for(number_employees = 0; ; number_employees++) { rms_status = sys$get(&rab); if (rms_status != RMS$_NORMAL && rms_status != RMS$_EOF) error_exit("$GET"); else if (rms_status == RMS$_EOF) break; printf("%.*s%.*s%.*s%.*s\n", SIZE_LNAME, record.last_name, SIZE_FNAME, record.first_name, SIZE_SSN, record.ssn, SIZE_COMMENTS, record.comments); } (7) if (number_employees) printf("\nTotal number of employees = %d.\n", number_employees); else printf("[Data file is empty.]\n"); } |
Key to Example 2-7:
Example 2-8 shows the function that prints the file on the printer. This function is called by the main function when ' p ' or ' P ' is entered in response to the menu.
Example 2-8 Utility Function: Printing the File |
---|
/* This segment of RMSEXP.C contains the function that * * prints the file. */ void print_employees(void) { int number_employees; FILE *fp; (1) fp = fopen("personnel.lis", "w", "rat=cr", "rfm=var", "fop=spl"); if (fp == NULL) { perror("RMSEXP - failed opening listing \ file"); exit(SS$_NORMAL); } (2) rab.rab$b_krf = 0; (3) rms_status = sys$rewind(&rab); if (rms_status != RMS$_NORMAL) error_exit("$REWIND"); (4) fprintf(fp,"\n\nEmployees (Sorted by SSN)\n\n"); fprintf(fp,"Last Name First Name SSN \ Comments\n"); fprintf(fp,"--------- ---------- ---------\ --------\n\n"); (5) rab.rab$b_rac = RAB$C_SEQ; rab.rab$l_ubf = (char *) &record; rab.rab$w_usz = RECORD_SIZE; (6) for(number_employees = 0; ; number_employees++) { rms_status = sys$get(&rab); if (rms_status != RMS$_NORMAL && rms_status != RMS$_EOF) error_exit("$GET"); else if (rms_status == RMS$_EOF) break; fprintf(fp, "%.*s%.*s%.*s%.*s", SIZE_LNAME,record.last_name, SIZE_FNAME,record.first_name, SIZE_SSN,record.ssn, SIZE_COMMENTS,record.comments); } (7) if (number_employees) fprintf(fp, "Total number of employees = %d.\n", number_employees); else fprintf(fp,"[Data file is empty.]\n"); (8) fclose(fp); printf("[Listing file\"personnel.lis\"spooled to \ SYS$PRINT.]\n"); } |
Key to Example 2-8:
Example 2-9 shows the function that updates the file. This function is called by the main function when ' u ' or ' U ' is entered in response to the menu.
Example 2-9 Utility Function: Updating the File |
---|
/* This segment of RMSEXP.C contains the function that * * updates the file. */ void update_employee(void) { int i; (1) do { printf("(UPDATE) Enter Social Security Number\ "); gets(response); i = strlen(response); } while(i == 0); (2) while(i < SIZE_SSN) response[i++] = ' '; (3) rab.rab$b_krf = 0; rab.rab$l_kbf = response; rab.rab$b_ksz = SIZE_SSN; rab.rab$b_rac = RAB$C_KEY; rab.rab$l_ubf = (char *) &record; rab.rab$w_usz = RECORD_SIZE; (4) rms_status = sys$get(&rab); if (rms_status != RMS$_NORMAL && rms_status != RMS$_RNF) error_exit("$GET"); else if (rms_status == RMS$_RNF) printf("RMSEXP - specified employee does not \ exist.\n"); (5) else { printf("Enter the new data or RETURN to leave \ data unmodified.\n\n"); printf("Last Name:"); gets(response); if (strlen(response)) strncpy(record.last_name, response, SIZE_LNAME); printf("First Name:"); gets(response); if (strlen(response)) strncpy(record.first_name, response, SIZE_FNAME); printf("Comments:"); gets(response); if (strlen(response)) strncpy(record.comments, response, SIZE_COMMENTS); (6) pad_record(); (7) rms_status = sys$update(&rab); if (rms_status != RMS$_NORMAL) error_exit("$UPDATE"); printf("[Record has been successfully \ updated.]\n"); } } |
Key to Example 2-9:
This chapter discusses the following topics:
The HP C compiler is part of the OpenVMS common language environment. This environment defines certain calling procedures and guidelines that allow you to call routines written in different languages from HP C programs, to call HP C functions from programs written in other languages, or to call prewritten system routines from HP C programs. You can call any one of the following routine types from HP C:
The terms routine, procedure, and function are used throughout this chapter. A routine is a closed, ordered set of instructions that performs one or more specific tasks. Every routine has an entry point (the routine name), and optionally an argument list. Procedures and functions are specific types of routines: a procedure is a routine that does not return a value; a function is a routine that returns a value by assigning that value to the function's identifier.
System routines are prewritten OpenVMS routines that perform common tasks, such as finding the square root of a number or allocating virtual memory. You can call any system routine from your program, provided that HP C supports the data structures required to call the routine. The system routines used most often are OpenVMS RTL routines and system services. System routines, which are discussed later in this chapter, are documented in detail in the VMS Run-Time Library Routines Volume and the HP OpenVMS System Services Reference Manual.
The HP OpenVMS Calling Standard describes the concepts used by all OpenVMS languages to invoke routines and pass data between them. It also describes the differences between the VAX and Alpha parameter-passing mechanisms. The OpenVMS calling standard specifies the following attributes:
The following sections discuss these attributes in more detail for OpenVMS VAX systems. For more detail on OpenVMS Alpha systems, see the HP OpenVMS Calling Standard.
The calling standard also defines such attributes as the calling sequence, the argument data types and descriptor formats, condition handling, and stack unwinding. These attributes are discussed in detail in the OpenVMS Programming Interfaces: Calling a System Routine.
The calling standard defines several registers and their uses, as listed in Table 3-1 for VAX systems and Table 3-2 for Alpha systems.
By definition, any called routine can use registers R2 through R11 for computation, and the AP register as a temporary register.
In the calling standard, a stack is defined as a last-in/first-out (LIFO) temporary storage area that the system allocates for every user process. The system keeps information about each routine call in the current image on the call stack. Then, each time you call a routine, the system creates a structure on this call stack, known as the call frame. The call frame for each active process contains the following data:
When a routine completes execution, the system uses the frame pointer in the call frame of the current routine to locate the frame of the previous routine. The system then removes the call frame of the current routine from the stack.
Figure 3-1 shows the call stack and several call frames for VAX processors. Function A calls function B, which calls function C. When a function reaches a return statement or when control reaches the end of the function, the system uses the frame pointer in the call frame of the current function to locate the frame of the previous function. It then removes the call frame of the current function from the stack.
Figure 3-1 The Call Stack
A function is a routine that returns a single value to the calling routine. The function value represents the value of the expression in the return statement. According to the calling standard, a function value may be returned as either an actual value or a condition value that indicates success or failure.
The HP OpenVMS Calling Standard also defines a data structure called the argument list. You use an argument list to pass information to a routine and receive results.
On OpenVMS Alpha systems, an argument list is formed using registers R16 to R21 or F16 to F21, and a collection of quadwords in memory (depending on the number and type of the arguments).
On OpenVMS VAX systems, an argument list is a collection of longwords in memory that represents a routine parameter list and possibly includes a function value. Figure 3-2 shows the structure of a typical OpenVMS VAX argument list.
Figure 3-2 Structure of an OpenVMS VAX Argument List
The first longword must be present; this longword stores the number of arguments (the argument count: n) as an unsigned integer value in the low byte of the longword with a maximum of 255 arguments. The remaining 24 bits of the first longword are reserved for use by HP and should be 0. The longwords labeled arg1 through argn are the actual parameters, which can be any of the following addresses or value:
The argument list contains the parameters that are passed to the routine. Depending on the passing mechanisms for these parameters, the forms of the arguments contained in the argument list vary. For example, if you pass three arguments, the first by value, the second by reference, and the third by descriptor, the argument list would contain the value of the first argument, the address of the second, and the address of the descriptor of the third. Figure 3-3 shows this argument list.
Figure 3-3 Example of an OpenVMS VAX Argument List
For additional information on the OpenVMS calling standard, see the HP OpenVMS Calling Standard.
Previous | Next | Contents | Index |
|