home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 17 / CD_ASCQ_17_101194.iso / vrac / cvtini.zip / CVTINI.C next >
C/C++ Source or Header  |  1994-08-26  |  22KB  |  873 lines

  1.  
  2. /*    Copyright (C) 1994 by Premia Corporation.  All rights reserved.    */
  3.  
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <malloc.h>
  8. #include <io.h>        // needed only for call to _access
  9.  
  10. #define COPYCOMMENTS        // copy lines that are commented out
  11.  
  12. #define    SEC_DEFAULTKMAP    (1)
  13. #define    SEC_KMAPASSIGN    (2)
  14. #define    SEC_LIBPRELOAD    (3)
  15. #define    SEC_HELP        (4)
  16. #define    SEC_COMPILER    (5)
  17. #define    SEC_RIBBON        (6)
  18. #define    SEC_MENU        (7)
  19. #define    SEC_HELPER        (8)
  20.  
  21. // iniAction values
  22. #define IA_COPY            (0x001)        // Copy this line
  23. #define IA_CHECKNAME    (0x002)        // Check against the valid list and warn if necessary
  24. #define IA_WARNSECTION    (0x004)        // Warn about the section
  25. #define IA_COMMENTOUT    (0x008)        // Comment out this line in the output, if COPY is set
  26. #define IA_CONVERT        (0x010)        // Change the name if it's in the conversion map; comment out otherwise.
  27. #define IA_CHECKALL        (0x020)        // Check all strings on the input line (for key bindings)
  28. #define IA_ADDSECTION    (0x040)        // Create a needed section because there wasn't one already
  29. #define IA_NOCHECK        (0x080)        // Don't check this line (primarily for comments)
  30.  
  31. // iniError values
  32. #define IE_BADAPI        (0x0001)    // API call not supported in Fusion
  33. #define IE_CHANGEDAPI    (0x0002)    // API call that acts differently in Fusion
  34. #define IE_NOCONVERSION    (0x0004)    // Library or keymap that couldn't be converted
  35. #define IE_OKCONVERSION    (0x0008)    // Library or keymap that was converted
  36. #define IE_COMMENTEDOUT    (0x0010)    // unsupported item commented out in output
  37. #define IE_OTHERSECTION    (0x0020)    // item in unsupported section (not currently handled)
  38. #define IE_HASHELPER    (0x0040)    // Input file already has [Helper] section
  39. #define IE_HASLDRAW        (0x0080)    // Output file already has LibPreload=cwvldraw.dll
  40. #define IE_HASCTL3D        (0x0100)    // Output file already has LibPreload=cwvctl3d.dll
  41. #define IE_HELPERERROR    (0x0200)    // [Helper] section couldn't be added 
  42. #define IE_BADDEFKMAP    (0x0400)    // Couldn't convert DefaultKeymap--cwvcua used instead.
  43.  
  44. #define HELPERNAME        ("[Helper]")
  45. #define HELPERSTUFF        ("Browse=0\nExactMatch=0\nUse_MSVC_Help=0\nCWHelpSearchPath=C:\\CWVC;C:\\MSVC\\HELP\n")
  46.  
  47. #define    PRSTR(x)        ((x)?(x):"<null>")
  48.  
  49. #define    IOBUSIZ    (1024)    // max. length of input line (including null byte)
  50.  
  51. char        *strRepStr        (char  *targPat,     char *repPat, char *inStr);
  52. static char *nexttok          (const char          *str, char *buf, const char *sep);
  53. char        *strSave          (char  *str);
  54. char        *convertName      (char  *call);
  55. int         checkName         (char  *call);
  56. char        *strSave          (char  *str);
  57. char        *stripDecorations (char  *str,         char *preBuf, char *sufBuf,
  58.                                const char          *baubles);
  59. char        *reDecorate       (char  *str,         char *preBuf, char *sufBuf);
  60. int         dispatch          (char  *sectionName, char *lineBuf,
  61.                                char  *apiCall,     int action);
  62. int         convertIni        (char  *fileName);
  63. void        blurb             (char  *progName,    char *inputFile, int errorLevel);
  64.  
  65. // characters outside of library/API/keymap/section names
  66. const  char *symbolWhitespace = " \t\n;\"'<,>.`~!@#$%^&*()-+={}[]:?/|\\";
  67.  
  68. // characters outside of input tokens
  69. const  char *inputWhitespace  = " \t=\n\"',.()";
  70.  
  71. long cvtOutputLineNumber = 1;
  72. FILE *cvtFpIn, *cvtFpOut, *cvtFpErr;
  73.  
  74. /*
  75.  *  Probably want to change this to write to a named file
  76.  *  and send error and warning messages to stdout so they
  77.  *  can be redirected easily.
  78.  */
  79. main(int c, char **v)
  80. {
  81.     char *inputName  =     NULL;      
  82.     int  errorLevel;
  83.     int  confirm     (char *fileName);
  84.  
  85.     if (!v[1])
  86.     {
  87.         cvtFpIn = stdin;
  88.         inputName = "Standard input";
  89.     }
  90.     else
  91.     {
  92.         if (!(cvtFpIn = fopen(v[1], "r")))
  93.         {
  94.             perror(v[1]);
  95.             exit(-1);
  96.         }
  97.         inputName = v[1];
  98.  
  99.         if (v[2])
  100.         {
  101.             if (!_access(v[2], 0))    // file exists
  102.             {
  103.                 if (!confirm(v[2]))
  104.                     exit(-1);
  105.             }
  106.             if (!(cvtFpOut = fopen(v[2], "w")))
  107.             {
  108.                 perror(v[2]);
  109.                 fclose(cvtFpIn);
  110.                 exit(-1);
  111.             }
  112.         }
  113.         else
  114.             cvtFpOut = stdout;
  115.     }
  116.         
  117.     if (cvtFpOut == stdout)
  118.         cvtFpErr = stderr;
  119.     else    
  120.         cvtFpErr = stdout;
  121.     errorLevel = convertIni(inputName);
  122.     blurb(v[0], inputName, errorLevel);
  123.     if (cvtFpIn != stdin)
  124.         fclose(cvtFpIn);
  125.     if (cvtFpOut != stdout)
  126.         fclose(cvtFpOut);
  127.     exit(0);
  128. }
  129.  
  130. int
  131. confirm(char *fileName)
  132. {
  133.     int c;
  134.     
  135.     fprintf(stderr, "%s exists.  Do you want to overwrite it? ", fileName);
  136.     while ((c = getchar()) != EOF && toupper(c) != 'Y' && toupper(c) != 'N')
  137.         ;
  138.     if (c == EOF || c == 'n' || c == 'N')
  139.         return(0);
  140.     return(1);    
  141. }
  142.  
  143. /*
  144.  *  Have a little heart-to-heart with the user advising them that
  145.  *  their system flags weren't checked (so that some unsupported
  146.  *  flags may be getting set with SysSetDefault and such).
  147.  */
  148.  
  149. void
  150. blurb(char *progName, char *inputFile, int errorLevel)
  151. {
  152.     fprintf(cvtFpErr, "\n\t%s has converted %s\n", progName, inputFile);
  153.     fprintf(cvtFpErr, "\tfor use with Fusion.\n");
  154.     if (!errorLevel)
  155.     {
  156.         fprintf(cvtFpErr, "\tThe conversion was entirely successful\n\n.");
  157.         return;
  158.     }
  159.     if (errorLevel & IE_BADAPI)
  160.     {
  161.         fprintf(cvtFpErr, "\n\t%s contained one or more calls to\n", inputFile);
  162.         fprintf(cvtFpErr, "\tCodewright functions not supported in Fusion.\n");
  163.     }
  164.     if (errorLevel & IE_CHANGEDAPI)
  165.     {
  166.         fprintf(cvtFpErr, "\n\t%s contained one or more calls to\n", inputFile);
  167.         fprintf(cvtFpErr, "\tCodewright functions that have different meaning in Fusion.\n");
  168.     }
  169.     if (errorLevel & IE_NOCONVERSION)
  170.     {
  171.         fprintf(cvtFpErr, "\n\t%s contained one or more references to\n", inputFile);
  172.         fprintf(cvtFpErr, "\tCodewright libraries or keymaps that have no equivalent in Fusion.\n");
  173.         fprintf(cvtFpErr, "\tAny functions contained in those libraries or keymaps\n");
  174.         fprintf(cvtFpErr, "\twill be unavailable unless you relink them for Fusion.\n");
  175.     }
  176.     if (errorLevel & IE_OKCONVERSION)
  177.     {
  178.         fprintf(cvtFpErr, "\n\t%s contained one or more references to\n", inputFile);
  179.         fprintf(cvtFpErr, "\tCodewright libraries or keymaps that were converted\n");
  180.         fprintf(cvtFpErr, "\tto their Fusion equivalents.\n");
  181.     }
  182.     if (errorLevel & IE_COMMENTEDOUT)
  183.     {
  184.         fprintf(cvtFpErr, "\n\tItems in %s that were not consistent with\n", inputFile);
  185.         fprintf(cvtFpErr, "\tFusion, and that could not be converted to Fusion equivalents,\n");
  186.         fprintf(cvtFpErr, "\twere copied to the new file as comments.  These items appear\n");
  187.         fprintf(cvtFpErr, "\tin the output file preceded by ';cvt: '.\n");
  188.     }
  189.     if (errorLevel & IE_BADDEFKMAP)
  190.     {
  191.         fprintf(cvtFpErr, "\n\tThe default keymap in %s could not be\n", inputFile);
  192.         fprintf(cvtFpErr, "\tconverted to a Fusion equivalent.  Cwvcua was substituted instead.\n");
  193.     }
  194.     
  195.     if (!(errorLevel & IE_HASHELPER))
  196.     {
  197.         fprintf(cvtFpErr, "\n\tThere was no [Helper] section in %s,\n", inputFile);
  198.         fprintf(cvtFpErr, "\tso a default was supplied.  Check the paths in that section\n");
  199.         fprintf(cvtFpErr, "\tto verify that they are appropriate for your setup.\n");
  200.     }
  201.     if (errorLevel)
  202.         fprintf(cvtFpErr, "\n\tConsult your Fusion Companion Reference for more information.\n");
  203.     fprintf(cvtFpErr, "\n");
  204. }
  205.  
  206. int
  207. convertIni(char *fileName)
  208. {
  209.     static char iobu[IOBUSIZ];
  210.     static char tokbu[IOBUSIZ];
  211.            char *p;
  212.            char *iop;
  213.            char *sectionName    = NULL;
  214.            int  sectionType     = 0;
  215.            int  iniAction       = 0;
  216.            int  errorLevel      = 0;
  217.            char *outStr;
  218.  
  219.     while (fgets(iobu, IOBUSIZ, cvtFpIn))
  220.     {
  221.         if (feof(cvtFpIn))
  222.             break;
  223.  
  224.         if (!(iop = nexttok(iobu, tokbu, inputWhitespace)) || !strlen(tokbu))
  225.             continue;
  226.  
  227.         if (tokbu[0] == ';')    // the line is commented out
  228. #ifdef COPYCOMMENTS
  229.             continue;
  230. #else
  231.             dispatch(NULL, iobu, NULL, IA_COPY);
  232. #endif
  233.  
  234.         iniAction = 0;
  235.             
  236.         if ((p = strchr(iobu, '\r')) || (p = strchr(iobu, '\n')))
  237.             *p = 0;
  238.  
  239.         if (tokbu[0] == '[')    // section header
  240.         {
  241.             if (p = strchr(tokbu, ']'))
  242.             {
  243.                 p[1] = 0;
  244. //                iniAction = 0;
  245.                 if (sectionName)
  246.                     free(sectionName);
  247.                 sectionName = strSave(tokbu);
  248.                 if (!_stricmp(sectionName,      "[DefaultKeymap]"))
  249.                     sectionType =  SEC_DEFAULTKMAP;
  250.                 else if (!_stricmp(sectionName, "[KmapAssign]"))
  251.                     sectionType =  SEC_KMAPASSIGN;
  252.                 else if (!_stricmp(sectionName, "[LibPreLoad]"))
  253.                     sectionType =  SEC_LIBPRELOAD;
  254.                 else if (!_stricmp(sectionName, "[Help]"))
  255.                 {
  256.                     sectionType =  SEC_HELP;
  257.                     iniAction = IA_WARNSECTION;    
  258.                 }
  259.                 else if (!_stricmp(sectionName, "[Helper]"))
  260.                 {
  261.                     sectionType =  SEC_HELPER;
  262.                     errorLevel = IE_HASHELPER;
  263.                 }
  264.                 else if (!_stricmp(sectionName, "[Compiler]"))
  265.                 {
  266.                     sectionType =  SEC_COMPILER;
  267.                     iniAction = IA_WARNSECTION;    
  268.                 }
  269.                 else if (!_stricmp(sectionName, "[Ribbon]"))
  270.                 {
  271.                     sectionType =  SEC_RIBBON;
  272.                     iniAction = IA_WARNSECTION;    
  273.                 }
  274.                 else if (!_stricmp(sectionName, "[Menu]"))
  275.                 {
  276.                     sectionType =  SEC_MENU;
  277.                     iniAction = IA_WARNSECTION;    
  278.                 }
  279.                 else
  280.                     sectionType =  -1;          // something unspecified
  281.                 // copy the line
  282.                 errorLevel |= dispatch(NULL, sectionName, NULL, iniAction | IA_COPY);
  283.             }
  284.             continue;
  285.         }
  286.         outStr = NULL;
  287.  
  288.         switch(sectionType)
  289.         {
  290.             case SEC_DEFAULTKMAP:
  291.                 nexttok(iop, tokbu, inputWhitespace);    // no default keymap?!
  292.                 iniAction = IA_COPY | IA_CONVERT;
  293.                 break;
  294.             case SEC_KMAPASSIGN:
  295.                 iniAction = IA_COPY | IA_CHECKALL;
  296.                 break;
  297.             case SEC_LIBPRELOAD:
  298.                 nexttok(iop, tokbu, inputWhitespace);    // empty LibPreload is OK
  299.                 iniAction = IA_COPY | IA_CONVERT;
  300.                 break;
  301.             case SEC_HELP:
  302.             case SEC_COMPILER:
  303.             case SEC_RIBBON:
  304.             case SEC_MENU:
  305.                 iniAction = IA_COPY | IA_COMMENTOUT | IA_WARNSECTION;
  306.                 break;
  307.             case 0:        // no section
  308.                 iniAction = IA_COPY | IA_COMMENTOUT | IA_WARNSECTION;
  309.                 break;
  310.             default:    // other section
  311.                 iniAction = IA_COPY | IA_CHECKNAME;
  312.                 break;
  313.         }
  314.         if (sectionType == SEC_DEFAULTKMAP)    // critical section
  315.         {
  316.             int tmpError = 0;
  317.             
  318.             tmpError = dispatch(sectionName, iobu, tokbu, iniAction);
  319.             if (tmpError & IE_NOCONVERSION)
  320.             {
  321.                 char *p;
  322.                 
  323.                 if (p = strRepStr(tokbu, "cwvcua", iobu))
  324.                 {
  325.                     tmpError = dispatch(sectionName, p, NULL, IA_COPY);
  326.                     free(p);
  327.                 }
  328.                 errorLevel |= IE_BADDEFKMAP;
  329.             }
  330.             else
  331.             {
  332.                 errorLevel |= tmpError;
  333.             }
  334.         }
  335.         else
  336.         {
  337. #if 0
  338.             char *p;
  339.             
  340.             if (p = strchr(tokbu))
  341.             {
  342.                 *p++ = 0;
  343.                 errorLevel |= dispatch(sectionName, iobu, tokbu, IA_COPY | IA_CONVERT);
  344.             }
  345. #endif
  346.             errorLevel |= dispatch(sectionName, iobu, tokbu, iniAction);
  347.         }
  348.      }
  349.     if (!(errorLevel & IE_HASHELPER))
  350.         errorLevel |= dispatch(HELPERNAME, HELPERSTUFF, NULL, IA_ADDSECTION);
  351.     return(errorLevel);
  352. }
  353.  
  354. /*
  355.  *  There are four things that can happen to a line of input:
  356.  *    1) it can get ignored
  357.  *    2) it can get copied to output
  358.  *    3) it can get turned into a comment and copied to output
  359.  *    4) it can undergo a substring substitution and get copied to output
  360.  */
  361. int
  362. dispatch(char *sectionName, char *lineBuf, char *apiCall, int action)
  363. {
  364.     char *lineOut    = lineBuf;
  365.     char *newAPICall = NULL;   
  366.     char *strip;    
  367.     char suf[256];  
  368.     char pre[256];  
  369.     int  checkErr;  
  370.     int  errorLevel  = 0;
  371.  
  372.     // If we're emitting a section name, precede with a blank line
  373.     // Assume that lineeOut doesn't change when sectionName is NULL.
  374.     
  375.     if (lineOut && !sectionName && (action & IA_COPY))
  376.     {
  377.         fprintf(cvtFpOut, "\n");
  378.         ++cvtOutputLineNumber;    
  379.     }
  380.     if (!sectionName && (action & IA_WARNSECTION))
  381.     {
  382.         fprintf(cvtFpErr, "Line %ld: %s is not a standard section in Fusion\n",
  383.             cvtOutputLineNumber, PRSTR(lineBuf));
  384.         errorLevel |= IE_OTHERSECTION;
  385.     }
  386.  
  387.     // apiCall may be of the form library[.dll]:apiname.
  388.     // Find the API call in there and check it.
  389.     
  390.     if (action & IA_CHECKNAME)
  391.     {
  392.         char *p;
  393.         
  394.         if (p = strchr(apiCall, ':'))
  395.         {
  396.             action |= IA_CONVERT;
  397.             p++;
  398.         }
  399.         else
  400.             p = apiCall;
  401.         strip = stripDecorations(p, pre, suf, symbolWhitespace);
  402.         if ((checkErr = checkName(strip)) > 1)
  403.         {
  404.             fprintf(cvtFpErr, "Line %ld: '%s' is not supported in Fusion\n",
  405.                 cvtOutputLineNumber, PRSTR(strip));
  406.             action |= (IA_COPY | IA_COMMENTOUT);
  407.             errorLevel |= IE_BADAPI;
  408.         }
  409.         else if (checkErr == 1)
  410.         {
  411.             fprintf(cvtFpErr,
  412.                 "Line %ld: '%s' has special meaning in Fusion--see Companion Reference\n",
  413.                 cvtOutputLineNumber, PRSTR(strip));
  414.             action |= (IA_COPY | IA_COMMENTOUT);
  415.             errorLevel |= IE_CHANGEDAPI;
  416.         }
  417.         else
  418.             action |= IA_COPY;
  419.         free(strip);
  420.     }
  421.  
  422.     if (action & IA_CHECKALL)
  423.     {
  424.         int erroneous = 0;
  425.         // reuse strip and suf here
  426.         
  427.         for (strip = lineBuf;
  428.             strip = nexttok(strip, suf, " \t;\"'<,>.`~!@#$%^&*()-+={}[]:?/|\\"); )
  429.         {
  430.             if ((checkErr = checkName(suf)) > 1)
  431.             {
  432.                 fprintf(cvtFpErr, "Line %ld: '%s' is not supported in Fusion\n",
  433.                     cvtOutputLineNumber, PRSTR(suf));
  434.                 erroneous = 1;
  435.                 errorLevel |= IE_BADAPI;
  436.             }
  437.             else if (checkErr == 1)
  438.             {
  439.                 fprintf(cvtFpErr,
  440.                     "Line %ld: '%s' has special meaning in Fusion--see Companion Reference\n",
  441.                     cvtOutputLineNumber, PRSTR(suf));
  442.                 erroneous = 1;
  443.                 errorLevel |= IE_CHANGEDAPI;
  444.             }
  445.         }
  446.         if (erroneous)
  447.             action |= (IA_COPY | IA_COMMENTOUT);
  448.         else    
  449.             action |= IA_COPY;
  450.     }
  451.  
  452.     // apiCall may be of the form library[.dll]:apiname.
  453.     // Find the library name in there and check/convert it.
  454.     // Or it may be a keymap, so ignore the above.
  455.     
  456.     if (action & IA_CONVERT)
  457.     {
  458.         char *p;
  459.         char buf[128];
  460.         
  461.         if ((p = strchr(apiCall, '.')) || (p = strchr(apiCall, ':')))
  462.         {
  463.             strncpy(buf, apiCall, p - apiCall);
  464.             buf[p - apiCall] = 0;
  465.         }
  466.         else
  467.             strcpy(buf, apiCall);
  468.         strip = stripDecorations(buf, pre, suf, symbolWhitespace);
  469.         if (!(newAPICall = convertName(strip)))
  470.         {
  471.             fprintf(cvtFpErr, "Line %ld: '%s' has no equivalent in Fusion\n",
  472.                 cvtOutputLineNumber, PRSTR(strip));
  473.             action |= (IA_COPY | IA_COMMENTOUT);
  474.              errorLevel |= IE_NOCONVERSION;
  475.         }
  476.         else
  477.         {
  478.             fprintf(cvtFpErr, "Line %ld: '%s' has been replaced with '%s'\n",
  479.                 cvtOutputLineNumber, buf, PRSTR(newAPICall));
  480.             action |= IA_COPY;
  481.             lineOut = strRepStr(strip, newAPICall, lineBuf);
  482.              errorLevel |= IE_OKCONVERSION;
  483.         }
  484.         free(strip);
  485.     }
  486.  
  487.     if (lineOut && (action & IA_COPY))
  488.     {
  489.         char *p;
  490.         
  491.         if (action & IA_COMMENTOUT)
  492.         {
  493.             fprintf(cvtFpOut, ";cvt: ");
  494.             errorLevel |= IE_COMMENTEDOUT;
  495.         }
  496.         fprintf(cvtFpOut, "%s\n", PRSTR(lineOut));
  497.         
  498.         // account for the newline in the above fprintf
  499.         ++cvtOutputLineNumber;
  500.         
  501.         // sync line numbers in case lineOut had newlines in it
  502.         for (p = lineOut; p = strchr(p, '\n'); ++p)
  503.             ++cvtOutputLineNumber;    
  504.     }
  505.     
  506.     if (action & IA_ADDSECTION)
  507.     {
  508.         fprintf(cvtFpOut, "\n%s\n", PRSTR(sectionName));
  509.         fprintf(cvtFpOut, "%s\n", PRSTR(lineOut));
  510.     }
  511.  
  512.     if (lineOut && lineOut != lineBuf)
  513.         free(lineOut);
  514.     return(errorLevel);    
  515. }
  516.  
  517. char *
  518. strSave(char *str)
  519. {
  520.     int  len; 
  521.     char *memp = NULL;
  522.  
  523.     if (str)
  524.          if (memp = malloc((len = strlen(str)) + 1))
  525.         {
  526.             strncpy(memp, str, len);
  527.             memp[len] = 0;
  528.         }
  529.     return(memp);
  530. }
  531.  
  532. /* Look for the next substring in <base> which is delimited by characters
  533.  * in the string <sep>.  If it's there, copy it into <buf> and return
  534.  * a pointer to the next starting point in <base>.  Otherwise, or on
  535.  * bad arguments, return NULL.  The stdlib function strtok() has similar
  536.  * functionality, but it's less convenient and not reentrant.
  537.  *
  538.  */
  539.  
  540. static char *
  541. nexttok(const char *str, char *buf, const char *sep)
  542. {
  543.     char *bufBase = buf;
  544.  
  545.  
  546.     // Handle aberrant arguments and the end-of-input case
  547.      if (buf)
  548.          *buf = 0;
  549.  
  550.     if (!str || !*str)
  551.         return(NULL);
  552.     if (!sep)
  553.         sep = "";
  554.  
  555.     // Skip any leading separators.
  556.     while (*str && strchr(sep, *str))
  557.         ++str;
  558.     if (!*str)  // no valid token characters in the input stream
  559.         return(NULL);
  560.     if (buf)
  561.     {
  562.         while (*str && !strchr(sep, *str))    // Copy the good stuff.
  563.             *buf++ = *str++;
  564.         *buf = 0;
  565.     }
  566.     else        // just skip to the next separator or end-of-input
  567.     {
  568.         while (*str && !strchr(sep, *str))
  569.             str++;
  570.     }
  571.     return((char *)str);            // Yep, give back this token
  572. }
  573.  
  574. /*
  575.  *  Return an allocated string which is a copy of str, with
  576.  *  every occurrence of targPat replaced with repPat.
  577.  */
  578.  
  579. char *
  580. strRepStr(char *targPat, char *repPat, char *inStr)
  581. {
  582.     char *targPos;                // pointer into the input string
  583.     char *buf     = NULL;         // holds partial result
  584.     char *outStr;                 // output string after each replacement
  585.     int  dot = 0;                 // offset of target in input string
  586.     int  repLen;                  // length of replacement string
  587.     int  targLen;                 // length of target string
  588.  
  589.     repLen  = strlen(repPat);
  590.     targLen = strlen(targPat);
  591.  
  592.     if (!targPat || !repPat || !inStr)
  593.         return(NULL);
  594.  
  595.     if (!(outStr = strSave(inStr)))
  596.         return(NULL);
  597.  
  598.      while (targPos = strstr(outStr + dot, targPat))
  599.      {
  600.         dot = targPos - outStr;
  601.         if (!(buf = malloc(strlen(outStr) + (repLen - targLen) + 1)))
  602.         {
  603.             free(outStr);
  604.             return(NULL);
  605.         }
  606.         strncpy(buf, outStr, dot);
  607.         strncpy(buf + dot, repPat, repLen);
  608.         strcpy(buf + dot + repLen, targPos + targLen);
  609.         free(outStr);
  610.         outStr = buf;
  611.         dot += repLen;
  612.     }
  613.     return(outStr);
  614. }
  615.  
  616.  
  617. char *nonFusionItems[] =
  618. {
  619.     "Browse",
  620.     "BrowseQFilename",
  621.     "BrowseSetFile",
  622.     "BufDiff",
  623.     "CompilerAdd",
  624.     "CompilerAddBuild",
  625.     "CompilerAssign",
  626.     "CompilerNewExt",
  627.     "CWHelpDefaultName",
  628.     "CWHelpSDKName",
  629.     "CWUseQuickHelp",
  630.     "ExecCompile",
  631.     "ExecDebug",
  632.     "ExecMake",
  633.     "ExecRebuild",
  634.     "ExecRun",
  635.     "MenuAddKeyString",
  636.     "MenuCommand",
  637.     "MenuDelete",
  638.     "MenuDeleteItem",
  639.     "MenuGetId",
  640.     "MenuGetItemId",
  641.     "MenuGetItemPos",
  642.     "MenuGetPos",
  643.     "MenuInsert",
  644.     "MenuInsertItem",
  645.     "MenuQCount",
  646.     "MenuQHandle",
  647.     "MenuQItemCount",
  648.     "MenuRegisterHandler",
  649.     "MenuRegisterInitializer",
  650.     "MouseCreateWin",
  651.     "RibbonAddBitmap",
  652.     "RibbonAddButton",
  653.     "RibbonAddControl",
  654.     "RibbonAddIcon",
  655.     "RibbonAddItem",
  656.     "RibbonControlAssign",
  657.     "RibbonControlPos",
  658.     "RibbonDelControl",
  659.     "RibbonQBinding",
  660.     "RibbonQHeight",
  661.     "RibbonQUnusedID",
  662.     "RibbonQWidth",
  663.     "RibbonRedraw",
  664.     "RibbonSetHeight",
  665.     "RibbonSetWidth",
  666.     "RibbonViewSideBar",
  667.     "SideBarControl",
  668.     "SysLoadDesktopBitmap",
  669.     "SysQuit",
  670.     "SysSetFileLocking",
  671.     "WinQHClient",
  672.     "WinQHInstance",
  673.     "WinQHRibbon",
  674.     "WinSetCreationPos",
  675.     NULL
  676. };
  677.  
  678. char *changedFusionItems[] =
  679. {
  680.     "BufCreate",
  681.     "BufQViews",
  682.     "ErrorNext",
  683.     "SysSetFlags",
  684.     "WinQHFrame",
  685.     NULL
  686. };
  687.  
  688. char *cwvcSections[] =
  689. {
  690.     "DefaultKeymap",
  691.     "KmapAssign",
  692.     "LibPreload",
  693.     "Editor",
  694.     "Printer",
  695.     "Helper",
  696.     "fmatch",
  697.     "SpellCheck",
  698.     NULL
  699. };
  700.  
  701. char *cwrightSections[] =
  702. {
  703.     "DefaultKeymap",
  704.     "KmapAssign",
  705.     "LibPreLoad",
  706.     "Editor",
  707.     "Colors",
  708.     "Printer",
  709.     "Definitions",
  710.     "Compiler",
  711.     "VersionControl",
  712.     NULL
  713. };
  714.  
  715.  
  716. /*
  717.  *  Who knows?  Maybe this is too slow?
  718.  */
  719. int
  720. checkName(char *call)
  721. {
  722.     char **vp;
  723.  
  724.     if (call)
  725.     {
  726.         for (vp = nonFusionItems; *vp; ++vp)
  727.         {
  728.             if (!strnicmp(*vp, call, strlen(*vp)))
  729.                 return(2);
  730.         }
  731.         for (vp = changedFusionItems; *vp; ++vp)
  732.         {
  733.             if (!strnicmp(*vp, call, strlen(*vp)))
  734.                 return(1);
  735.         }
  736.     }
  737.     return(0);
  738. }
  739.  
  740.  
  741. /*
  742.  *  If there's no valid keymap name, print fatal error.
  743.  *  If there are no errors, say so.
  744.  *  Otherwise, print exit-with-warning status.
  745.  */
  746.  
  747. char *changedNameTab[] =
  748. {
  749.     "cua",     "cwvcua",
  750.     "brief",   "cwvbrief",
  751.     "vi",      "cwvvi",
  752.     "epsilon", "cwvepsln",
  753.     "cwctl3d", "cwvctl3d",
  754.     "cwldraw", "cwvldraw",
  755.     NULL, NULL
  756. };
  757.  
  758. char *
  759. convertName(char *call)
  760. {
  761.     char **vp;
  762.     char *callBu;
  763.     char *p;
  764.     
  765.     if (call)
  766.     {
  767.         callBu = strSave(call);
  768.         // could be 'LibAutoLoad=dogface: kid' or 'LibAutoLoad=dogface(kid)'
  769.         // or 'LibPreload=dogface.dll'
  770.         if (p = strchr(callBu, '.'))
  771.             *p = 0;
  772.         if (p = strchr(callBu, ':'))
  773.             *p = 0;
  774.         if (p = strchr(callBu, '('))
  775.             *p = 0;
  776.  
  777.         for (vp = changedNameTab; vp[0] && vp[1]; vp += 2)
  778.         {
  779.             if (!stricmp(*vp, callBu))
  780.             {
  781.                 free(callBu);
  782.                 return(vp[1]);
  783.             }
  784.         }
  785.         free(callBu);
  786.     }
  787.     return(NULL);
  788. }
  789.  
  790. /*
  791.  *  Strips characters in a specified set from the beginning
  792.  *  and end of str.  Returns an allocated string consisting
  793.  *  of the input string without leading or trailing decoration.  If
  794.  *  preBuf and sufBuf are non-NULL, prefix and suffix ornamentation
  795.  *  is copied into them.  The function assumes that preBuf and
  796.  *  sufBuf, if not NULL, are large enough to hold the decoration.
  797.  */
  798. char *
  799. stripDecorations(char *str, char *preBuf, char *sufBuf, const char *baubles)
  800. {
  801.     char *stripStr;
  802.     char *stripP;
  803.  
  804.     if (!str || !*str || !baubles)
  805.         return(NULL);
  806.  
  807.     stripStr = stripP = malloc(strlen(str) + 1);
  808.     if (preBuf)
  809.     {
  810.         while (*str && strchr(baubles, *str))
  811.             *preBuf++ = *str++;
  812.         *preBuf = 0;
  813.     }
  814.     else
  815.     {
  816.         while (*str && strchr(baubles, *str))
  817.             str++;
  818.     }
  819.     while (*str && !strchr(baubles, *str))
  820.         *stripP++ = *str++;
  821.     *stripP = 0;
  822.     if (sufBuf)
  823.     {
  824.         while (*str && strchr(baubles, *str))
  825.             *sufBuf++ = *str++;
  826.         *sufBuf = 0;
  827.     }
  828.     else
  829.     {
  830.         while (*str && strchr(baubles, *str))
  831.             str++;
  832.     }
  833.     return(stripStr);
  834. }
  835.  
  836. /*
  837.  *  Restores decoration to the given string.
  838.  *  Returns an allocated string consisting of the input string with
  839.  *  preBuf prepended and sufBuf appended.  Either may be NULL.
  840.  */
  841. char *
  842. reDecorate(char *str, char *preBuf, char *sufBuf)
  843. {
  844.     int  preLen;
  845.     int  sufLen;
  846.     int  strLen; 
  847.     char *newStr;
  848.  
  849.     if (!str)
  850.         return(NULL);
  851.  
  852.     if (preBuf)
  853.         preLen = strlen(preBuf);
  854.     else
  855.         preLen = 0;
  856.     if (sufBuf)
  857.         sufLen = strlen(sufBuf);
  858.     else
  859.         sufLen = 0;
  860.     strLen = strlen(str);
  861.  
  862.     if (newStr = malloc(strLen + preLen + sufLen + 1))
  863.     {
  864.         if (preBuf)
  865.             strncpy(newStr, preBuf, preLen);
  866.         strncpy(newStr + preLen, str, strLen);
  867.         if (sufBuf)
  868.             strncpy(newStr + preLen + strLen, sufBuf, sufLen);
  869.         newStr[preLen + strLen + sufLen] = 0;
  870.     }
  871.     return(newStr);
  872. }
  873.