home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume36 / unpost / part06 / modflnm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-18  |  8.2 KB  |  301 lines

  1. /******************************************************************************
  2. * Module    :   File Names --- File name utilities.
  3. *
  4. * Author    :   John W. M. Stevens
  5. ******************************************************************************/
  6.  
  7. #include    "compiler.h"
  8.  
  9. #include    "unpost.h"
  10. #include    "sets.h"
  11. #include    "modflnm.h"
  12.  
  13. /*  Sets.   */
  14. static      int     InitSets = 1;
  15. static      SET     StandSet;
  16. static      SET     ThrowSet;
  17. static      SET     NoSet;
  18. static      SET     AlphaSet;
  19.  
  20. /*  Strings for character sets. */
  21. static      char    *Stand = "a-z0-9_.-";
  22. static      char    *Throw = "aeiouy_-";
  23. static      char    *Numbers = "0-9";
  24. static      char    *Alpha = "a-z";
  25.  
  26. /*-----------------------------------------------------------------------------
  27. | Routine   :   ChkFlNmLen() --- Check the file name length.
  28. |
  29. | Inputs    :   FileName    - File name.
  30. -----------------------------------------------------------------------------*/
  31.  
  32. static
  33. int     ChkFlNmLen(char     *FileNm)
  34. {
  35.     register    int     i;
  36.  
  37.     /*  Count file characters.  */
  38.     for (i = 0;
  39.          FileNm[i] && FileNm[i] != EXT_SEP_CHAR;
  40.          i++)
  41.         ;
  42.  
  43.     /*  Return True or False.   */
  44.     return( i );
  45. }
  46.  
  47. /*-----------------------------------------------------------------------------
  48. | Routine   :   FlNmFilter() --- Filter a string so that only characters from
  49. |               the set of standard file name characters are left.
  50. |
  51. | Inputs    :
  52. -----------------------------------------------------------------------------*/
  53.  
  54. void    FlNmFilter(char     *FlName)
  55. {
  56.     auto        char    *cp;
  57.     auto        char    *tp;
  58.     auto        char    c;
  59.  
  60.     /*  Create character sets.  */
  61.     if ( InitSets )
  62.     {
  63.         tp = Stand;
  64.         CrtSet(&tp, StandSet);
  65.         tp = Throw;
  66.         CrtSet(&tp, ThrowSet);
  67.         tp = Numbers;
  68.         CrtSet(&tp, NoSet);
  69.         tp = Alpha;
  70.         CrtSet(&tp, AlphaSet);
  71.         InitSets = 0;
  72.     }
  73.  
  74.     /*  Convert string to lower case and strip out illegal characters.  */
  75.     for (cp = tp = FlName; *tp; tp++)
  76.     {
  77.         /*  First, convert to lower case.   */
  78.         c = (char) tolower( *tp );
  79.  
  80.         /*  Next, check for standards conformity.   */
  81.         if (c == ' ' || c == '\t' || InSet(StandSet, c))
  82.             *cp++ = c;
  83.     }
  84.     *cp = '\0';
  85. }
  86.  
  87. /*-----------------------------------------------------------------------------
  88. | Routine   :   ModifyFlNm() --- Convert to lower case and make sure that
  89. |               this file name conforms to MS-DOS restrictions/limitations
  90. |               and USENET posting standards.
  91. |
  92. | Inputs    :   FlName  - File name.
  93. |               Ext     - Extension.
  94. | Outputs   :   OutName - Modified file name.
  95. -----------------------------------------------------------------------------*/
  96.  
  97. int     ModifyFlNm(char     *FlName,
  98.                    char     *Ext,
  99.                    char     *OutName)
  100. {
  101.     register    int     i;
  102.     auto        int     len;
  103.     auto        int     ChopFlag;
  104.     auto        char    *cp;
  105.     auto        char    *tp;
  106.     auto        char    c;
  107.     extern      FILE    *ErrFile;
  108.  
  109.     /*  Create character sets.  */
  110.     if ( InitSets )
  111.     {
  112.         tp = Stand;
  113.         CrtSet(&tp, StandSet);
  114.         tp = Throw;
  115.         CrtSet(&tp, ThrowSet);
  116.         tp = Numbers;
  117.         CrtSet(&tp, NoSet);
  118.         tp = Alpha;
  119.         CrtSet(&tp, AlphaSet);
  120.         InitSets = 0;
  121.     }
  122.  
  123.     /*  Convert string to lower case and strip out illegal characters.  */
  124.     for (cp = OutName, tp = FlName; *tp; tp++)
  125.     {
  126.         /*  First, convert to lower case.   */
  127.         c = (char) tolower( *tp );
  128.  
  129.         /*  Next, check for standards conformity.   */
  130.         if ( InSet(StandSet, c) )
  131.             *cp++ = c;
  132.     }
  133.     *cp = '\0';
  134.  
  135.     /*  If we have more than MAX_FILE characters in the file name,
  136.     *   then shorten the file name.
  137.     */
  138.     if ((len = ChkFlNmLen( OutName )) > MAX_FILE)
  139.     {
  140.         /*  Shorten by removing vowels and separator characters.    */
  141.         for (tp = cp = OutName, i = len;
  142.              *tp && *tp != EXT_SEP_CHAR && i > MAX_FILE;
  143.              tp++)
  144.         {
  145.             /*  If this is not a throw away character, save it back
  146.             *   in the string.
  147.             */
  148.             if (! InSet(ThrowSet, *tp))
  149.             {
  150.                 *cp++ = *tp;
  151.                 continue;
  152.             }
  153.             else if (tp == OutName)
  154.             {
  155.                 *cp++ = *tp;
  156.                 continue;
  157.             }
  158.  
  159.             /*  Decrement the file name size.   */
  160.             i--;
  161.         }
  162.         strcpy(cp, tp);
  163.     }
  164.     else
  165.         goto ShortEnough;
  166.  
  167.     /*  If we still have more than MAX_FILE characters in the file
  168.     *   name, chop off leading zeros in any numeric strings in the
  169.     *   file name.
  170.     */
  171.     if ((len = ChkFlNmLen( OutName )) > MAX_FILE)
  172.     {
  173.         /*  Loop through string.    */
  174.         for (tp = cp = OutName, i = len;
  175.              *tp && *tp != EXT_SEP_CHAR && i > MAX_FILE;
  176.              tp++)
  177.         {
  178.             /*  If this is a numeric sub-string, strip any leading
  179.             *   zeros.
  180.             */
  181.             if (tp[1] && tp[1] != '.' &&
  182.                 InSet(NoSet, *tp) && InSet(NoSet, tp[1]) &&
  183.                 *tp == '0')
  184.             {
  185.                 i--;
  186.                 continue;
  187.             }
  188.  
  189.             /*  Copy character in.  */
  190.             *cp++ = *tp;
  191.         }
  192.         strcpy(cp, tp);
  193.     }
  194.     else
  195.         goto ShortEnough;
  196.  
  197.     /*  If we still have more than MAX_FILE characters in the file name, chop
  198.     *   alphabetic strings short by throwing away excess characters.
  199.     */
  200.     while ((len = ChkFlNmLen( OutName )) > MAX_FILE)
  201.     {
  202.         /*  Loop through string.    */
  203.         for (tp = cp = OutName, ChopFlag = 0, i = len;
  204.              *tp && *tp != EXT_SEP_CHAR && i > MAX_FILE;
  205.              tp++)
  206.         {
  207.             /*  Do not throw away numeric characters at this point. */
  208.             if ( InSet(NoSet, *tp) )
  209.             {
  210.                 *cp++ = *tp;
  211.                 continue;
  212.             }
  213.  
  214.             /*  Throw away the trailing character in an alphabetic
  215.             *   substring.
  216.             */
  217.             if (*tp && tp[1] != EXT_SEP_CHAR &&
  218.                 InSet(AlphaSet, *tp) && InSet(AlphaSet, tp[1]))
  219.             {
  220.                 *cp++ = *tp;
  221.                 continue;
  222.             }
  223.  
  224.             /*  Yup, we are chopping out a character.   */
  225.             i--;
  226.             ChopFlag = 1;
  227.         }
  228.         strcpy(cp, tp);
  229.  
  230.         /*  If not even one character is chopped out in a pass
  231.         *   through the file name list, drop out and issue an
  232.         *   error.
  233.         */
  234.         if (ChopFlag == 0)
  235.         {
  236.             fprintf(ErrFile,
  237.                     "%s %d : Error - Could not modify file name to be ",
  238.                     __FILE__,
  239.                     __LINE__);
  240.             fprintf(ErrFile,
  241.                     "MS-DOS conformant.\n");
  242.             return( 1 );
  243.         }
  244.     }
  245.  
  246.     /*  Done with file name, now fix extension. */
  247. ShortEnough:
  248.     for (tp = OutName;
  249.          *tp && *tp != EXT_SEP_CHAR;
  250.          tp++)
  251.         ;
  252.     if (*tp == EXT_SEP_CHAR)
  253.     {
  254.         /*  Were we able to identify this file? */
  255.         if ( *Ext )
  256.             strcpy(tp, Ext);
  257.         else
  258.         {
  259.             /*  Move four characters across (including '.') and we
  260.             *   are done.
  261.             */
  262.             for (i = 0, tp++;
  263.                  *tp && *tp != EXT_SEP_CHAR && i < MAX_EXT;
  264.                  i++, tp++)
  265.                 ;
  266.             *tp = '\0';
  267.         }
  268.     }
  269.     else
  270.     {
  271.         /*  No extension, so append one.    */
  272.         strcpy(tp, Ext);
  273.     }
  274.  
  275.     /*  Return no error.    */
  276.     return( 0 );
  277. }
  278.  
  279. /*-----------------------------------------------------------------------------
  280. | Routine   :   ModExten() --- Modify the file name extension.
  281. |
  282. | Inputs    :   FlName  - File name.
  283. -----------------------------------------------------------------------------*/
  284.  
  285. void    ModExten(char   *FlName,
  286.                  char   *Exten,
  287.                  char   *OutFlNm)
  288. {
  289.     auto    char    *tp;
  290.     auto    char    *op;
  291.  
  292.     /*  Search for the first file name extension separator character.   */
  293.     for (tp = FlName, op = OutFlNm;
  294.          *tp && *tp != EXT_SEP_CHAR;
  295.          )
  296.         *op++ = *tp++;
  297.  
  298.     /*  Copy in new extension.  */
  299.     strcpy(op, Exten);
  300. }
  301.