AcePerl
view release on metacpan or search on metacpan
acelib/freesubs.c view on Meta::CPAN
/*******************/
/* Sometimes you may need to know if a function below you succeeded in */
/* changing a stream level. */
UTIL_FUNC_DCL int freeCurrLevel(void)
{
return streamlevel ;
}
/*******************/
static void freeExtend (unsigned char **pin)
{ /* only happens when getting card */
unsigned char *oldCard = card ;
maxcard *= 2 ;
card = (unsigned char *) messalloc (maxcard) ;
if (oldCard) /* jtm june 22, 1992 */
memcpy (card, oldCard, maxcard/2) ;
cardEnd = &card[maxcard-1] ;
*pin += (card - oldCard) ;
messfree (oldCard) ;
messfree (word) ;
word = (unsigned char *) messalloc (maxcard) ;
}
/********************/
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 */
( run in 0.736 second using v1.01-cache-2.11-cpan-5837b0d9d2c )