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 )