home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR9 / WDOS0793.ZIP / DUDLEY.ZIP / MAKEMSG.C < prev    next >
C/C++ Source or Header  |  1993-05-28  |  11KB  |  340 lines

  1. /* for "Preparing a C application for non-English 
  2. speaking users"
  3.  * William F. Dudley Jr.
  4.  *
  5.  * Usage:       makemsg msg_file c_file c_file2 . . .
  6.  * Example:     makemsg msg_file ../*.c
  7.  *
  8.  * Note: all the hooks are in place for sorting the strings for
  9.  *   faster searching. We are doing linear search for now, but if
  10.  *   speed becomes a problem, we can wire it up.
  11.  */
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <dir.h>
  15. #include <errno.h>
  16. #if __TURBOC__
  17. #include <mem.h>
  18. #include <alloc.h>
  19. #elif MSC
  20. #include <memory.h>
  21. #include <malloc.h>
  22. #define MAXPATH 80
  23. #define MAXDRIVE 3
  24. #define MAXDIR 66
  25. #define MAXFILE 9
  26. #define MAXEXT 5
  27. #define EXTENSION 0x02
  28. #define FILENAME  0x04
  29. #define DIRECTORY 0x08
  30. #define DRIVE     0x10
  31. int fnsplit (char *, char *, char *, char *, char *);
  32. void fnmerge (char *, char *, char *, char *, char *);
  33. #endif
  34.  
  35. #define FALSE 0
  36. #define TRUE  1
  37. #define MAIN  1
  38. #include "makemsg.h"
  39.  
  40. int loadmsgs (unsigned *, struct msg *, FILE *, int);
  41. FILE *xsrc, *xold, *xnew, *xmsg, *xhdr;
  42. char qsrc[MAXPATH], qold[MAXPATH], qnew[MAXPATH], qmsg[100];
  43. char p[100], q[100], pout[100], psav[100];
  44.  
  45. int jmsg, jcomment, jquote, kquote, jprintf, jif;
  46. int i, j, k, l, m, n;
  47.  
  48. main (argc, argv)
  49. int   argc;
  50. char      **argv;
  51. {
  52.   int error = 0;
  53.   unsigned int cnt;
  54.   char qdisk[MAXDRIVE], qpath[MAXDIR], qfname[MAXFILE], qext[MAXEXT];
  55.   char *tok;
  56.   int exists;
  57.   int pathbits, files, argcnt;
  58.  
  59.                 /* Open message file and find highest number. */
  60.     if (argc > 1)
  61.  
  62. @CSOURCE7 =         strcpy (qmsg, argv[1]);
  63.     else {
  64.         printf ("Msg file -- ");
  65.         scanf ("%s", qmsg);
  66.     }
  67.     xmsg = fopen (qmsg, "r");
  68.     if (xmsg == NULL) {
  69.         printf ("No message file %s found.\n", qmsg);
  70.         exit (9);
  71.     }
  72.  
  73.     /* read existing message file into memory */
  74.     cnt = sizeof (txt)/sizeof (struct msg);
  75.     error = loadmsgs (&cnt, txt, xmsg, 1);
  76.     if (error) exit (error);
  77.     jmsg = cnt;
  78.     fclose (xmsg);
  79.     xmsg = fopen (qmsg, "a");
  80.  
  81.     if (argc > 2) {
  82.         strcpy (qsrc, argv[2]);
  83.         files = argc - 2;
  84.     }
  85.     else {
  86.         printf ("Source file -- ");
  87.         scanf ("%s", qsrc);
  88.         files = 1;
  89.     }
  90.     for(argcnt =  0 ; argcnt < files ; argcnt++) {
  91.         /* first src file is already in qsrc, strcpy not needed */
  92.         /* subsequent src files need to be gotten, however */
  93.         if (argcnt) strcpy (qsrc, argv[argcnt+2]);
  94.         xsrc = fopen (qsrc, "r");
  95.         if (xsrc == NULL) {
  96.             printf ("No source file %s found.\n", qsrc);
  97.             exit (9);
  98.         }
  99.  
  100.         /* strip off disk and path */
  101.         pathbits = fnsplit (qsrc, qdisk, qpath, qfname, qext);
  102.         fnmerge (qold, NULL, NULL, qfname, qext);
  103.         /* make qnew have no drive or directory, new files made in 
  104. CWD */
  105.         fnmerge (qnew, NULL, NULL, qfname, qext);
  106.         /* if source is not in another directory,
  107.          * append 'n' & 'o' to file names           */
  108.         if (!(pathbits & (DIRECTORY | DRIVE))) {
  109.             strcat (qold, "o");
  110.             strcat (qnew, "n");
  111.         }
  112.  
  113.         xnew = fopen (qnew, "w");
  114.  
  115.         jcomment = FALSE;  jprintf = FALSE;  jif = FALSE;
  116.         while (TRUE) {
  117.             fgets (q, 128, xsrc);
  118.             if (feof (xsrc))  break;
  119.  
  120.             jquote = 0;
  121.             kquote = 0;
  122.             if (q[0] != '#') {
  123.  
  124. @CSOURCE7 =                 for (j = 0; q[j]; j++) {
  125.                     if (!strncmp(&q[j], "printf", 6))  jprintf 
  126. =  TRUE;
  127.                     if (!strncmp(&q[j], "#if", 3))     jif 
  128. =  TRUE;
  129.                     if (!strncmp(&q[j], "#endif", 6))  jif 
  130. = FALSE;
  131.  
  132.                     if (q[j] == '/' && q[j+1] == '*')  jcomment = 
  133. TRUE;
  134.                     if (q[j] == '*' && q[j+1] == '/')  jcomment = 
  135. FALSE;
  136.  
  137.                     if (jprintf == TRUE  && jcomment == FALSE &&
  138.                             jif == FALSE && q[j] == '\"')
  139.                     {
  140.                         if      (jquote == 0)  jquote = j;
  141.                         else if (kquote == 0)  kquote = j;
  142.                     }
  143.                 }
  144.             }
  145.             if (jquote && kquote) {
  146.                         /* extract the string, save it in psav[], 
  147. */
  148.                         /* expand it into pout[] */
  149.                 k = 0;
  150.                 for (j = jquote+1; j < kquote; j++)  {  psav[k] = 
  151. q[j];  k++;  }
  152.                 psav[k] = 0;
  153.                 for (j = 0, tok = psav; *tok ; tok++) {
  154.                     if (*tok != '\\')
  155.                         pout[j++] = *tok;
  156.                     else {
  157.                         switch (tok[1]) {
  158.                             case 'n' :/* we found "\n" */
  159.                                 pout[j++] = '\n';
  160.                                 break;
  161.                             case 't' :
  162.                                 pout[j++] = '\t';
  163.                                 break;
  164.                             case 'v' :
  165.                                 pout[j++] = '\v';
  166.                                 break;
  167.                             case 'b' :
  168.                                 pout[j++] = '\b';
  169.                                 break;
  170.                             case 'r' :
  171.                                 pout[j++] = '\r';
  172.                                 break;
  173.                             case 'f' :
  174.                                 pout[j++] = '\f';
  175.                                 break;
  176.                             case '0' : case '1' : case '2' : case 
  177. '3' :
  178.                             case '4' : case '5' : case '6' : case 
  179. '7' :
  180.                                 i=tok[3]-'0'+(tok[2]-'0')*8+(tok[1]-'0')*8;
  181.                                 tok += 2;
  182.                                 pout[j++] = (char)i;
  183.                                 break;
  184.                             case '\\' :
  185.                                 pout[j++] = '\\';
  186.                                 break;
  187.                             default :
  188.                                 tok<197>; /* don't skip 2 chars */
  189.                                 break;
  190.                         }
  191.                         tok++;    /* because we prob. found "\n" 
  192. */
  193.                     }
  194.  
  195. @CSOURCE7 =                 }
  196.                 pout[j] = '\0';
  197.                 if (kquote-jquote < 3) {
  198.                     fprintf (xnew, "%s", q);
  199.                 }
  200.                 else {
  201.                     exists = -1;
  202.                     /* is string found in existing message file ? 
  203. */
  204.                     for(j = 0 ; j <= jmsg ; j++) {
  205.                         if(!strcmp(pout, txt[j].s)) break; 
  206.                     }
  207.                     /* does string exists in message file already 
  208. ? */
  209.                     if (j != jmsg+1) exists = txt[j].index;
  210.                     if (exists >= 0)
  211.                         printf ("%s: string found in msg 
  212. file, #%d: Fixing.\n", qsrc, exists);
  213.                     else {
  214.                         /* does user want to move string out of source 
  215. file ? */
  216. Query:
  217.                         printf ("\n%s\n", q);
  218.                         printf ("\t\tLeave it or Fix it?  ");  scanf 
  219. ("%s", p);
  220.                         if(p[0] == 'l' || p[0] == 'L') {
  221.                             fprintf (xnew, "%s", q);
  222.                             continue;
  223.                         }
  224.                         else if (p[0] != 'f' && p[0] != 'F')
  225.                             goto Query;
  226.                     }
  227.  
  228.                     if (exists < 0) {
  229.                         /* then we haven't seen this string before 
  230. */
  231.                         jmsg++;         /* Bump message counter. */
  232.                         if (jmsg > MAX_MSGS) {
  233.                             fprintf (stderr, "too many strings\n");
  234.                             exit (ENOMEM);
  235.                         }
  236.                                 /* now store message in bufr array 
  237. */
  238.                         j = strlen (pout);
  239.                         txt[jmsg].s = calloc (j+1, 1);
  240.                         if (txt[jmsg].s == NULL) {
  241.                             fprintf(stderr,"can't alloc more memory, 
  242. line %u\n", msg);
  243.                             exit (ENOMEM);
  244.                         }
  245.                         strcpy (txt[jmsg].s, pout);
  246.                         txt[jmsg].index = jmsg;
  247.                         exists = jmsg;
  248.                         fprintf (xmsg, "%d %s_%03d\n", jmsg, 
  249. qfname, jmsg);
  250.                         fprintf (xmsg, "%s\n\004\n", pout);
  251.                     }
  252.                               /* Print the line without quoted string. 
  253. */
  254.                     strncpy(p, q, jquote); k = jquote;
  255.                     k += sprintf (p+k, "txt[%d]", exists);
  256.                     for (j = kquote+1; q[j]; j++)  {  p[k] = q[j];  k++;  }
  257.                     p[k] = '\0';
  258.                     fprintf (xnew, "%s", p);
  259.                         /* And put a comment into the code with the 
  260. string. */
  261.                     m = 60-strlen(psav);
  262.                     while (m > 7)  {  fprintf (xnew, "\t");  m 
  263. -= 8;  }
  264.                     while (m > 0)  {  fprintf (xnew, " 
  265. ");   m -= 1;  }
  266.  
  267.                     fprintf (xnew, "/* >> %s << */\n", 
  268. psav);
  269.                 }
  270.             }
  271.             else fprintf (xnew, "%s", q);
  272.         }
  273.         fclose (xsrc);
  274.         fclose (xnew);
  275.         if (!(pathbits & (DIRECTORY | DRIVE))) {
  276.             unlink (qold);
  277.             rename (qsrc, qold);
  278.             rename (qnew, qsrc);
  279.         }
  280.     }
  281.  
  282.     fclose (xmsg);
  283.     jmsg++;
  284.     xhdr = fopen ("menuload.h", "w");
  285.     fprintf (xhdr, "char *txt[%d];\n", jmsg);
  286.     fclose (xhdr);
  287.  
  288.     exit (0);
  289. }
  290.  
  291. #ifdef MSC
  292. /* this function is in the Turbo-C library */
  293.  
  294. int fnsplit (path,  disk,  dir,  name,  ext)
  295. char        *path, *disk, *dir, *name, *ext;
  296. {
  297. char bdisk[MAXDRIVE], bdir[MAXDIR], bname[MAXFILE], bext[MAXEXT];
  298. char *cp1, *cp2;
  299. register int i;
  300. int result;
  301.  
  302.     i = 0;
  303.     cp1 = strchr(path, ':');
  304.     if (cp1 == NULL) cp1 = &path[-1];
  305.     else for( ; &path[i] <= cp1 ; i++) bdisk[i] = path[i];
  306.     bdisk[i] = '\0';
  307.     cp2 = strrchr(path, '\\');
  308.     i = 0;
  309.     if (cp2 == NULL) cp2 = strrchr(path, '/');
  310.     if (cp2 == NULL) cp2 = cp1;
  311.     else for( cp1++ ; cp1 <= cp2 ; i++, cp1++) bdir[i] = *cp1;
  312.     bdir[i] = '\0';
  313.     for( i = 0, cp2++ ; ((*cp2)&&(i < 8)&&(*cp2!='.')) ; i++, 
  314. cp2++) {
  315.         bname[i] = *cp2;
  316.     }
  317.     bname[i] = '\0';
  318.     for( i = 0 ; ((*cp2)&&(i < 4)) ; i++, cp2++) {
  319.         bext[i] = *cp2;
  320.     }
  321.     bext[i] = '\0';
  322.     if (disk!=NULL) strcpy(disk, bdisk);
  323.     if (dir!=NULL) strcpy(dir, bdir);
  324.     if (name!=NULL) strcpy(name, bname);
  325.     if (ext!=NULL) strcpy(ext, bext);
  326.     result  = (strlen(bdisk)) ? DRIVE : 0 ;
  327.     result += (strlen(bdir)) ? DIRECTORY : 0 ;
  328.     result += (strlen(bname)) ? FILENAME : 0 ;
  329.  
  330.     result += (strlen(bext)) ? EXTENSION : 0 ;
  331.     return(result);
  332. }
  333.  
  334. void fnmerge (path,  disk,  dir,  name,  ext)
  335. char         *path, *disk, *dir, *name, *ext;
  336. {
  337.     sprintf (path, "%s%s%s%s%s", path, disk, dir, name, ext);
  338. }
  339. #endif
  340.