home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 554b.lha / WFile_v1.10 / source / wfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-10  |  10.7 KB  |  504 lines

  1. /***************************************************************************
  2. * WFile.c : Work file - work (do things) on (ASCII-) files                 *
  3. *                                       *
  4. *      - add or remove CRs (0x0d)                                          *
  5. *      - expand tabs to multiple spaces or vice versa               *
  6. *      - change foreign symbols and special characters               *
  7. *                                       *
  8. * V1.00 - 12-Jan-91 Joerg Fenin / Metalworx                   *
  9. ***************************************************************************/
  10.  
  11. /* --------------------- source code revisions, tracked by RCS ---------- */
  12.  
  13. /* $Header: Hard0:C-Compiler/src/wfile/rcs/wfile.c,v 1.0 91/08/12 20:28:34 Mtwx Exp $ */
  14. /* $Log:    wfile.c,v $
  15.  * Revision 1.0  91/08/12  20:28:34  Mtwx
  16.  * Initial revision
  17.  *  */
  18.  
  19. /* -------------------------- Includes ---------------------------------- */
  20.  
  21. #include <stdio.h>
  22. #ifdef AMIGA
  23. #include <ctype.h>
  24. #include <exec/types.h>
  25. #endif
  26.  
  27. #include "wfile.h"
  28.  
  29. /* -------------------------- Defines ----------------------------------- */
  30.  
  31. #ifdef UNIX
  32. #define TRUE 1
  33. #define FALSE 0
  34. typedef short BOOL;
  35. #endif
  36.  
  37. #ifdef MSDOS
  38. #define TRUE 1
  39. #define FALSE 0
  40. typedef short BOOL;
  41. #endif
  42.  
  43. /* -------------------------- global variables -------------------------- */
  44.  
  45. unsigned char ch_src_sym[MAXCHANGE]; /* Change table for foreign symbols */
  46. unsigned char ch_trg_sym[MAXCHANGE];
  47. unsigned char final_chr;  /* takes desired final char if specified */
  48. char *templ_argv[MAXOPTIONS];    /* Array of pointers for templated
  49.                    argvs */
  50. int change_count=0;        /* counter for changes to be done */
  51. #ifdef AMIGA
  52. char color_on[]="\033[2m";
  53. char color_off[]="\033[0m";
  54. #else
  55. char color_on[];
  56. char color_off[];
  57. #endif
  58.  
  59. /* -------------------------- forward references ------------------------ */
  60.  
  61. void usage(),parse_change();
  62. #ifndef __SASC
  63. char *strupr();
  64. #endif
  65. int workfile();
  66.  
  67. /* -------------------------- external references ----------------------- */
  68.  
  69. extern int Revision;
  70. extern char Version[],Date[];
  71.  
  72. extern int parse_profile(),unix2msdos(),msdos2unix();
  73. extern void whelp();
  74.  
  75. /* -------------------------- main control loop ------------------------- */
  76.  
  77. int main(argc,argv)
  78. int argc;
  79. char *argv[];
  80. {
  81.   int ExpFactor=2,i,j,num_options=0,Options=0,tabsize, t_argc;
  82.   long len;
  83.   char *rbuf,*wbuf,backup_filename[100], pro_filename[100],
  84.        *argument[MAXOPTIONS];
  85.   FILE *file;
  86.  
  87.   printf("\n%s %s/%d - %s  (C) 1991 Metalworx\n",argv[0],Version,Revision,
  88.      Date);
  89.  
  90. /* evaluate command line */
  91.   if(argc < 2)
  92.   {
  93.     usage(argv[0]);
  94.     exit(1);
  95.   }
  96.  
  97.   if(strcmp(argv[1],"-?")==NULL)
  98.   {
  99.     whelp();
  100.     exit(1);
  101.   }
  102.  
  103.   if(argc>2)
  104.   {
  105.     for(i=2;i<argc;i++,num_options++)
  106.     {
  107.       argument[num_options]=(char *)malloc(strlen(argv[i])+1);
  108.       strcpy(argument[num_options],argv[i]);
  109.     }
  110.     for(i=0;i<num_options;i++)
  111.     {
  112.       if(toupper(argument[i][1])=='F')  /* read commands from profile */
  113.       {
  114.     if(strlen(&argument[i][2]))             /* profile name given */
  115.       strcpy(pro_filename,&argument[i][2]);
  116.     else
  117.       strcpy(pro_filename,"wfile.pro");     /* default profile name */
  118.     t_argc=parse_profile(pro_filename);
  119.     for(j=0;j<t_argc;j++)
  120.       argument[num_options++]=templ_argv[j];
  121.     continue;
  122.       }
  123.  
  124.       if(strcmp(strupr(&argument[i][1]),"AI")==NULL)
  125.       {
  126.     t_argc=amiga2msdos(argument[i]);
  127.     for(j=0;j<t_argc;j++)
  128.       argument[num_options++]=templ_argv[j];
  129.     continue;
  130.       }
  131.  
  132.       if(strcmp(strupr(&argument[i][1]),"IA")==NULL)
  133.       {
  134.     t_argc=msdos2amiga(argument[i]);
  135.     for(j=0;j<t_argc;j++)
  136.       argument[num_options++]=templ_argv[j];
  137.     continue;
  138.       }
  139.  
  140.       if(strcmp(strupr(&argument[i][1]),"AU")==NULL)
  141.       {
  142.     t_argc=amiga2unix(argument[i]);
  143.     for(j=0;j<t_argc;j++)
  144.       argument[num_options++]=templ_argv[j];
  145.     continue;
  146.       }
  147.  
  148.       if(strcmp(strupr(&argument[i][1]),"UA")==NULL)
  149.       {
  150.     t_argc=unix2amiga(argument[i]);
  151.     for(j=0;j<t_argc;j++)
  152.       argument[num_options++]=templ_argv[j];
  153.     continue;
  154.       }
  155.  
  156.       if(strcmp(strupr(&argument[i][1]),"UI")==NULL)
  157.       {
  158.     t_argc=unix2msdos(argument[i]);
  159.     for(j=0;j<t_argc;j++)
  160.       argument[num_options++]=templ_argv[j];
  161.     continue;
  162.       }
  163.  
  164.       if(strcmp(strupr(&argument[i][1]),"IU")==NULL)
  165.       {
  166.     t_argc=msdos2unix(argument[i]);
  167.     for(j=0;j<t_argc;j++)
  168.       argument[num_options++]=templ_argv[j];
  169.     continue;
  170.       }
  171.  
  172. /* add final character */
  173.       if(argument[i][0]=='+' && isdigit(argument[i][1]))
  174.       {
  175.     Options|=ADD_FINAL_CHR;
  176.     final_chr=atoi(&argument[i][1]);
  177.       }
  178.  
  179. /* change (foreign) characters ? */
  180.       if(strpos(argument[i],"=") > -1)
  181.       {
  182.     parse_change(argument[i],change_count);
  183.     change_count++;
  184.       }
  185.  
  186.       if(strcmp(strupr(&argument[i][1]),"CR")==NULL)
  187.       {
  188.     switch(argument[i][0])
  189.     {
  190.       case '+':
  191.         Options|=ADDCR;
  192.         break;
  193.       case '-':
  194.         Options|=REMCR;
  195.         break;
  196.       default:
  197.         Options|=CRMODE;
  198.         printf("Unknown \"CR\" mode! %s assumed.\n",CRTEXT);
  199.         break;
  200.     }
  201.       }
  202.  
  203.       if(toupper(argument[i][1])=='T')
  204.       {
  205.     tabsize=atoi(&argument[i][2]);
  206.     if(tabsize==0)
  207.     {
  208.       tabsize=TABSIZE;
  209.       printf("Tabsize %d assumed.\n",tabsize);
  210.     }
  211.     if(tabsize==1)
  212.     {
  213.       puts("Tabsize of 1 doesn't make sense! - Try something from 2 upwards.");
  214.       exit(1);
  215.     }
  216.     switch(argument[i][0])
  217.     {
  218.       case '+':
  219.         Options|=SHRSPACE;
  220.         break;
  221.       case '-':
  222.         Options|=EXPTABS;
  223.         break;
  224.       default:
  225.         Options|=TABMODE;
  226.         printf("Unknown \"TAB\" mode! %s assumed.\n",TABTEXT);
  227.         break;
  228.     }
  229.       }
  230.  
  231.       if(strcmp(argument[i][1],"0")==NULL)
  232.     Options|=REAL_NULL;   /* really replace something against a NULL
  233.                  char */
  234.  
  235.       if(toupper(argument[i][1])=='B')
  236.     Options|=NO_BACKUP;
  237.     }
  238.   }
  239.   if(change_count)
  240.     Options|=CHANGE_FOREIGN;
  241.  
  242. /* now check presence of file (argv[1]) and get length */
  243.  
  244.   if ((file = fopen(argv[1], "r")) == NULL)
  245.   {
  246.     perror(argv[1]);
  247.     exit(1);
  248.   }
  249.   fseek(file, 0, 2); /* set to EOF - 0 Bytes */
  250.   len = ftell(file);
  251.   printf("%s: %6ld bytes read, ", argv[1],len);
  252.   fflush(stdout);
  253.   if(len <= 0)
  254.   {
  255.     puts("File read error!");
  256.     exit(1);
  257.   }
  258.  
  259. /* allocate memory buffer */
  260.  
  261.   if(Options & EXPTABS)
  262.     ExpFactor ++;
  263.   if(Options & ADDCR)
  264.     ExpFactor ++;
  265.   rbuf = (char *)malloc(len*ExpFactor);
  266.   if(rbuf==NULL)
  267.   {
  268.     printf("Couldn't get %d bytes of memory!!\n",len*ExpFactor);
  269.     exit(1);
  270.   }
  271.   printf("%7ld bytes allocated, ",len*ExpFactor);
  272.   fflush(stdout);
  273.  
  274. /* read file into buffer */
  275.  
  276.   fseek(file,0,0);  /* set to start of file */
  277.   if(fread(rbuf,len,1,file) != 1)
  278.   {
  279.     perror(argv[1]);
  280.     puts("read failed!!");
  281.     exit(1);
  282.   }
  283.   fclose(file);
  284.  
  285. /* create backup of original file */
  286.  
  287.   if(!(Options & NO_BACKUP))
  288.   {
  289.     strcpy(backup_filename,argv[1]);
  290. #ifdef AMIGA
  291.     strcat(backup_filename,".bak");
  292. #endif
  293. #ifdef UNIX
  294.     strcat(backup_filename,".bak");
  295. #endif
  296. #ifdef MSDOS
  297.     i=strpos(argv[1],".");
  298.     if(i>-1)
  299.       strcat(&backup_filename[i],".bak");
  300.     else
  301.       strcat(backup_filename,".bak");
  302. #endif
  303.     if((file=fopen(backup_filename,"w"))==NULL)
  304.     {
  305.       perror(argv[1]);
  306.       puts("opening of backup file failed!");
  307.       exit(1);
  308.     }
  309.     else
  310.       if(fwrite(rbuf,len,1,file) !=1)
  311.       {
  312.     perror(argv[1]);
  313.     puts("write to backup file failed!");
  314.     exit(1);
  315.       }
  316.   }
  317.  
  318. /* start up user desired routines */
  319.  
  320.   wbuf=rbuf+len;      /* save start address of write buffer */
  321.   len=workfile(rbuf,len,Options,tabsize);
  322.  
  323. /* write back file with new contents */
  324.  
  325.   if ((file=fopen(argv[1],"w")) == NULL)
  326.   {
  327.     perror(argv[1]);
  328.     puts("open to write failed!");
  329.     exit(1);
  330.   }
  331.   fflush(stdout);
  332.   if(fwrite(wbuf,len,1,file) != 1)
  333.   {
  334.     perror(argv[1]);
  335.     puts("write failed!");
  336.     exit(1);
  337.   }
  338.   printf("%6ld bytes written\n",len);
  339.   fclose(file);
  340.  
  341. /* clean up and exit */
  342.  
  343.   free(rbuf);
  344.   printf("\n");
  345.   exit(0);
  346. }
  347.  
  348. /* -------------------------- referenced functions ---------------------- */
  349.  
  350. void parse_change(param,num)
  351. char *param;
  352. int num;
  353. {
  354.   int i;
  355.  
  356.   if(param[1]=='\'' && param[3]=='\'')    /* quoted character */
  357.     ch_src_sym[num]=param[2];
  358.   else                      /* decimal value */
  359.     ch_src_sym[num]=atoi(¶m[1]);
  360.   i=strpos(param,"=");
  361.   switch(param[i+1])
  362.   {
  363.     case '\'':
  364.       ch_trg_sym[num]=param[i+2];
  365.       break;
  366.     default:
  367.       ch_trg_sym[num]=atoi(¶m[i+1]);
  368.       break;
  369.   }
  370. }
  371.  
  372. void usage(name)
  373. char *name;
  374. {
  375.   printf("Usage: %s < file| -? >  [<+|->CR] [<+|->T[size]] [-%sddd%s=%sddd%s [...] [-0]]\n",
  376.      name,color_on,color_off,color_on,color_off);
  377.   printf("%*s [-b] [-f[file]] [-AI] [-IA] [-AU] [-UA] [-UI] [-IU] [+%sddd%s]\n",
  378.      strlen(name)+7," ",color_on,color_off);
  379.   printf("\nValues in %sthis color%s must be entered as (decimal) ASCII values.\n",
  380.      color_on,color_off);
  381. }
  382.  
  383. #ifndef __SASC
  384. char *strupr(s)
  385. char *s;
  386. {
  387.   register int i;
  388.   char *us;
  389.  
  390.   if(strlen(s))
  391.   {
  392.     us=(char *)malloc(strlen(s)+1);
  393.     if(us)
  394.       for(i=0;i<=strlen(s);i++)
  395.     us[i]=toupper(s[i]);
  396.     return us;
  397.   }
  398.   else
  399.     return NULL;
  400. }
  401. #endif
  402.  
  403. int workfile(buf,len,Options,tabsize)
  404. register char *buf;
  405. register long len;
  406. int Options;
  407. int tabsize;
  408. {
  409.   register char *ptr = buf + len;
  410.   register int i,j,k,l;
  411.   int nl_pos_i=-1,nl_pos_j=-1;
  412.               /*  holds buffer position of last newline */
  413.   BOOL shr_possible,quoted=FALSE;
  414.  
  415.   for(i=j=0;i<len;i++)
  416.   {
  417.     switch(buf[i])
  418.     {
  419.       case 0x0d:
  420.     if (Options & REMCR)
  421.       continue;
  422.     else
  423.       ptr[j++]=0x0d;
  424.     break;
  425.       case 0x0a:
  426.     if (Options & ADDCR)
  427.     {
  428.       ptr[j++]=0x0d;
  429.       ptr[j++]=0x0a;
  430.     }
  431.     else
  432.       ptr[j++]=0x0a;
  433.     nl_pos_i=i;    /* save pos of newline in read buffer  */
  434.     nl_pos_j=j-1;    /* save pos of newline in write buffer */
  435.     break;
  436.       case '\t':
  437.     if ((Options & EXPTABS) && (quoted==FALSE))
  438.     {
  439.       l=j;        /* use origin position of write buffer */
  440.       for(k=l-nl_pos_j-1;
  441.           k < (((l-nl_pos_j-1)/tabsize+1) * tabsize);
  442.           k++)
  443.         ptr[j++]=' ';
  444.     }
  445.     else
  446.       ptr[j++]='\t';
  447.     break;
  448.       case ' ':
  449.     if ((Options & SHRSPACE) && (quoted==FALSE))
  450.     {
  451.       shr_possible=TRUE;
  452.       for(k=i-nl_pos_i-1,l=0;
  453.           k < (((i-nl_pos_i-1)/tabsize+1) * tabsize);
  454.           k++,l++)
  455.       {
  456.         if(buf[i+l] != ' ')
  457.           shr_possible=FALSE;
  458.       }
  459.       if(l==1)
  460.         shr_possible=FALSE; /* doesn't make sense to shrink one
  461.                    SPACE into one TAB */
  462.       if(shr_possible==TRUE)
  463.       {
  464.         ptr[j++]='\t';
  465.         i+=l-1;
  466.       }
  467.       else
  468.         ptr[j++]=' ';
  469.     }
  470.     else
  471.       ptr[j++]=' ';
  472.     break;
  473.       case '\"':
  474.     if(buf[i-1]!='\\')  /* not quoted itself */
  475.       quoted=1-quoted;  /* negate quotation status */
  476.     ptr[j++]='\"';
  477.     break;
  478.       default:
  479.     if(Options & CHANGE_FOREIGN)
  480.     {
  481.       l=FALSE;        /* set found indicator to NOT FOUND */
  482.       for(k=0;k<change_count;k++)
  483.         if(buf[i]==ch_src_sym[k])
  484.         {
  485.           l=TRUE;        /* set found indicator to FOUND */
  486.           if(ch_trg_sym[k]!='\0') /* anything else than a NULL char ? */
  487.         ptr[j++]=ch_trg_sym[k];
  488.           else if(Options & REAL_NULL) /* should the NULL really be
  489.                           inserted ? */
  490.         ptr[j++]=ch_trg_sym[k];
  491.         }
  492.       if(l==FALSE)          /* not a symbol that is to be changed */
  493.         ptr[j++]=buf[i];
  494.     }
  495.     else
  496.       ptr[j++]=buf[i];
  497.     break;
  498.     }
  499.   }
  500.   if(Options & ADD_FINAL_CHR)
  501.     ptr[j++]=final_chr;
  502.   return j;
  503. }
  504.