/**************************************************************************** * * * Copyright (c) 1987 * * by DIGITAL Equipment Corporation, Maynard, Mass. * * * * This software is furnished under a license and may be used and copied * * only in accordance with the terms of such license and with the * * inclusion of the above copyright notice. This software or any other * * copies thereof may not be provided or otherwise made available to any * * other person. No title to and ownership of the software is hereby * * transferred. * * * * The information in this software is subject to change without notice * * and should not be construed as a commitment by DIGITAL Equipment * * Corporation. * * * * DIGITAL assumes no responsibility for the use or reliability of its * * software on equipment which is not supplied by DIGITAL. * * * ****************************************************************************/ /* **++ ** FACILITY: ** ** PLI Sample Program - Phone Book Database ** ** ABSTRACT: ** ** This program maintains a phone book for the user. It allows him ** to add, modify and delete entries from his book. He can also ** lookup names and dates. ** ** AUTHORS: ** ** Karen Michaels ** ** ** CREATION DATE: 16-Feb-1987 ** ** NOTES: ** ** 1. Error checking should be added. A check is never made that the data ** that we read in is correct. ** ** 2. This program assumes that dates are in the form dd-mmm-yyyy. It ** distinguishes 01-May from 1-May. This should probably be fixed. ** ** 3. All input is upcased when it is read in. This is to prevent key lookups ** from failing due to different cases. ** ** 4. When the arrow keys are hit when an entry is being modified or added ** strange things occur. ** ** 5. When displaying all occurences in a given month or for a given date there ** may be a problem if more than a screen full of names must be displayed. ** ** MODIFICATION HISTORY: **-- **/ %include 'constants.pli'; %include 'entry.pli'; /* * Display entry points. */ dcl display_menu entry; dcl select_operation entry returns(fixed binary(31)); dcl display_entry_template entry; dcl display_record entry(pointer value, bit(1) aligned value); dcl display_name_record entry(pointer value); dcl enter_record entry(pointer value) returns(bit(1) aligned value); dcl write_inquiry_message entry(character(*) varying,character(*) varying, fixed binary(31) value) returns(fixed binary(31)); dcl write_info_message entry(character(*) varying); dcl erase_info_message entry; dcl write_title_message entry(character(*) varying); dcl read_a_key entry returns(fixed binary(31)); dcl get_a_name entry(character(*) varying) returns(character(NAME_SIZE)); dcl get_a_month_record entry(character(MONTH_SIZE), bit(1) aligned value, bit(1) aligned value) returns(pointer); dcl get_a_date_record entry(character(DATE_SIZE), bit(1) aligned value, bit(1) aligned value) returns(pointer); dcl write_date_line entry (pointer value, bit(1) aligned value); /* * Database entry points. */ dcl get_a_record entry(character(NAME_SIZE), bit(1) aligned value) returns(pointer); dcl delete_a_record entry(character(NAME_SIZE)) returns(bit(1) aligned); dcl write_a_record entry(pointer value); dcl get_a_month entry returns(character(MONTH_SIZE)); dcl get_a_date entry returns(character(DATE_SIZE)); /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This is the main driver routine for this program. It does the ** initialization. It then determines the user action and invoke ** the appropriate routine to perform the action. ** ** FORMAL PARAMETERS: ** ** none ** ** IMPLICIT INPUTS: ** ** none ** ** IMPLICIT OUTPUTS: ** ** none ** ** RETURN VALUE: ** ** none ** ** SIDE EFFECTS: ** ** none ** **-- **/ phone: procedure options(main, ident('V1.0')); dcl operation fixed binary(31); /* The selected operation */ on finish call finish; %include 'operations.pli'; /* * Initialize */ call initialize; /* * Read and process command until exit is encountered. */ call display_menu; operation = select_operation(); do while(operation ^= EXIT_KEY); /* * Call the appropriate procedure to process the operation. */ select (operation); when (lookup_key) call lookup_entry; when (add_key) call add_entry; when (modify_key) call modify_entry; when (delete_key) call delete_entry; when (month_key) call month_query; when (date_key) call date_query; otherwise ; end; call display_menu; operation = select_operation(); end; /* * Cleanup */ call finish; end phone; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine does all the necessary initialization for this program. ** ** FORMAL PARAMETERS: ** ** none ** ** IMPLICIT INPUTS: ** ** none ** ** IMPLICIT OUTPUTS: ** ** none ** ** RETURN VALUE: ** ** none ** ** SIDE EFFECTS: ** ** none ** **-- **/ initialize: procedure; dcl initialize_screen entry; dcl open_phonebook entry; call initialize_screen; call open_phonebook; end initialize; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine does all the necessary cleanup before the program ** terminates. ** ** FORMAL PARAMETERS: ** ** none ** ** IMPLICIT INPUTS: ** ** none ** ** IMPLICIT OUTPUTS: ** ** none ** ** RETURN VALUE: ** ** none ** ** SIDE EFFECTS: ** ** none ** **-- **/ finish: procedure; dcl close_phonebook entry; dcl clear_screen entry; call close_phonebook; call clear_screen; end finish; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine gets up an entry in the database and displays it to the ** user. ** ** FORMAL PARAMETERS: ** ** none ** ** IMPLICIT INPUTS: ** ** none ** ** IMPLICIT OUTPUTS: ** ** none ** ** RETURN VALUE: ** ** none ** ** SIDE EFFECTS: ** ** none ** **-- **/ lookup_entry: procedure; dcl name character(NAME_SIZE); /* Name to lookup */ dcl record_ptr pointer init(null()); /* A pointer to the current record */ dcl key fixed binary(31); /* The key read in */ dcl done bit(1) aligned init(false); /* True when user wishes to stop seeing entries */ dcl i fixed binary(31); %include 'keys.pli'; /* * Get the name to lookup and look for it in the database. */ do while (record_ptr = null()); name = get_a_name('Enter Name to Lookup (Last First)'); record_ptr = get_a_record(name,true); if record_ptr = null() then /* * Warn the user that the record was not found and see if he wants to * try again. */ if write_inquiry_message(trim(name)||' was not found in Phone Book', 'Hit to try again or any other key to continue',ENTER_KEY) ^= ENTER_KEY then return; end; /* * Display all the matching entries. */ do while (record_ptr ^= null() & ^done); call display_entry_template; call display_record(record_ptr,false); done = (write_inquiry_message('', 'Hit to see next entry or any other key to return to main menu', ENTER_KEY) ^= ENTER_KEY); if ^done then record_ptr = get_a_record(name,false); end; end lookup_entry; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine adds a new entry to the database. ** ** FORMAL PARAMETERS: ** ** none ** ** IMPLICIT INPUTS: ** ** none ** ** IMPLICIT OUTPUTS: ** ** none ** ** RETURN VALUE: ** ** none ** ** SIDE EFFECTS: ** ** none ** **-- **/ add_entry: procedure; dcl name character(NAME_SIZE); /* Name to add */ dcl record_ptr pointer init(null());/* A pointer to the current record */ dcl key fixed binary(31); /* The key read in */ /* * Allocate a new record and clear its contents. */ allocate entry set (record_ptr); record_ptr->entry_string = ''; /* * Display the template and read in the fields. */ call display_entry_template; call display_record(record_ptr,true); if enter_record(record_ptr) then call write_a_record(record_ptr); end add_entry; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine modifies a specified entry in the database. ** ** FORMAL PARAMETERS: ** ** none ** ** IMPLICIT INPUTS: ** ** none ** ** IMPLICIT OUTPUTS: ** ** none ** ** RETURN VALUE: ** ** none ** ** SIDE EFFECTS: ** ** none ** **-- **/ modify_entry: procedure; dcl name character(NAME_SIZE); /* Name to modify */ dcl old_name character(NAME_SIZE); /* Name before modification */ dcl record_ptr pointer init(null()); /* A pointer to the current record */ dcl key fixed binary(31); /* The key read in */ dcl status bit(1) aligned; /* The status of the delete operation */ dcl i fixed binary(31); %include 'keys.pli'; do while (record_ptr = null()); name = get_a_name('Enter Name to Modify (Last First)'); record_ptr = get_a_record(name,true); if record_ptr = null() then /* * Warn the user that the record was not found and see if he wants to * try again. */ if write_inquiry_message(trim(name)||' was not found in Phone Book', 'Hit to try again or any other key to continue', ENTER_KEY) ^= ENTER_KEY then return; end; /* * Modify all the matching entries. */ do while (record_ptr ^= null()); /* * Display the record and let the user create a new one. * Save the old name in case he changes it. */ old_name = record_ptr->full_name; call display_entry_template; call display_record(record_ptr,true); if enter_record(record_ptr) then do; /* * See if the name has been modified. */ if old_name ^= record_ptr->full_name then status = delete_a_record(old_name); /* * Write the new record. */ call write_a_record(record_ptr); /* * Read the next record. */ record_ptr = get_a_record(name,false); end; else record_ptr = null(); end; end modify_entry; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine deletes a specified entry from the database. ** ** FORMAL PARAMETERS: ** ** none ** ** IMPLICIT INPUTS: ** ** none ** ** IMPLICIT OUTPUTS: ** ** none ** ** RETURN VALUE: ** ** none ** ** SIDE EFFECTS: ** ** none ** **-- **/ delete_entry: procedure; dcl name character(NAME_SIZE); /* Name to delete */ dcl record_ptr pointer init(null()); /* A pointer to the current record */ dcl key fixed binary(31); /* The key read in */ dcl done bit(1) aligned init(false); /* True when user wishes to stop deleting entries */ dcl status bit(1) aligned; /* The status of the delete operation */ dcl i fixed binary(31); %include 'keys.pli'; /* * Get the name to delete and look for it in the database. */ do while (record_ptr = null()); name = get_a_name('Enter Name to Delete (Last First)'); record_ptr = get_a_record(name,true); if record_ptr = null() then /* * Warn the user that the record was not found and see if he wants to * try again. */ if write_inquiry_message(trim(name)||' was not found in Phone Book', 'Hit to try again or any other key to continue',ENTER_KEY) ^= ENTER_KEY then return; end; /* * Display all the matching entries. */ do while (record_ptr ^= null() & ^done); /* * Display the next name and see what action should be taken. */ call display_name_record(record_ptr); key = write_inquiry_message('Hit to delete, to save or', 'any other key to return to main menu',KP0_KEY); /* * Delete the record. */ if key = ENTER_KEY then status = delete_a_record(record_ptr->full_name); done = (key = OTHER_KEY); if ^done then record_ptr = get_a_record(name,false); end; end delete_entry; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine displays all entries whose birthday or anniversary occur ** in the specified month. ** ** FORMAL PARAMETERS: ** ** none ** ** IMPLICIT INPUTS: ** ** none ** ** IMPLICIT OUTPUTS: ** ** none ** ** RETURN VALUE: ** ** none ** ** SIDE EFFECTS: ** ** none ** **-- **/ month_query: procedure; dcl month character(MONTH_SIZE); /* The month when an event occurs */ dcl record_ptr pointer init(null()); /* A pointer to the current record */ dcl key fixed binary(31); /* The key read in */ dcl done bit(1) aligned init(false); /* True when user wishes to stop seeing entries */ dcl try_bday bit(1) aligned; /* True if currently trying birthdays */ %include 'keys.pli'; /* * Get the month to lookup and look for it in the database. */ do while (record_ptr = null()); month = get_a_month(); /* * Try birthdays first. */ try_bday = true; record_ptr = get_a_month_record(month,true,try_bday); if record_ptr = null() then do; /* * Try Anniversaries. */ try_bday = false; record_ptr = get_a_month_record(month,true,try_bday); if record_ptr = null() then /* * Warn the user that the record was not found and see if he wants * to try again. */ if write_inquiry_message('No Events occurring in '||month|| ' were found in Phone Book', 'Hit to try again or any other key to continue',ENTER_KEY) ^= ENTER_KEY then return; end; end; /* * Display all the matching entries. */ do while( ^done ); /* * Title the display. */ if try_bday then call write_title_message('Birthdays occuring in '||month); else call write_title_message('Anniversarys occuring in '||month); /* * Write all the matching entries. */ do while (record_ptr ^= null()); call write_date_line(record_ptr, try_bday); record_ptr = get_a_month_record(month,false,try_bday); end; key = write_inquiry_message('','Hit any key to continue',OTHER_KEY); /* * See if anniversarys should now be tried. */ if try_bday then do; try_bday = false; record_ptr = get_a_month_record(month,true,try_bday); if record_ptr = null() then done = true; end; else done = true; end; end month_query; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine displays all entries whose birthday or anniversary occur ** on the specified date. ** ** FORMAL PARAMETERS: ** ** none ** ** IMPLICIT INPUTS: ** ** none ** ** IMPLICIT OUTPUTS: ** ** none ** ** RETURN VALUE: ** ** none ** ** SIDE EFFECTS: ** ** none ** **-- **/ date_query: procedure; dcl 1 date like birthdate.date_union; /* The date when an event occurs */ dcl record_ptr pointer init(null()); /* A pointer to the current record */ dcl key fixed binary(31); /* The key read in */ dcl done bit(1) aligned init(false); /* True when user wishes to stop seeing entries */ dcl try_bday bit(1); /* True if currently trying birthdays */ %include 'keys.pli'; /* * Get the date to lookup and look for it in the database. */ do while (record_ptr = null()); date.date = get_a_date(); /* * Try birthdays first. */ try_bday = true; record_ptr = get_a_date_record(date.date,true,try_bday); if record_ptr = null() then do; /* * Try Anniversaries. */ try_bday = false; record_ptr = get_a_date_record(date.date,true,try_bday); if record_ptr = null() then /* * Warn the user that the record was not found and see if he wants * to try again. */ if write_inquiry_message('No Events occurring on '||date.day||'-'|| date.month||' were found in Phone Book', 'Hit to try again or any other key to continue',ENTER_KEY) ^= ENTER_KEY then return; end; end; /* * Display all the matching entries. */ do while( ^done ); /* * Title the display. */ if try_bday then call write_title_message('Birthdays occuring on '||date.day||'-'|| date.month); else call write_title_message('Anniversarys occuring on '||date.day||'-'|| date.month); /* * Write all the matching entries. */ do while (record_ptr ^= null()); call write_date_line(record_ptr, try_bday); record_ptr = get_a_date_record(date.date,false,try_bday); end; key = write_inquiry_message('','Hit any key to continue',OTHER_KEY); /* * See if anniversarys should now be tried. */ if try_bday then do; try_bday = false; record_ptr = get_a_date_record(date.date,true,try_bday); if record_ptr = null() then done = true; end; else done = true; end; end date_query;