Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.2 SOURCE/6/PARSEFN.C
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

196 lines
8.1 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/***************************************************************************
*
* _ p a r s e f n F u n c t i o n
* ---------------------------------
* Copyright 1983 by Digital Research Inc. All rights reserved.
*
* Function "_parsefn()" is used to parse a filename into the CP/M fcb.
* NOTE: For PCDOS, an OS call is written in assembler ("_pc_parse()").
*
* Calling Sequence:
* ret = _parsefn(filnam,fcbp);
*
* Where:
* filnam Is a null-terminated CP/M filename
* ret Is NULLPTR if entire string parsed,
* -1 if there was an error, or
* a pointer to the next item to parse
* fcbp Is the address of a CP/M File Control Block (fcb).
* Note: password will get stuffed into bytes 16-23
* user # (plus 1) in byte 24, if supplied in filnam.
* File Spec:
* #d:filename.typ;passwd
*
* Modified:
* 1/84 whf handle 68K parsing error.
* 3/84 sw Fix off by 1 user #
****************************************************************************/
#include "portab.h"
#include "osif.h"
#include "ctype.h"
#define FAILPTR ((BYTE *)(-1)) /* FAILURE */
BYTE * /****************************/
_parsefn(filnam,fcbp) /* */
REG BYTE *filnam; /* -> filename */
struct fcbtab *fcbp; /* -> FCB address */
{ /****************************/
#if PCDOS /*================================================================*/
REG BYTE *retp; /* To convert to ret val */
BYTE *_pc_parse(); /* Use PC-DOS parse call */
/* */
retp = _pc_parse(filnam,fcbp); /* return 1st char after fnam*/
if( fcbp->fname[0] == ' ' ) /* PC-DOS convention for bad*/
return FAILPTR; /* ...filename */
while( isspace(*retp) ) /* skip trailing white stuff*/
++retp; /* */
if( *retp == NULL ) /* parsed to EOS? */
return NULLPTR; /* yes, say so */
else return retp; /* no, return ptr */
}
#endif /*==================================================================*/
#if CPM /*==================================================================*/
BYTE tokbuf[32]; /* Token temporary buffer */
BYTE *get_token(); /* Tokenize the file name */
/****************************/
blkfill(fcbp,NULL,32); /* Init fcb area to NULLs */
blkfill(&(fcbp->fname[0]),' ',11); /* with name area to spaces */
/* */
filnam = get_token(filnam,tokbuf,32); /* Get the first token */
if(*filnam == ':') /* Is the delim a colon? */
{ /* If yes, then a drive spec*/
if(stuff_drive(fcbp,tokbuf) == FAILURE) /* Check drive OK */
return FAILPTR; /* Return error if bad */
filnam=get_token(++filnam,tokbuf,32); /* Get next token */
} /****************************/
/* */
if(*filnam == '*') /* Delimiter is a "*"?? */
{ /* */
blkfill(&(fcbp->fname[0]),'?',8); /* Yes, fill with ?'s 1st */
filnam++; /* Bump to next character */
} /****************************/
_strcpy(tokbuf,fcbp->fname,8); /* Copy the file name in */
if(*filnam == '.') /* If extension specified */
{ /* */
filnam=get_token(++filnam,tokbuf,32); /* get extension token */
if(*filnam == '*') /* Is wildcarded ext? */
{ /* */
blkfill(&(fcbp->fname[8]),'?',3); /* If yes, fill with ?'s */
filnam++; /* Bump to next character */
} /* */
_strcpy(tokbuf,&(fcbp->fname[8]),3); /* Copy the string */
} /* */
if(*filnam == ';') /* If password specified */
{ /* */
filnam=get_token(++filnam,tokbuf,32); /* get extension token */
_strcpy(tokbuf,&(fcbp->fpasswd[0]),8);/* Copy the string */
} /* */
switch(*filnam) /* Check for EOS */
{ /* */
case NULL: /* Null terminated */
case '\n': /* CCPM compatible */
case '\r': /* " " */
return NULLPTR; /* everything a-ok */
} /**** */
return FAILPTR; /* Not legal file name */
} /****************************/
MLOCAL _strcpy(s,d,c) /* Special string copy func */
REG BYTE *s; /* Source string */
REG BYTE *d; /* Destination area */
REG WORD c; /* Count */
{ /****************************/
while ((*s) && (c)) /* */
{ /* */
*d++ = toupper(*s); /* Copy a byte */
s++; /* Up source */
c--; /* Down count */
} /* */
} /****************************/
/****************************************************************************/
/* */
/* G e t _ t o k e n R o u t i n e */
/* --------------------------------- */
/* */
/* Routine get_token takes the next token from the input string. */
/* */
/* Calling Sequence: */
/* ret = get_token(src,dest,len); */
/* */
/* Where: */
/* src is the address of the source string */
/* dest is the address of the destination area */
/* len is the number of bytes in "dest". */
/* */
/* ret is the returned address of the delimiter */
/* */
/****************************************************************************/
MLOCAL BYTE *_delim="<>.,=:|[]*\n\r"; /* Delimiter set */
MLOCAL BYTE *get_token(src,dest,len) /* */
REG BYTE *src; /* -> source */
REG BYTE *dest; /* -> destination */
REG WORD len; /* output area size */
{ /****************************/
while(*src && (!strchr(_delim,*src)) && len)/* Until done */
{ /* */
*dest++ = *src++; /* Move 1 byte */
len--; /* Down count */
} /****************************/
*dest = '\0'; /* Drop in null terminator */
return(src); /* Return delimiter addr. */
} /****************************/
/****************************************************************************/
/* */
/* S t u f f _ d r i v e F u n c t i o n */
/* --------------------------------------- */
/* */
/* Routine "stuff_drive" loads the user and drive code fields from */
/* the filename string. */
/* */
/* Calling sequence: */
/* ret = stuff_drive(fcbp,src); */
/* */
/* Where: */
/* fcbp Is the FCB address within the ccb */
/* src Is the source filename string */
/* ret Is SUCCESS if ok, FAILURE o.w. */
/* */
/****************************************************************************/
MLOCAL WORD stuff_drive(fcbp,src) /* */
struct fcbtab *fcbp; /* -> FCB area */
REG BYTE *src; /* -> Source string */
{ /****************************/
REG WORD i; /* Accumulator */
i = 0; /* Zap to zero */
while(isdigit(*src)) /* As long as source is dig.*/
{ /* */
i = (i*10) + *src++ - '0'; /* Convert to number */
fcbp->fuser = i+1; /* store user number */
} /****************************/
/* */
if(*src) /* Drive code letter? */
{ /* Here => yes */
fcbp->drive = toupper(*src)-'A'+1; /* get drive code byte */
src++; /* Increment source pointer */
} /* */
if(*src || /* Illegal stuff? */
(fcbp->fuser > 16) || /*sw Bad user #? */
(fcbp->drive > 15) ) /* Bad drive? */
return(FAILURE); /* Yes, quit */
return(SUCCESS); /* OK to continue */
} /****************************/
#endif /*==================================================================*/
============================================*/
============================================*/