AcePerl
view release on metacpan or search on metacpan
acelib/freesubs.c view on Meta::CPAN
static char special[256] ;
void freespecial (char* text)
{
if (!text)
messcrash ("freespecial received 0 text") ;
if (strlen(text) > 23)
messcrash ("freespecial received a string longer than 23") ;
if (text != stream[streamlevel].special)
strcpy (stream[streamlevel].special, text) ;
memset (special, 0, (mysize_t) 256) ;
while (*text)
special [((int) *text++) & 0xFF] = TRUE ;
special[0] = TRUE ;
special[(unsigned char)EOF] = TRUE ; /* better have these to ensure streams terminate! */
}
/********************/
void freeforcecard (char *string)
{ int level = freesettext (string, "") ;
freespecial ("") ;
freecard (level) ;
}
/********************/
char* freecard (int level) /* returns 0 when streamlevel drops below level */
{
unsigned char *in,ch,*cp ;
int kpar ;
int isecho = FALSE ; /* could reset sometime? */
FILE *fil ;
BOOL acceptShell, acceptCommand ;
restart :
if (level > streamlevel)
return 0 ;
if (isecho)
printf (!currfil ? "From text >" : "From file >") ;
in = card ; --in ;
acceptCommand = special['@'] ;
acceptShell = special['$'] ;
while (TRUE)
{ if (++in >= cardEnd)
freeExtend (&in) ;
*in = _FREECHAR ;
lao:
if (special[((int) *in) & 0xFF] && *in != '$' && *in != '@' )
switch (*in)
{
#if defined(WIN32)
case '\r':
continue ; /* ignore carriage returns */
#endif
case '\n': /* == '\x0a' */
case ';': /* card break for multiple commands on one line */
goto got_line ;
case (unsigned char) EOF:
case '\0':
freeclose(streamlevel) ;
goto got_line;
case '\t': /* tabs should get rounded to 8 spaces */
if (isecho) /* write it out */
putchar (*in) ;
*in++ = ' ' ;
while ((in - card) % 8)
{ if (in >= cardEnd)
freeExtend (&in) ;
*in++ = ' ' ;
}
--in ;
continue ;
case '/': /* // means start of comment */
if ((ch = _FREECHAR) == '/')
{ while ((ch = _FREECHAR) != '\n' && ch != (unsigned char)EOF) ;
goto got_line ;
}
else
{ if (isecho) putchar (*in) ;
if (currfil) /* push back ch */
ungetc (ch, currfil) ;
else
--currtext ;
}
break ;
case '%': /* possible parameter */
--in ; kpar = 0 ;
while (isdigit (ch = _FREECHAR))
kpar = kpar*10 + (ch - '0') ;
if (kpar > 0 && kpar <= stream[streamlevel].npar)
for (cp = (unsigned char *) stackText (parStack,
stream[streamlevel].parMark[kpar-1]) ; *cp ; ++cp)
{ if (++in >= cardEnd)
freeExtend (&in) ;
*in = *cp ;
if (isecho)
putchar (*in) ;
}
else
messout ("Parameter %%%d can not be substituted", kpar) ;
if (++in >= cardEnd)
freeExtend (&in) ;
*in = ch ;
goto lao ; /* mieg */
case '\\': /* escapes next character - interprets \n */
*in = _FREECHAR ;
if (*in == '\n') /* fold continuation lines */
{ if (isInteractive && !streamlevel)
printf (" Continuation >") ;
while ((ch = _FREECHAR) == ' ' || ch == '\t') ;
/* remove whitespace at start of next line */
if (currfil) /* push back ch */
ungetc (ch, currfil) ;
else
--currtext ;
stream[streamlevel].line++ ;
--in ;
}
#if !defined(WIN32)
else if (*in == 'n') /* reinterpret \n as a format */
{ *in = '\n' ;
}
#endif
else /* keep the \ till freeword is called */
{ *(in+1) = *in ;
*in = '\\' ;
if (++in >= cardEnd)
freeExtend (&in) ;
}
break ;
default:
messerror ("freesubs got unrecognised special character 0x%x = %c\n",
*in, *in) ;
}
else
{ if (!isprint(*in) && *in != '\t' && *in != '\n') /* mieg dec 15 94 */
--in ;
else if (isecho) /* write it out */
putchar (*in) ;
}
} /* while TRUE loop */
got_line:
stream[streamlevel].line++ ;
*in = 0 ;
if (isecho)
putchar ('\n') ;
pos = card ;
_losewhite ;
if (acceptCommand && _stepover ('@')) /* command file */
{ char *name ;
if ((name = freeword ()) &&
(fil = filopen (name, 0, "r")))
freesetfile (fil, (char*) pos) ;
goto restart ;
}
if (acceptShell && _stepover ('$')) /* shell command */
{
#if !defined(MACINTOSH)
system ((char*)pos) ;
#endif
goto restart ;
}
return (char*) card ;
}
/************************************************/
void freecardback (void) /* goes back one card */
{ stream[streamlevel].line-- ;
freesettext ((char*) card, "") ;
}
/************************************************/
BOOL freeread (FILE *fil) /* reads card from fil */
{
unsigned char ch, *in = card ;
int *line, chint ;
if (!assFind (filAss, fil, &line))
{ line = (int*) messalloc (sizeof (int)) ;
assInsert (filAss, fil, line) ;
}
--in ;
while (TRUE)
{ ++in ;
if (in >= cardEnd)
freeExtend (&in) ;
chint = getc(fil) ;
if (ferror(fil))
messerror ("chint was bad");
*in = chint ;
switch (*in)
{
case '\n' :
++*line ;
case (unsigned char) EOF :
goto got_line ;
case '/' : /* // means start of comment */
if ((ch = getc (fil)) == '/')
{ while (getc(fil) != '\n' && !feof(fil)) ;
++*line ;
if (in > card) /* // at start of line ignores line */
goto got_line ;
else
--in ; /* in = 0 unprintable, so backstepped */
}
else
ungetc (ch,fil) ;
break ;
case '\\' : /* escape next character */
*in = getc(fil) ;
if (*in == '\n') /* continuation */
{ ++*line ;
acelib/freesubs.c view on Meta::CPAN
{
freenewstream (parms) ;
currfil = fil ;
currtext = 0 ;
return streamlevel ;
}
int freesetpipe (FILE *fil, char *parms)
{
freenewstream (parms) ;
currfil = fil ;
currtext = 0 ;
stream[streamlevel].isPipe = TRUE ;
return streamlevel ;
}
void freeclose(int level)
{ int kpar ;
while (streamlevel >= level)
{ if (currfil && currfil != stdin && currfil != stdout)
{
if (stream[streamlevel].isPipe)
pclose (currfil) ;
else
filclose (currfil) ;
}
for (kpar = stream[streamlevel].npar ; kpar-- ;)
popText (parStack) ;
--streamlevel ;
currfil = stream[streamlevel].fil ;
currtext = stream[streamlevel].text ;
freespecial (stream[streamlevel].special) ;
}
}
/************************************************/
/* freeword(), freewordcut() and freestep() are the only calls that
directly move pos forward -- all others act via freeword().
freeback() moves pos back one word.
*/
char *freeword (void)
{
unsigned char *cw ;
_losewhite ; /* needed in case of intervening freestep() */
if (_stepover ('"'))
{ for (cw = word ; !_stepover('"') && *pos ; *cw++ = *pos++)
if (_stepover('\\')) /* accept next char unless end of line */
if (!*pos)
break ;
_losewhite ;
*cw = 0 ;
return (char*) word ; /* always return a word, even if empty */
}
/* default: break on space and \t, not on comma */
for (cw = word ; isgraph (*pos) && *pos != '\t' ; *cw++ = *pos++)
if (_stepover('\\')) /* accept next char unless end of line */
if (!*pos)
break ;
_losewhite ;
*cw = 0 ;
return *word ? (char*) word : 0 ;
}
/************************************************/
#if defined(WIN32)
char *freepath (void)
{
unsigned char *cw ;
_losewhite ; /* needed in case of intervening freestep() */
if (_stepover ('"'))
{ for (cw = word ; !_stepover('"') && *pos ; *cw++ = *pos++)
if (_stepover('\\')) /* accept next char unless end of line */
if (!*pos)
break ;
_losewhite ;
*cw = 0 ;
return (char*) word ; /* always return a word, even if empty */
}
/* default: break on space, \t or end of line, not on comma
also, does not skip over backslashes which are assumed to be
MS DOS/Windows path delimiters */
for (cw = word ; ( *pos == '\\' || isgraph (*pos) ) && *pos != '\t' ; *cw++ = *pos++) ;
_losewhite ;
*cw = 0 ;
return *word ? (char*) word : 0 ;
}
#endif
/************************************************/
char *freewordcut (char *cutset, char *cutter)
/* Moves along card, looking for a character from cut, which is a
0-terminated char list of separators.
Returns everything up to but not including the first match.
pos is moved one char beyond the character.
*cutter contains the char found, or if end of card is reached, 0.
*/
{ unsigned char *cc,*cw ;
for (cw = word ; *pos ; *cw++ = *pos++)
for (cc = (unsigned char *) cutset ; *cc ; ++cc)
if (*cc == *pos)
goto wcut ;
wcut:
*cutter = *pos ;
if (*pos)
++pos ;
_losewhite ;
*cw = 0 ;
return *word ? (char*) word : 0 ;
}
/************************************************/
void freeback (void) /* goes back one word - inefficient but reliable */
{unsigned char *now = pos ;
unsigned char *old = pos ;
pos = card ; _losewhite ;
while (pos < now)
{old = pos ;
freeword () ;
}
pos = old ;
}
/************************************************/
#define NON_INT -(1<<30)
#define NON_FLOAT -(1<<30)
BOOL freeint (int *p)
{unsigned char *keep = pos ;
unsigned char *cp ;
int value = 0 ;
BOOL isMinus = FALSE ;
( run in 1.573 second using v1.01-cache-2.11-cpan-f56aa216473 )