/**************************************************************************/
/* Copyright (c) 1989 by Daniel R. Zemke -- CompuServe [73230,1543]       */
/*                                                                        */
/* Purpose:     Creates one or more libraries from all "*.c" files        */
/*              in the current directory.                                 */
/*                                                                        */
/* Example:     Executing      buildlib mylib scl                         */
/*                                                                        */
/*              Creates: mylibS.lib, mylibC.lib AND mylibL.lib            */
/*              (i.e. small, compact and large library versions of MYLIB) */
/*                                                                        */
/* Parameters:  Two and only two parameters are required.  The first is   */
/*              used to specify the common name prefix for the series     */
/*              of generated libraries.  The second parameter is a char   */
/*              string of one or more characters indicating desired       */
/*              memory models.  Each library name is formed by suffixing  */
/*              the library series name with a character from the memory  */
/*              model list.  The memory model list consists of            */
/*              contiguous characters without any surrounding quotes.     */
/*              Valid characters for the memory model list are :          */
/*                         t s m c l h                                    */
/*                                                                        */
/* Assumptions: Turbo C for compile of source and DOS 2+ for execution.   */
/*              TCC and TLIB are in the current search path.              */
/*              Every "*.c" file in the current directory is to be        */
/*                 included in target lib(s).                             */
/*              Adequate memory to invoke tcc from within BUILDLIB        */
/*                 using the system() call.                               */
/**************************************************************************/

#include <dir.h>
#include <process.h>
#include <stdio.h>
#include <string.h>

#define MAX_LIBNAME_CHARS 7
#define MAX_CMD_SIZE      255

void add_obj(char *lib_add_cmd, char *obj_name)
/*********************************************************/
/* Adds "obj_name" to lib and then deletes the original. */
/*********************************************************/
{
char cmd[MAX_CMD_SIZE];

   sprintf(cmd,"%s%s",lib_add_cmd,obj_name);
   system(cmd);
   sprintf(cmd,"del %s",obj_name);
   system(cmd);
}

void create_lib(char *lib_name)
/**********************************************************************/
/* Creates a library out of all object files in the current directory */
/**********************************************************************/
{
char cmd[MAX_CMD_SIZE];
struct ffblk dos_fcb;

   if ( findfirst("*.obj",&dos_fcb,0) == 0) {
       sprintf(cmd,"del %s.lib",lib_name);   /*Attempt delete "lib_name.lib"*/
       system(cmd);
/* Create lib from "*.obj" in current directory */
       sprintf(cmd,"tlib %s /E +",lib_name);
       add_obj(cmd,dos_fcb.ff_name);
       while(findnext(&dos_fcb) == 0)
          add_obj(cmd,dos_fcb.ff_name);
   }

/* Delete "lib_name.bak" created by using "/E" for extended directory */
   sprintf(cmd,"del %s.bak",lib_name);
   system(cmd);
}

void compile(char *lib_type)
/**********************************************************************/
/* Compiles all ".c" files in the current directory with memory model */
/* specified by "lib_type".                                           */
/**********************************************************************/
{
static char *lib_type_pos = NULL;
#define LIB_TYPE_POS      '^'     /* change compile_cmd if this is changed */
static char *compile_cmd  = "tcc -m^ -k- -a -c -G -O -Z -d *.c";
/***********************************************************************/
/* The above variable specifies the compile options for building libs. */
/* Note : The '^' after the "-m" is required and will be replaced by a */
/*        character indicating a valid memory model during execution.  */
/***********************************************************************/

   if (lib_type_pos == NULL)
      lib_type_pos = strchr(compile_cmd,LIB_TYPE_POS);

   *lib_type_pos = *lib_type;

   system(compile_cmd);
}

int chk_parms(int argc, char **argv)
/************************************************/
/* Checks that program parameters are resonable */
/************************************************/
{
   if (argc != 3) {
      fprintf(stderr,"2 and only 2 parameters are required\n");
      fprintf(stderr,"   1st parm specifies base lib_name\n");
      fprintf(stderr,"   2nd parm is a char list of memory models : tsmclh\n");
      return(1);
   }

   if (strlen(argv[1]) > MAX_LIBNAME_CHARS) {
      fprintf(stderr,"Length of base lib_name is too long\n");
      return(1);
   }

   if ( strspn(argv[2],"tsmclh") != strlen(argv[2]) ) {
      fprintf(stderr,"Invalid memory model specified in 2nd parm\n");
      return(1);
   }

   return(0);
}

int main(int argc, char **argv)
{
char lib_name[MAX_LIBNAME_CHARS + 2];
char *lib_mod;
char *lib_type;

   if (chk_parms(argc,argv))
      return(1);

   strcpy(lib_name,argv[1]);
   lib_mod = lib_name + strlen(lib_name);
   strcat(lib_name," ");

   for (lib_type = argv[2]; *lib_type; lib_type++) {
      compile(lib_type);
      *lib_mod = *lib_type;
      create_lib(lib_name);
   }

   return(0);
}
