home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 v2.4 Fix / W95-v2.4fix.iso / ACADWIN / ASE / SAMPLE / ASISMP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-08  |  56.9 KB  |  1,720 lines

  1. /*****************************************************************************
  2.     Name: astsmp.c
  3.  
  4.     Description:
  5.  
  6.     Author: Alexander Nikolayev
  7.             Autodesk, Inc.
  8.             Moscow, Russia.
  9.  
  10.     (c) Copyright 1991-93 Autodesk Inc.
  11.    ***************************************************************************
  12.       Permission to use, copy, modify, and distribute this software and its
  13.       documentation for the purpose of creating applications for AutoCAD, is
  14.       hereby granted in accordance with the terms of the License Agreement
  15.       accompanying this product.
  16.    ***************************************************************************
  17.  
  18.       AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. AUTODESK
  19.       SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY OR
  20.       FITNESS FOR A PARTICULAR USE. AUTODESK, INC. DOES NOT WARRANT THAT
  21.       THE OPERATION OF THE PROGRAM WILL BE UNINTERRUPTED OR ERROR FREE.
  22.  
  23.    ***************************************************************************
  24.                            RESTRICTED RIGHTS LEGEND
  25.  
  26.       Use, duplication, or disclosure by the U.S. Government is subject
  27.       to restrictions set forth in FAR 52.227-19 (Commerical Computer
  28.       Software - Restricted Rights) and DFAR 252.227-7013 (c) (1) (ii)
  29.       (Rights in Technical Data and Computer Software), as applicable.
  30.    ***************************************************************************
  31.  
  32.     Entry Points:
  33.  
  34.     Modification History:
  35.  
  36.     Bugs and restriction on use:
  37.  
  38.     Notes:
  39.  
  40. *****************************************************************************/
  41.  
  42. /****************************************************************************/
  43. /* INCLUDES */
  44. /****************************************************************************/
  45. #include <adslib.h>
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #include <time.h>
  50. #include <asiappl.h>
  51.  
  52.  
  53. /****************************************************************************/
  54. /* TYPEDEFS */
  55. /****************************************************************************/
  56. char      * bittoXstr       _((char *, int,  unsigned char *, int));
  57. void        write_string    _((char *));
  58.  
  59. void        display_section _((char *));
  60. void        print_row       _((ASICURSOR, char **));
  61. void        print_rowset    _((ASICURSOR));
  62. void        scan_rowset     _((ASICURSOR));
  63.  
  64. void        do_statement    _((char *));
  65. EAsiBoolean do_csr_update   _((ASICURSOR csr));
  66. void        do_cursor       _((ASISTATEMENT));
  67. void        do_single_select _((ASISTATEMENT));
  68. void        do_ordinary     _((ASISTATEMENT));
  69. void        print_coldsc    _((ASIHANDLE));
  70. void        print_pardsc    _((ASIHANDLE));
  71. EAsiBoolean initParams      _((ASIHANDLE, struct hbinds **));
  72. void        readParams      _((ASIHANDLE, struct hbinds *));
  73. void        termParams      _((struct hbinds *));
  74. EAsiBoolean initDst         _((ASIHANDLE, struct hbinds **));
  75. void        print_currow    _((ASICURSOR  csr));
  76.  
  77. void        nullbody        _((void));
  78. void        do_settings     _((void));
  79. void        do_connect      _((void));
  80. void        do_disconnect   _((void));
  81. void        do_sqled        _((void));
  82. void        do_script       _((void));
  83. void        create_env      _((void));
  84. void        drop_env        _((void));
  85.  
  86. /**************************************************************************/
  87. /*  TYPEDEFS */
  88. /**************************************************************************/
  89. /* The following structure defines buffers to be bound with SQl
  90.    statement parameters */
  91. struct hbinds {
  92.   char      buffer [256];  // Host buffer
  93.   short     indp;          // Indicator variable
  94. };
  95.  
  96. /****************************************************************************/
  97. /* GLOBALS */
  98. /****************************************************************************/
  99.  
  100.  
  101. typedef struct {
  102.     char *cmdname;
  103.     void (*cmdfunc)();
  104. } CMDRX;                              /* Typedef for command definition */
  105.  
  106. static CMDRX cmd[] =  {
  107.                         {"C:ASISETUP",      do_settings},
  108.                         {"C:ASISQLED",      do_sqled},
  109.                         {"C:ASISCRIPT",     do_script},
  110.                         {"C:ASICONNECT",    do_connect},
  111.                         {"C:ASIDISCONNECT", do_disconnect},
  112.                         {"C:ASICREATEENV",  create_env},
  113.                         {"C:ASIDROPENV",    drop_env}
  114.                       };
  115.  
  116. /* Diagnostics parameters */
  117. struct {
  118.   EAsiDiag dPar;       // Diagnostics parameter
  119.   char     name[32];   // Name
  120. } diag [10] =
  121. {
  122.   { kAsiServerName,         "Server"             },
  123.   { kAsiConnectionName,     "Connection"         },
  124.   { kAsiConstraintCatalog,  "Constraint catalog" },
  125.   { kAsiConstraintSchema,   "Constraint schema"  },
  126.   { kAsiConstraintName,     "Constraint"         },
  127.   { kAsiCatalogName,        "Catalog"            },
  128.   { kAsiSchemaName,         "Schema"             },
  129.   { kAsiTableName,          "Table"              },
  130.   { kAsiColumnName,         "Column"             },
  131.   { kAsiCursorName,         "Cursor"             }
  132. };
  133.  
  134.  
  135. static ASIENV      appl        = 0;          /* Asi application */
  136. static ASISESSION  session     = 0;          /* Asi session */
  137. static EAsiBoolean isConnected = kAsiFalse;  /* Connection is active */
  138.  
  139. static char        EnvName  [128];           /* Current environment name */
  140. static char        UserName [128];           /* Current user name */
  141.  
  142.  
  143.  
  144. static EAsiBoolean oldScrFile  = kAsiFalse;     // Old style script file
  145. static EAsiBoolean askCsrMode  = kAsiFalse;     // Ask for cursor mode
  146. static EAsiBoolean showDsc     = kAsiFalse;     // Show result descriptor
  147.  
  148. // Default cursor type
  149. static EAsiCurSns  csrSns      = kAsiSnsUndef; // Sensitivity
  150. static EAsiCurScr  csrScr      = kAsiNonScroll;// Scrollabilty
  151.  
  152. static EAsiBoolean showOne     = kAsiFalse;     // Scroll by one row
  153. static EAsiBoolean stopPage    = kAsiTrue;      // Stop after each page
  154. static EAsiBoolean pauseAfter  = kAsiFalse;     // Pause after statement execution
  155. static EAsiBoolean pauseAfterE = kAsiTrue;      // Pause after error
  156. static EAsiBoolean doAgain     = kAsiFalse;     // Ask for statement reexecution
  157. static EAsiBoolean echoToFile  = kAsiFalse;     // Echo to file
  158. static char        FileName[128];               // Echo file namne
  159. static EAsiBoolean timeMeasure = kAsiFalse;     // Print elapsed time
  160. static FILE      * efDsc       = 0;             // Echo file handle
  161.  
  162. // Temporary buffers
  163. static  char      buffer [128];       // Buffer for line input
  164. static  char      buff   [1024];      // another buffer
  165. static  char      stm    [1024];      // SQL statement
  166.  
  167. // Temporary buffer for build character strings
  168. static  char      bufgen [1024];      // Buffer for convert Unicode string
  169.                                       // to character string
  170.  
  171.  
  172.  
  173. /****************************************************************************/
  174. /* FUNCTIONS */
  175. /****************************************************************************/
  176.  
  177. /**************************************************************************
  178.   Switch boolean value
  179. **************************************************************************/
  180. EAsiBoolean switch_boolean (EAsiBoolean t)
  181. {
  182.    return (t == kAsiTrue) ? kAsiFalse : kAsiTrue;
  183. }
  184.  
  185. /***************************************************************************
  186.   This function displays string on the screen and echoes it to the protocol
  187.   file
  188. ***************************************************************************/
  189. void write_string (char * buffer)
  190. {
  191.    ads_printf (buffer);
  192.  
  193.    if (echoToFile == kAsiTrue && efDsc != 0) {
  194.       fprintf (efDsc, buffer);
  195.    }
  196. }
  197.  
  198. /****************************************************************************
  199.   This function converts bit buffer to hexadecimal string
  200. ****************************************************************************/
  201. char * bittoXstr (
  202.    char          * buffer,   // Destination buffer
  203.    int             len,      // Length of destination buffer
  204.    unsigned char * bbuffer,  // source bit buffer
  205.    int             blen      // Number of bits in bbuffer
  206. )
  207. {
  208.    int    bytelength = 0;
  209.    char * p = 0;
  210.    int    ii;
  211.  
  212.    bytelength = blen / 8 + ((blen % 8 > 0) ? 1 : 0);
  213.  
  214.    for (ii = 0, p = buffer; ii < bytelength && p - buffer < len - 2; ii ++) {
  215.       sprintf (p, "%02X", bbuffer[ii]);
  216.       p +=2;
  217.    }
  218.    return buffer;
  219.  
  220. }
  221.  
  222.  
  223.  
  224. /***************************************************************************
  225.   This function displays section from the asi.ini file
  226. ****************************************************************************/
  227. void display_section (char *section)
  228. {
  229.    char      * buffer  = 0;  /* Destination buffer */
  230.    char      * pEntry  = 0;
  231.    char        pValue [128];
  232.    ASICONFIG   config;        /* configuration file handle */
  233.  
  234.    /* Construct configuration file */
  235.    if (asi_constr_cfg (&config) == kAsiBad) {
  236.       ads_printf ("\nCannot construct ASI configuration file handle");
  237.       return ;
  238.    }
  239.  
  240.    buffer = malloc (sizeof (char) * 4096);
  241.    if (buffer == 0) {
  242.       asi_destroy_cfg (&config);
  243.       ads_printf ("\nInsufficient memory for temporary buffer");
  244.       return ;
  245.    }
  246.    /* Display contents */
  247.    if (asi_getcfgstring (config, section, NULL, "", buffer, 4096) > 0) {
  248.        for (pEntry = buffer; * pEntry != '\0'; pEntry += strlen (pEntry) + 1) {
  249.           asi_getcfgstring (config, section, pEntry, "", pValue, 128);
  250.           ads_printf ("\n%-16s %s", pEntry, pValue);
  251.        }
  252.    }
  253.    ads_printf ("\n");
  254.    free (buffer);
  255.    asi_destroy_cfg (&config);   /* Destroy configuration handke */
  256.    return;
  257. }
  258.  
  259. /*************************************************************************
  260.   This function displays the ENVIRONMENTS section from the asi.ini file
  261. **************************************************************************/
  262. void display_env (void)
  263. {
  264.    ads_printf ("\nAvailable environments:\n");
  265.    display_section ("ENVIRONMENTS");
  266. }
  267.  
  268.  
  269. /***************************************************************************
  270.   This function prints out diagnostics info
  271. ****************************************************************************/
  272. static void print_diag (ASIHANDLE  handle)
  273. {
  274.    int         iCount;                // Temp variables
  275.    int         ii, jj;                // Indexing variable
  276.    char        buff [128];
  277.  
  278.    // Print number of conditions in diagnostics area
  279.    if ((iCount = asi_condqty (handle)) > 0) {
  280.       ads_printf("\nNumber of conditions: %d",iCount);
  281.       // Print position where error was detected
  282.       if (asi_synerrpos (handle) != 0) {
  283.           ads_printf("\nError position:       %d",asi_synerrpos (handle));
  284.       }
  285.       ads_printf("\n#        SQLSTATE    Message");
  286.       for (jj = 0; jj < iCount; jj++ ) {
  287.            asi_errmsg (handle, buff, 256, jj);
  288.            ads_printf("\n%10d%-12s%s", jj, asi_sqlstate (handle, jj), buff);
  289.  
  290.            // Print diagnostics parameters
  291.            for (ii = 0; ii < 10; ii ++) {
  292.               if (asi_getdiagpar (handle, diag[ii].dPar, buff, 256, jj) == kAsiTrue) {
  293.                  ads_printf ("\n%20s: ", diag[ii].name);
  294.                  ads_printf ("%s", buff);
  295.               }
  296.            }
  297.       }
  298.    }
  299.  
  300. } // print_diag()
  301.  
  302. /*******************************************************************************************
  303.   This function prints resulting table descriptor
  304. *******************************************************************************************/
  305. static void print_coldsc (ASIHANDLE  handle)
  306. {
  307.    int           iCount, ii;              // Temp variables
  308.    ASICOLDSC     coldsc;                  /* Column descriptoir handle */
  309.    ASIDATADSC    datadsc;                 /* Data descriptor handle */
  310.    ASIIDENT      name;                    /* Identifier: column name */
  311.  
  312.  
  313.    if (showDsc == kAsiFalse) {
  314.       return;
  315.    }
  316.  
  317.    iCount = asi_colcount (handle);        /* Get number of columns */
  318.    ads_printf("\n     Table structure");
  319.    for (ii = 0; ii < iCount; ii ++) {
  320.         if (asi_cds (handle, ii, &coldsc) == kAsiGood) { /* Get column descriptor */
  321.             // Print column name
  322.             asi_cdsc_name (coldsc, &name);              /* Get column name */
  323.             ads_printf("\n %30S", asi_get_ident (name, buff, 128));
  324.             asi_destroy_ident (&name);
  325.  
  326.             /* Get column data descriptor and print it */
  327.             asi_cdsc_ddsc (coldsc, &datadsc);
  328.             if (asi_cdsc_ddsc (coldsc, &datadsc) == kAsiGood) {
  329.                 ads_printf("   %s", asi_ddsc_sqltype (datadsc, buff, 256));
  330.                 asi_destroy_ddsc (&datadsc);
  331.             }
  332.         }
  333.    }
  334. }
  335.  
  336.  
  337. ///////////////////////////////////////////////////////////////////
  338. static void print_pardsc (ASIHANDLE  handle)
  339. {
  340.    int            iCount, ii;        // Temp variables
  341.    ASIPARDSC      pardsc;            /* Parameter descriptor */
  342.    ASIDATADSC     datadsc;           /* Data descriptor */
  343.    ASIIDENT       name;              /* Parameter name */
  344.  
  345.    iCount = asi_parcount (handle);   /* Number of parameters */
  346.    if (iCount == 0) {
  347.       return ;      /* No parameters */
  348.    }
  349.  
  350.    ads_printf("\n     Parameters in statement");
  351.    ads_printf("\n %30s%15s%s","Name","Nulability","   SQL Type");
  352.  
  353.    for (ii = 0; ii < iCount; ii ++) {
  354.         /* Get parameter descriptor */
  355.         if (asi_pds (handle, ii, &pardsc) != kAsiBad) {
  356.             /* Print parameter name */
  357.             asi_pdsc_name (pardsc, &name);
  358.             ads_printf("\n %30s", asi_get_ident (name,  buff, 256));
  359.             asi_destroy_ident (&name);
  360.  
  361.             /* Print parameter nullability */
  362.             if (asi_pdsc_nullable (pardsc) == kAsiTrue ) {
  363.                 ads_printf("%15s","yes");
  364.             } else {
  365.                 ads_printf("%15s","no");
  366.             }
  367.             /* Get parameter data descriptor and print it */
  368.             if (asi_pdsc_ddsc (pardsc, &datadsc) == kAsiGood) {
  369.                 ads_printf("   %s", asi_ddsc_sqltype (datadsc, buff, 256));
  370.                 asi_destroy_ddsc (&datadsc);
  371.             }
  372.         }
  373.    }
  374. }
  375.  
  376.  
  377.  
  378. /****************************************************************************
  379.   This function initializes input parameters and binnds them with
  380.   the host program buffers
  381. ****************************************************************************/
  382. EAsiBoolean initParams (ASIHANDLE  Stm, struct hbinds **  hosts)
  383. {
  384.    int             iCount;
  385.    int             ii;
  386.    struct hbinds * buffers;
  387.  
  388.    iCount = asi_parcount (Stm);
  389.    if (iCount != 0) {
  390.       // Allocate host buffers
  391.       buffers = (struct hbinds *) malloc (sizeof (struct hbinds) * iCount);
  392.       if (buffers == 0) {
  393.          return kAsiBad;
  394.       }
  395.       // bind them with SQL statement
  396.       for (ii = 0; ii < iCount; ii ++) {
  397.          asi_bndnum (Stm, ii, buffers[ii].buffer, & buffers[ii].indp, 256, kAsiHchar);
  398.       }
  399.       * hosts = buffers;
  400.    }
  401.    return kAsiGood;
  402. }
  403.  
  404.  
  405.  
  406. /****************************************************************************
  407.    This function reads values for input parameters and places them
  408.    into buffers bound with SQL statement parameters
  409. ****************************************************************************/
  410. void readParams (ASIHANDLE  Stm, struct hbinds *  buffers)
  411. {
  412.    int             iCount;
  413.    int             ii;
  414.    ASIPARDSC       pardsc;
  415.    ASIIDENT        name;
  416.  
  417.    iCount = asi_parcount (Stm);
  418.    for (ii = 0; ii < iCount; ii ++) {
  419.       if (asi_pds (Stm, ii, &pardsc) != kAsiBad) {
  420.           // Print parameter name
  421.           asi_pdsc_name (pardsc, &name);
  422.           ads_printf("\n %-30s", asi_get_ident (name, buff, 256));
  423.           asi_destroy_ident (&name);
  424.  
  425.           // Get parameter value
  426.           ads_getstring (1, ": ", buffer);
  427.           if (*buffer == '.' && * (buffer + 1) == '\0') {
  428.               buffers[ii].indp = -1;    /* NULL Value */
  429.           } else {
  430.               strncpy (buffers[ii].buffer, buffer, 128);
  431.           }
  432.       }
  433.    }
  434.    return;
  435. }
  436.  
  437. /***************************************************************************
  438.   This function releases host buffers
  439. ***************************************************************************/
  440. void termParams (struct hbinds *  buffers)
  441. {
  442.    if (buffers != 0) {
  443.       free (buffers);
  444.    }
  445. }
  446.  
  447.  
  448.  
  449. /***************************************************************************
  450.   This function initializes destinations for output values and bind them with
  451.   the output parameters
  452. ***************************************************************************/
  453. EAsiBoolean initDst (ASIHANDLE Stm, struct hbinds **  hosts)
  454. {
  455.    int             iCount;
  456.    int             ii;
  457.    struct hbinds * buffers;
  458.  
  459.    iCount = asi_colcount (Stm);
  460.    if (iCount != 0) {
  461.       // Allocate host buffers
  462.       buffers = (struct hbinds *) malloc (sizeof (struct hbinds) * iCount);
  463.       if (buffers == 0) {
  464.          return kAsiBad;
  465.       }
  466.       // bind them with output parameters of SQL statement
  467.       for (ii = 0; ii < iCount; ii ++) {
  468.          asi_sob (Stm, ii, buffers[ii].buffer, & buffers[ii].indp, 256, kAsiHchar);
  469.       }
  470.       * hosts = buffers;
  471.    }
  472.    return kAsiGood;
  473.  
  474. }
  475.  
  476. /*************************************************************************
  477.   This function does positioned update
  478. *************************************************************************/
  479. static EAsiBoolean do_csr_update (ASICURSOR csr)
  480. {
  481.    ASICOLDSC    coldsc;          // Column descriptor
  482.    ASIIDENT     name;            // Column name
  483.    EAsiHostType type;            // Type of buffer
  484.  
  485.    int          ii;
  486.    int          iCount;
  487.  
  488.    iCount = asi_colcount (csr);
  489.    for (ii = 0; ii < iCount; ii++) {
  490.        if (asi_cds (csr, ii, &coldsc) == kAsiGood) {
  491.            // Print column name
  492.            asi_cdsc_name (coldsc, &name);
  493.            ads_printf("%-30s", asi_get_ident (name, buff, 128));
  494.            ads_getstring (1, ": ", buffer);
  495.            if (* buffer == '\0') {
  496.               continue;
  497.            }
  498.            if (*buffer == '.' && *(buffer + 1) == '\0') {
  499.               type = kAsiHnull;
  500.            } else {
  501.               type = kAsiHchar;
  502.            }
  503.            if (asi_update (csr, name, type, strlen (buffer), buffer, (ASIIDENT) 0) == kAsiBad) {
  504.               print_diag (csr);
  505.               ads_printf ("\nColumn %s update error", asi_get_ident (name, buff, 128));
  506.            }
  507.            asi_destroy_ident (&name);
  508.        }
  509.    }
  510.    return kAsiTrue;
  511. }
  512.  
  513. /****************************************************************************
  514.   This function prints current row
  515. ****************************************************************************/
  516. static void print_currow (ASICURSOR  csr)
  517. {
  518.    // Column descriptor and name
  519.    ASICOLDSC          coldsc;
  520.    ASIIDENT           name;
  521.  
  522.    // Value of the column
  523.    char               buffer [128];
  524.    unsigned char      bbuffer[128];   // Destination for bits
  525.    short              indp;
  526.  
  527.    // Temporary variables
  528.    int                ii;
  529.  
  530.    ASIDATADSC         ddsc;
  531.    EAsiBoolean        rCode = kAsiBad;
  532.  
  533.  
  534.    ads_printf ("\n");
  535.    for (ii = 0; ii < asi_colcount (csr); ii ++) {
  536.         // Print column name
  537.         if (asi_cds (csr, ii, &coldsc) == kAsiGood) {
  538.             asi_cdsc_name (coldsc, &name);
  539.             ads_printf("\n%-30s: ", asi_get_ident (name, buff, 128));
  540.             asi_destroy_ident (&name);
  541.         }
  542.  
  543.         // Print column data
  544.         asi_cdsc_ddsc (coldsc, &ddsc);   // Get data descriptor
  545.         if (asi_ddsc_type (ddsc) == kAsiBit || asi_ddsc_type (ddsc) == kAsiBitVar) {
  546.             if ((rCode = asi_cvl (csr, ii, bbuffer, &indp, 128*8, kAsiHbinary)) == kAsiGood) {
  547.                 // Indicator holds the actual number of bits
  548.                 // stored in the destination buffer
  549.                 if (indp >= 0) {
  550.                    ads_printf("[%s]", bittoXstr ((char *) buffer, 256, bbuffer, (int) indp));
  551.                 } else {
  552.                    ads_printf(".");
  553.                 }
  554.             }
  555.         } else {
  556.             // Get result as cha
  557.             if ((rCode = asi_cvl (csr, ii, buffer, &indp, 128, kAsiHchar)) == kAsiGood) {
  558.                if (indp >= 0) {
  559.                    ads_printf("[%s]", buffer);
  560.                } else {
  561.                    ads_printf(".");
  562.                }
  563.             }
  564.         }
  565.         if (rCode == kAsiBad) {
  566.             // Print diagnostics
  567.             print_diag (csr);
  568.         }
  569.         asi_destroy_ddsc (&ddsc);
  570.    }
  571. }
  572.  
  573.  
  574. /**************************************************************************
  575.   This function prepares formats for browsing selection rowset
  576. **************************************************************************/
  577. char **make_formats (ASICURSOR csr)
  578. {
  579.    char       ** formats  = 0;
  580.    ASICOLDSC     coldsc;       // Column descriptor
  581.    ASIDATADSC    dDsc;        // Data descriptor
  582.    ASIIDENT      name;
  583.    int           ii;
  584.  
  585.  
  586.    formats = (char **) malloc (sizeof (char *) * asi_colcount (csr));
  587.    if (formats == 0) {
  588.       return 0;
  589.    }
  590.  
  591.    for (ii = 0; ii < asi_colcount (csr); ii ++) {
  592.       asi_cds (csr, ii, &coldsc);
  593.       asi_cdsc_name (coldsc, &name);
  594.       asi_get_ident (name, buff, 256);
  595.       asi_cdsc_ddsc (coldsc, & dDsc);
  596.       if (dDsc != 0) {
  597.         formats[ii] = (char *) malloc (32);
  598.         if (formats [ii] != 0) {
  599.            if (asi_ddsc_type (dDsc) == kAsiChar || asi_ddsc_type (dDsc) == kAsiCharVar) {
  600.                 sprintf (formats[ii], "  %%-%ds",
  601.                          ASI_MAX (strlen (buff), asi_ddsc_length (dDsc)));
  602.            } else if (asi_ddsc_type (dDsc) == kAsiBit ||
  603.                       asi_ddsc_type (dDsc) == kAsiBitVar) {
  604.                 sprintf (formats[ii], "b  %%-%ds",
  605.                       ASI_MAX (strlen (buff), asi_ddsc_length (dDsc) / 4 + 1));
  606.            } else {
  607.                 sprintf (formats[ii], " %%%ds ",
  608.                          ASI_MAX ( strlen (buff), asi_ddsc_length (dDsc)));
  609.            }
  610.            asi_destroy_ddsc (&dDsc);
  611.         }
  612.         asi_destroy_ident (&name);
  613.       }
  614.    }
  615.    return formats;
  616. }
  617.  
  618.  
  619. /***************************************************************************
  620.   This function prints rowset header
  621. ***************************************************************************/
  622.  
  623. void print_header (ASICURSOR  csr, char ** formats)
  624. {
  625.    ASICOLDSC     coldsc;            // Column descriptor
  626.    ASIIDENT      name;
  627.    int           ii;
  628.  
  629.    write_string ("\n");
  630.    for (ii = 0; ii < asi_colcount (csr); ii ++) {
  631.       asi_cds (csr, ii, &coldsc);
  632.       asi_cdsc_name (coldsc, &name);
  633.       sprintf (buffer, formats[ii]+1, asi_get_ident (name, buff, 256));
  634.       write_string (buffer);
  635.       asi_destroy_ident (&name);
  636.    }
  637.    write_string ("\n");
  638.    write_string ("========================================================");
  639. }
  640.  
  641. /**********************************************************************
  642.   This function prints row on one line
  643. ***********************************************************************/
  644. void print_row (ASICURSOR csr, char ** formats)
  645. {
  646.    short              indp;
  647.    int                ii;
  648.    unsigned char      bbuffer [256];      // Bit destination
  649.    EAsiBoolean        rCode = kAsiBad;
  650.  
  651.    write_string ("\n");
  652.    for (ii = 0; ii < asi_colcount (csr); ii ++) {
  653.         if (*formats[ii] == 'b') {
  654.             if ((rCode = asi_cvl (csr, ii, bbuffer, &indp, 128*8, kAsiHbinary)) == kAsiGood &&
  655.                 indp > 0) {
  656.                  bittoXstr (buff, 256, bbuffer, (int) indp);
  657.             }
  658.         } else {
  659.             // Get result as char buffer
  660.             rCode = asi_cvl (csr, ii, buff, &indp, 128, kAsiHchar);
  661.         }
  662.         if (indp < 0 || rCode == kAsiBad) {
  663.             buff [0] = 0;
  664.         }
  665.         if (*formats[ii] == 'b') {
  666.             sprintf(buffer, formats[ii]+1, buff);
  667.         } else {
  668.             sprintf(buffer, formats[ii]+1, buff);
  669.         }
  670.         write_string (buffer);
  671.    }
  672. }
  673.  
  674.  
  675. /**********************************************************************
  676.   This function browses resulting rowset
  677. ***********************************************************************/
  678. void print_rowset (ASICURSOR csr)
  679. {
  680.     char ** formats  = 0;
  681.     int     ii       = 0;
  682.  
  683.     formats = make_formats (csr);
  684.     print_header (csr, formats);
  685.     while (asi_fetch (csr) == kAsiGood) {
  686.        print_row (csr, formats);
  687.        ii ++;
  688.        if (ii == 21 && stopPage == kAsiTrue) {
  689.            ads_getstring (0, "\nPress return to continue or [e] to exit immediatelly ...", buffer);
  690.            if (*buffer == 'e') {
  691.               break;
  692.            }
  693.            print_header (csr, formats);
  694.            ii = 0;
  695.        }
  696.     }
  697.     for (ii = 0; ii < asi_colcount (csr); ii ++) {
  698.        if (formats[ii] != 0) {
  699.           free (formats[ii]);
  700.        }
  701.     }
  702.     free (formats);
  703. }
  704.  
  705. /**************************************************************************
  706.   This functions scans selction set displaying only one row
  707. **************************************************************************/
  708. void scan_rowset (ASICURSOR csr)
  709. {
  710.      char        cBuffer[127];                 // Temporary buffer
  711.      EAsiBoolean rCode         = kAsiFalse;     // Return code
  712.      long        lOffset;                      // Relative and absolute fetch value
  713.  
  714.      cBuffer[0] = 'n';
  715.      for (;;) {
  716.          switch ( cBuffer[0] ) {
  717.          case 'n':                   // Fetch next
  718.             rCode = asi_fetch (csr);
  719.             break;
  720.          case 'f':                   // Fetch first
  721.             rCode = asi_fetchFirst (csr);
  722.             break;
  723.          case 'p':                  // Fetch prior
  724.             rCode = asi_fetchPrior (csr);
  725.             break;
  726.          case 'l':                  // Fetch last
  727.             rCode = asi_fetchLast (csr);
  728.             break;
  729.          case 'r':                  // Fetch relative
  730.             ads_getint ("\nEnter relative row number: ", (int*)&lOffset);
  731.             rCode = asi_fetchRelative (csr, lOffset);
  732.             break;
  733.          case 'a':                 // Fetch absolute
  734.             ads_getint ("\nEnter absolute row number: ", (int*)&lOffset);
  735.             rCode = asi_fetchAbsolute (csr, lOffset);
  736.             break;
  737.          case 'd':                 // Delete current row
  738.             rCode = asi_delete (csr);
  739.             break;
  740.          case 'u':                // Update current row
  741.             rCode = do_csr_update (csr);
  742.             break;
  743.          default:
  744.             cBuffer[0] = 'e';
  745.             break;
  746.          }
  747.          if ( cBuffer[0] == 'e' ) {
  748.              break;
  749.          }
  750.          if ( rCode == kAsiGood ) {
  751.              print_currow (csr);
  752.          }
  753.          print_diag(csr);
  754.          ads_getstring(0, "\nEnter [n]ext/[f]irst/[p]revios/[l]ast/[r]elative/[a]bsolute/[d]elete/[u]pdate: ", cBuffer);
  755.      }
  756.      return;
  757. }
  758.  
  759.  
  760. /**************************************************************************
  761.   This function processes cursor
  762. **************************************************************************/
  763. void do_cursor (ASISTATEMENT Stm)
  764. {
  765.     ASICURSOR   Csr;                          // Cursor
  766.     char        cBuffer[127];                 // Temporary buffer
  767.  
  768.     // Cursor attributes
  769.     EAsiCurScr  scr          = csrScr;
  770.     EAsiCurSns  sns          = csrSns;
  771.  
  772.     struct hbinds * iparams  = 0;
  773.  
  774.  
  775.     if (askCsrMode == kAsiTrue) {
  776.        ads_getstring(0, "\nEnter [s] for scrollable cursor: ", cBuffer);
  777.        if (cBuffer[0] == 's') {
  778.            scr = kAsiScroll;
  779.            sns = kAsiInsensitive;
  780.            ads_printf("\nScrollable cursor is assumed insensitive");
  781.        }
  782.        if (scr != kAsiScroll) {
  783.            ads_getstring(0, "\nEnter [i] for insensitive cursor: ", cBuffer);
  784.            if (cBuffer[0] == 'i') {
  785.                sns = kAsiInsensitive;
  786.            }
  787.        }
  788.     }
  789.     // Construct cursor
  790.     asi_constr_csr (&Csr);
  791.  
  792.     // Allocate cursor
  793.     if ( asi_alloc_csr (Csr, Stm, "MyCursor", scr, sns) == kAsiGood ) {
  794.         // Bind parameters
  795.         if (initParams (Csr, & iparams) == kAsiBad) {
  796.            asi_destroy_csr (&Csr);
  797.            return;
  798.         }
  799.         // Read parameters and open cursor repeatedly
  800.         do {
  801.             readParams (Csr, iparams);    // Read parameters if any
  802.             if ( asi_open (Csr) == kAsiBad ) {      // Open cursor
  803.                 print_diag(Csr);               // Print diagnostics
  804.             } else {
  805.                 if (showOne == kAsiFalse) {
  806.                     print_rowset (Csr);
  807.                 } else {
  808.                     scan_rowset (Csr);
  809.                 }
  810.                 if ( asi_close (Csr) == kAsiBad ) {    // close cursor
  811.                     print_diag(Csr);
  812.                 }
  813.             }
  814.             * cBuffer = '\0';
  815.             if (doAgain == kAsiTrue) {
  816.                 ads_getstring(0, "\nEnter [r] for re-open cursor: ", cBuffer);
  817.             }
  818.         } while ( cBuffer[0] == 'r' );
  819.         termParams (iparams);
  820.     } else {
  821.         print_diag(Csr);
  822.     }
  823.     // Destroy cursor
  824.     asi_destroy_csr (&Csr);
  825. }
  826.  
  827. /***************************************************************************
  828.   This function processes single row select statement
  829.   Select * into :a, etc...
  830. ***************************************************************************/
  831. static void do_single_select (ASISTATEMENT  Stm)
  832. {
  833.     struct hbinds * iparams  = 0;
  834.     struct hbinds * oparams  = 0;
  835.     char            cBuffer[127];
  836.     int             ii;
  837.  
  838.     if (initParams (Stm, & iparams) == kAsiBad) {
  839.         return;
  840.     }
  841.     // Initialize output buffer and bind them with output parameters
  842.     if (initDst (Stm, & oparams) == kAsiBad) {
  843.         termParams (iparams);
  844.         return;
  845.     }
  846.  
  847.     do {
  848.         readParams (Stm, iparams);
  849.         if (asi_execute (Stm) == kAsiBad ) {
  850.             print_diag(Stm);
  851.         } else {
  852.             for (ii = 0; ii < asi_colcount (Stm); ii ++) {
  853.                if (oparams[ii].indp >= 0) {
  854.                   ads_printf ("\n%s", oparams[ii].buffer);
  855.                }  else {
  856.                   ads_printf ("\nNull value");
  857.                }
  858.             }
  859.         }
  860.         if (doAgain == kAsiTrue) {
  861.            ads_getstring(0, "\nEnter [r] to re-execute: ", cBuffer);
  862.         }
  863.     } while ( cBuffer[0] == 'r' );
  864.  
  865.     termParams (iparams);
  866.     termParams (oparams);
  867. }
  868.  
  869.  
  870. /**************************************************************************
  871.    This function processes statements other than cursor and single
  872.    row select statement
  873. **************************************************************************/
  874. static void do_ordinary (ASISTATEMENT  Stm)
  875. {
  876.     struct hbinds * iparams  = 0;
  877.     char            cBuffer[127];
  878.  
  879.  
  880.     if (initParams (Stm, & iparams) == kAsiBad) {
  881.         return;
  882.     }
  883.     do {
  884.         readParams (Stm, iparams);
  885.         if (asi_execute (Stm) == kAsiBad ) {
  886.             print_diag(Stm);
  887.         } else {
  888.             if (asi_stm (Stm) == kAsiINSERT ||
  889.                 asi_stm (Stm) == kAsiDELETE_WHERE ||
  890.                 asi_stm (Stm) == kAsiUPDATE_WHERE) {
  891.                 ads_printf("\n %d row(s) affected", asi_rowqty (Stm));
  892.             }
  893.         }
  894.         if (doAgain == kAsiTrue) {
  895.            ads_getstring (0, "\nEnter [r] to re-execute: ", cBuffer);
  896.         }
  897.     } while ( cBuffer[0] == 'r' );
  898.     termParams (iparams);
  899. }
  900.  
  901.  
  902.  
  903. /******************************************************************************
  904.   This function processes SQL statement
  905. ******************************************************************************/
  906. void do_statement (char * stm)
  907. {
  908.    ASISTATEMENT Stm;     // SQL statement
  909.  
  910.    // Write to protocol file
  911.    if (echoToFile == kAsiTrue) {
  912.       fprintf (efDsc, "\n%s", stm);
  913.    }
  914.    /* If statement is prefixed by "N ", then the native DBMS statement is 
  915.       assummed */
  916.  
  917.  
  918.    if (stm[0]  == 'N' && stm[1] == ' ') {
  919.       /* Native statement */
  920.       asi_constr_native_stm (&Stm);
  921.       if (asi_iexecute  (Stm, session, stm + 2) == kAsiBad) {
  922.           ads_printf ("\nExecution of the native statement failed");
  923.           print_diag(Stm);
  924.       }
  925.  
  926.    } else {
  927.  
  928.       asi_constr_stm (&Stm);  /* Construct statement */
  929.  
  930.  
  931.       // Prepare SQL statement
  932.       //
  933.       if ( asi_prepare (Stm, session,  stm) == kAsiBad ) {
  934.           print_diag(Stm);
  935.           ads_printf ("\n%s", stm + asi_synerrpos (Stm));
  936.           if (pauseAfterE == kAsiTrue && pauseAfter == kAsiFalse) {
  937.               ads_getstring (0, "\nPress return to continue ...", buffer);
  938.           }
  939.       } else {
  940.           ads_printf("\nSQL statement type: %d", asi_stm (Stm));
  941.           print_pardsc(Stm);
  942.           switch (asi_stm (Stm)) {
  943.           case kAsiCURSOR:        /* Cursor */
  944.              print_coldsc(Stm);
  945.              do_cursor (Stm);
  946.              break;
  947.           case kAsiSELECT:       /* Single row select statement */
  948.              print_coldsc(Stm);
  949.              do_single_select(Stm);
  950.              break;
  951.           default:              /* Other types of statements */
  952.              do_ordinary(Stm);
  953.              break;
  954.           }
  955.       }
  956.    }
  957.    if (pauseAfter == kAsiTrue) {
  958.        ads_getstring (0, "\nPress return to continue ...", buffer);
  959.    }
  960.    asi_destroy_stm (&Stm);
  961. }
  962.  
  963. /**************************************************************************
  964.   This function creates environment description in asi.ini file
  965. **************************************************************************/
  966.  
  967. void create_env ()
  968. {
  969.    static char env [128];
  970.    static char drv [128];
  971.    ASICONFIG   config;
  972.  
  973.    display_section ("ENVIRONMENTS");
  974.    ads_getstring (0, "\nEnter new environemnt name : ", env);
  975.    if (*env == '\0') {
  976.       return;
  977.    }
  978.    display_section ("ASI DRIVERS");
  979.    ads_getstring (0, "\nEnter driver name : ", env);
  980.    if (*env == '\0') {
  981.       ads_printf ("\nDriver that runs environment must be specified");
  982.       return;
  983.    }
  984.    if (asi_constr_cfg (&config) == kAsiBad) {
  985.       ads_printf ("\nCan't construct configuration handle");
  986.       return ;
  987.    }
  988.    if (asi_createenv(config, env, drv) == kAsiBad) {
  989.       ads_printf ("\nError during environment creation");
  990.    }
  991.    asi_destroy_cfg (&config);
  992.  
  993. }
  994.  
  995. /****************************************************************************
  996.   This function drops environment description from the asi.ini file
  997. ****************************************************************************/
  998. void drop_env ()
  999. {
  1000.    static char env [128];
  1001.    ASICONFIG   config;
  1002.  
  1003.    display_section ("ENVIRONMENTS");
  1004.    ads_getstring (0, "\nEnter environemnt name to drop: ", env);
  1005.    if (*env == '\0') {
  1006.       return;
  1007.    }
  1008.    if (asi_constr_cfg (&config) == kAsiBad) {
  1009.       ads_printf ("\nCan't construct configuration handle");
  1010.       return ;
  1011.    }
  1012.    if (asi_dropenv(config, env) == kAsiBad) {
  1013.       ads_printf ("\nCannot drop environment");
  1014.    }
  1015.    asi_destroy_cfg (&config);
  1016. }
  1017.  
  1018.  
  1019. /**************************************************************************
  1020.   This function tunes ast sample program.
  1021. ***************************************************************************/
  1022. void
  1023. /*FCN*/do_settings ()
  1024. {
  1025.     static char buffer [128];
  1026.     EAsiBoolean keepDoing = kAsiTrue;
  1027.  
  1028.     for (keepDoing = kAsiTrue; keepDoing == kAsiTrue;) {
  1029.         // Print current settings
  1030.         ads_printf ("\nCurrent settings:\n");
  1031.         ads_printf ("\n1.  Script file format              <%s>", oldScrFile == kAsiTrue ? "Old" : "New");
  1032.         ads_printf ("\n2.  Show resulting table descriptor <%s>", showDsc == kAsiTrue ? "Yes" : "No");
  1033.         ads_printf ("\n3.  Prompt for cursor type          <%s>", askCsrMode == kAsiTrue ? "Yes" : "No");
  1034.         ads_printf ("\n4.  Scroll selection set            <%s>", showOne == kAsiTrue ? "By one row" : "Browse");
  1035.         ads_printf ("\n5.  Stop at page end                <%s>", stopPage == kAsiTrue ? "Yes" : "No");
  1036.         ads_printf ("\n6.  Pause after statement execution <%s>", pauseAfter == kAsiTrue ? "Yes" : "No");
  1037.         ads_printf ("\n7.  Pause after error               <%s>", pauseAfterE == kAsiTrue ? "Yes" : "No");
  1038.         ads_printf ("\n8.  Prompt for re-execution         <%s>", doAgain == kAsiTrue ? "Yes" : "No");
  1039.         ads_printf ("\n");
  1040.         ads_printf ("\nDefault cursor type:");
  1041.         ads_printf ("\n9.  Insensitive                     <%s>", csrSns == kAsiInsensitive ? "Yes": "No");
  1042.         ads_printf ("\n10. Scroll                          <%s>", csrScr == kAsiScroll ? "Yes": "No");
  1043.         ads_printf ("\n");
  1044.         if (echoToFile == kAsiFalse) {
  1045.             ads_printf ("\n11. Do not write output to protocol file");
  1046.         } else {
  1047.             ads_printf ("\n11. Write to protocol file          <%s>", FileName);
  1048.         }
  1049.  
  1050.         ads_getstring (0, "\n\nEnter number to switch item or return to exit: ", buffer);
  1051.  
  1052.         switch (atoi (buffer)) {
  1053.         case 1:
  1054.              oldScrFile = switch_boolean (oldScrFile);
  1055.              break;
  1056.         case 2:
  1057.              showDsc = switch_boolean (showDsc);
  1058.              break;
  1059.         case 3:
  1060.              askCsrMode = switch_boolean (askCsrMode);
  1061.              break;
  1062.         case 4:
  1063.              showOne = switch_boolean (showOne);
  1064.              break;
  1065.         case 5:
  1066.              stopPage = switch_boolean (stopPage);
  1067.              break;
  1068.  
  1069.         case 6:
  1070.              pauseAfter = switch_boolean (pauseAfter);
  1071.              break;
  1072.  
  1073.         case 7:
  1074.              pauseAfterE = switch_boolean (pauseAfterE);
  1075.              break;
  1076.  
  1077.         case 8:
  1078.              doAgain = switch_boolean (doAgain);
  1079.              break;
  1080.  
  1081.         case 9:
  1082.              if (csrSns == kAsiInsensitive)
  1083.                 csrSns = kAsiSnsUndef;
  1084.              else
  1085.                 csrSns = kAsiInsensitive;
  1086.              break;
  1087.  
  1088.         case 10:
  1089.              if (csrScr == kAsiScroll)
  1090.                 csrScr = kAsiNonScroll;
  1091.              else
  1092.                 csrScr = kAsiScroll;
  1093.              break;
  1094.  
  1095.         case 11:
  1096.              if (echoToFile == kAsiTrue) {
  1097.                 if (efDsc != 0) {
  1098.                    fclose (efDsc);
  1099.                    efDsc = 0;
  1100.                 }
  1101.                 echoToFile = kAsiFalse;
  1102.              } else {
  1103.                 ads_getstring (0, "\nEnter protocol file name: ", FileName);
  1104.                 if (*FileName == '\0') {
  1105.                    break;
  1106.                 }
  1107.                 efDsc = fopen (FileName, "at");
  1108.                 if (efDsc == 0) {
  1109.                     ads_printf ("\nCan't open file for append");
  1110.                     break;
  1111.                 }
  1112.                 {
  1113.                    char t[32], d[32];
  1114.                    echoToFile = kAsiTrue;
  1115.                    fprintf (efDsc, "\nStart writing %s, %s", _strdate (d), _strtime (t));
  1116.                 }
  1117.              }
  1118.              break;
  1119.         case 0:
  1120.              keepDoing = kAsiFalse;
  1121.              break;
  1122.  
  1123.         }
  1124.     }
  1125. }
  1126.  
  1127.  
  1128. /***********************************************************************
  1129.   This functions connects to SQL environment
  1130. ***********************************************************************/
  1131. void do_connect (void)
  1132. {
  1133.    // SQL environment name, username, and password.
  1134.    // Environment name is equal to the name of the DBMS driver executable.
  1135.    //
  1136.    static   char Password [128];
  1137.  
  1138.    static   char buffer[128];      // Temporary buffer
  1139.  
  1140.    if (session == 0) {
  1141.       // Construct session
  1142.       if (asi_constr_session (&session, appl) == kAsiBad) {
  1143.          ads_printf ("\nUnable to construct session");
  1144.          return;
  1145.       }
  1146.    }
  1147.  
  1148.  
  1149.    // Disconnect if already connection exists
  1150.    if (isConnected == kAsiTrue) {
  1151.       if (asi_disconnect (session) == kAsiBad) {
  1152.           ads_printf ("\nCan't terminate SQL session. Fix problems and try again ...");
  1153.           print_diag(session);
  1154.           return;
  1155.       }
  1156.       isConnected = kAsiFalse;
  1157.    }
  1158.  
  1159.    for (;;) {
  1160.        display_env ();    // Display available environments
  1161.  
  1162.        ads_getstring (0, "\nEnvironment: ", buffer);
  1163.        if ( * buffer == '\0' ) {
  1164.            break;
  1165.        }
  1166.  
  1167.        strncpy (EnvName, buffer, 128);
  1168.  
  1169.        ads_getstring (0, "User       : ", buffer);
  1170.        strncpy (UserName, buffer, 128);
  1171.  
  1172.        ads_getstring (0, "Password   : ", Password);
  1173.  
  1174.        if ( asi_connect (session, EnvName, UserName, Password) == kAsiGood ) {
  1175.            // display driver information
  1176.            asi_dbms (session, buffer, 128);
  1177.            ads_printf ("\nDBMS:          %s", buffer);
  1178.  
  1179.            asi_sqlobject (session, buffer, 128);
  1180.            ads_printf ("\nSQL Object Id: %s", buffer);
  1181.  
  1182.            asi_message (session, buffer, 128);
  1183.            ads_printf ("\nMessage:       %s", buffer);
  1184.            isConnected = kAsiTrue;
  1185.            break;
  1186.        }
  1187.        // Error found check diagnostic information...
  1188.        print_diag(session);
  1189.    }
  1190.    return ;
  1191. }
  1192.  
  1193. /****************************************************************************
  1194.   This function disconnects from SQL environment
  1195. ****************************************************************************/
  1196. void do_disconnect ()
  1197. {
  1198.    if (isConnected == kAsiFalse) {
  1199.       ads_printf ("\nNo current connection. Use ASICONNECT");
  1200.       return;
  1201.    }
  1202.    if (asi_disconnect (session) == kAsiBad) {
  1203.       print_diag (session);
  1204.       return;
  1205.    }
  1206.    isConnected = kAsiTrue;
  1207.    return;
  1208. }
  1209.  
  1210. /***************************************************************************
  1211.    This function prompt user for SQL statement and pass it to
  1212.    statment processing function.
  1213. ***************************************************************************/
  1214. void do_sqled ()
  1215. {
  1216.    EAsiBoolean      isNeedNew = kAsiTrue;  // End of read loop
  1217.  
  1218.    if (isConnected == kAsiFalse) {
  1219.        ads_printf ("\nNo current connection. Use ASICONNECT");
  1220.        return;
  1221.    }
  1222.  
  1223.    // Read SQL statements and process them
  1224.    //
  1225.    for (isNeedNew = kAsiTrue; isNeedNew == kAsiTrue; ) {
  1226.       * stm = '\0';
  1227.       ads_printf ("\n%s/%s", EnvName, UserName);
  1228.       for (;;) {
  1229.           // Print prompt and get line
  1230.           //
  1231.           ads_getstring (1, "> ", buffer);
  1232.  
  1233.           // Test for end and return if void response.
  1234.           //
  1235.           if ( * stm == '\0' && * buffer == '\0' ) {
  1236.               isNeedNew = kAsiFalse;
  1237.               break;
  1238.           }
  1239.  
  1240.           if ( buffer[strlen(buffer) - 1] == '\n' ) {
  1241.               buffer[strlen(buffer) - 1] = '\0';
  1242.           }
  1243.           if ( buffer[strlen(buffer) - 1] == ';' ) {
  1244.               buffer[strlen(buffer) - 1] = '\0';
  1245.               strcat (stm, buffer);
  1246.               do_statement (stm);
  1247.               * stm = 0;
  1248.               break;
  1249.           } else {
  1250.               strcat (stm, buffer);
  1251.               strcat (stm, " ");
  1252.           }
  1253.       }
  1254.    }
  1255.    return;
  1256. }
  1257.  
  1258. /****************************************************************************
  1259.    This function processes a new script file.
  1260.    Statement is terminated by ; symbol
  1261. ****************************************************************************/
  1262. void do_new_file (FILE * fh)
  1263. {
  1264.    char        * p;
  1265.  
  1266.    * stm = '\0';
  1267.    while (fgets (buffer, 127, fh) != 0) {
  1268.       if (strncmp (buffer, "//", 2) == 0) {
  1269.           continue;                       // Skip comments
  1270.       }
  1271.       if (strncmp (buffer, "@@", 2) == 0) {
  1272.           ads_printf ("%s", buffer + 2);
  1273.           continue;                       // Echo
  1274.       }
  1275.       if ( buffer[strlen(buffer) - 1] == '\n' ) {
  1276.           buffer[strlen(buffer) - 1] = '\0';    // Kill LF
  1277.       }
  1278.       if (*buffer == '\0') {
  1279.           continue;                       // Skip empty line
  1280.       }
  1281.  
  1282.       ads_printf ("%s\n", buffer);              // Echo line
  1283.  
  1284.       // Kill trailing blanks
  1285.       for (p = buffer + strlen (buffer) - 1; p != buffer; p --) {
  1286.          if (* p == ' ') {
  1287.             * p = '\0';
  1288.          } else {
  1289.             break;
  1290.          }
  1291.       }
  1292.       if (*buffer == '\0') {
  1293.           continue;                       // Skip empty line
  1294.       }
  1295.  
  1296.       if ( buffer[strlen(buffer) - 1] == ';' ) {
  1297.           buffer[strlen(buffer) - 1] = '\0';
  1298.           strcat (stm, buffer);
  1299.           do_statement (stm);
  1300.           ads_printf ("\n");
  1301.           *stm = '\0';
  1302.       } else {
  1303.           strcat (stm, buffer);
  1304.           strcat (stm, " ");
  1305.       }
  1306.    }
  1307.  
  1308.    return;
  1309. }
  1310.  
  1311.  
  1312. /*****************************************************************************
  1313.   This function reads the old script file (R12)
  1314.   (Line continuation symbol is & at the end of line)
  1315. *****************************************************************************/
  1316. void do_old_file (FILE * fh)
  1317. {
  1318.    char        * p;
  1319.  
  1320.    * stm = '\0';
  1321.    while (fgets (buffer, 127, fh) != 0) {
  1322.       if (*buffer == '$') {
  1323.           continue;                       // Skip comments
  1324.       }
  1325.       if ( buffer[strlen(buffer) - 1] == '\n' ) {
  1326.           buffer[strlen(buffer) - 1] = '\0';    // Kill LF
  1327.       }
  1328.       if (*buffer == '\0') {
  1329.           continue;                       // Skip empty line
  1330.       }
  1331.  
  1332.       // Kill trailing blanks
  1333.       for (p = buffer + strlen (buffer) - 1; p != buffer; p --) {
  1334.          if (* p == ' ') {
  1335.             * p = '\0';
  1336.          } else {
  1337.             break;
  1338.          }
  1339.       }
  1340.  
  1341.       if (*buffer == '\0') {
  1342.           continue;                          // Skip empty line
  1343.       }
  1344.  
  1345.       ads_printf ("%s\n", buffer);              // Echo line
  1346.       if ( buffer[strlen(buffer) - 1] == '&' ) {
  1347.           buffer[strlen(buffer) - 1] = '\0';
  1348.           strcat (stm, " ");
  1349.           strcat (stm, buffer);
  1350.           ads_printf ("\n");
  1351.       } else {
  1352.           strcat (stm, buffer);
  1353.           do_statement (stm);
  1354.           * stm = '\0';
  1355.       }
  1356.    }
  1357.    return;
  1358. }
  1359.  
  1360.  
  1361. /***************************************************************************
  1362.   This function processes the script file
  1363. ***************************************************************************/
  1364. void do_script (void)
  1365. {
  1366.  
  1367.    FILE        * fh = 0;
  1368.  
  1369.    if (isConnected == kAsiFalse) {
  1370.        ads_printf ("\nNo current connection. Use ASICONNECT");
  1371.        return;
  1372.    }
  1373.  
  1374.    ads_getstring (0, "\nEnter file name or return to exit: ", buffer);
  1375.    if (*buffer == 0) {
  1376.       return;
  1377.    }
  1378.  
  1379.    fh = fopen (buffer, "rt");
  1380.    if (fh == 0) {
  1381.       ads_printf ("\nCannot open file <%s>", buffer);
  1382.       return;
  1383.    }
  1384.  
  1385.    if (oldScrFile == kAsiFalse) {
  1386.       do_new_file (fh);
  1387.    } else {
  1388.       do_old_file (fh);
  1389.    }
  1390.    fclose (fh);
  1391. }
  1392.  
  1393.  
  1394. /****************************************************************************
  1395.   This function reads program setting from the asi.ini file
  1396. ****************************************************************************/
  1397. void readSettings ()
  1398. {
  1399.    ASICONFIG   config;        /* configuration file handle */
  1400.  
  1401.  
  1402.    /* Construct configuration file */
  1403.    if (asi_constr_cfg (&config) == kAsiBad) {
  1404.       ads_printf ("\nCannot construct ASI configuration file handle");
  1405.       return ;
  1406.    }
  1407.  
  1408.    // Script file version
  1409.    if (asi_getcfgstring (config, "ASISAMPLE", "ScriptVersion", "", buffer, 128) > 0) {
  1410.       if (strcmpi (buffer, "OLD") == 0) {
  1411.          oldScrFile = kAsiTrue;
  1412.       }
  1413.    }
  1414.  
  1415.    // Cursor mode query
  1416.    if (asi_getcfgstring (config, "ASISAMPLE", "AskCursor", "", buffer, 128) > 0) {
  1417.       if (strcmpi (buffer, "Yes") == 0) {
  1418.          askCsrMode = kAsiTrue;
  1419.       }
  1420.    }
  1421.  
  1422.    // Show result descriptor
  1423.    if (asi_getcfgstring (config, "ASISAMPLE", "ShowTableDsc", "", buffer, 128) > 0) {
  1424.       if (strcmpi (buffer, "Yes") == 0) {
  1425.          showDsc = kAsiTrue;
  1426.       }
  1427.    }
  1428.  
  1429.    // Read default cursor declartions
  1430.    if (asi_getcfgstring (config, "ASISAMPLE", "CsrSensitivity", "", buffer, 128) > 0) {
  1431.       if (strcmpi (buffer, "Insensitive") == 0) {
  1432.          csrSns = kAsiInsensitive;
  1433.       }
  1434.    }
  1435.    if (asi_getcfgstring (config, "ASISAMPLE", "CsrScrollability", "", buffer, 128) > 0) {
  1436.       if (strcmpi (buffer, "Scroll") == 0) {
  1437.          csrScr = kAsiScroll;
  1438.       }
  1439.    }
  1440.  
  1441.    // Read browse mode
  1442.    if (asi_getcfgstring (config, "ASISAMPLE", "Browse", "", buffer, 128) > 0) {
  1443.       if (strcmpi (buffer, "No") == 0) {
  1444.          showOne = kAsiTrue;
  1445.       }
  1446.    }
  1447.  
  1448.    // Read page stop flag
  1449.    if (asi_getcfgstring (config, "ASISAMPLE", "PageStop", "", buffer, 128) > 0) {
  1450.       if (strcmpi (buffer, "No") == 0) {
  1451.          stopPage = kAsiFalse;
  1452.       }
  1453.    }
  1454.  
  1455.    // Read "pause after statement execution" flag
  1456.    if (asi_getcfgstring (config, "ASISAMPLE", "PauseAfterExecution", "", buffer, 128) > 0) {
  1457.       if (strcmpi (buffer, "Yes") == 0) {
  1458.          pauseAfter = kAsiTrue;
  1459.       }
  1460.    }
  1461.  
  1462.    // Read "pause after error" flag
  1463.    if (asi_getcfgstring (config, "ASISAMPLE", "PauseAfterError", "", buffer, 128) > 0) {
  1464.       if (strcmpi (buffer, "No") == 0) {
  1465.          pauseAfterE = kAsiFalse;
  1466.       }
  1467.    }
  1468.  
  1469.    // Re-execute statement
  1470.    if (asi_getcfgstring (config, "ASISAMPLE", "Re-execute", "", buffer, 128) > 0) {
  1471.       if (strcmpi (buffer, "Yes") == 0) {
  1472.          doAgain = kAsiTrue;
  1473.       }
  1474.    }
  1475.  
  1476.    // Echo to file
  1477.    if (asi_getcfgstring (config, "ASISAMPLE", "EchoToFile", "", buffer, 128) > 0) {
  1478.       if (strcmpi (buffer, "Yes") == 0) {
  1479.          echoToFile = kAsiTrue;
  1480.       }
  1481.    }
  1482.  
  1483.    // Echo file name
  1484.    if (asi_getcfgstring (config, "ASISAMPLE", "EchoFile", "", buffer, 128) > 0) {
  1485.        strcpy (FileName, buffer);
  1486.    }
  1487.  
  1488.    // Time stattistics
  1489.    if (asi_getcfgstring (config, "ASISAMPLE", "ElapseTime", "", buffer, 128) > 0) {
  1490.       if (strcmpi (buffer, "Yes") == 0) {
  1491.          timeMeasure = kAsiTrue;
  1492.       }
  1493.    }
  1494.    asi_destroy_cfg (&config);   /* Destroy configuration handle */
  1495.  
  1496. }
  1497.  
  1498. /***********************************************************************
  1499.   This function writes its configuration into the asi.ini file
  1500.  
  1501. ***********************************************************************/
  1502. void writeSettings ()
  1503. {
  1504.    ASICONFIG config = 0;
  1505.  
  1506.    /* Construct configuration file */
  1507.    if (asi_constr_cfg (&config) == kAsiBad) {
  1508.       ads_printf ("\nCannot construct ASI configuration file handle");
  1509.       return ;
  1510.    }
  1511.  
  1512.    // Script file version
  1513.    if (oldScrFile == kAsiTrue) {
  1514.       asi_setcfgstring (config, "ASISAMPLE", "ScriptVersion", "Old");
  1515.    } else {
  1516.       asi_setcfgstring (config, "ASISAMPLE", "ScriptVersion", "New");
  1517.    }
  1518.  
  1519.    // Cursor mode query
  1520.    if (askCsrMode == kAsiTrue) {
  1521.       asi_setcfgstring (config, "ASISAMPLE", "AskCursor", "Yes");
  1522.    } else {
  1523.       asi_setcfgstring (config, "ASISAMPLE", "AskCursor", "No");
  1524.    }
  1525.  
  1526.    // Show result descriptor
  1527.    if (showDsc == kAsiTrue) {
  1528.       asi_setcfgstring (config, "ASISAMPLE", "ShowTableDsc", "Yes");
  1529.    } else {
  1530.       asi_setcfgstring (config, "ASISAMPLE", "ShowTableDsc", "No");
  1531.    }
  1532.  
  1533.    // Read default cursor declartions
  1534.    if (csrSns == kAsiInsensitive) {
  1535.       asi_setcfgstring (config, "ASISAMPLE", "CsrSensitivity", "Insensitive");
  1536.    } else {
  1537.       asi_setcfgstring (config, "ASISAMPLE", "CsrSensitivity", "");
  1538.    }
  1539.    if (csrScr == kAsiScroll) {
  1540.       asi_setcfgstring (config, "ASISAMPLE", "CsrScrollability", "Scroll");
  1541.    } else {
  1542.       asi_setcfgstring (config, "ASISAMPLE", "CsrScrollability", "");
  1543.    }
  1544.  
  1545.    //  browse mode
  1546.    if (showOne == kAsiTrue) {
  1547.       asi_setcfgstring (config, "ASISAMPLE", "Browse", "No");
  1548.    } else {
  1549.       asi_setcfgstring (config, "ASISAMPLE", "Browse", "Yes");
  1550.    }
  1551.  
  1552.    // page stop flag
  1553.    if (stopPage == kAsiFalse) {
  1554.       asi_setcfgstring (config, "ASISAMPLE", "PageStop", "No");
  1555.    } else {
  1556.       asi_setcfgstring (config, "ASISAMPLE", "PageStop", "Yes");
  1557.    }
  1558.  
  1559.    // "pause after statement execution" flag
  1560.    if (pauseAfter == kAsiTrue) {
  1561.       asi_setcfgstring (config, "ASISAMPLE", "PauseAfterExecution", "Yes");
  1562.    } else {
  1563.       asi_setcfgstring (config, "ASISAMPLE", "PauseAfterExecution", "No");
  1564.    }
  1565.  
  1566.    // Read "pause after error" flag
  1567.    if (pauseAfterE == kAsiFalse) {
  1568.       asi_setcfgstring (config, "ASISAMPLE", "PauseAfterError", "No");
  1569.    } else {
  1570.       asi_setcfgstring (config, "ASISAMPLE", "PauseAfterError", "Yes");
  1571.    }
  1572.  
  1573.    // Re-execute statement
  1574.    if (doAgain == kAsiTrue) {
  1575.       asi_setcfgstring (config, "ASISAMPLE", "Re-execute", "Yes");
  1576.    } else {
  1577.       asi_setcfgstring (config, "ASISAMPLE", "Re-execute", "No");
  1578.    }
  1579.  
  1580.    // Echo to file
  1581.    if (echoToFile == kAsiTrue) {
  1582.       asi_setcfgstring (config, "ASISAMPLE", "EchoToFile", "Yes");
  1583.    } else {
  1584.       asi_setcfgstring (config, "ASISAMPLE", "EchoToFile", "No");
  1585.    }
  1586.  
  1587.    // Echo file name
  1588.    if (*FileName != '\0') {
  1589.       asi_setcfgstring (config, "ASISAMPLE", "EchoFile", FileName);
  1590.    } else {
  1591.       asi_setcfgstring (config, "ASISAMPLE", "EchoFile", "");
  1592.    }
  1593.  
  1594.    // Time stattistics
  1595.    if (timeMeasure == kAsiTrue) {
  1596.       asi_setcfgstring (config, "ASISAMPLE", "ElapseTime", "Yes");
  1597.    } else {
  1598.       asi_setcfgstring (config, "ASISAMPLE", "ElapseTime", "No");
  1599.    }
  1600.  
  1601.    asi_destroy_cfg (&config);
  1602.  
  1603.  
  1604. }
  1605.  
  1606. /***********************************************************************
  1607.     This function is called to load external functions into AutoLISP.
  1608.     It also initializes asi application and reads program settings
  1609.     from the ASISAMPLE section in the asi.ini file
  1610. ***********************************************************************/
  1611. static short loadfunc ()
  1612. {
  1613.     short i = sizeof(cmd) /
  1614.               sizeof(CMDRX);          /* Number of functions */
  1615.  
  1616.  
  1617.  
  1618.     /* Initialize Asi application */
  1619.     if (asi_initasi (&appl) == kAsiBad) {
  1620.        ads_printf ("\nCannot initialize ASI");
  1621.        return RSERR;
  1622.     }
  1623.  
  1624.     /* Display ASI version */
  1625.     asi_version (appl, buff, 128);
  1626.     ads_printf ("\n%s", buff);
  1627.     ads_printf ("\n--------------------------------------\n");
  1628.  
  1629.     readSettings ();           /* Read ASISAMPLE section from the asi.ini file */
  1630.  
  1631.     while (i--)                       /* For every function from cmd */
  1632.     if (ads_defun(cmd[i].cmdname, i) != RTNORM)
  1633.         return RSERR;                 /* Wrong function definition */
  1634.  
  1635.     return RSRSLT;                    /* All functions were defined right */
  1636. }                                     /* End of loadfunc () */
  1637.  
  1638.  
  1639. /****************************************************************************
  1640.     This function is called to unload external functions into AutoLISP.
  1641. ****************************************************************************/
  1642. static short unloadfunc ()
  1643. {
  1644.     short i = sizeof(cmd) /
  1645.               sizeof(CMDRX);          /* Number of functions */
  1646.  
  1647.     writeSettings ();                 /* Write settings to asi.ini file */
  1648.  
  1649.     asi_termasi (&appl);              /* Terminate ASI */
  1650.  
  1651.     while (i--)                       /* For every function from cmd */
  1652.     if (ads_undef(cmd[i].cmdname, i) != RTNORM)
  1653.         return RSERR;                 /* Wrong function definition */
  1654.  
  1655.     return RTNORM ;                    /* All functions were defined right */
  1656. }                                     /* End of unloadfunc () */
  1657.  
  1658. /****************************************************************************
  1659.     This function is called to start external function.
  1660. ****************************************************************************/
  1661. static short execfunc ()
  1662. {
  1663.     int i = ads_getfuncode ();        /* Function number */
  1664.  
  1665.     ads_retvoid ();                   /* command returns void */
  1666.     if (i == RTERROR)
  1667.         return RSERR;                 /* Error */
  1668.  
  1669.     (cmd[i].cmdfunc)();               /* Call function */
  1670.  
  1671.     return RSRSLT;                    /* OK */
  1672. }                                     /* End of execfunc () */
  1673.  
  1674.  
  1675. /****************************************************************************
  1676.     Main entry point.
  1677. ****************************************************************************/
  1678. void
  1679. /*FCN*/main (int argc,                /* Argument count */
  1680.              char *argv[])            /* Argument vector */
  1681. {
  1682.     short scode = RSRSLT;             /* Default result code */
  1683.     int stat;                         /* Return value from ads_link */
  1684.  
  1685.     ads_init(argc, argv);             /* Initialize the interface */
  1686.  
  1687.     for (;;) {                        /* Main loop */
  1688.                                       /* Link with AutoCAD */
  1689.         if ((stat = ads_link (scode)) < 0) {
  1690.                                       /* AutoCAD error */
  1691.                                       /* Print error message */
  1692.             printf("\nBad status from ads_link() = %d\n", stat);
  1693.             fflush (stdout);          /* Fflush the print buffer */
  1694.             exit (1);                 /* Exit */
  1695.         }
  1696.  
  1697.         scode = RSRSLT;                // Default result value
  1698.  
  1699.         switch (stat) {                // Check for the following cases here
  1700.         case RQXLOAD:                  // Load function by (xload) command
  1701.            scode = loadfunc ();        // Register ADS external functions
  1702.                                        // and initialize ASI
  1703.            break;
  1704.  
  1705.         case RQSUBR:                  /* Invoke function */
  1706.            scode = execfunc ();       /* Call function */
  1707.            break;
  1708.  
  1709.         case RQXUNLD:
  1710.         case RQEND:
  1711.         case RQQUIT:
  1712.             unloadfunc() ;            /* Unload the commands and terminate ASI */
  1713.             break ;
  1714.         }
  1715.     }
  1716. }                                     /* End of main () */
  1717.  
  1718. /*EOF*/
  1719.  
  1720.