home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / UTILITY / CHUCKSUB.ZIP / CHUCKSUB.C next >
C/C++ Source or Header  |  1994-02-23  |  8KB  |  292 lines

  1. /*
  2.  * Combine a group of files, sorted by a number extension.  Designed
  3.  * mostly for combining WWIV Link subs listings into a single text file.
  4.  *
  5.  * This will make sure that the files are put together like 1,2,3,..etc.
  6.  * and not 1,10,11,2,3,4... etc...
  7.  *
  8.  * This program will also allow you to specify a header file to be placed
  9.  * at the begining of the subs listings.
  10.  *
  11.  * Created: 1/17/94 by Charles R. Grosvenor Jr.
  12.  *
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <alloc.h>
  19. #include <io.h>
  20. #include <dos.h>
  21. #include <dir.h>
  22.  
  23. void create_subs(char *filespec);
  24. void add_name(char name[], struct name_rec *first);
  25. void print_list(char *outputfilename, char *headerfilename);
  26. void delete_rec(struct name_rec *first);
  27. int string_num_cmp(char *name1, char *name2);
  28.  
  29. struct name_rec{
  30.   char name[121];
  31.   struct name_rec *next, *previous;
  32. };
  33.  
  34. struct name_rec *subs_first;
  35.  
  36.  
  37. void main(int argc, char **argv)
  38. {
  39.   if (argc>3)
  40.   {
  41.     create_subs(argv[1]);
  42.     print_list(argv[2],argv[3]);
  43.     delete_rec(subs_first);
  44.   }
  45.   else
  46.   {
  47.     printf("Need command line arguments: subs.?? output.lst header.asc\n\n");
  48.     printf("Where subs.?? is the file spec for the subs to find\n");
  49.     printf("..... output.lst is the file to create\n");
  50.     printf("and header.asc is the name of a file to place before the subs lists\n\n");
  51.   }
  52. }
  53.  
  54.  
  55. void create_subs(char *filespec)
  56. /* Name:    Charles R. Grosvenor Jr.
  57.  * Date:    September 14, 1993
  58.  * Purpose:     Grabs the names of the files that fit the file spec.
  59.  * Revision:    Level 1 -=- Charles R. Grosvenor Jr. 09/14/93
  60.  */
  61. {
  62.   struct ffblk fileinfo;
  63.   char tempfilename[81], path[81],specs[81];
  64.   int loop,loop2;
  65.  
  66.   /* gotta seperate the path */
  67.   strcpy(path,filespec);
  68.   loop=strlen(filespec)-1;
  69.   loop2=0;
  70.   while ( (path[loop]!='\\') && (loop>=0) )
  71.   {
  72.     specs[loop2++]=path[loop];
  73.     path[loop--]='\0';
  74.   }
  75.   specs[loop2]='\0';
  76.  
  77.   if (findfirst(filespec, &fileinfo, FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_ARCH) ==-1)
  78.   {
  79.     printf("Unsuccessful attempt to create sub files for command line: %s.",filespec);
  80.   }
  81.   else
  82.   {
  83.     printf("%12s \r\n",fileinfo.ff_name);
  84.     strcpy(tempfilename,path);
  85.     strcat(tempfilename,fileinfo.ff_name);
  86.     add_name(tempfilename, subs_first);
  87.     while (findnext(&fileinfo)==0)
  88.     {
  89.       printf("%12s\r\n",fileinfo.ff_name);
  90.       strcpy(tempfilename,path);
  91.       strcat(tempfilename,fileinfo.ff_name);
  92.       add_name(tempfilename, subs_first);
  93.     }
  94.   }
  95. }
  96.  
  97.  
  98. void add_name(char name[], struct name_rec *first)
  99. /* Name       : add_name
  100.  * Dependicies: needs the name to add to the list, the pointer
  101.  *        to the first data element in that list
  102.  * Purpose    :  Adds and sorts the names passed to it
  103.  * Revision   :  October 17, 1993 -=- Charles R. Grosvenor Jr. -=- Level 0
  104.  *               Januray 17, 1994 -=- Charles R. Grosvenor Jr. -=- Level 1
  105.  *               Changed to create just one alphebtical list
  106.  */
  107.  
  108. {
  109.   struct name_rec *temp_ptr;
  110.  
  111.   if (NULL==first)
  112.   {
  113.     /* allocate the memory */
  114.     if ( (first=(struct name_rec*)malloc(sizeof(struct name_rec))) == NULL)
  115.     {
  116.       printf("Out of memory\r\n");
  117.       exit(1);
  118.     }
  119.     else
  120.     {
  121.       strcpy(first->name,name);
  122.       first->next=NULL;
  123.       first->previous=NULL;
  124.       subs_first=first; 
  125.     /* the structure is not initalized to a memory location, so one */
  126.     /* needs to be set up, when it is, we can't assign it to NULL,  */
  127.     /* so we have to use the above case statements. */
  128.     }
  129.   }
  130.   else
  131.   {  /* sort it */
  132.     while ( (first->next!=NULL) && (string_num_cmp(first->name,name)<0) )
  133.     {
  134.       first=first->next;
  135.     }
  136.     if (string_num_cmp(first->name,name)<0)  /* this item is the largest */
  137.     {
  138.       if ( (temp_ptr=(struct name_rec*)malloc(sizeof(struct name_rec))) == NULL)
  139.       {
  140.     printf("Out of memory\r\n");
  141.     exit(1);
  142.       }
  143.       else
  144.       {
  145.     temp_ptr->next=NULL;
  146.     temp_ptr->previous=first;
  147.     first->next=temp_ptr;
  148.     strcpy(temp_ptr->name,name);
  149.       }
  150.     }
  151.     else /* inserting inbetween */
  152.     {
  153.       if ( (temp_ptr=(struct name_rec*)malloc(sizeof(struct name_rec))) == NULL)
  154.       {
  155.     printf("Out of memory\r\n");
  156.     exit(1);
  157.       }
  158.       else
  159.       {
  160.     temp_ptr->next=first;
  161.     temp_ptr->previous=first->previous;
  162.     first->previous=temp_ptr;
  163.     strcpy(temp_ptr->name,name);
  164.     if (temp_ptr->previous!=NULL)
  165.     {
  166.       temp_ptr=temp_ptr->previous;
  167.       temp_ptr->next=first->previous;
  168.     }
  169.     else
  170.     {
  171.         subs_first=temp_ptr;
  172.     }
  173.       }
  174.     }
  175.   }
  176. }
  177.  
  178. void delete_rec(struct name_rec *first)
  179. /* Name       : delete_rec
  180.  * Dependicies: pointer to the list to destroy
  181.  * Purpose    : Frees memory at the end of the program's run
  182.  * Revision   : October 17, 1993 -=- Charles R. Grosvenor Jr. -=- Level 0
  183.  */
  184.  
  185. {
  186.   struct name_rec *temp_ptr;
  187.  
  188.   while (first!=NULL)
  189.   {
  190.     temp_ptr=first->next;
  191.     free((struct name_rec *)first);
  192.     first=temp_ptr;
  193.   }
  194. }
  195.  
  196. void print_list(char *outputfilename, char *headerfilename)
  197. /* Name       : print_list
  198.  * Dependicies: needs to already have the lists defined
  199.  * Purpose    : writes the text file out to the disk
  200.  * Revision   : October 17, 1993 -=- Charles R. Grosvenor Jr. -=- Level 0
  201.  */
  202.  
  203. {
  204.   struct name_rec *tempsubs;
  205.   FILE *master, *current;
  206.   char templine[181];
  207.  
  208.   master=fopen(outputfilename,"w");
  209.   if ((current=fopen(headerfilename, "r"))==NULL)
  210.   {
  211.     printf("No header description file found\n\n");
  212.   }
  213.   else
  214.   {
  215.     while (!feof(current))
  216.     {
  217.       fgets(templine, 180, current);
  218.       fputs(templine, master);
  219.     }
  220.     fclose(current);
  221.   }
  222.   tempsubs=subs_first;
  223.   while (tempsubs!=NULL)
  224.   {
  225.     printf("%s\r\n", tempsubs->name);
  226.     /* add to the master file */
  227.     current=fopen(tempsubs->name, "r");
  228.     while (!feof(current))
  229.     {
  230.       fgets(templine, 180, current);
  231.       fputs(templine, master);
  232.     }
  233.     fclose(current);
  234.     tempsubs=tempsubs->next;
  235.   }
  236.   fclose(master);
  237.   printf("end of list\r\n");
  238. }
  239.  
  240. int string_num_cmp(char *name1, char *name2)
  241. /* Name       : string_num_cmp
  242.  * Dependicies: none that I remember
  243.  * Purpose    : Compares two filenames, if the first part of the extension is
  244.  *              equal, then it checks the last half numerically if they
  245.  *              begin with numbers.
  246.  * Revision   : January 17, 1994 -=- Charles R. Grosvenor Jr. -=- Level 0
  247.  */
  248.  
  249. {
  250.   char string1[81], string2[81], temp_name1[81], temp_name2[81];
  251.   int  number1, number2, return_value;
  252.  
  253.   strcpy(temp_name1, name1);
  254.   strcpy(temp_name2, name2);
  255.   strcpy(string1,strtok(temp_name1,".\0"));
  256.   strcpy(string2,strtok(temp_name2,".\0"));
  257.   return_value=strcmpi(string1,string2);
  258.   if (return_value==0)
  259.   { /* first part of extensions are equal */
  260.     strcpy(temp_name1, name1);
  261.     strcpy(temp_name2, name2);
  262.     strcpy(string1,strtok(temp_name1,"."));
  263.     strcpy(string1,strtok(NULL,"."));
  264.     strcpy(string2,strtok(temp_name2,"."));
  265.     strcpy(string2,strtok(NULL,"."));
  266.     if ( (string1[0]>='0') && (string1[0]<='9') &&
  267.      (string2[0]>='0') && (string2[0]<='9') )
  268.     {  /* both extensions begin with numbers */
  269.        number1=atoi(string1);
  270.        number2=atoi(string2);
  271.        if (number1<number2)
  272.        {
  273.      return_value=-1;
  274.        }
  275.        else
  276.        if (number1>number2)
  277.        {
  278.      return_value=1;
  279.        }
  280.        else
  281.        {
  282.      return_value=0;
  283.        }
  284.     }
  285.     else
  286.     {
  287.       return_value=strcmpi(temp_name1, temp_name2);
  288.     }
  289.   }
  290.   return(return_value);
  291. }
  292.