home *** CD-ROM | disk | FTP | other *** search
- # include <stdio.h>
- # include <bench.h>
- # include <proc.io>
- # include "field.h"
- # include "screen.h"
- # include "iodef.h"
- # include "sup.h"
- # include "passwd.h"
-
- extern int tot_size;
- extern int pending;
-
- /*
- * Driving ADD Mode Logic
- *
- * Start by hitting ADD KEY, and record is
- * actually added by hitting ADD KEY again
- */
- int add_mode(tab, head, lptr, table, mode)
- struct _table *tab;
- struct a_line **head, **lptr;
- int table, mode;
- {
- int stat, try = 0;
- struct a_line *tmp, *top = ANULL;
- int curidx, deltmp; /* TVE */
-
- if (!(tab->perms & PERM_ADD))
- {
- errmsg(ERR_NOADD);
- return (IOPERM);
- }
-
- /*
- * Switch on Transaction Processing for the duration
- */
- if (tab->tp)
- tran_p(tab);
-
- /*
- * In Add mode, we are adding new items on
- * to the list. With multiple records on the
- * page, we add to max depth, then scroll the
- * list up.
- */
- do
- {
- curidx = *(tab->index); /* save this for later (TVE) */
- /*
- * Work out the index to add to
- */
- for (*(tab->index) = 0, tmp = *head; tmp != ANULL; (*(tab->index))++, tmp = tmp->next)
- ;
-
- /*
- * Bottom of list, so scroll around
- */
- if (*(tab->index) == tab->maximum)
- {
- /*
- * Take copy of top record, in case
- * the user aborts the add.
- */
- if (*head != ANULL)
- {
- if (top == ANULL)
- top = (struct a_line *) alloc(tot_size);
-
- bytecpy(top->rec, (*head)->rec, tab->size);
- deltmp = (*head)->deleted; /*TVE*/
- }
-
- (*(tab->index))--;
- if (tab->maximum > 1) /* More than 1 to display */
- {
- reorder_mode(tab, head, lptr, FORWARD);
- do_page_mode(tab, head, lptr, mode);
- }
- }
- else
- new_record(tab, head, lptr);
-
- /*
- * If required, to copy the previous record's
- * values into the current record as defaults,
- * then swap these over.
- *
- * 1 : bytecpy((*lptr)->rec, tab->rec, tab->size);
- *
- * 2 : zerorec(tab->rec, tab->size);
- * if (tab->dsp_fn != (void (*)())0)
- * (*tab->dsp_fn)(UNDERLINED, CLR);
- */
- zerorec(tab->rec, tab->size);
- if (tab->dsp_fn != (void (*)())0)
- (*tab->dsp_fn)(UNDERLINED, CLR);
- }
- while ((*tab->inp_fn)(ADD, tab, head, lptr, table) != FALSE);
-
- /*
- * If the user aborts the add having already performed
- * the auto-increment, then we need to remove the pre-added
- * record from the file.
- */
- if ((*lptr)->curr != ANULL)
- {
- free ((*lptr)->curr);
- (*lptr)->curr = ANULL;
- stat = removerec(tab->fd, tab->rec);
- }
-
- /*
- * Commit any pending transactions
- */
- if (tab->tp)
- comm_p(tab);
-
- /*
- * We need to reset the key search order in case an
- * auto increment was performed
- */
- selectinx(tab->fd, *(tab->keynum), *(tab->keymatch), tab->retry);
-
- /*
- * If we have a depth of just 1, then we can copy
- * the previous record's values into the current
- * record when they abort the add.
- *
- * If the depth is greater than 1, then the top of
- * page is saved each time a record is added
- * and is restored upon exit, thus restoring the
- * full page of display.
- */
- if (top != ANULL)
- {
- bytecpy((*lptr)->rec, top->rec, tab->size);
- bytecpy(tab->rec, (*lptr)->rec, tab->size);
-
- if (tab->maximum > 1)
- reorder_mode(tab, head, lptr, BACKWARD);
-
- (*head)->deleted = deltmp; /*TVE*/
-
- free (top);
- top = ANULL;
- }
- else
- delete_list(tab, head, lptr, tab->index);
-
- /*
- *lptr = *head;
- *(tab->index) = 0;
- */
-
- /* TVE .... */
- /*
- * reset that which was previously saved
- * *lptr is set in the process as well
- */
- for ( *(tab->index) = 0, *lptr = *head;
- *(tab->index) != curidx && *lptr != ANULL;
- (*(tab->index))++, *lptr = (*lptr)->next )
- ;
-
- /*
- if (*lptr != ANULL)
- bytecpy(tab->rec, (*lptr)->rec, tab->size);
-
- do_page_mode(tab, head, lptr, mode);
- */
-
- if (*lptr != ANULL)
- {
- /*
- * Re-find the current record
- */
- bytecpy(tab->rec, (*lptr)->rec, tab->size); /*TVE*/
-
- stat = findkey(tab->fd, tab->rec);
-
- /*
- * Try & Lock retry times before failing
- */
- while (stat != IOGOOD && ++try <= tab->retry)
- {
- if (stat != IOGOOD && stat != IOLOCKED)
- return (do_error(stat));
-
- stat = lock_rec(tab->fd, tab->rec);
- }
-
- if (stat != IOGOOD)
- return (do_error(stat));
-
- /*
- * If we didn't find right one,
- * we better make sure the one we found
- * is the current one.
- * Also, since it's not the right one,
- * might as well make it the top one in the list
- * - will often get lucky, and this will be the previous top record,
- * - or it will be easier for the user to use next & prevs
- * to re-order the list properly
- * Unfortunately, we cannot rebuild the list because
- * we don't know whether to use fill_list or make_list
- * TVE
- * Oh yes we can because Add mode is only called on the main
- * table or Update tables, which use fill_list, Not make_list
- * NIG
- */
- if (memcmp((*lptr)->rec, tab->rec, tab->size) != 0)
- {
- if (tab->messages)
- errmsg(NO_CURR_EST);
- bytecpy((*head)->rec, tab->rec, tab->size);
-
- /*
- * This call to fill_list will perform the same
- * lookups as the call from the generated proggy
- * due to the Table Driven nature of these funcs.
- */
- fill_list_mode(tab, head, lptr);
-
- *lptr = *head;
- *(tab->index) = 0;
- }
- }
-
- do_page_mode(tab, head, lptr, mode);
-
- return (IOGOOD);
- }
-
- /*
- * Add a new record to the file
- */
- int add_record(tab, head, lptr)
- struct _table *tab;
- struct a_line **head, **lptr;
- {
- int stat;
-
- if (*lptr == ANULL)
- return (FALSE);
-
- /*
- * Confirm the Addition
- */
- if (tab->query_box && !warning (99, ADD_CONFIRM))
- return (FALSE);
-
- /*
- * Copy record to be added into list
- */
- bytecpy((*lptr)->rec, tab->rec, tab->size);
-
- /*
- * Free up curr pointer if necessary.
- * Only set on Auto-Add in add mode.
- * If Set, then update the record, as
- * one has been pre-added, else simply
- * add the record.
- */
- no_msg = !(tab->messages);
-
- if ((*lptr)->curr != ANULL)
- {
- free ((*lptr)->curr);
- (*lptr)->curr = ANULL;
- stat = updrec(tab->fd, tab->rec);
- }
- else
- stat = appendrec(tab->fd, tab->rec);
-
- /*
- * Commit or Rollback the pending operations
- */
- pending = TRUE;
-
- if (tab->tp)
- {
- if (stat == IOGOOD)
- comm_p(tab);
- else
- roll_p(tab);
- }
-
- if (do_error(stat) == IOGOOD)
- return (TRUE);
-
- return (FALSE);
- }
-
-