home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 125.img / PRO-C4.ZIP / BENCH1.ZIP / GENSUP / ADD.C next >
Encoding:
C/C++ Source or Header  |  1990-05-28  |  6.4 KB  |  294 lines

  1. # include <stdio.h>
  2. # include <bench.h>
  3. # include <proc.io>
  4. # include "field.h"
  5. # include "screen.h"
  6. # include "iodef.h"
  7. # include "sup.h"
  8. # include "passwd.h"
  9.  
  10. extern int tot_size;
  11. extern int pending;
  12.  
  13. /*
  14.  * Driving ADD Mode Logic
  15.  *
  16.  * Start by hitting ADD KEY, and record is 
  17.  * actually added by hitting ADD KEY again
  18. */
  19. int add_mode(tab, head, lptr, table, mode)
  20. struct _table *tab;
  21. struct a_line **head, **lptr;
  22. int table, mode;
  23. {
  24.     int stat, try = 0;
  25.     struct a_line *tmp, *top = ANULL;
  26.     int curidx, deltmp;        /* TVE */
  27.  
  28.     if (!(tab->perms & PERM_ADD))
  29.     {
  30.         errmsg(ERR_NOADD);
  31.         return (IOPERM);
  32.     }
  33.  
  34.     /*
  35.      * Switch on Transaction Processing for the duration
  36.     */
  37.     if (tab->tp)
  38.         tran_p(tab);
  39.  
  40.     /*
  41.      * In Add mode, we are adding new items on
  42.      * to the list.  With multiple records on the
  43.      * page, we add to max depth, then scroll the 
  44.      * list up.
  45.     */
  46.     do
  47.     {
  48.         curidx = *(tab->index);  /* save this for later (TVE) */
  49.         /*
  50.          * Work out the index to add to
  51.         */
  52.         for (*(tab->index) = 0, tmp = *head; tmp != ANULL; (*(tab->index))++, tmp = tmp->next)
  53.             ;
  54.  
  55.         /*
  56.          * Bottom of list, so scroll around
  57.         */
  58.         if (*(tab->index) == tab->maximum)
  59.         {
  60.             /*
  61.              * Take copy of top record, in case
  62.              * the user aborts the add.
  63.             */
  64.             if (*head != ANULL)
  65.             {
  66.                 if (top == ANULL)
  67.                     top = (struct a_line *) alloc(tot_size);
  68.  
  69.                 bytecpy(top->rec, (*head)->rec, tab->size);
  70.                 deltmp = (*head)->deleted;   /*TVE*/
  71.             }
  72.  
  73.             (*(tab->index))--;
  74.             if (tab->maximum > 1)    /* More than 1 to display */
  75.             {
  76.                 reorder_mode(tab, head, lptr, FORWARD);
  77.                 do_page_mode(tab, head, lptr, mode);
  78.             }
  79.         }
  80.         else
  81.             new_record(tab, head, lptr);
  82.  
  83.         /*
  84.          * If required, to copy the previous record's 
  85.          * values into the current record as defaults,
  86.          * then swap these over.
  87.          *
  88.            * 1 : bytecpy((*lptr)->rec, tab->rec, tab->size);
  89.          *
  90.          * 2 : zerorec(tab->rec, tab->size);
  91.          *     if (tab->dsp_fn != (void (*)())0) 
  92.            *        (*tab->dsp_fn)(UNDERLINED, CLR);
  93.         */
  94.         zerorec(tab->rec, tab->size);
  95.         if (tab->dsp_fn != (void (*)())0) 
  96.               (*tab->dsp_fn)(UNDERLINED, CLR);
  97.     }
  98.     while ((*tab->inp_fn)(ADD, tab, head, lptr, table) != FALSE);
  99.  
  100.     /*
  101.      * If the user aborts the add having already performed
  102.      * the auto-increment, then we need to remove the pre-added
  103.      * record from the file.
  104.     */
  105.     if ((*lptr)->curr != ANULL)
  106.     {
  107.         free ((*lptr)->curr);
  108.         (*lptr)->curr = ANULL;
  109.         stat = removerec(tab->fd, tab->rec);
  110.     }
  111.  
  112.     /*
  113.      * Commit any pending transactions
  114.     */
  115.     if (tab->tp)
  116.         comm_p(tab);
  117.  
  118.     /*
  119.      * We need to reset the key search order in case an
  120.      * auto increment was performed
  121.     */
  122.       selectinx(tab->fd, *(tab->keynum), *(tab->keymatch), tab->retry);
  123.  
  124.     /*
  125.      * If we have a depth of just 1, then we can copy
  126.      * the previous record's values into the current 
  127.      * record when they abort the add.
  128.      *
  129.      * If the depth is greater than 1, then the top of
  130.      * page is saved each time a record is added
  131.      * and is restored upon exit, thus restoring the
  132.      * full page of display.
  133.     */
  134.     if (top != ANULL)
  135.     {
  136.           bytecpy((*lptr)->rec, top->rec, tab->size);
  137.           bytecpy(tab->rec, (*lptr)->rec, tab->size);
  138.  
  139.         if (tab->maximum > 1)
  140.             reorder_mode(tab, head, lptr, BACKWARD);
  141.  
  142.         (*head)->deleted = deltmp;  /*TVE*/
  143.  
  144.         free (top);
  145.         top = ANULL;
  146.     }
  147.     else
  148.         delete_list(tab, head, lptr, tab->index);
  149.  
  150.     /*
  151.         *lptr = *head;
  152.         *(tab->index) = 0;
  153.     */
  154.  
  155.     /* TVE .... */
  156.     /*
  157.      * reset that which was previously saved
  158.      * *lptr is set in the process as well
  159.     */
  160.     for ( *(tab->index) = 0, *lptr = *head;
  161.             *(tab->index) != curidx && *lptr != ANULL;
  162.             (*(tab->index))++, *lptr = (*lptr)->next )
  163.         ;
  164.         
  165.     /*
  166.     if (*lptr != ANULL)
  167.           bytecpy(tab->rec, (*lptr)->rec, tab->size);
  168.  
  169.     do_page_mode(tab, head, lptr, mode);
  170.     */
  171.  
  172.     if (*lptr != ANULL)
  173.     {
  174.         /*
  175.          * Re-find the current record
  176.         */
  177.           bytecpy(tab->rec, (*lptr)->rec, tab->size);   /*TVE*/
  178.  
  179.         stat = findkey(tab->fd, tab->rec);
  180.  
  181.         /*
  182.          * Try & Lock retry times before failing
  183.         */
  184.         while (stat != IOGOOD && ++try <= tab->retry)
  185.         {
  186.             if (stat != IOGOOD && stat != IOLOCKED)
  187.                 return (do_error(stat));
  188.  
  189.             stat = lock_rec(tab->fd, tab->rec); 
  190.         }
  191.  
  192.         if (stat != IOGOOD)
  193.             return (do_error(stat));
  194.  
  195.         /*
  196.          * If we didn't find right one,
  197.          * we better make sure the one we found
  198.          * is the current one.
  199.          * Also, since it's not the right one,
  200.          * might as well make it the top one in the list
  201.          * - will often get lucky, and this will be the previous top record,
  202.          * - or it will be easier for the user to use next & prevs
  203.          *   to re-order the list properly
  204.          * Unfortunately, we cannot rebuild the list because 
  205.          * we don't know whether to use fill_list or make_list
  206.          * TVE
  207.          * Oh yes we can because Add mode is only called on the main 
  208.          * table or Update tables, which use fill_list, Not make_list
  209.          * NIG
  210.         */
  211.         if (memcmp((*lptr)->rec, tab->rec, tab->size) != 0)
  212.         {
  213.             if (tab->messages)
  214.                 errmsg(NO_CURR_EST);
  215.             bytecpy((*head)->rec, tab->rec, tab->size);
  216.  
  217.             /*
  218.              * This call to fill_list will perform the same
  219.              * lookups as the call from the generated proggy
  220.              * due to the Table Driven nature of these funcs.
  221.             */
  222.             fill_list_mode(tab, head, lptr);
  223.  
  224.             *lptr = *head;
  225.             *(tab->index) = 0;
  226.         }
  227.     }
  228.  
  229.     do_page_mode(tab, head, lptr, mode);
  230.  
  231.     return (IOGOOD);
  232. }
  233.  
  234. /*
  235.  * Add a new record to the file
  236. */
  237. int add_record(tab, head, lptr)
  238. struct _table *tab;
  239. struct a_line **head, **lptr;
  240. {
  241.     int stat;
  242.  
  243.     if (*lptr == ANULL)
  244.         return (FALSE);
  245.  
  246.    /* 
  247.      * Confirm the Addition
  248.     */
  249.     if (tab->query_box && !warning (99, ADD_CONFIRM))
  250.         return (FALSE);
  251.  
  252.     /*
  253.      * Copy record to be added into list
  254.     */
  255.     bytecpy((*lptr)->rec, tab->rec, tab->size);
  256.  
  257.     /*
  258.      * Free up curr pointer if necessary.
  259.      * Only set on Auto-Add in add mode.
  260.      * If Set, then update the record, as
  261.      * one has been pre-added, else simply
  262.      * add the record.
  263.     */
  264.     no_msg = !(tab->messages);
  265.  
  266.     if ((*lptr)->curr != ANULL)
  267.     {
  268.         free ((*lptr)->curr);
  269.         (*lptr)->curr = ANULL;
  270.         stat = updrec(tab->fd, tab->rec);
  271.     }
  272.     else
  273.         stat = appendrec(tab->fd, tab->rec);
  274.  
  275.     /*
  276.      * Commit or Rollback the pending operations
  277.     */
  278.     pending = TRUE;
  279.  
  280.     if (tab->tp)
  281.     {
  282.         if (stat == IOGOOD)
  283.             comm_p(tab);
  284.         else
  285.             roll_p(tab);
  286.     }
  287.  
  288.     if (do_error(stat) == IOGOOD)
  289.         return (TRUE);
  290.  
  291.     return (FALSE);
  292. }
  293.  
  294.