/******************************************************************************
**
** Source File Name = makeapi.sqc  1.15
** Licensed Materials - Property of IBM
**
** (C) COPYRIGHT International Business Machines Corp. 1995, 1999 
** All Rights Reserved.
**
** US Government Users Restricted Rights - Use, duplication or
** disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
**
**
**    PURPOSE :
**       This program is an example of how API programs are compiled and
**       bounded for DB2 applications.  Input parameters from the command line
**       are as follows:
**
**             makeapi programName.ext databaseName
**
**       The program will discern how to compile and link the programs from
**       the extensions that are input from the programName in the command
**       line.  Preparing and Binding will be done on appropriate programs.
**
**
**    STRUCTURES USED :
**       sqlopt
**       sqlca
**
**    APIs USED :
**       START DATABASE MANAGER     sqlepstart()
**       PREOCOMPILE PROGRAM        sqlaprep()
**       BIND                       sqlabndx()
**       STOP DATABASE MANAGER      sqlepstp()
**
**    FUNCTIONS DECLARED :
**       'C' COMPILER LIBRARY :
**          stdio.h  -  printf
**          string.h -  strncpy
**
**       DBMS LIBRARY :
**          sqlenv.h -  see "APIs USED" above
**
**       OTHER :
**
**    EXTERNAL DEPENDANCIES :
**       - Existing database for precompile purposes.
**       - Precompile with the SQL precompiler (PREP in DB2)
**       - Binding to a database (BIND in DB2)
**       - Compiling and linking with the appropriate compiler
**
**    EXAMPLE USAGE:
**       - "makeapi updat.sqc sample" 
**
** For more information about these samples see the README file.
**
** For more information on programming in C, see the:
**   -  "Programming in C and C++" section of the Application Development Guide
** For more information on Building C Applications, see the:
**   -  "Building C Applications" section of the Application Building Guide.
**
** For more information on the SQL language see the SQL Reference.
**
*******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlenv.h>
#include "util.h"

#define CHECKERR( CE_STR ) if ( check_error( CE_STR, &sqlca ) != 0 ) return( 1 ) ;

EXEC SQL INCLUDE SQLCA ;

int main ( int argc, char *argv[] ) {

   struct sqlopt * sqloptStructPointer ;
   struct sqloptions * optionsPointer ;
   int i, rc ;
   char programName[15] ;
   char bindName[15] ;
   char compiler_line[255] ;
   char linker_line[255] ;
   char * extension ;
   char connInput[19] ;
   char option ;

   EXEC SQL BEGIN DECLARE SECTION ;
      char dbAlias[9] ;
      char userid[9] ;
      char passwd[19] ;
   EXEC SQL END DECLARE SECTION ;

   if ( argc != 3 ) {
      printf( "\nUSAGE : makeapi program db_name\n\n" ) ;
      return( 1 ) ;
   }

   if ( ( extension = strstr( argv[1], "." ) ) == 0 ) return( 1 ) ;

   if ( strcmp( extension, ".sqc" ) == 0 ||
        strcmp( extension, ".c" ) == 0 ||
        strcmp( extension, ".o" ) == 0 ||
        strcmp( extension, ".obj" ) == 0
      ) {

         /* this input file needs to be compiled and/or linked */
         strcpy( programName, argv[1] ) ;
         i = strlen( programName ) - 1 ;
         while ( i > 0 ) {
           if ( programName[i] == '.' ) {
              programName[i] = '\0' ;
              break ;
           }
           i-- ;
         }

         strcpy( bindName, programName ) ;
         strcat( bindName, ".bnd" ) ;

         printf("\nEnsure the compiler and linker options and the path for DB2 include and\n");
         printf("library files are set correctly in this program. If they are not,\n");
         printf("change the 'compile_line' and/or 'linker_line' strings in the program.\n\n");

         #if defined(DB2AIX)
           strcpy( compiler_line, "xlc -I/usr/lpp/db2_05_00/include -c util.c " ) ;
           strcat( compiler_line, programName ) ;
           strcat( compiler_line, ".c" ) ;
           strcpy( linker_line, "xlc -o " ) ;
           strcat( linker_line, programName ) ;
           strcat( linker_line, " " ) ;
           strcat( linker_line, programName ) ;
           strcat( linker_line, ".o " ) ;
           strcat( linker_line, "util.o -L/usr/lpp/db2_05_00/lib -ldb2" ) ;
         #elif defined(DB2HP)
           strcpy( compiler_line, "cc -Aa +e -I/opt/IBMdb2/v5.0/include -c util.c " ) ;
           strcat( compiler_line, programName ) ;
           strcat( compiler_line, ".c" ) ;
           strcpy( linker_line, "cc -o " ) ;
           strcat( linker_line, programName ) ;
           strcat( linker_line, " " ) ;
           strcat( linker_line, programName ) ;
           strcat( linker_line, ".o " ) ;
           strcat( linker_line, "util.o -L/opt/IBMdb2/v5.0/lib -ldb2 -lhppa" ) ;
         #elif defined(DB2SUN)
           strcpy( compiler_line, "cc -I/opt/IBMdb2/v5.0/include -c util.c " ) ;
           strcat( compiler_line, programName ) ;
           strcat( compiler_line, ".c" ) ;
           strcpy( linker_line, "cc -o " ) ;
           strcat( linker_line, programName ) ;
           strcat( linker_line, " " ) ;
           strcat( linker_line, programName ) ;
           strcat( linker_line, ".o " ) ;
           strcat( linker_line, "util.o -L/opt/IBMdb2/v5.0/lib -ldb2" ) ;
         #elif defined(DB2NT)
           strcpy( compiler_line, "cl -Z7 -Od -c -W2 -D_X86_=1 -DWIN32 -Ic:\\sqllib\\include util.c " ) ;
           strcat( compiler_line, programName ) ;
           strcat( compiler_line, ".c" ) ;
           strcpy( linker_line, "link -debug:full -debugtype:cv -out:" ) ;
           strcat( linker_line, programName ) ;
           strcat( linker_line, ".exe " ) ;
           strcat( linker_line, programName ) ;
           strcat( linker_line, ".obj " ) ;
           strcat( linker_line, "util.obj db2api.lib" ) ;
         #elif defined(DB2OS2)
           strcpy( compiler_line, "icc -C+ -O- -Ti+ -Ic:\\sqllib\\include util.c " ) ;
           strcat( compiler_line, programName ) ;
           strcat( compiler_line, ".c" ) ;
           strcpy( linker_line, "ilink /NOFREE /NOI /DEBUG /ST:32000 /PM:VIO util.obj " ) ;
           strcat( linker_line, programName ) ;
           strcat( linker_line, ".obj, " ) ;
           strcat( linker_line, programName ) ;
           strcat( linker_line, ".exe" ) ;
           strcat( linker_line, ",,c:\\sqllib\\lib\\db2api;" ) ;
         #endif

         if (strstr(argv[1], ".sqc" ) != NULL ||
            strstr(argv[1], ".c" ) != NULL) {

            if (strstr(argv[1], ".sqc" ) != NULL) {
               /* the file is an embedded SQL program */

               printf( "--->starting the Database Manager\n" ) ;
               /***********************************\
               * START DATABASE MANAGER API called *
               \***********************************/
               sqlepstart(NULL, &sqlca) ;
               CHECKERR( "START DATABASE MANAGER" ) ;

               printf( "input your user id: (default: none)\n" ) ;
               gets( connInput ) ;
               strcpy( userid, connInput ) ;

               printf( "input your password: (default: none)\n" ) ;
               gets( connInput ) ;
               strcpy( passwd, connInput ) ;

               printf( "\n--->Connecting to %s database\n", argv[2] ) ;
               /* by definition of this program,
                  the last argument must be the name of the database */
               strcpy( dbAlias, argv[2] ) ;
               EXEC SQL CONNECT TO :dbAlias USER :userid USING :passwd ;
               CHECKERR( "CONNECT TO database" ) ;
               sqloptStructPointer = ( struct sqlopt * )
                 malloc( sizeof( struct sqlopt ) + ( sizeof( struct sqloptions ) * 2 ) ) ;
               sqloptStructPointer->header.allocated = 2 ;
               sqloptStructPointer->header.used = 2 ;
               optionsPointer = sqloptStructPointer->option ;

               optionsPointer->type = SQL_BIND_OPT ;
               optionsPointer->val = 0 ;            /* bind with default name */
               optionsPointer++ ;
               optionsPointer->type = SQL_PKG_OPT ;
               optionsPointer->val = 0 ;

               printf( "\n--->precompiling the program: %s\n", argv[1] ) ;
               /*******************************\
               * PRECOMPILE PROGRAM API called *
               \*******************************/
               sqlaprep( argv[1], "message.pb1", sqloptStructPointer, &sqlca ) ;
               CHECKERR( "precompile program" ) ;
               printf( "precompiling successful\n" ) ;
               /* nullifying the options for the BIND API */
               optionsPointer = sqloptStructPointer->option ;
               optionsPointer->type = SQL_NO_OPT ;
               optionsPointer->val = 0 ;
               optionsPointer++ ;
               optionsPointer->type = SQL_NO_OPT ;
               optionsPointer->val = 0 ;

               printf( "\n--->binding the application: %s\n", bindName ) ;
               /*****************\
               * BIND API called *
               \*****************/
               sqlabndx( bindName, "message.pb2", sqloptStructPointer, &sqlca ) ;
               CHECKERR( "binding the application" ) ;

               printf( "\n--->connect resetting\n" ) ;
               EXEC SQL CONNECT RESET ;
               CHECKERR( "CONNECT RESET" ) ;

               printf( "\nWould you like to stop the Database Manager? (y/n)\n" ) ;
               option = getc( stdin ) ;
               if ( option == 'y' ) {
                  printf( "\n--->stopping the Database Manager\n" ) ;
                  /**********************************\
                  * STOP DATABASE MANAGER API called *
                  \**********************************/
                  sqlepstp(NULL, &sqlca ) ;
                  CHECKERR( "stopping database manager" ) ;
               }  /* endif */
            }  /* endif */

            /* executing the compiler */
            printf( "\n--->compiling program %s\n", programName ) ;
            rc = system( compiler_line );
            if (rc) printf( "return value = %d\n", rc ) ;

         }
      } else {
         if ( extension != NULL )
            printf( ":%s: can not be compiled, must end with '.c' or '.sqc'\n", argv[1] ) ;
      }

   /* executing the linker */
   printf( "\n--->linking program %s\n", programName ) ;
   rc = system( linker_line );
   if (rc) printf( "return value = %d\n", rc ) ;

   return( 0 ) ;

}  /* end of program : makeapi.sqc */