Beispiel #1
0
/* ---------------------------------------------------------------------- */
Bool xdforall(ps_context_t *pscontext)
{
  register int32 i ;
  register OBJECT *o1 , *o2 ;
  register DPAIR *dplist ;
  OBJECT *thed ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  o1 = stackindex( 3 , & executionstack ) ;
  i = oInteger(*o1) - 1 ;
  o2 = stackindex( 1 , & executionstack ) ;

  thed = oDict(*o2) ;
  if ( i < 0 ) { /* end of dict array reached, check for extension */
    OBJECT *ext = thed - 1;

    if ( oType(*ext) == ONOTHING ) {
      npop( 4 , & executionstack ) ;
      return TRUE ;
    }
    Copy( o2 , ext ) ;       /* put chain dictionary onto exec stack */
    /* set new dictionary and search length: */
    thed = oDict(*o2) ;
    i = DICT_ALLOC_LEN(thed) - 1;
  }

  dplist = ( DPAIR * )( thed + 1 ) ;

  /* Get next key-object pair in the dictionary */
  dplist = ( & ( dplist[ i ] )) ;
  while ( i >= 0 ) {
    if ( oType(theIKey(dplist)) != ONOTHING )
      break ;
    --i ;
    --dplist ;
  }
  if ( i < 0 ) {
    npop( 4, & executionstack );
    return TRUE;
  }

/* Push key */
  if ( ! push( & theIKey( dplist ) , & operandstack ))
    return FALSE ;
/* Push name */
  if ( ! push( & theIObject( dplist ), & operandstack ))
    return FALSE ;

  oInteger(*o1) = i ;
  o1 = stackindex( 2 , & executionstack ) ;
  if ( oExecutable(*o1) )
    return push( o1 , & executionstack ) ;
  else
    return push( o1 , & operandstack ) ;
}
Beispiel #2
0
/* ----------------------------------------------------------------------------
   function:            exit_()            author:              Andrew Cave
   creation date:       22-Oct-1987        last modification:   ##-###-####
   arguments:           none .
   description:

   See PostScript reference manual page 154.

---------------------------------------------------------------------------- */
Bool exit_(ps_context_t *pscontext)
{
  register OBJECT *o1 ;

  execStackSizeNotChanged = FALSE ;
  while ( ! isEmpty( executionstack )) {
    o1 = theTop( executionstack ) ;

    switch ( oType(*o1) ) {
    case OARRAY:
      /* This case used to be explicitly represented as the first if-branch.
         Presumably it was explicitly different to the default for efficiency
         reasons, but that seems a bit spurious now. */
      pop( & executionstack ) ;
      break ;

    case ONOTHING:
      /* Represents a looping context if len non-zero */
      if ( theLen(*o1)) {
        npop( theLen(*o1), & executionstack ) ;
        return TRUE ;
      }
      pop( & executionstack ) ;
      break ;

    case ONULL :
      switch ( theLen(*o1)) {
      case ISINTERPRETEREXIT:
        oInteger(*o1) = NAME_exit;
        return TRUE;

      case ISPATHFORALL :
        path_free_list(thePathOf(*(PATHFORALL *)oOther(*o1)), mm_pool_temp) ;
        free_forallpath(oOther(*o1)) ;
        npop( 5 , & executionstack ) ;
        return TRUE ;
      }
      pop( & executionstack ) ;
      break ;

    case OMARK :       /* Represents a stopped mark */
      return error_handler( INVALIDEXIT ) ;

    case OFILE :       /* Represents a run object - if length set to special value */
      currfileCache = NULL ;
      if ( IsRunFile( o1 ))
        return error_handler( INVALIDEXIT ) ;

    default:
      pop( & executionstack ) ;
    }
  }
  return quit_(pscontext) ;
}
Beispiel #3
0
/* ----------------------------------------------------------------------------
   function:            ifelse_()          author:              Andrew Cave
   creation date:       22-Oct-1987        last modification:   ##-###-####
   arguments:           none .
   description:

   See PostScript reference manual page 169.

---------------------------------------------------------------------------- */
Bool ifelse_(ps_context_t *pscontext)
{
  register OBJECT *o1 , *o2 , *o3 ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  if ( theStackSize( operandstack ) < 2 )
    return error_handler( STACKUNDERFLOW ) ;

  o3 = theTop( operandstack ) ;
  o2 = ( & o3[ -1 ] ) ;
  o1 = ( & o3[ -2 ] ) ;
  if ( ! fastStackAccess( operandstack )) {
    o2 = stackindex( 1 , & operandstack ) ;
    o1 = stackindex( 2 , & operandstack ) ;
  }

  if ( oType(*o1) != OBOOLEAN )
    return error_handler( TYPECHECK ) ;

  switch ( oType(*o2) ) {
  case OARRAY :
  case OPACKEDARRAY :
    break ;
  default:
    return error_handler( TYPECHECK ) ;
  }
  switch ( oType(*o3) ) {
  case OARRAY :
  case OPACKEDARRAY :
    if ( (!oCanExec(*o2) && !object_access_override(o2)) ||
         (!oCanExec(*o3) && !object_access_override(o3)) )
      return error_handler( INVALIDACCESS ) ;
    break ;
  default:
    return error_handler( TYPECHECK ) ;
  }

  if ( oBool(*o1) )
    o3 = o2 ;

  if ( oExecutable(*o3) ) {
    execStackSizeNotChanged = FALSE ;
    if ( ! push( o3 , & executionstack ))
      return FALSE ;
    npop( 3 , & operandstack ) ;
  }
  else {
    Copy( o1 , o3 ) ;
    npop( 2 , & operandstack ) ;
  }

  return TRUE ;
}
Beispiel #4
0
/* ----------------------------------------------------------------------------
   function:            myexp_()           author:              Andrew Cave
   creation date:       09-Feb-1987        last modification:   ##-###-####
   arguments:           none .
   description:

   See PostScript reference manual page 223.

---------------------------------------------------------------------------- */
Bool myexp_(ps_context_t *pscontext)
{
  SYSTEMVALUE args[ 2 ] ;
  SYSTEMVALUE result ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  if ( ! stack_get_numeric(&operandstack, args, 2) )
    return FALSE ;

  if (( args[ 0 ] == OINFINITY_VALUE ) || ( args[ 1 ] == OINFINITY_VALUE ))
    return TRUE ;

  if (( args[ 0 ] < 0.0 ) && ( args[ 1 ] - (( int32 ) args[ 1 ] ) != 0.0 ))
    return error_handler( UNDEFINEDRESULT ) ;

  result = ( SYSTEMVALUE )pow(( double ) args[ 0 ] , ( double ) args[ 1 ] ) ;

  if ( ! realrange( result ))
    return error_handler( RANGECHECK ) ;
  if ( ! realprecision( result ))
    result = 0.0 ;

  npop( 2 , & operandstack ) ;

  return stack_push_real( result, &operandstack ) ;
}
Beispiel #5
0
/* ---------------------------------------------------------------------- */
Bool xlsforall(ps_context_t *pscontext)
{
  OBJECT  *theo ;
  LONGSTR *lstr ;
  int32    idx ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  theo = stackindex( 1 , & executionstack ) ;
  lstr = oLongStr(*theo) ;

  HQASSERT( lstr, "xsforall: invalid longstring object" ) ;

  theo = stackindex( 3 , & executionstack ) ;
  idx = oInteger(*theo) ;
  if ( idx == theLSLen(* lstr )) {
    npop( 4 , & executionstack ) ;
    return TRUE ;
  }

  if ( ! stack_push_integer((int32)theLSCList(*lstr)[idx],
                            &operandstack))
    return FALSE ;

  oInteger(*theo) = idx + 1 ;

  theo = stackindex( 2 , & executionstack ) ;
  if ( oExecutable(*theo) )
    return push( theo , & executionstack ) ;
  else
    return push( theo , & operandstack ) ;
}
Beispiel #6
0
Bool pdfop_BDC( PDFCONTEXT *pdfc )
{
  STACK *stack ;
  OBJECT *properties ;
  OBJECT *tag ;
  PDF_IMC_PARAMS *imc ;

  PDF_CHECK_MC( pdfc ) ;
  PDF_GET_IMC( imc ) ;

  stack = ( & imc->pdfstack ) ;
  if ( theIStackSize( stack ) < 1 )
    return error_handler( RANGECHECK ) ;

  tag = stackindex( 1 , stack ) ;
  if ( oType(*tag) != ONAME )
    return error_handler( TYPECHECK ) ;

  properties = theITop( stack ) ;
  if ( oType(*properties) != ODICTIONARY &&
       oType(*properties) != ONAME )
    return error_handler( TYPECHECK ) ;

  if (!pdf_mc_pushitem(pdfc,tag,properties))
    return FALSE;

  npop( 2 , stack ) ;
  return TRUE ;
}
Beispiel #7
0
/* ---------------------------------------------------------------------- */
Bool xsforall(ps_context_t *pscontext)
{
  register OBJECT *theo ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  theo = stackindex( 1 , & executionstack ) ;

  if ( ! theLen(*theo)) {
    npop( 3 , & executionstack ) ;
    return TRUE ;
  }

  if ( ! stack_push_integer(( int32 )*oString(*theo), &operandstack) )
    return FALSE ;

  if ( --theLen(*theo) == 0 )
    oString(*theo) = NULL ;
  else
    ++oString(*theo) ;

  theo = stackindex( 2 , & executionstack ) ;
  if ( oExecutable(*theo) )
    return push( theo , & executionstack ) ;
  else
    return push( theo , & operandstack ) ;
}
Beispiel #8
0
long double TSolver::solvepolstp(const long double step)         //solves polish record
{if (S==NULL || !strlen(S)) seterr(E_VOID);
 if (!converted || !poled) seterr(E_EXPR);
 if (Err!=E_NO)
   {free(S);
    return 0;
   }
 char n[20]="";
 int sl=strlen(S);
 int i,j=0;
 long double r;

 nst_clear;
 if (!good)
   {for (i=0;i<sl;i++)
      if (!isgood(S[i]))
	{Err=E_FN;
	 return 0;
	}
    good=1;
   }
 for (i=0;i<sl;i++)
   {if (S[i]!=' ')
      {if (isnumc(S[i]) || (S[i]=='-' && S[i+1]!=' ')) {n[j++]=S[i];continue;}
       else
	 {switch (argcnt(S[i]))
	    {case 0: npush(gcalc(S[i],0,0,step));continue;
	     case 1: nst_end=gcalc(S[i],nst_end,0,step);continue;
	     case 2: r=gcalc(S[i],nst_end,npop(),step);
		     nst_end=r;
		     continue;
	     }
	  if (Err!=E_NO) return 0;
	 }
      }
    else
      if (strcmp(n,""))
	{n[j]='\0';
	 npush(_atold(n));
	 strcpy(n,"");
	 j=0;
	}
   }
 return R=npop();
}
Beispiel #9
0
/* ----------------------------------------------------------------------------
   function:            repeat_()          author:              Andrew Cave
   creation date:       22-Oct-1987        last modification:   ##-###-####
   arguments:           none .
   description:

   See PostScript reference manual page 202.

---------------------------------------------------------------------------- */
Bool repeat_(ps_context_t *pscontext)
{
  register OBJECT *o1 , *o2 ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  if ( theStackSize( operandstack ) < 1 )
    return error_handler( STACKUNDERFLOW ) ;

  o2 = theTop( operandstack ) ;
  o1 = ( & o2[ -1 ] ) ;
  if ( ! fastStackAccess( operandstack ))
    o1 = stackindex( 1 , & operandstack ) ;

  if ( oType(*o1) != OINTEGER )
    return error_handler( TYPECHECK ) ;

  switch ( oType(*o2) ) {
  case OARRAY :
  case OPACKEDARRAY :
    break ;
  default:
    return error_handler( TYPECHECK ) ;
  }
  if ( ! oExecutable(*o2) && !object_access_override(o2) )
    return error_handler( INVALIDACCESS ) ;

  if ( oInteger(*o1) < 0 )
    return error_handler( RANGECHECK ) ;
  else if ( oInteger(*o1) == 0 || theLen(*o2) == 0 ) {
    npop( 2 , & operandstack ) ;
    return TRUE ;
  }
  if ( ! push( o1 , & executionstack ))
    return FALSE ;
  if ( ! push( o2 , & executionstack ))
    return FALSE ;
  if ( ! xsetup_operator( NAME_xrepeat , 3 ))
    return FALSE ;

  npop( 2 , & operandstack ) ;
  return TRUE ;
}
Beispiel #10
0
Bool removeglyphs_(ps_context_t *pscontext)
{
  UNUSED_PARAM(ps_context_t *, pscontext) ;

  if ( theStackSize(operandstack) < 2 )
    return error_handler(STACKUNDERFLOW);

  npop(3, &operandstack);
  return TRUE;
}
Beispiel #11
0
int proc_npop_back(NetworkServer *net, Link *link, const Request &req, Response *resp){
	SSDBServer *serv = (SSDBServer *)net->data;
	CHECK_NUM_PARAMS(3);

	const Bytes &name = req[1];
	uint64_t limit = req[2].Uint64();
	NIterator *it = serv->ssdb->nrscan(name, "", "", limit);
	npop(it, serv, name, resp);
	delete it;
	return 0;
}
Beispiel #12
0
static Bool macroFilterInit(FILELIST *filter, OBJECT *args, STACK *stack)
{
  int32 pop_args = 0 ;

  HQASSERT(filter != NULL, "filter is NULL") ;

  HQASSERT(args != NULL || stack != NULL,
           "Arguments and stack should not both be empty") ;
  if ( ! args && !isEmpty(*stack) ) {
    args = theITop(stack) ;
    if ( oType(*args) == ODICTIONARY )
      pop_args = 1 ;
  }

  if ( args && oType(*args) == ODICTIONARY ) {
    if ( ! oCanRead(*oDict(*args)) &&
         ! object_access_override(oDict(*args)) )
      return error_handler( INVALIDACCESS ) ;
    if ( ! FilterCheckArgs( filter , args ))
      return FALSE ;
    OCopy( theIParamDict( filter ), *args ) ;
  } else
    args = NULL ;

  /* Get underlying source/target if we have a stack supplied. */
  if ( stack ) {
    if ( theIStackSize(stack) < pop_args )
      return error_handler(STACKUNDERFLOW) ;

    if ( ! filter_target_or_source(filter, stackindex(pop_args, stack)) )
      return FALSE ;

    ++pop_args ;
  }

  theIBuffer( filter ) = mm_alloc( mm_pool_temp ,
                                   MACROBUFFSIZE + 1 ,
                                   MM_ALLOC_CLASS_PCL_CONTEXT ) ;

  if ( theIBuffer( filter ) == NULL )
    return error_handler( VMERROR ) ;

  theIBuffer( filter )++ ;
  theIPtr( filter ) = theIBuffer( filter ) ;
  theICount( filter ) = 0 ;
  theIBufferSize( filter ) = MACROBUFFSIZE ;
  theIFilterState( filter ) = FILTER_INIT_STATE ;

  HQASSERT(pop_args == 0 || stack != NULL, "Popping args but no stack") ;
  if ( pop_args > 0 )
    npop(pop_args, stack) ;

  return TRUE ;
}
Beispiel #13
0
/* ---------------------------------------------------------------------- */
Bool xfori(ps_context_t *pscontext)
{
  register OBJECT *theo , *ano ;
  register int32 inc , current , ilimit ;
  SYSTEMVALUE slimit ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  theo = stackindex( 4 , & executionstack ) ;
  current = oInteger(*theo) ;
  inc = oInteger(*stackindex(3, &executionstack)) ;

  ano = stackindex( 2 , & executionstack ) ;
  if ( oType(*ano) == OINTEGER ) {
    ilimit = oInteger(*ano) ;
    if (( inc > 0 ) ? ( current > ilimit ) : ( current < ilimit )) {
      npop( 5 , & executionstack ) ;
      return TRUE ;
    }
  }
  else {
    slimit = oReal(*ano) ;
    if (( inc > 0 ) ? ( current > slimit ) : ( current < slimit )) {
      npop( 5 , & executionstack ) ;
      return TRUE ;
    }
  }

  oInteger(inewobj) = current ;
  if ( ! push( & inewobj , & operandstack ))
    return FALSE ;

  oInteger(*theo) = current + inc ;

  theo = stackindex( 1 , & executionstack ) ;
  if ( oExecutable(*theo) )
    return push( theo , & executionstack ) ;
  else
    return push( theo , & operandstack ) ;
}
Beispiel #14
0
static Bool try_roam_named_colors(GS_COLORinfo *colorInfo,
                                  NAMECACHE *sepname,
                                  EQUIVCOLOR equivs,
                                  Bool *foundEquivs,
                                  EXTRADATA *extraData)
{
  OBJECT namedColorIntercept;
  Bool foundResource;

  /* Find out if the Roam NamedColor resource exists; it is an optional resource.
   * If it doesn't exist, just return success with foundEquivs unset.
   */
  if (!run_ps_string((uint8*)"/Roam /NamedColorOrder resourcestatus")) {
    HQFAIL("Internal resourcestatus failed for Roam NamedColorOrder");
    /* If this fails then the tidyup is handled by the client. */
    return FALSE;
  }
  foundResource = oBool(*theTop(operandstack));
  pop(&operandstack);
  if (!foundResource)
    return TRUE;

  /* pop the other 2 items left by a successful resourcestatus */
  npop(2, &operandstack);

  /* The Roam resource exists so and set it in the gstate. Then attempt to
   * get equivalent colors using the named color interception.
   * NB1. The NamedColor databases used in this method can be quite different
   *      to the ones used in the standard method.
   * NB2. The resource can be obtained via a PS callout and placed into a dict
   *      ready for passing to setinterceptcolorspace, but it must be installed
   *      into the correct colorInfo.
   */
  if (!run_ps_string((uint8*)"<< /NamedColor  /Roam /NamedColorOrder findresource >>")) {
    HQFAIL("Internal findresource failed for Roam NamedColorOrder");
    /* If this fails then the tidyup is handled by the client. */
    return FALSE;
  }

  Copy(&namedColorIntercept, theTop(operandstack));
  pop(&operandstack);

  if (!gsc_setinterceptcolorspace(colorInfo, &namedColorIntercept))
    return FALSE;

  return named_colors_common(colorInfo, sepname, equivs,
                             foundEquivs, extraData->outputSpaceId,
                             extraData->equivColorType);
}
Beispiel #15
0
/* Common part of insideness testing for gstate paths and userpaths. Path to
   check inside is passed in as inpath, nargs gives number of operands on
   stack before call. */
static Bool inpath_common( int32 filltype, PATHLIST *inpath, int32 nargs )
{
  OBJECT *arg ;
  int32 type ;
  Bool result ;
  Bool inside ;

  if ( theStackSize(operandstack) < nargs )
    return error_handler(STACKUNDERFLOW) ;

  arg = stackindex(nargs++, &operandstack) ;

  type = oType(*arg) ;

  if ( type == OARRAY || type == OPACKEDARRAY ) { /* aperture intersection */
    PATHINFO appath ;

    if ( ! upath_to_path(arg, UPARSE_CLOSE, &appath) )
      return FALSE ;

    result = path_in_path(thePath(appath), inpath, filltype, &inside) ;

    path_free_list(thePath(appath), mm_pool_temp) ;
  } else { /* point in path */
    SYSTEMVALUE px, py, tx, ty ;

    if ( ! object_get_numeric(arg, &py) )
      return FALSE ;

    if ( theStackSize(operandstack) < nargs )
      return error_handler(STACKUNDERFLOW) ;

    arg = stackindex(nargs++, &operandstack) ;

    if ( ! object_get_numeric(arg, &px) )
      return FALSE ;

    MATRIX_TRANSFORM_XY( px, py, tx, ty, & thegsPageCTM(*gstateptr)) ;

    result = point_in_path(tx, ty, inpath, filltype, &inside) ;
  }

  if ( result ) { /* remove consumed operands */
    npop(nargs, &operandstack) ;
    result = push((inside ? &tnewobj : &fnewobj), &operandstack) ;
  }

  return result ;
}
Beispiel #16
0
/* ---------------------------------------------------------------------- */
Bool xforr(ps_context_t *pscontext)
{
  register OBJECT *theo , *other ;
  SYSTEMVALUE inc , current , limit ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  theo = stackindex( 2 , & executionstack ) ;
  if ( oType(*theo) == OREAL )
    limit = oReal(*theo) ;
  else
    limit = OINFINITY_VALUE ;
  theo = stackindex( 4 , & executionstack ) ;
  if ( oType(*theo) == OREAL )
    current = oReal(*theo) ;
  else
    current = OINFINITY_VALUE ;
  other = stackindex( 3 , & executionstack ) ;
  if ( oType(*other) == OREAL )
    inc = oReal(*other) ;
  else
    inc = OINFINITY_VALUE ;

  if (( inc > 0.0 ) ? ( current > limit ) : ( current < limit )) {
    npop( 5 , & executionstack ) ;
    return TRUE ;
  }
  if ( ! stack_push_real( current, &operandstack ))
    return FALSE ;

  current += inc ;

  if ( realrange( current )) {
    if ( ! realprecision( current ))
      oReal(*theo) = 0.0f ;
    else
      oReal(*theo) = ( USERVALUE )current ;
  }
  else
    theTags(*theo) = OINFINITY | LITERAL ;

  theo = stackindex( 1 , & executionstack ) ;
  if ( oExecutable(*theo) )
    return push( theo , & executionstack ) ;
  else
    return push( theo , & operandstack ) ;
}
Beispiel #17
0
/* ---------------------------------------------------------------------- */
Bool xrepeat(ps_context_t *pscontext)
{
  register OBJECT *theo ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  theo = stackindex( 2 , & executionstack ) ;
  if ( ! oInteger(*theo) ) {
    npop( 3 , & executionstack ) ;
    return TRUE ;
  }
  --oInteger(*theo) ;
  theo = stackindex( 1 , & executionstack ) ;
  if ( oExecutable(*theo) )
    return push( theo , & executionstack ) ;
  else
    return push( theo , & operandstack ) ;
}
Beispiel #18
0
Bool pdfop_DP( PDFCONTEXT *pdfc )
{
  STACK *stack ;
  OBJECT *tag ;
  OBJECT *properties ;
  PDF_IMC_PARAMS *imc ;

  PDF_CHECK_MC( pdfc ) ;
  PDF_GET_IMC( imc ) ;

  stack = ( & imc->pdfstack ) ;
  if ( theIStackSize( stack ) < 1 )
    return error_handler( RANGECHECK ) ;

  tag = stackindex( 1 , stack ) ;
  if ( oType(*tag) != ONAME )
    return error_handler( TYPECHECK ) ;

  properties = theITop( stack ) ;
  if ( oType(*properties) != ODICTIONARY &&
       oType(*properties) != ONAME )
    return error_handler( TYPECHECK ) ;

  /* an OC tag will set the OC context to a given group
     directly. Currently this is only cleared by a similar
     tag or an OC tag from BDC
  */
  switch (oName(*tag) - system_names) {
    case NAME_OC:
      imc->mc_DP_oc_status = TRUE;
      if (!pdf_oc_getstate_fromprops(pdfc, properties, & imc->mc_DP_oc_status))
        return FALSE;

      if (! imc->mc_DP_oc_status) {
        if (!change_optional_content_on(FALSE))
          return FALSE;
      }
      break;
  }

  npop( 2 , stack ) ;
  return TRUE ;
}
Beispiel #19
0
void interpret_packet(void) {
    int size = rx(); // ignore.  protocol is self-terminating.
    (void)size;

    int command = rx();
    switch(command & 0x0F) {
    default:
    case 0: ack(); break;
    case 1: npush(); break;
    case 2: npop(); break;
    case 3: jsr(); break;
    case 4: lda(); break;
    case 5: ldf(); break;
    case 7: intr(); break;
    case 8: nafetch(); break;
    case 9: nffetch(); break;
    case 10: nastore(); break;
    case 11: nfstore(); break;
    }
    infof("\n");
}
Beispiel #20
0
/* For xaforall, the execution stack contains:
      0 ONOTHING  len=size of this block (3 or 5)  oOp = xaforall
      1 OARRAY    len=elements left to deliver  oArray=next element to deliver
        or OEXTENDED  len=0  oArray = trampoline below
      2 OARRAY - the proc to run
   For long arrays:
      3 OARRAY    len=0  oArray = next element to deliver
      4 OINTEGER  len=0  oInteger = remaining elements
*/
Bool xaforall(ps_context_t *pscontext)
{
  register OBJECT *theo ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  theo = stackindex( 1 , & executionstack ) ;

  if ( ! theXLen(*theo)) {
    npop( theLen(*theTop(executionstack)) , & executionstack ) ;
    return TRUE ;
  }

  if ( oType(*theo) == OEXTENDED ) {  /* Long arrays */

    if ( !push(oLongArray(*theo), &operandstack) )
      return FALSE ;

    if (--oLongArrayLen(*theo) == 0)
      oLongArray(*theo) = NULL ;
    else
      ++oLongArray(*theo) ;

  } else {  /* Normal arrays */

    if ( ! push(oArray(*theo) , & operandstack ))
      return FALSE ;

    if ( --theLen(*theo) == 0 )
      oArray(*theo) = NULL ;
    else
      ++oArray(*theo) ;
  }

  theo = stackindex( 2 , & executionstack ) ;
  if ( oExecutable(*theo) )
    return push( theo , & executionstack ) ;
  else
    return push( theo , & operandstack ) ;
}
Beispiel #21
0
/* ---------------------------------------------------------------------- */
Bool xfastfori(ps_context_t *pscontext)
{
  register OBJECT *o1 , *o2 , *o3 , *o4 ;
  register int32 inc , current , ilimit , inext ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  o4 = stackindex( 1 , & executionstack ) ;
  o3 = ( & o4[ -1 ] ) ;
  o2 = ( & o4[ -2 ] ) ;
  o1 = ( & o4[ -3 ] ) ;
  if ( ! fastStackAccess( executionstack )) {
    o3 = stackindex( 2 , & executionstack ) ;
    o2 = stackindex( 3 , & executionstack ) ;
    o1 = stackindex( 4 , & executionstack ) ;
  }

  current = oInteger(*o1) ;
  inc = oInteger(*o2) ;
  ilimit = oInteger(*o3) ;
  inext = current + inc;

  /* Check for overflow when checking termination condition
   * Preserve inconsistent behaviour when inc == 0 */
  if (( inc > 0 ) ? ( inext > ilimit || inext < current) : ( inext < ilimit || inext > current)) {
    npop( 5 , & executionstack ) ;
    return TRUE ;
  }

  oInteger(inewobj) = inext ;
  if ( ! push( & inewobj , & operandstack ))
    return FALSE ;

  oInteger(*o1) = inext ;

  return push( o4 , & executionstack ) ;
}
Beispiel #22
0
/*----------------------------------------------------------------------------*/
static Bool obFontFilterInit(FILELIST *filter,
                             OBJECT *args,
                             STACK *stack)
{
  HQASSERT(args == NULL && stack != NULL, "Stack but no args please") ;

  if (theIStackSize(stack) < 2)
    return error_handler(STACKUNDERFLOW);

  args = theITop(stack);
  if ( args && oType(*args) != OSTRING )
    return error_handler(TYPECHECK);

  if ( !filter_target_or_source(filter, stackindex(1, stack)) )
    return FALSE;

  /* allocate a buffer */
  theIBuffer(filter) = (uint8 *)mm_alloc(mm_pool_temp,
                                         OBFONTBUFFSIZE + 1,
                                         MM_ALLOC_CLASS_FILTER_BUFFER);
  if ( theIBuffer(filter) == NULL )
    return error_handler(VMERROR);

  theIBuffer(filter)++;
  theIPtr(filter) = theIBuffer(filter);
  theICount(filter) = 0;
  theIBufferSize(filter) = OBFONTBUFFSIZE;
  theIFilterState(filter) = FILTER_INIT_STATE;

  /* the deobfuscation string is also the flag that it needs applying */
  theIFilterPrivate(filter) = args;

  npop(2, stack);

  return TRUE;
}
Beispiel #23
0
static Bool genericFilterInit( FILELIST *filter ,
                               OBJECT *args ,
                               STACK *stack )
{
  DEVICELIST  *dlist;
  uint8       *buff;
  DEVICE_FILEDESCRIPTOR desc;
  int32 flag;
  int32 pop_args = 0 ;

  HQTRACE( debug_filters , ( "In genericFilterInit" )) ;

  dlist = theIDeviceList( filter );
  HQASSERT(dlist, "encountered bad filter");
  theINextDev( dlist ) = ( DEVICELIST *)filter;   /* connect up strs */

  HQASSERT(args != NULL || stack != NULL,
           "Arguments and stack should not both be empty") ;
  if ( ! args && !isEmpty(*stack) ) {
    args = theITop(stack) ;
    if ( oType(*args) == ODICTIONARY )
      pop_args = 1 ;
  }

  if ( args && oType(*args) == ODICTIONARY ) {
    if ( ! oCanRead(*oDict(*args)) &&
         ! object_access_override(oDict(*args)))
      return error_handler(INVALIDACCESS ) ;
    if ( ! FilterCheckArgs( filter , args ))
      return FALSE ;
    OCopy( theIParamDict( filter ), *args ) ;
  } else
    args = NULL ;

  /* Get underlying source/target if we have a stack supplied. */
  if ( stack ) {
    if ( theIStackSize(stack) < pop_args )
      return error_handler(STACKUNDERFLOW) ;

    if ( ! filter_target_or_source(filter, stackindex(pop_args, stack)) )
      return FALSE ;

    ++pop_args ;
  }

  if ( args ) {
    if ( ! walk_dictionary( args, device_set_params, (void *)dlist) )
      return FALSE ;
  }

  /* allocate space for buffer */
  theIBufferSize( filter ) = (*theIGetBuffSize( dlist ))( dlist );
  buff = ( uint8 * )mm_alloc( mm_pool_temp , theIBufferSize( filter ) + 4 ,
                              MM_ALLOC_CLASS_FILTER_BUFFER ) ;
  if ( buff == NULL )
    return error_handler( VMERROR ) ;
  theIBuffer( filter ) = buff + 4 ;
  theIPtr( filter ) = buff + 4 ;
  theICount( filter ) = 0 ;
  theIFilterState( filter ) = FILTER_INIT_STATE ;

  if ( isIInputFile( filter ))
    flag = SW_RDONLY ;
  else                         /* assume isIOutputFile is TRUE */
    flag = SW_WRONLY ;

 /* open a file on the transform device */

  desc = ( * theIOpenFile( dlist ))( dlist , NULL , flag ) ;
  if ( desc < 0 )
    return device_error_handler(dlist);

  theIDescriptor( filter ) = desc ;

  HQASSERT(pop_args == 0 || stack != NULL, "Popping args but no stack") ;
  if ( pop_args > 0 )
    npop(pop_args, stack) ;

  return TRUE ;
}
Beispiel #24
0
/* ----------------------------------------------------------------------------
   function:            forall_()          author:              Andrew Cave
   creation date:       22-Oct-1987        last modification:   ##-###-####
   arguments:           none .
   description:

   See PostScript reference manual page 161.

---------------------------------------------------------------------------- */
Bool forall_(ps_context_t *pscontext)
{
  int32 which, number, type ;
  OBJECT *o1, *o2, *accessobj ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  if ( theStackSize( operandstack ) < 1 )
    return error_handler( STACKUNDERFLOW ) ;

  o2 = theTop( operandstack ) ;
  switch ( oType(*o2) ) {
  case OARRAY :
  case OPACKEDARRAY :
    break ;
  default:
    return error_handler( TYPECHECK ) ;
  }
  number = 3 ;
  accessobj = o1 = stackindex(1, &operandstack) ;
  type = oXType(*o1) ;

  switch ( type ) {

  case ODICTIONARY :
    accessobj = oDict(*o1) ;
    oInteger(inewobj) = DICT_ALLOC_LEN(accessobj);
    if ( ! push( & inewobj , & executionstack ))
      return FALSE ;
    which = NAME_xdforall ;
    ++number ;
    break ;
  case OSTRING :
    which = NAME_xsforall ;
    break ;
  case OLONGSTRING :
    oInteger(inewobj) = 0 ;
    if ( ! push( & inewobj , & executionstack ))
      return FALSE ;
    which = NAME_xlsforall ;
    ++number ;
    break ;
  case OLONGARRAY :
  case OLONGPACKEDARRAY :
    /* The trampoline must be pushed too, as it is modified by xaforall */
    if ( ! push( oArray(*o1)   , & executionstack ) || /* length */
         ! push( oArray(*o1)+1 , & executionstack ))   /* subarray */
      return FALSE ;
    number+=2;
    /* drop through */
  case OARRAY :
  case OPACKEDARRAY :
    which = NAME_xaforall ;
    break ;
  default:
    return error_handler( TYPECHECK ) ;
  }
  if ( (!oCanRead(*accessobj) && !object_access_override(accessobj)) ||
       (!oCanExec(*o2) && !object_access_override(o2)) ) {
    while ( number-- > 3 )
      pop( & executionstack ) ;
    return error_handler( INVALIDACCESS ) ;
  }
  if ( ! push( o2 , & executionstack ))
    return FALSE ;
  if ( ! push( o1 , & executionstack ))
    return FALSE ;

  switch ( type ) {
    case OLONGARRAY:
    case OLONGPACKEDARRAY:
      /* point the pushed OEXTENDED at the pushed trampoline below it */
      o1 = theTop(executionstack) ;
      oArray(*o1) = stackindex( 3 , & executionstack ) ;
      break ;
  }

  if ( ! xsetup_operator( which , number ))
    return FALSE ;

  npop( 2 , & operandstack ) ;

  return TRUE ;
}
Beispiel #25
0
/* ----------------------------------------------------------------------------
   function:            pathforall_()      author:              Andrew Cave
   creation date:       22-Oct-1987        last modification:   ##-###-####
   arguments:           none .
   description:

   See PostScript reference manual page 192.

---------------------------------------------------------------------------- */
Bool pathforall_(ps_context_t *pscontext)
{
  int32 pushed = 0 ;
  PATHINFO newpath = {0} ;
  PATHFORALL *newone ;
  PATHINFO *lpath = &(thePathInfo(*gstateptr)) ;
  Bool result = FALSE ;
  OBJECT opfa = OBJECT_NOTVM_NULL ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  if ( ( thePathInfo(*gstateptr)).protection)
    return error_handler( INVALIDACCESS ) ;

  if ( theStackSize( operandstack ) < 3 )
    return error_handler( STACKUNDERFLOW ) ;

  if ( lpath->lastline == NULL ) {
    npop( 4 , & operandstack ) ;
    return TRUE ;
  }

  for ( pushed = 0 ; pushed < 4 ; ++pushed ) {
    if ( ! push( stackindex( pushed , & operandstack ) , & executionstack )) {
      npop(pushed, &executionstack) ;
      return FALSE ;
    }
  }

  if ( NULL == ( newone = get_forallpath())) {
    npop(pushed, &executionstack) ;
    return error_handler( VMERROR ) ;
  }

  SET_SINV_SMATRIX( & thegsPageCTM(*gstateptr) , NEWCTM_ALLCOMPONENTS ) ;
  if ( SINV_NOTSET( NEWCTM_ALLCOMPONENTS )) {
    free_forallpath( newone ) ;
    npop(pushed, &executionstack) ;
    return error_handler( UNDEFINEDRESULT ) ;
  }
  MATRIX_COPY(&thePathCTM(*newone), &sinv) ;

  execStackSizeNotChanged = FALSE ;
  theLen(opfa) = ISPATHFORALL ;
  oCPointer(opfa) = newone ;

  if ( push(&opfa, &executionstack) && ++pushed > 0 &&
       path_copy_list(lpath->firstpath, &newpath.firstpath,
                      &newpath.lastpath, &newpath.lastline, mm_pool_temp) &&
       path_close(MYCLOSE, &newpath) ) {

    thePathOf(*newone) = newpath.firstpath ;
    npop(4, &operandstack) ;
    result = TRUE ;

  } else {

    free_forallpath(newone) ;
    npop(pushed, &executionstack) ;
  }

  return result ;
}
Beispiel #26
0
static Bool dothestop(ps_context_t *pscontext, Bool super)
{
  execStackSizeNotChanged = FALSE ;

  while ( ! isEmpty( executionstack )) {
    register OBJECT *o1 = theTop(executionstack) ;
    int32 *tptr ;
    FILELIST *flptr ;

    switch ( oType(*o1) ) {
    case OMARK :   /* Represents a stopped mark */
      if ( ! super || theLen(*o1)) {
        mm_context_t *mmc = ps_core_context(pscontext)->mm_context;

        if ( theLen(*o1)) {
          allow_interrupt = FALSE; /* superstop disables interrupt */
          clear_interrupts();
        }
        /* Reset allocation cost after error handling. */
        if ( mmc != NULL) /* this can run before MM init */
          mm_set_allocation_cost(mmc, mm_cost_normal);
        pop( & executionstack ) ;
        return push( & tnewobj , & operandstack ) ;
      }
      pop( & executionstack ) ;
      break ;

    case ONULL :
      switch ( theLen(*o1)) {
      case ISINTERPRETEREXIT :
        /* indicate that we're in a stopped context by changing the object's
           value */
        oInteger(*o1) = super ? NAME_superstop : NAME_stop ;
        return TRUE;

      case ISPATHFORALL :
        tptr = oOther(*o1) ;
        path_free_list(thePathOf(*(PATHFORALL *)tptr), mm_pool_temp) ;
        free_forallpath( tptr ) ;
        npop( 4 , & executionstack ) ;
        break ;
      }
      pop( & executionstack ) ;
      break ;

    case OFILE : /* Represents a run object - if length is special value */
      currfileCache = NULL ;
      if ( IsRunFile ( o1 )) {
        flptr = oFile(*o1) ;
        if ( isIOpenFileFilter( o1 , flptr ))
          (void)(*theIMyCloseFile( flptr ))( flptr, CLOSE_EXPLICIT ) ;
      }
      pop( & executionstack ) ;
      break ;

    default:
      pop( & executionstack ) ;
    }
  }

  return quit_(pscontext) ;
}
Beispiel #27
0
static Bool runlengthFilterInit( FILELIST *filter,
                                 OBJECT *args ,
                                 STACK *stack )
{
  int32 buffsize = RUNLENGTHBUFFSIZE ;
  int32 pop_args = 0 ;

  HQASSERT(args != NULL || stack != NULL,
           "Arguments and stack should not both be empty") ;

  if ( isIOutputFile( filter )) { /* encoding filter */
    OBJECT *theo ;
    int32  record_size ;

    /* Can't pass args directly to RunLengthEncode, since it
     * has no dictionary only form (Adobe oversight?). We might have
     * to add our own if we ever want RLE for pdf out.
     */
    HQASSERT( ! args ,
              "Can't handle direct dictionary arguments in RunLengthEncode." ) ;

    if ( isEmpty(*stack) )
      return error_handler( STACKUNDERFLOW ) ;

    theo = theITop(stack) ;
    pop_args = 1 ;

    if ( oType(*theo) != OINTEGER )
      return error_handler( TYPECHECK ) ;
    record_size = oInteger(*theo) ;
    if ( record_size < 0 ||
         record_size > 65536 )
      return error_handler( RANGECHECK ) ;

    theIDescriptor( filter ) = record_size ;
    if ( buffsize < record_size )
      buffsize = record_size ;
  }

  if ( ! args && theIStackSize(stack) >= pop_args ) {
    args = stackindex(pop_args, stack) ;
    if ( oType(*args) == ODICTIONARY )
      ++pop_args ;
  }

  if ( args && oType(*args) == ODICTIONARY ) {
    if ( ! oCanRead(*oDict(*args)) &&
         ! object_access_override(args) )
      return error_handler( INVALIDACCESS ) ;
    if ( ! FilterCheckArgs( filter , args ))
      return FALSE ;
    OCopy( theIParamDict( filter ), *args ) ;
  } else
    args = NULL ;

  /* Get underlying source/target if we have a stack supplied. */
  if ( stack ) {
    if ( theIStackSize(stack) < pop_args )
      return error_handler(STACKUNDERFLOW) ;

    if ( ! filter_target_or_source(filter, stackindex(pop_args, stack)) )
      return FALSE ;

    ++pop_args ;
  }

  theIBuffer( filter ) = ( uint8 * )
                         mm_alloc_with_header( mm_pool_temp ,
                                               buffsize + 1 ,
                                               MM_ALLOC_CLASS_RUNLEN_BUFFER ) ;
  if ( theIBuffer( filter ) == NULL )
    return error_handler( VMERROR ) ;

  theIBuffer( filter )++ ;
  theIPtr( filter ) = theIBuffer( filter ) ;
  theICount( filter ) = 0 ;
  theIBufferSize( filter ) = buffsize ;
  theIFilterState( filter ) = FILTER_INIT_STATE ;

  HQASSERT(pop_args == 0 || stack != NULL, "Popping args but no stack") ;
  if ( pop_args > 0 )
    npop(pop_args, stack) ;

  return TRUE ;
}
Beispiel #28
0
static Bool ascii85FilterInit( FILELIST *filter ,
                               OBJECT *args ,
                               STACK *stack )
{
  ASCII85DECODESTATE *ascii85state ;
  int32 pop_args = 0 ;

  HQASSERT(args != NULL || stack != NULL,
           "Arguments and stack should not both be empty") ;
  if ( ! args && !isEmpty(*stack) ) {
    args = theITop(stack) ;
    if ( oType(*args) == ODICTIONARY )
      pop_args = 1 ;
  }

  if ( args && oType(*args) == ODICTIONARY ) {
    if ( ! oCanRead(*oDict(*args)) &&
         ! object_access_override(oDict(*args)) )
      return error_handler( INVALIDACCESS ) ;
    if ( ! FilterCheckArgs( filter , args ))
      return FALSE ;
    OCopy( theIParamDict( filter ), *args ) ;
  } else
    args = NULL ;

  /* Get underlying source/target if we have a stack supplied. */
  if ( stack ) {
    if ( theIStackSize(stack) < pop_args )
      return error_handler(STACKUNDERFLOW) ;

    if ( ! filter_target_or_source(filter, stackindex(pop_args, stack)) )
      return FALSE ;

    ++pop_args ;
  }

  if ( isIInputFile( filter )) {
    /* decoding filter requires an extra byte at the begining in order
     * to cope with an UnGetc. However, ascii85DecodeBuffer writes four
     * bytes at a time, so we add 4 here to keep the resulting buffer word
     * aligned.
     */
    theIBuffer( filter ) = ( uint8 * )mm_alloc( mm_pool_temp ,
                                                ASCII85BUFFSIZE + 4 ,
                                                MM_ALLOC_CLASS_ASCII_85 ) ;

    if ( theIBuffer( filter ) == NULL )
      return error_handler( VMERROR ) ;

    theIBuffer( filter ) += 4 ; /* keep the buffer word-aligned */

    /* Allocate filter private state. */
    ascii85state = (ASCII85DECODESTATE *)mm_alloc( mm_pool_temp ,
                                                   sizeof(ASCII85DECODESTATE) ,
                                                   MM_ALLOC_CLASS_ASCII_85_STATE ) ;
    if ( ascii85state == NULL )
      return error_handler( VMERROR ) ;
    theIFilterPrivate( filter ) = ascii85state ;
    ascii85state->cached_error = NOT_AN_ERROR ;
  } else {
    theIBuffer( filter ) = ( uint8 * )mm_alloc( mm_pool_temp ,
                                                ASCII85BUFFSIZE ,
                                                MM_ALLOC_CLASS_ASCII_85 ) ;

    if ( theIBuffer( filter ) == NULL )
      return error_handler( VMERROR ) ;
  }

  theIPtr( filter ) = theIBuffer( filter ) ;
  theICount( filter ) = 0 ;
  theIBufferSize( filter ) = ASCII85BUFFSIZE ;
  theIFilterState( filter ) = FILTER_INIT_STATE ;

  HQASSERT(pop_args == 0 || stack != NULL, "Popping args but no stack") ;
  if ( pop_args > 0 )
    npop(pop_args, stack) ;

  return TRUE ;
}
Beispiel #29
0
/* ----------------------------------------------------------------------------
   function:            for_()             author:              Andrew Cave
   creation date:       22-Oct-1987        last modification:   ##-###-####
   arguments:           none .
   description:

   See PostScript reference manual page 160.  The manual does not define
   correct behaviour when increment is zero, so we emulate behaviour observed
   in (Level 2 and 3) Adobe RIPs, which is to finish without looping if
   initial < limit, and loop forever otherwise, pushing initial on each iteration.

---------------------------------------------------------------------------- */
Bool for_(ps_context_t *pscontext)
{
  register int32 inc , current , ilimit ;
  register OBJECT *o1 , *o2 , *o3 , *o4 ;
  int32 loop ;
  SYSTEMVALUE args[ 3 ] ;

  UNUSED_PARAM(ps_context_t *, pscontext) ;

  if ( theStackSize( operandstack ) < 3 )
    return error_handler( STACKUNDERFLOW ) ;

  o4 = theTop( operandstack ) ;
  o3 = ( & o4[ -1 ] ) ;
  o2 = ( & o4[ -2 ] ) ;
  o1 = ( & o4[ -3 ] ) ;
  if ( ! fastStackAccess( operandstack )) {
    o3 = stackindex( 1 , & operandstack ) ;
    o2 = stackindex( 2 , & operandstack ) ;
    o1 = stackindex( 3 , & operandstack ) ;
  }

  switch ( oType(*o4) ) {
  case OARRAY :
  case OPACKEDARRAY :
    break ;
  default:
    return error_handler( TYPECHECK ) ;
  }
  if ( ! oCanExec(*o4) && !object_access_override(o4) )
    return error_handler( INVALIDACCESS ) ;

  if ( oType(*o1) == OINTEGER &&
       oType(*o2) == OINTEGER &&
       oType(*o3) == OINTEGER ) {
    current     = oInteger(*o1) ;
    inc         = oInteger(*o2) ;
    ilimit      = oInteger(*o3) ;

    /* Tests indicate we should loop forever iff inc == 0 && current >= ilimit */

    if (( inc > 0 ) ? ( current > ilimit ) : ( current < ilimit )) {
      npop( 4 , & operandstack ) ;
      return TRUE ;
    }

    if ( ! push4( o1, o2 , o3 , o4 , & executionstack ))
      return FALSE ;
    if ( ! xsetup_operator( NAME_xfastfori , 5 ))
      return FALSE ;
    if ( ! push( o4 , & executionstack ))
      return FALSE ;

    npop( 3 , & operandstack ) ;
    HQASSERT(oInteger(*o1) == current, "current changed mysteriously") ;

    return TRUE ;
  }
/* Slow default case. */

  if ( !object_get_numeric(o1, &args[0]) ||
       !object_get_numeric(o2, &args[1]) ||
       !object_get_numeric(o3, &args[2]) )
    return FALSE ;

  if ( oType(*o1) == OINTEGER && oType(*o2) == OINTEGER && intrange(args[2])) {
    if ( ! push4( o1 , o2 , o3 , o4 , & executionstack ))
      return FALSE ;
    if ( ! xsetup_operator( NAME_xfori , 5 ))
      return FALSE ;
  }
  else {
    for ( loop = 0 ; loop < 3 ; ++loop )
      if ( ! stack_push_real(args[loop], &executionstack) )
        return FALSE ;
    if ( ! push( o4 , & executionstack ))
      return FALSE ;
    if ( ! xsetup_operator( NAME_xforr , 5 ))
      return FALSE ;
  }
  npop( 4 , & operandstack ) ;
  return TRUE ;
}
Beispiel #30
0
/* ---------------------------------------------------------------------- */
Bool xpathforall(PATHFORALL *thepath)
{
  OBJECT *theo ;
  LINELIST *currline , *theline , *templine ;
  PATHLIST *currpath ;
  SYSTEMVALUE x , y ;

  currpath = thePathOf(*thepath) ;
  currline = theSubPath(*currpath) ;

  for (;;) {
    if ( ! currline ) {
      if ( ! currpath->next) {
        path_free_list( currpath, mm_pool_temp ) ;
        free_forallpath( thepath ) ;
        npop( 5 , & executionstack ) ;
        return TRUE ;
      }
      else {
        thePathOf(*thepath) = currpath->next ;
        currpath->next = NULL ;
        path_free_list( currpath, mm_pool_temp ) ;
        currpath = thePathOf(*thepath) ;
        currline = theSubPath(*currpath) ;
      }
    }
    switch ( theLineType(*currline) ) {
    case MYMOVETO :
      currline = currline->next ;
      continue ;
    case MYCLOSE :
      thePathOf(*thepath) = currpath->next ;
      currpath->next = NULL ;
      path_free_list( currpath, mm_pool_temp ) ;
      currpath = thePathOf(*thepath) ;
      if ( ! currpath ) {
        free_forallpath( thepath ) ;
        npop( 5 , & executionstack ) ;
        return TRUE ;
      }
      currline = theSubPath(*currpath) ;
      continue ;
    }
    break ;
  }

  theo = NULL ;

  switch ( theLineType(*currline) ) {

  case CURVETO :
    theo = stackindex( 3 , & executionstack ) ;
    MATRIX_TRANSFORM_XY( theX(thePoint(*currline)),
                         theY(thePoint(*currline)),
                         x, y, &thePathCTM(*thepath)) ;
    if ( ! stack_push_real( x, &operandstack ))
      return FALSE ;
    if ( ! stack_push_real( y, &operandstack ))
      return FALSE ;
    currline = currline->next ;
    MATRIX_TRANSFORM_XY( theX(thePoint(*currline)),
                         theY(thePoint(*currline)),
                         x, y, &thePathCTM(*thepath)) ;
    if ( ! stack_push_real( x, &operandstack ))
      return FALSE ;
    if ( ! stack_push_real( y, &operandstack ))
      return FALSE ;
    currline = currline->next ;

  case MOVETO :
    if ( ! theo )
      theo = stackindex( 1 , & executionstack ) ;

  case LINETO :
    if ( ! theo )
      theo = stackindex( 2 , & executionstack ) ;
    MATRIX_TRANSFORM_XY( theX(thePoint(*currline)),
                         theY(thePoint(*currline)),
                         x, y, &thePathCTM(*thepath)) ;
    if ( ! stack_push_real( x, &operandstack ))
      return FALSE ;
    if ( ! stack_push_real( y, &operandstack ))
      return FALSE ;

  case CLOSEPATH :
    if ( ! theo )
      theo = stackindex( 4 , & executionstack ) ;
    currline = currline->next ;
    break ;
  }

/* Free any structs going ... */
  theline = theSubPath(*currpath) ;
  while ( theline != currline ) {
    templine = theline ;
    theline = theline->next ;
    free_line( templine, mm_pool_temp ) ;
  }
  theSubPath(*currpath) = theline ;

  return setup_pending_exec( theo, FALSE ) ;
}