home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / FILECAT.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  5KB  |  237 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4. ** FILECAT.C - Adds one file onto another vertically, as with a column
  5. ** block in QEdit.
  6. **
  7. ** Must be compiled in Compact or Large memory models to use larger
  8. ** files.
  9. **
  10. ** Public Domain by Chad Wallace, 1996
  11. */
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include "filecat.h"
  17.  
  18. #ifndef FALSE
  19. #define FALSE 0
  20. #define TRUE 1
  21. #endif
  22.  
  23. /*
  24. ** filecat() error codes
  25. */
  26.  
  27. enum {
  28.       FC_SUCCESS = 0,         /* Success */
  29.       FC_RDEST,               /* Error reading dest file */
  30.       FC_WDEST,               /* Error writing dest file */
  31.       FC_SRC,                 /* Error with src file */
  32.       FC_MEM,                 /* Out of memory */
  33.       FC_LINES,               /* Too many lines (increase max_lines) */
  34.       FC_LINE                 /* Line too long (increase line_max) */
  35. };
  36.  
  37. /*
  38. ** These are global to save overhead when calling cleanup function
  39. */
  40.  
  41. static char ** str_arr;
  42. static char * temp_str;
  43.  
  44. /*
  45. ** Frees all allocated memory and closes specified file
  46. */
  47.  
  48. static void cleanup(int tot_lines, FILE * fp)
  49. {
  50.       if (str_arr)
  51.       {
  52.             for ( ; tot_lines >= 0; tot_lines--)
  53.                   free(str_arr[tot_lines]);
  54.             free(str_arr);
  55.       }
  56.       if (temp_str)
  57.             free(temp_str);
  58.       if (fp)
  59.             fclose(fp);
  60. }
  61.  
  62. int filecat(char * dest_file, char * src_file, int line_max, int max_lines)
  63. {
  64.       int i, tot_lines;
  65.       unsigned int lines_len;
  66.       FILE * fp;
  67.  
  68.       if ((temp_str = malloc(line_max + 1)) == NULL)
  69.             return FC_MEM;
  70.  
  71.       /* Allocate memory for pointers to line strings */
  72.  
  73.       if ((str_arr = calloc(max_lines + 1, sizeof(char *))) == NULL)
  74.       {
  75.             free(temp_str);
  76.             return FC_MEM;
  77.       }
  78.  
  79.       /* Open destination file */
  80.  
  81.       if ((fp = fopen(dest_file, "rt")) == NULL)
  82.       {
  83.             free(temp_str);
  84.             free(str_arr);
  85.             return FC_RDEST;
  86.       }
  87.  
  88.       /* Read destination file into string array line-by-line */
  89.  
  90.       for (i = 0;
  91.            (fgets(temp_str, line_max + 1, fp) != NULL) && (i <= max_lines);
  92.            i++)
  93.       {
  94.             /* Strip trailing newline from line read */
  95.  
  96.             if (temp_str[strlen(temp_str) - 1] == '\n')
  97.                   temp_str[strlen(temp_str) - 1] = '\0';
  98.  
  99.             /* Allocate memory */
  100.  
  101.             if ((str_arr[i] = malloc(line_max + 1)) == NULL)
  102.             {
  103.                   /* Clean up and return memory error */
  104.  
  105.                   cleanup(i, fp);
  106.  
  107.                   return FC_MEM;
  108.             }
  109.  
  110.             /* Copy the string to its new home */
  111.  
  112.             strcpy(str_arr[i], temp_str);
  113.       }
  114.  
  115.       fclose(fp);
  116.  
  117.       if (i > max_lines)
  118.       {
  119.             /* Clean up and return too many lines error */
  120.  
  121.             cleanup(i, NULL);
  122.  
  123.             return FC_LINES;
  124.       }
  125.  
  126.       /* Get length of longest line */
  127.  
  128.       lines_len = max_line(str_arr);
  129.  
  130.       /* Open source file */
  131.  
  132.       if ((fp = fopen(src_file, "rt")) == NULL)
  133.       {
  134.             /* Clean up and return source file error */
  135.  
  136.             cleanup(i, NULL);
  137.  
  138.             return FC_SRC;
  139.       }
  140.  
  141.       tot_lines = i;
  142.  
  143.       /*
  144.       ** Get each line from src file and append to corresponding line from
  145.       ** dest file
  146.       */
  147.  
  148.       for (i = 0;
  149.            (fgets(temp_str, line_max + 1, fp) != NULL) && (i < max_lines);
  150.            i++)
  151.       {
  152.             int j;
  153.  
  154.             /* Has this line been allocated yet? */
  155.  
  156.             if (str_arr[i] == NULL)
  157.             {
  158.                   /* Allocate memory */
  159.  
  160.                   if ((str_arr[i] = malloc(line_max + 1)) == NULL)
  161.                   {
  162.                         /* Clean up and return memory error */
  163.  
  164.                         cleanup(tot_lines, fp);
  165.  
  166.                         return FC_MEM;
  167.                   }
  168.  
  169.                   /* Initialize string */
  170.  
  171.                   str_arr[i][0] = '\0';
  172.  
  173.                   tot_lines++;
  174.             }
  175.  
  176.             /* Pad with spaces to make this line as long as longest */
  177.  
  178.             for (j = strlen(str_arr[i]); j < lines_len; j++)
  179.                   str_arr[i][j] = ' ';
  180.             str_arr[i][j] = '\0';
  181.  
  182.             /* Check size of resulting line when strcat'd */
  183.  
  184.             if (lines_len + strlen(temp_str) > line_max)
  185.             {
  186.                   cleanup(tot_lines, fp);
  187.  
  188.                   return FC_LINE;
  189.             }
  190.  
  191.             strcat(str_arr[i], temp_str);
  192.       }
  193.  
  194.       fclose(fp);
  195.  
  196.       if (i > max_lines)
  197.       {
  198.             /* Clean up and return too many lines error */
  199.  
  200.             cleanup(i, NULL);
  201.  
  202.             return FC_LINES;
  203.       }
  204.  
  205.       /* Open dest file again, to write this time */
  206.  
  207.       if ((fp = fopen(dest_file, "wt")) == NULL)
  208.       {
  209.             /* Clean up and return source file error */
  210.  
  211.             cleanup(i, NULL);
  212.  
  213.             return FC_WDEST;
  214.       }
  215.  
  216.       for (i = 0; i < tot_lines; i++)
  217.       {
  218.             if ((fputs(str_arr[i], fp) == EOF) /*|| (fputc('\n', fp) == EOF)*/)
  219.             {
  220.                   cleanup(i, fp);
  221.  
  222.                   return FC_WDEST;
  223.             }
  224.       }
  225.  
  226.       cleanup(i, fp);
  227.  
  228.       return FC_SUCCESS;
  229. }
  230.  
  231. int main(int argc, char ** argv)
  232. {
  233.       printf("Filecat returned %d\n", filecat(argv[1], argv[2], 2048, 4096));
  234.  
  235.       return 0;
  236. }
  237.