/******************************************************************************
* Module : File Names --- File name utilities.
*
* Author : John W. M. Stevens
******************************************************************************/
#include "compiler.h"
#include "unpost.h"
#include "sets.h"
#include "modflnm.h"
/* Sets. */
static int InitSets = 1;
static SET StandSet;
static SET ThrowSet;
static SET NoSet;
static SET AlphaSet;
/* Strings for character sets. */
static char *Stand = "a-z0-9_.-";
static char *Throw = "aeiouy_-";
static char *Numbers = "0-9";
static char *Alpha = "a-z";
/*-----------------------------------------------------------------------------
| Routine : ChkFlNmLen() --- Check the file name length.
|
| Inputs : FileName - File name.
-----------------------------------------------------------------------------*/
static
int ChkFlNmLen(char *FileNm)
{
register int i;
/* Count file characters. */
for (i = 0;
FileNm[i] && FileNm[i] != EXT_SEP_CHAR;
i++)
;
/* Return True or False. */
return( i );
}
/*-----------------------------------------------------------------------------
| Routine : FlNmFilter() --- Filter a string so that only characters from
| the set of standard file name characters are left.
|
| Inputs :
-----------------------------------------------------------------------------*/
void FlNmFilter(char *FlName)
{
auto char *cp;
auto char *tp;
auto char c;
/* Create character sets. */
if ( InitSets )
{
tp = Stand;
CrtSet((unsigned char **) &tp, StandSet);
tp = Throw;
CrtSet((unsigned char **) &tp, ThrowSet);
tp = Numbers;
CrtSet((unsigned char **) &tp, NoSet);
tp = Alpha;
CrtSet((unsigned char **) &tp, AlphaSet);
InitSets = 0;
}
/* Convert string to lower case and strip out illegal characters. */
for (cp = tp = FlName; *tp; tp++)
{
/* First, convert to lower case. */
c = (char) tolower( *tp );
/* Next, check for standards conformity. */
if (c == ' ' || c == '\t' || InSet(StandSet, (unsigned char) c))
*cp++ = c;
}
*cp = '\0';
}
/*-----------------------------------------------------------------------------
| Routine : ModifyFlNm() --- Convert to lower case and make sure that
| this file name conforms to MS-DOS restrictions/limitations
| and USENET posting standards.
|
| Inputs : FlName - File name.
| Ext - Extension.
| Outputs : OutName - Modified file name.
-----------------------------------------------------------------------------*/
int ModifyFlNm(char *FlName,
char *Ext,
char *OutName)
{
register int i;
auto int len;
auto int ChopFlag;
auto char *cp;
auto char *tp;
auto char c;
extern FILE *ErrFile;
/* Create character sets. */
if ( InitSets )
{
tp = Stand;
CrtSet((unsigned char **) &tp, StandSet);
tp = Throw;
CrtSet((unsigned char **) &tp, ThrowSet);
tp = Numbers;
CrtSet((unsigned char **) &tp, NoSet);
tp = Alpha;
CrtSet((unsigned char **) &tp, AlphaSet);
InitSets = 0;
}
/* Convert string to lower case and strip out illegal characters. */
for (cp = OutName, tp = FlName; *tp; tp++)
{
/* First, convert to lower case. */
c = (char) tolower( *tp );
/* Next, check for standards conformity. */
if ( InSet(StandSet, (unsigned char) c) )
*cp++ = c;
}
*cp = '\0';
/* If we have more than MAX_FILE characters in the file name,
* then shorten the file name.
*/
if ((len = ChkFlNmLen( OutName )) > MAX_FILE)
{
/* Shorten by removing vowels and separator characters. */
for (tp = cp = OutName, i = len;
*tp && *tp != EXT_SEP_CHAR && i > MAX_FILE;
tp++)
{
/* If this is not a throw away character, save it back
* in the string.
*/
if (! InSet(ThrowSet, (unsigned char) *tp))
{
*cp++ = *tp;
continue;
}
else if (tp == OutName)
{
*cp++ = *tp;
continue;
}
/* Decrement the file name size. */
i--;
}
strcpy(cp, tp);
}
else
goto ShortEnough;
/* If we still have more than MAX_FILE characters in the file
* name, chop off leading zeros in any numeric strings in the
* file name.
*/
if ((len = ChkFlNmLen( OutName )) > MAX_FILE)
{
/* Loop through string. */
for (tp = cp = OutName, i = len;
*tp && *tp != EXT_SEP_CHAR && i > MAX_FILE;
tp++)
{
/* If this is a numeric sub-string, strip any leading
* zeros.
*/
if (tp[1] && tp[1] != '.' &&
InSet(NoSet, (unsigned char) *tp) &&
InSet(NoSet, (unsigned char) tp[1]) &&
*tp == '0')
{
i--;
continue;
}
/* Copy character in. */
*cp++ = *tp;
}
strcpy(cp, tp);
}
else
goto ShortEnough;
/* If we still have more than MAX_FILE characters in the file name, chop
* alphabetic strings short by throwing away excess characters.
*/
while ((len = ChkFlNmLen( OutName )) > MAX_FILE)
{
/* Loop through string. */
for (tp = cp = OutName, ChopFlag = 0, i = len;
*tp && *tp != EXT_SEP_CHAR && i > MAX_FILE;
tp++)
{
/* Do not throw away numeric characters at this point. */
if ( InSet(NoSet, (unsigned char) *tp) )
{
*cp++ = *tp;
continue;
}
/* Throw away the trailing character in an alphabetic
* substring.
*/
if (*tp && tp[1] != EXT_SEP_CHAR &&
InSet(AlphaSet, (unsigned char) *tp) &&
InSet(AlphaSet, (unsigned char) tp[1]))
{
*cp++ = *tp;
continue;
}
/* Yup, we are chopping out a character. */
i--;
ChopFlag = 1;
}
strcpy(cp, tp);
/* If not even one character is chopped out in a pass
* through the file name list, drop out and issue an
* error.
*/
if (ChopFlag == 0)
{
fprintf(ErrFile,
"%s %d : Error - Could not modify file name to be ",
__FILE__,
__LINE__);
fprintf(ErrFile,
"MS-DOS conformant.\n");
return( 1 );
}
}
/* Done with file name, now fix extension. */
ShortEnough:
for (tp = OutName;
*tp && *tp != EXT_SEP_CHAR;
tp++)
;
if (*tp == EXT_SEP_CHAR)
{
/* Were we able to identify this file? */
if ( *Ext )
strcpy(tp, Ext);
else
{
/* Move four characters across (including '.') and we
* are done.
*/
for (i = 0, tp++;
*tp && *tp != EXT_SEP_CHAR && i < MAX_EXT;
i++, tp++)
;
*tp = '\0';
}
}
else
{
/* No extension, so append one. */
strcpy(tp, Ext);
}
/* Return no error. */
return( 0 );
}
/*-----------------------------------------------------------------------------
| Routine : ModExten() --- Modify the file name extension.
|
| Inputs : FlName - File name.
-----------------------------------------------------------------------------*/
void ModExten(char *FlName,
char *Exten,
char *OutFlNm)
{
auto char *InPtr;
auto char *OutPtr;
auto char *ExtPtr;
/* Search for the first file name extension separator character. */
for (InPtr = FlName, OutPtr = OutFlNm, ExtPtr = NULL;
*InPtr;
InPtr++, OutPtr++
)
{
/* Copy Characters. */
*OutPtr = *InPtr;
/* Check for extension separator character. */
if (*OutPtr == EXT_SEP_CHAR)
ExtPtr = OutPtr;
}
*OutPtr = '\0';
/* Copy in new extension. */
if ( ExtPtr )
strcpy(ExtPtr, Exten);
else
strcpy(OutPtr, Exten);
}
syntax highlighted by Code2HTML, v. 0.9.1