HP OpenVMS SystemsC Programming Language |
Compaq C
|
| Previous | Contents | Index |
Example 2-3 shows the function that initializes the RMS data structures. See the RMS documentation for more information about the file access block, record access block, and extended attribute block structure members.
| Example 2-3 Function Initializing RMS Data Structures |
|---|
/* This segment of RMSEXP.C contains the function that *
* initializes the RMS data structures. */
void initialize(char *fn)
{
(1) fab = cc$rms_fab; /* Initialize FAB */
fab.fab$b_bks = 4;
fab.fab$l_dna = DEFAULT_FILE_EXT;
fab.fab$b_dns = sizeof DEFAULT_FILE_EXT -1;
fab.fab$b_fac = FAB$M_DEL | FAB$M_GET |
FAB$M_PUT | FAB$M_UPD;
fab.fab$l_fna = fn;
fab.fab$b_fns = strlen(fn);
(2) fab.fab$l_fop = FAB$M_CIF;
fab.fab$w_mrs = RECORD_SIZE;
fab.fab$b_org = FAB$C_IDX;
(3) fab.fab$b_rat = FAB$M_CR;
fab.fab$b_rfm = FAB$C_FIX;
fab.fab$b_shr = FAB$M_NIL;
fab.fab$l_xab = &primary_key;
(4) rab = cc$rms_rab; /* Initialize RAB */
rab.rab$l_fab = &fab;
(5) primary_key = cc$rms_xabkey; /* Initialize Primary *
* Key XAB */
primary_key.xab$b_dtp = XAB$C_STG;
primary_key.xab$b_flg = 0;
(6) primary_key.xab$w_pos0 = (char *) &record.ssn -
(char *) &record;
primary_key.xab$b_ref = 0;
primary_key.xab$b_siz0 = SIZE_SSN;
primary_key.xab$l_nxt = &alternate_key;
primary_key.xab$l_knm = "Employee Social Security \
Number ";
(7) alternate_key = cc$rms_xabkey; /* Initialize Alternate *
* Key XAB */
alternate_key.xab$b_dtp = XAB$C_STG;
(8) alternate_key.xab$b_flg = XAB$M_DUP | XAB$M_CHG;
alternate_key.xab$w_pos0 = (char *) &record.last_name -
(char *) &record;
alternate_key.xab$b_ref = 1;
alternate_key.xab$b_siz0 = SIZE_LNAME;
(9) alternate_key.xab$l_knm = "Employee Last Name \
";
}
|
Key to Example 2-3:
Example 2-4 shows the internal functions for the program.
| Example 2-4 Internal Functions |
|---|
/* This segment of RMSEXP.C contains the functions that *
* control the data manipulation of the program. */
void open_file(void)
{
(1) rms_status = sys$create(&fab);
if (rms_status != RMS$_NORMAL &&
rms_status != RMS$_CREATED)
error_exit("$OPEN");
if (rms_status == RMS$_CREATED)
printf("[Created new data file.]\n");
(2) rms_status = sys$connect(&rab);
if (rms_status != RMS$_NORMAL)
error_exit("$CONNECT");
}
(3)void type_options(void)
{
printf("Enter one of the following:\n\n");
printf("A Add an employee.\n");
printf("D Delete an employee specified by SSN.\n");
printf("P Print employee(s) by ascending SSN on \
line printer.\n");
printf("T Type employee(s) by ascending last name \
on terminal.\n");
printf("U Update employee specified by SSN.\n\n");
printf("? Type this text.\n");
printf("^Z Exit this program.\n\n");
}
(4)void pad_record(void)
{
int i;
for(i = strlen(record.ssn); i < SIZE_SSN; i++)
record.ssn[i] = ' ';
for(i = strlen(record.last_name); i < SIZE_LNAME; i++)
record.last_name[i] = ' ';
for(i = strlen(record.first_name); i < SIZE_FNAME; i++)
record.first_name[i] = ' ';
for(i = strlen(record.comments);i < SIZE_COMMENTS; i++)
record.comments[i] = ' ';
}
/* This subroutine is the fatal error-handling routine. */
(5)void error_exit(char *operation)
{
printf("RMSEXP - file %s failed (%s)\n",
operation, filename);
exit(rms_status);
}
|
Key to Example 2-4:
Example 2-5 shows the function that adds a record to the file. This function is called when ' a ' or ' A ' is entered in response to the menu.
| Example 2-5 Utility Function: Adding Records |
|---|
/* This segment of RMSEXP.C contains the function that *
* adds a record to the file. */
void add_employee(void)
{
(1) do
{
printf("(ADD) Enter Social Security Number:");
gets(response);
}
while(strlen(response) == 0);
strncpy(record.ssn,response,SIZE_SSN);
do
{
printf("(ADD) Enter Last Name:");
gets(response);
}
while(strlen(response) == 0);
strncpy(record.last_name,response,SIZE_LNAME);
do
{
printf("(ADD) Enter First Name:");
gets(response);
}
while(strlen(response) == 0);
strncpy(record.first_name,response,SIZE_FNAME);
do
{
printf("(ADD) Enter Comments:");
gets(response);
}
while(strlen(response) == 0);
strncpy(record.comments,response,SIZE_COMMENTS);
(2) pad_record();
(3) rab.rab$b_rac = RAB$C_KEY;
rab.rab$l_rbf = (char *) &record;
rab.rab$w_rsz = RECORD_SIZE;
(4) rms_status = sys$put(&rab);
(5) if (rms_status != RMS$_NORMAL && rms_status !=
RMS$_DUP && rms_status != RMS$_OK_DUP)
error_exit("$PUT");
else
if (rms_status == RMS$_NORMAL || rms_status ==
RMS$_OK_DUP)
printf("[Record added successfully.]\n");
else
printf("RMSEXP - Existing employee with same SSN, \
not added.\n");
}
|
Key to Example 2-5:
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:
| Previous | Next | Contents | Index |