home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 125.img / PRO-C4.ZIP / BENCH1.ZIP / GENSUP / READWRIT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-28  |  10.8 KB  |  542 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. /*
  11.  * Free up the memory used by a list
  12. */
  13. void freelist_mode(tab, head, lptr)
  14. struct _table *tab;
  15. struct a_line **head, **lptr;
  16. {
  17.    struct a_line *tmp;
  18.  
  19.     /*
  20.      * Get straight out if the list is empty
  21.     */
  22.     if (*lptr == ANULL)
  23.         return;
  24.  
  25.     /*
  26.      * Find the end of the list
  27.     */
  28.    if (*lptr != ANULL)
  29.       while ((*lptr)->next != ANULL)
  30.          *lptr = (*lptr)->next;
  31.  
  32.     /*
  33.      * Free each record in turn
  34.     */
  35.    while (*lptr != ANULL)
  36.    {
  37.       tmp = (*lptr)->prev;
  38.       free((char *)*lptr);
  39.       *lptr = tmp;
  40.    }
  41.  
  42.     /*
  43.      * Reset pointers
  44.     */
  45.     *lptr = *head = ANULL;
  46.  
  47.     /*
  48.      * Clear the display
  49.     */
  50.    do_page_mode(tab, head, lptr, CLR);
  51.  
  52.     *(tab->index) = 0;   /* If we clear the list, then reset the pointer */
  53. }
  54.  
  55. /*
  56.  * Driving routine behind building a list of records
  57.  *
  58.  * Used for doing X-Ref Read/Write & Read, at 1st
  59.  * sub level where linkage can be 1 -> N
  60. */
  61. int fill_list_mode(tab, head, lptr)
  62. struct _table *tab;
  63. struct a_line **head, **lptr;
  64. {
  65.    int stat, try = 0, maxread = 0;
  66.  
  67.     /*
  68.      * Make sure we are searching on the right key
  69.     */
  70.    selectinx(tab->fd, *(tab->keynum), *(tab->keymatch), tab->retry);
  71.  
  72.     no_msg = !(tab->messages);
  73.  
  74.     /*
  75.      * Get first record in sequence
  76.     */
  77.     switch (tab->mode)
  78.     {
  79.     case K_HOME :
  80.          stat = firstkey(tab->fd, tab->rec);
  81.         break;
  82.     case K_END  :
  83.          stat = lastkey(tab->fd, tab->rec);
  84.         break;
  85.     default     :
  86.         stat = findkey(tab->fd, tab->rec);
  87.     }
  88.  
  89.     /*
  90.      * Try & Lock retry times before failing
  91.     */
  92.     while (stat != IOGOOD && ++try <= tab->retry)
  93.     {
  94.         if (stat != IOGOOD && stat != IOLOCKED)
  95.         {
  96.             if (tab->dsp_fn != (void (*)())0) 
  97.                 (*tab->dsp_fn)(UNDERLINED, CLR);
  98.             return (do_error(stat));
  99.         }
  100.  
  101.         stat = lock_rec(tab->fd, tab->rec); 
  102.     }
  103.  
  104.     if (stat != IOGOOD)
  105.         return (do_error(stat));
  106.  
  107.     /*
  108.      * Unlock if previously locked
  109.     */
  110.     if (tab->retry != 0)
  111.         ulock_rec(tab->fd, tab->rec);
  112.  
  113.     /*
  114.      * We found at least one record, so free up the list
  115.      * and build it again
  116.     */
  117.     freelist_mode(tab, head, lptr);
  118.  
  119.     /*
  120.      * Having found the 1st record ok, the messages can be
  121.      * disabled here to avoid ugly messages
  122.     */
  123.     no_msg = TRUE;
  124.  
  125.     /*
  126.      * Get rest of records to maximum display size
  127.     */
  128.     if (*(tab->seq) == ASCENDING)
  129.        do
  130.           new_line(tab, head, lptr);
  131.        while (++maxread < tab->maximum && (stat = nextrec(tab->fd, tab->rec)) == IOGOOD);
  132.     else
  133.        do
  134.           new_line(tab, head, lptr);
  135.        while (++maxread < tab->maximum && (stat = prevrec(tab->fd, tab->rec)) == IOGOOD);
  136.  
  137.     /*
  138.      * Reset Current Record if more 
  139.      * than 1 record in list
  140.     */
  141.     if (tab->maximum > 1 && *head != ANULL)
  142.     {
  143.        bytecpy(tab->rec, (*head)->rec, tab->size);
  144.  
  145.         /*
  146.          * Don't forget to reset the current record
  147.         */
  148.         switch (tab->mode)
  149.         {
  150.         case K_HOME :
  151.              stat = firstkey(tab->fd, tab->rec);
  152.             break;
  153.         case K_END  :
  154.              stat = lastkey(tab->fd, tab->rec);
  155.             break;
  156.         default     :
  157.             stat = findkey(tab->fd, tab->rec);
  158.         }
  159.  
  160.         /*
  161.          * Try & Lock retry times before failing
  162.         */
  163.         while (stat != IOGOOD && ++try <= tab->retry)
  164.         {
  165.             if (stat != IOGOOD && stat != IOLOCKED)
  166.             {
  167.                 if (tab->dsp_fn != (void (*)())0) 
  168.                     (*tab->dsp_fn)(UNDERLINED, CLR);
  169.                 return (do_error(stat));
  170.             }
  171.     
  172.             stat = lock_rec(tab->fd, tab->rec); 
  173.         }
  174.     
  175.         if (stat != IOGOOD)
  176.             return (do_error(stat));
  177.  
  178.         /*
  179.          * Unlock if previously locked
  180.         */
  181.         if (tab->retry != 0)
  182.             ulock_rec(tab->fd, tab->rec);
  183.     }
  184.    return(IOGOOD);
  185. }
  186.  
  187. /*
  188.  * Size of the biggest record in any program
  189.  * using a union of the record structures
  190. */
  191. extern int tot_size;
  192.  
  193. void new_record(tab, head, lptr)
  194. struct _table *tab;
  195. struct a_line **head, **lptr;
  196. {
  197.    struct a_line *tmp, *ptr;
  198.  
  199.     /*
  200.      * Allocate enough room for the record & pointers
  201.     */
  202.    tmp = (struct a_line *) alloc(tot_size);
  203.     tmp->deleted = FALSE;
  204.  
  205.    tmp->prev = tmp->next = ANULL;
  206.  
  207.    bytecpy(tmp->rec, tab->rec, tab->size);
  208.  
  209.     /*
  210.      * Adjust pointers depending on the direction
  211.      * we are adding this record
  212.     */
  213.     ptr = *lptr;
  214.  
  215.     if (*(tab->seq) == ASCENDING)
  216.     {
  217.         if (ptr != ANULL)
  218.             while (ptr->next != ANULL)
  219.                 ptr = ptr->next;
  220.  
  221.        if (ptr != ANULL)
  222.           ptr->next = tmp;
  223.        tmp->prev = ptr;
  224.        tmp->next = ANULL;
  225.     }
  226.     else /* up */
  227.     {
  228.         if (ptr != ANULL)
  229.             while (ptr->prev != ANULL)
  230.                 ptr = ptr->prev;
  231.  
  232.        if (ptr != ANULL)
  233.           ptr->prev = tmp;
  234.        tmp->next = ptr;
  235.        tmp->prev = ANULL;
  236.     }
  237.  
  238.       *lptr = tmp;
  239.  
  240.     /*
  241.      * Find the head of the list
  242.     */
  243.     for (*head = *lptr;  (*head)->prev != ANULL;  (*head) = (*head)->prev)
  244.         ;
  245. }
  246.  
  247. /*
  248.  * Insert a new record into the list
  249. */
  250. void new_line(tab, head, lptr)
  251. struct _table *tab;
  252. struct a_line **head, **lptr;
  253. {
  254.     new_record(tab, head, lptr);
  255.  
  256.     (*(tab->index))++;
  257. }
  258.  
  259. /*
  260.  * Same as above, but don't increment the index 
  261. */
  262. void new_line_2(tab, head, lptr)
  263. struct _table *tab;
  264. struct a_line **head, **lptr;
  265. {
  266.     new_record(tab, head, lptr);
  267. }
  268.  
  269. /*
  270.  * Read records into list starting from the top of file
  271. */
  272. int first_mode(tab, head, lptr, table, mode)
  273. struct _table *tab;
  274. struct a_line **head, **lptr;
  275. int table, mode;
  276. {
  277.     int stat;
  278.  
  279.     if (!(tab->perms & PERM_INQUIRE))
  280.     {
  281.         errmsg(ERR_NOINQ);
  282.         return (IOPERM);
  283.     }
  284.  
  285.    zerorec(tab->rec, tab->size);
  286.  
  287.     *(tab->seq)    = ASCENDING;
  288.     tab->mode      = K_HOME;
  289.     *(tab->index)  = 0;
  290.  
  291.    if ((stat = fill_list_mode(tab, head, lptr)) != IOGOOD)
  292.       return (stat);
  293.  
  294.     *(tab->index) = 0;
  295.  
  296.     head_list(tab, head, lptr, mode);
  297.  
  298.    return (stat);
  299. }
  300.  
  301. /*
  302.  * Read records into list starting from the end of file
  303. */
  304. int last_mode(tab, head, lptr, table, mode)
  305. struct _table *tab;
  306. struct a_line **head, **lptr;
  307. int table, mode;
  308. {
  309.     int stat;
  310.  
  311.     if (!(tab->perms & PERM_INQUIRE))
  312.     {
  313.         errmsg(ERR_NOINQ);
  314.         return (IOPERM);
  315.     }
  316.  
  317.    zerorec(tab->rec, tab->size);
  318.  
  319.     *(tab->seq)   = DESCENDING;
  320.     tab->mode     = K_END;
  321.     *(tab->index) = 0;
  322.  
  323.    if ((stat = fill_list_mode(tab, head, lptr)) != IOGOOD)
  324.       return(stat);
  325.  
  326.     (*(tab->index))--;
  327.  
  328.     /* *(tab->index) = 0; */
  329.  
  330.     head_list(tab, head, lptr, mode);
  331.  
  332.    return(stat);
  333. }
  334.  
  335. /*
  336.  * Read the file, using a user entered
  337.  * value as the first record to find
  338. */
  339. int inquire_mode(tab, head, lptr, table, mode)
  340. struct _table *tab;
  341. struct a_line **head, **lptr;
  342. int table, mode;
  343. {
  344.    int stat, try = 0, curidx;   /*TVE*/
  345.     struct a_line *curr = ANULL;
  346.     struct a_line *top = ANULL;  /*TVE*/
  347.  
  348.     if (!(tab->perms & PERM_INQUIRE))
  349.     {
  350.         errmsg(ERR_NOINQ);
  351.         return (IOPERM);
  352.     }
  353.  
  354.     /*
  355.      * Take copy of current record
  356.      * and top record (TVE)
  357.     */
  358.     if (*lptr != ANULL)
  359.     {
  360.        curr = (struct a_line *) alloc(tot_size);
  361.           bytecpy(curr->rec, (*lptr)->rec, tab->size);
  362.         curidx = *(tab->index);   /*TVE*/
  363.        top = (struct a_line *) alloc(tot_size);   /*TVE*/
  364.           bytecpy(top->rec, (*head)->rec, tab->size);   /*TVE*/
  365.     }
  366.  
  367.     /* 
  368.      * get search value
  369.      *
  370.      * build key is generated in the screen program
  371.     */
  372.     ichar = K_CR;
  373.     if (tab->key_fn != (void (*)())0)
  374.        (*tab->key_fn)(*(tab->keynum));
  375.  
  376.    if (ichar == K_ESC)
  377.     {
  378.         if (curr != ANULL)
  379.         {
  380.               bytecpy((*lptr)->rec, curr->rec, tab->size);
  381.               bytecpy(tab->rec, (*lptr)->rec, tab->size);
  382.               bytecpy((*head)->rec, top->rec, tab->size);  /*TVE*/
  383.             do_page_mode(tab, head, lptr, mode);  /*TVE*/
  384.             /*if (tab->dsp_fn != (void (*)())0) 
  385.                   (*tab->dsp_fn)(UNDERLINED, mode);*/
  386.  
  387.             free (curr);
  388.             curr = ANULL;
  389.             free (top);     /*TVE*/
  390.             top = ANULL;     /*TVE*/
  391.         }
  392.         return (IOGOOD);
  393.     }
  394.  
  395.     *(tab->seq)   = ASCENDING;
  396.     tab->mode     = 0;
  397.     *(tab->index) = 0;
  398.  
  399.     /*
  400.      * Load 'em up, and restore old value if none to load
  401.     */
  402.    if ((stat = fill_list_mode(tab, head, lptr)) != IOGOOD)
  403.     {
  404.         if (curr != ANULL)
  405.         {
  406.               bytecpy((*lptr)->rec, curr->rec, tab->size);
  407.               bytecpy(tab->rec, (*lptr)->rec, tab->size);
  408.               bytecpy((*head)->rec, top->rec, tab->size);  /*TVE*/
  409.             *(tab->index) = curidx;   /*TVE*/
  410.             if (tab->dsp_fn != (void (*)())0) 
  411.                   (*tab->dsp_fn)(UNDERLINED, mode);
  412.  
  413.             /*
  414.              * Re-find the current record
  415.             */
  416.             stat = findkey(tab->fd, tab->rec);
  417.     
  418.             /*
  419.              * Try & Lock retry times before failing
  420.             */
  421.             while (stat != IOGOOD && ++try <= tab->retry)
  422.             {
  423.                 if (stat != IOGOOD && stat != IOLOCKED)
  424.                     return (do_error(stat));
  425.     
  426.                 stat = lock_rec(tab->fd, tab->rec); 
  427.             }
  428.     
  429.             if (stat != IOGOOD)
  430.                 return (do_error(stat));
  431.     
  432.             /*
  433.               * If we didn't find right one, (because of dup keys)
  434.               * we better make sure the one we found
  435.               * is the current one.
  436.               * Also, since it's not the right one,
  437.               * might as well make it the top one in the list
  438.               * - will often get lucky, and this will be the previous top record,
  439.               * - or it will be easier for the user to use next & prevs
  440.               *   to re-order the list properly
  441.               * TVE
  442.               * could use fill_list to rebuild the list?
  443.              * - but should do same as add_mode to be consistent
  444.              *
  445.              * Now does the same as Add mode.  Again this is only
  446.              * called from the main table and update links, so
  447.              * fill_list is safe.
  448.              * NIG
  449.             */
  450.             if (memcmp((*lptr)->rec, tab->rec, tab->size) != 0)
  451.             {
  452.                 if (tab->messages)
  453.                     errmsg(NO_CURR_EST);
  454.                 bytecpy((*head)->rec, tab->rec, tab->size);
  455.                 *lptr = *head;
  456.                 *(tab->index) = 0;
  457.  
  458.                 fill_list_mode(tab, head, lptr);
  459.             }
  460.  
  461.             free (top);     /*TVE*/
  462.             top = ANULL;     /*TVE*/
  463.             free (curr);
  464.             curr = ANULL;
  465.  
  466.             do_page_mode(tab, head, lptr, mode);     /*TVE*/
  467.         }
  468.       return (do_error(stat));
  469.     }
  470.  
  471.     *(tab->index) = 0;
  472.  
  473.     if (curr != ANULL)
  474.     {
  475.         free (curr);
  476.         curr = ANULL;
  477.     }
  478.  
  479.     head_list(tab, head, lptr, mode);
  480.  
  481.     return (stat);
  482. }
  483.  
  484. /*
  485.  * Driving routine behind building a list of records
  486.  *
  487.  * Used for doing X-Ref Read Only stuff at sub-sub levels
  488.  * where linkage is basically 1 -> 1.
  489. */
  490. int make_list(tab, head, lptr)
  491. struct _table *tab;
  492. struct a_line **head, **lptr;
  493. {
  494.    int stat, read = 0;
  495.     struct a_line *tmp;
  496.  
  497.     /*
  498.      * Make sure we are searching on the right key
  499.     */
  500.    selectinx(tab->fd, *(tab->keynum), *(tab->keymatch), tab->retry);
  501.  
  502.     no_msg = !(tab->messages);
  503.  
  504.     /*
  505.      * Get record
  506.     */
  507.    stat = findkey(tab->fd, tab->rec);
  508.  
  509.    if (do_error(stat) != IOGOOD)
  510.         zerorec(tab->rec, tab->size);
  511.  
  512.     /*
  513.      * Reset index if empty list
  514.     */
  515.     if (*head == ANULL)
  516.         *(tab->index) = 0;
  517.  
  518.     /*
  519.      * Check for already in the list
  520.     */
  521.     for (read = 0, tmp = *head; tmp != ANULL; tmp = tmp->next, read++)
  522.     {
  523.         if (read == *(tab->index))
  524.         {
  525.            bytecpy(tmp->rec, tab->rec, tab->size);
  526.             *lptr = tmp;
  527.             (*lptr)->deleted = (stat != IOGOOD);   /*TVE*/
  528.            return (stat);   /*TVE*/
  529.         }
  530.     }
  531.  
  532.     /*
  533.      * New one so Add on the list
  534.     */
  535.     new_line_2(tab, head, lptr);
  536.  
  537.     (*lptr)->deleted = (stat != IOGOOD);   /*TVE*/
  538.  
  539.    return (stat);
  540. }
  541.  
  542.