Example #1
0
void HttpHandler::HandleRequest(const HttpRequest* req, HttpResponse* resp) {
    switch (req->Method()) {
    case HttpRequest::METHOD_HEAD:
        HandleHead(req, resp);
        break;
    case HttpRequest::METHOD_GET:
        HandleGet(req, resp);
        break;
    case HttpRequest::METHOD_POST:
        HandlePost(req, resp);
        break;
    case HttpRequest::METHOD_PUT:
        HandlePut(req, resp);
        break;
    case HttpRequest::METHOD_DELETE:
        HandleDelete(req, resp);
        break;
    case HttpRequest::METHOD_OPTIONS:
        HandleOptions(req, resp);
        break;
    case HttpRequest::METHOD_TRACE:
        HandleTrace(req, resp);
        break;
    case HttpRequest::METHOD_CONNECT:
        HandleConnect(req, resp);
        break;
    default:
        MethodNotAllowed(req, resp);
        break;
    }
}
Example #2
0
static void camfree(CameraStruct **x)
{
  if (*x) {
    if ((*x)->cam) CamDelete( (*x)->cam );
    if ((*x)->h) HandleDelete( (*x)->h );
    DELETE(*x);
  }
}
Example #3
0
int
comm_object(char *str, HandleOps *ops, Handle **hp, Ref **rp, int now)
{
  int c, ok = 0;
  Pool *p;

  if (str == NULL)
    return 0;
  if (strcmp(str, "-") == 0 || access(str, 0) == 0) {
    Handle *h = HandleReferringTo('<', str, ops, hp);
    /*
     * If we haven't read something from this file yet,
     * forget it.
     */
    if (h) {
      if (HandleObject(h)) {
	ok = 1;
	if (rp) {
	  HandleUpdRef(&h, NULL, rp);
	}
      } else if (((p = PoolByName(HandleName(h), ops))) == NULL ||
		 (p->flags & PF_ANY) || (!p->seekable && !now)) {
		
	/* When reading plain files, always demand an object. When
	 * reading others (pipe, tty), demand one if 'now' set. Use
	 * PF_ANY flag as an alternate hint of reading an object,
	 * since reading commands leaves no object attached to h.
	 */
	ok = 1;
      } else {
	/* Failed */
	HandleDelete(h);
	if (hp) {
	  *hp = NULL;
	}
      }
    }
    /* If not ok, close the file.
     * If 'now' and not some sort of pipe, also close the file.
     */
    if ((p = PoolByName(str, ops)) != NULL && (!ok || (now && p->seekable))) {
      if (now && ok) {
	/* Read as much as possible if we need it right now. */
	while(PoolInputFile(p) != NULL &&
	      (c = async_iobfnextc(PoolInputFile(p), 0)) != NODATA &&
	      c != EOF && (*ops->strmin)(p, hp, rp))
	  ;
      }
      PoolClose(p);
      MyPoolDelete(p);
    } else if (iobfile(PoolInputFile(p)) == stdin 
	       && PoolOutputFile(p) == NULL) {
      p = PoolStreamOpen(PoolName(p), stdout, 1, ops);
    }
    return ok;
  } else if (strpbrk(str, "({ \t\n")) {
    static Pool *pcache;	/* Cache a pool for handling strings */
    static bool inuse = false;	/* Use cached pool unless already in use */
    IOBFILE *inf = iobfileopen(fmemopen(str, strlen(str), "rb"));
    /* Caching implies this first pool has a long lifetime;
     * suitable for expressing (interest (...)) 
     */
    if (!inuse) {
      if ((p = pcache) == NULL) {
	p = pcache = PoolStreamTemp(str, inf, stdout, 2, ops);
      } else {
	p->inf  = inf; /* hack */
	p->outf = stdout; /* hack */
      }
      inuse = true;
    } else {
      p = PoolStreamTemp(str, inf, stdout, 2, ops);
    }
    if (p == NULL) {
      return 0;		/* Failed */
    }
    while(iobfnextc(inf, 0) != EOF) {
      ok = (*ops->strmin)(p, hp, rp);
    }
    PoolClose(p);
    if (p == pcache) {
      inuse = false;
    } else {
      MyPoolDelete(p); /* Delete temp pool unless it's our cached one */
    }
  } else {
    /* Print the "No such file..." error left by access() */
    fprintf(stderr, "%s: %s\n", str, sperror());
  }
  return ok;
}
Example #4
0
/*----------------------------------------------------------------------------
	DispatchEvent 
	
	Handles all OSL messages that this object should handle
----------------------------------------------------------------------------*/
void AEGenericClass::DispatchEvent(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
{
	OSErr		err = noErr;
	
	AEEventID		eventID;
	OSType		typeCode;
	Size			actualSize 	= 0L;
	
	// Get the event ID
	err = AEGetAttributePtr(appleEvent, 	keyEventIDAttr, 
									typeType, 
									&typeCode, 
									(Ptr)&eventID, 
									sizeof(eventID), 
									&actualSize);
	ThrowIfOSErr(err);
	
	try
	{
		switch (eventID)
		{
			case kAEClone:
				HandleDuplicate(token, appleEvent, reply);
				break;
				
			case kAEClose:
				HandleClose(token, appleEvent, reply);
				break;
				
			case kAECountElements:
				HandleCount(token, appleEvent, reply);
				break;
				
			case kAECreateElement:
				HandleMake(token, appleEvent, reply);
				break;
				
			case kAEDelete:
				HandleDelete(token, appleEvent, reply);
				break;
				
			case kAEDoObjectsExist:
				HandleExists(token, appleEvent, reply);
				break;
				
			case kAEGetData:
				HandleGetData(token, appleEvent, reply);
				break;
				
			case kAEGetDataSize:
				HandleDataSize(token, appleEvent, reply);
				break;
				
			case kAEMove:
				HandleMove(token, appleEvent, reply);
				break;
				
			case kAEOpen:		// == kAEOpenDocuments
				HandleOpen(token, appleEvent, reply);
				break;
				
			case kAEPrint:
				HandlePrint(token, appleEvent, reply);
				break;
			
			case kAEOpenApplication:
				HandleRun(token, appleEvent, reply);
				break;
			
			case kAEReopenApplication:
			  HandleReOpen(token, appleEvent, reply);
			  break; 
							
			case kAEQuitApplication:
				HandleQuit(token, appleEvent, reply);
				break;
				
			case kAESave:
				HandleSave(token, appleEvent, reply);
				break;
				
			case kAESetData:
				HandleSetData(token, appleEvent, reply);
				break;

			// MT-NW suite
			case kAEExtract:
				HandleExtract(token, appleEvent, reply);
				break;
				
			case kAESendMessage:
				HandleSendMessage(token, appleEvent, reply);
				break;
				
			default:
				err = errAEEventNotHandled;
				break;
		}
	}
	catch (OSErr catchErr)
	{
		PutReplyErrorNumber(reply, catchErr);
		throw;
	}
	catch ( ... )
	{
		PutReplyErrorNumber(reply, paramErr);
		throw;
	}
}
Example #5
0
/* see the comments in src/lib/gprim/geom/geomstream.c */
int
TxStreamIn(Pool *p, Handle **hp, Texture **txp)
{
  IOBFILE *stream;
  char *fname;
  Handle *h = NULL;
  Texture *tx = NULL;
  float val[16];
  struct txkw *kw;
  char *w, *raww;
  int i, k = 0;
  int brack = 0;
  int empty = 1;
  bool braces = true;
  /*int plus = 0;*/
  bool more, mine = true; /* Questionable -- we'll report all errors */

  if ((stream = PoolInputFile(p)) == NULL) {
    return 0;
  }
  fname = PoolName(p);

  more = false;
  do {
    iobfnextc(stream, 0);

    switch(i = iobfgetc(stream)) {
    case ':':
    case '<':
      w = iobfdelimtok("{}()", stream, 0);
      /*
       * Consider doing a path search.
       * Do this before calling HandleReferringTo()
       * to prevent spurious error messages.
       */
      if (i == '<' && (h = HandleByName(w, &TextureOps)) == NULL && w[0] != '/') {
	w = findfile(fname, raww = w);
	if (w == NULL) {
	  OOGLSyntax(PoolInputFile(p),
		     "Error reading \"%s\": can't find file \"%s\"",
		     fname, raww);
	}
      } else if (h) {
	HandleDelete(h);
      }
      h = HandleReferringTo(i, w, &TextureOps, NULL);
      if (h != NULL) {
	tx = (Texture *)HandleObject(h);
	RefIncr((Ref*)tx);
      }
      break;

    case EOF: brack = 0; break;
    case '{': brack++; braces = true; break;
    case '}':
      if (brack-- <= 0) {
	iobfungetc(i, stream);
      }
      break;
    case '-':
    case '!':
      /*plus = -1;*/
      break;
    case '+':
      /*plus = 1;*/
      break;
    case '*':  break;

    default:
      more = false;
      iobfungetc(i, stream);
      w = iobfdelimtok("{}()", stream, 0);
      if (w == NULL) {
	break;
      }	    

      for (i = sizeof(tx_kw)/sizeof(tx_kw[0]), kw = tx_kw; --i >= 0; kw++)
	if (!strcmp(kw->word, w))
	  break;
      if (i < 0) {
	if (mine)
	  OOGLSyntax(stream, "%s: unknown texture keyword %s",
		     fname, w);
	return 0;
      }
      if (tx == NULL) {
	tx = TxCreate(TX_END);
      }

      if (kw->args < 0) {
	char allowed[256], *tail = allowed;
	w = iobfdelimtok("{}()", stream, 0);
	if (w == NULL) w = "";
	allowed[0] = '\0';
	for (k = 1; strcmp((kw+k)->word, w); k++) {
	  sprintf(tail, " %s", (kw+k)->word);
	  tail += strlen(tail);
	  if (k + kw->args >= 0) {
	    OOGLSyntax(stream, "%s: %s %s: expected one of: %s",
		       fname, kw->word, w, allowed);
	    TxDelete(tx);
	    return 0;
	  }
	}
      } else if (kw->args > 0) {
	int n = iobfgetnf(stream, kw->args, val, 0);
	if (n != kw->args) {
	  OOGLSyntax(stream, "%s: %s expected %d numeric values",
		     fname, w, kw->args);
	  TxDelete(tx);
	  return 0;
	}
      }

      empty++;

      switch((int)kw->aval) {
      case -1:
	mine = more = true;
	empty--;
	break;

      case TX_APPLY:
	tx->apply = (enum apply_enum)(kw+k)->aval;
	break;

      case TX_FILE:
      case TX_ALPHAFILE:
	raww = iobfdelimtok("{}()", stream, 0);
	w = findfile(fname, raww);
	if (w == NULL) {
	  OOGLSyntax(stream,
		     "Warning: reading \"%s\": can't find file \"%s\", ignoring texture",
		     fname, raww);
	} else {
	  TxSet(tx, kw->aval, w, TX_END);
	}
	break;

#if 0 /* does not belong here */
      case TX_XSIZE:
      case TX_YSIZE:
      case TX_CHANNELS:
	if (val[0] < 1 ||
	    val[0] > (tx_kw[i].aval==TX_CHANNELS) ? 4 : 100000) {
	  OOGLSyntax(stream, "%s: Bad value for %s: %s",
		     fname, kw->word, w);
	  TxDelete(tx);
	  return 0;
	}
	TxSet(tx, kw->aval, (int)val[0], TX_END);
	break;
#endif

#if 0 /* not implemented */
      case TX_COORDS:
	tx->coords = (kw+k)->aval;
	break;
#endif
      case TX_BACKGROUND: {
	/* We allow ColorA for compatibility, but the texture
	 * background color really is only RGB, not RGBA (see
	 * glTexEnvf(3)). So: if the next character is not a closing
	 * brace and not '\n', consume the next float which should be
	 * the alpha component
	 */
	float dummy;
	int c;

	if ((c = iobfnextc(stream, 1)) != '\n' && c != '}' && c != EOF) {
	  if (iobfgetnf(stream, 1, &dummy, 0) < 1) {
	    OOGLSyntax(stream, "%s: background color expected", fname);
	    TxDelete(tx);
	    return false;
	  }
	}
	TxSet(tx, kw->aval, val, TX_END);
	break;
      }
      case TX_HANDLE_IMAGE:
	if (!ImgStreamIn(p, &tx->imghandle, &tx->image)) {
	  OOGLSyntax(stream, "%s: texture image definition expected",
		     fname);
	  TxDelete(tx);
	  return false;
	}
	if (tx->filename) {
	  OOGLFree(tx->filename);
	  tx->filename = NULL;
	}
	if (tx->alphafilename) {
	  OOGLFree(tx->alphafilename);
	  tx->alphafilename = NULL;
	}
	if (tx->imghandle) {
	  HandleRegister(&tx->imghandle, (Ref *)tx, &tx->image,
			 TxUpdateImage);
	}
	break;
      case TX_HANDLE_TRANSFORM:
	if (!TransStreamIn(p, &tx->tfmhandle, tx->tfm)) {
	  OOGLSyntax(stream, "%s: 4x4 texture transform expected",
		     fname);
	  TxDelete(tx);
	  return false;
	}
	if (tx->tfmhandle) {
	  HandleRegister(&tx->tfmhandle, (Ref *)tx,
			 tx->tfm, TransUpdate);
	}
	break;
      case TX_DOCLAMP:
	tx->flags = (kw+k)->aval;
	break;


      default:
	break;
      }
      /*plus = 0;*/
    }
  } while (brack > 0 || more);

  /* handle file and alphafile constructs */
  if (h == NULL && tx->filename) {
    struct stat st;
    char hname[2*(4+(INO_T_LSIZE+DEV_T_LSIZE+TIME_T_LSIZE)*SIZEOF_LONG)+1];
    char *ptr;

    if (tx->imghandle) {
      HandlePDelete(&tx->imghandle);
      tx->imghandle = NULL;
    }
    if (tx->image) {
      ImgDelete(tx->image);
      tx->image = NULL;
    }
	
    if (stat(tx->filename, &st) < 0) {
      OOGLSyntax(stream, "%s: cannot stat file %s", fname, tx->filename);
      TxDelete(tx);
      return 0;
    }

    ptr = hname;
    ptr += stat_to_handle(ptr, st.st_dev, st.st_ino, st.st_mtime);

    if (tx->alphafilename) {
      if (stat(tx->alphafilename, &st) < 0) {
	OOGLSyntax(stream,
		   "%s: cannot stat file %s", fname, tx->filename);
	TxDelete(tx);
	return 0;
      }
      ptr += stat_to_handle(ptr, st.st_dev, st.st_ino, st.st_mtime);
    }
    /* we share texture images defined by the same files, as was
     * the previous behaviour. However, this is implemented using
     * references and handles to image objects.
     */
    tx->imghandle = HandleByName(hname, &ImageOps);
    if (tx->imghandle != NULL) {
      tx->image = REFGET(Image, HandleObject(tx->imghandle));
    } else {
      /* This means there is no image, create one */
      tx->image = tx->alphafilename
	? ImgCreate(IMG_DATA_CHAN_FILE,
		    IMGF_AUTO, NULL, tx->filename,
		    IMG_DATA_CHAN_FILE,
		    IMGF_ALPHA, NULL, tx->alphafilename,
		    IMG_END)
	: ImgCreate(IMG_DATA_CHAN_FILE,
		    IMGF_AUTO, NULL, tx->filename,
		    IMG_END);
      if (!tx->image) {
	OOGLSyntax(stream,
		   "%s: cannot create image from given file(s) "
		   "(\"%s\"/\"%s\"",
		   fname, tx->filename, tx->alphafilename);
	TxDelete(tx);
	return 0;
      }
      /* Generate a new reference */
      tx->imghandle = HandleAssign(hname, &ImageOps, (Ref *)tx->image);
      tx->imghandle->permanent = false;
    }
  }

  /* Pass the ownership of h and tx to the caller if requested */

  if (hp != NULL) {
    /* pass on ownership of the handle h to the caller of this function */
    if (*hp != NULL) {
      if (*hp != h) {
	HandlePDelete(hp);
      } else {
	HandleDelete(*hp);
      }
    }
    *hp = h;
  } else if (h) {
    /* Otherwise delete h because we are its owner. Note that
     * HandleReferringTo() has passed the ownership of h to us;
     * explicitly defined handles (hdefine and define constructs)
     * will not be deleted by this call.
     */
    HandleDelete(h);
  }

  /* same logic as for hp */
  if (txp != NULL) {
    if (*txp != NULL) {
      TxDelete(*txp);
    }
    *txp = tx;
  } else if(tx) {
    TxDelete(tx);
  }

  return (tx != NULL || h != NULL || (empty && braces));
}
Example #6
0
/*
 * Load Camera from file.
 * Syntax:
 *  [camera] < "filename_containing_camera"	[or]
 *  [camera] {   keyword  value   keyword  value   ...  }
 *
 */
int
CamStreamIn(Pool *p, Handle **hp, Camera **camp)
{
  char *w, *raww;
  IOBFILE *f;
  Handle *h = NULL;
  Handle *hname = NULL;
  Camera *cam = NULL;
  int credible = 0;
  int i;
  int got;
  float v;
  int brack = 0;
  int empty = 1, braces = 0;
  static struct kw {
    char *name;
    char args;
    int kbit;
  } kw[] = {
    { "camtoworld", 0, CAMF_NEWC2W },
    { "worldtocam", 0, CAMF_W2C },
    { "flag",	    1, CAMF_PERSP|CAMF_STEREO },
    { "halfyfield", 1, CAMF_FOV },
    { "frameaspect",1, CAMF_ASPECT },
    { "focus",	    1, CAMF_FOCUS },       /*  5 */
    { "near",	    1, CAMF_NEAR },
    { "far",	    1, CAMF_FAR },
    { "stereo_sep", 1, CAMF_STEREOGEOM },
    { "stereo_angle",1, CAMF_STEREOGEOM },
    { "stereyes",   0, CAMF_STEREOXFORM }, /* 10 */
    { "whicheye",   1, CAMF_EYE },
    { "define",	    0, 0 },
    { "camera",     0, 0 },
    { "perspective",1, CAMF_PERSP },
    { "stereo",     1, CAMF_STEREO },      /* 15 */
    { "hyperbolic", 1, 0 /* CAMF_HYPERBOLIC is now obsolete */ },
    { "fov",	    1, CAMF_FOV },
    { "bgcolor",    0, 0 },
    { "bgimage",    0, 0 },
  };

  if ((f = PoolInputFile(p)) == NULL)
    return 0;

  for(;;) {
    switch(i = iobfnextc(f, 0)) {
    case '<':
    case ':':
    case '@':
      iobfgetc(f);
      w = iobfdelimtok("(){}", f, 0);
      if (i == '<' && (h = HandleByName(w, &CamOps)) == NULL && w[0] != '\0') {
	w = findfile(PoolName(p), raww = w);
	if (w == NULL) {
	  OOGLSyntax(f, "Reading camera from \"%s\": can't find file \"%s\"",
		     PoolName(p), raww);
	}
      } else if (h) {
	/* HandleByName() increases the ref. count s.t. the
	 * caller of HandleByName() owns the returned handle.
	 */
	HandleDelete(h);
      }

      if ((h = HandleReferringTo(i, w, &CamOps, hp)) != NULL) {
	cam = (Camera *)h->object;
	/* Increment the ref. count. This way we can call
	 * HandleDelete() and CamDelete() independently.
	 */
	RefIncr((Ref*)cam);
      }
      if (!brack) goto done;
      break;

    case '{': brack++; iobfgetc(f); break;
    case '}':
      if (brack > 0) { iobfgetc(f); braces = 1; }
      if (--brack <= 0) goto done;
      /* Otherwise, fall through into... */
    default:
      empty = 0;
      w = iobfdelimtok("(){}", f, 0);
      if (w == NULL)
	goto done;
      
      for(i = sizeof(kw)/sizeof(kw[0]); --i >= 0; )
	if (!strcmp(w, kw[i].name))
	  break;

      if (i < 0) {
	if (credible)
	  OOGLSyntax(f, "Reading camera from \"%s\": unknown camera keyword \"%s\"",
		     PoolName(p), w);
	if (cam) CamDelete(cam);
	return 0;
      } else if ( (got= iobfgetnf(f, kw[i].args, &v, 0)) != kw[i].args ) {
	OOGLSyntax(f, "Reading camera from \"%s\": \"%s\" expects %d values, got %d",
		   PoolName(p), w, kw[i].args, got);
	CamDelete(cam);
	return false;
      }
      if (i != 13 && cam == NULL) {
	cam = CamCreate(CAM_END);
	credible = 1;
      }
      if (cam) {
	cam->changed |= kw[i].kbit;
      }
      switch (i) {
      case 0: {
	TransObj *tobj = NULL;
	Handle *thandle = NULL;
	if (TransObjStreamIn(p, &thandle, &tobj)) {
	  CamSet(cam, CAM_C2W, tobj->T, CAM_C2WHANDLE, thandle, CAM_END);
	  HandleDelete(thandle);
	  TransDelete(tobj);
	}
	break;
      }
      case 1: {
	TransObj *tobj = NULL;
	Handle *thandle = NULL;
	if (TransObjStreamIn(p, &thandle, &tobj)) {
	  CamSet(cam, CAM_W2C, tobj, CAM_W2CHANDLE, thandle, CAM_END);
	  HandleDelete(thandle);
	  TransDelete(tobj);
	}
	break;
      }
      case 2: cam->flag = (int)v; break;
      case 3: CamSet(cam, CAM_HALFYFIELD, v, CAM_END); break;
      case 4: CamSet(cam, CAM_ASPECT, v, CAM_END); break;
      case 5: CamSet(cam, CAM_FOCUS, v, CAM_END); break;
      case 6: cam->cnear = v; break;
      case 7: cam->cfar = v; break;
      case 8: CamSet(cam, CAM_STEREOSEP, v, CAM_END); break;
      case 9: CamSet(cam, CAM_STEREOANGLE, v, CAM_END); break;
      case 10: {
	TransObj *tobj[2] = { NULL, NULL };
	Handle *thandle[2] = { NULL, NULL };
	int i;
	if (TransObjStreamIn(p, &thandle[0], &tobj[0]) &&
	    TransObjStreamIn(p, &thandle[1], &tobj[1])) {
	  TmCopy(tobj[0]->T, cam->stereyes[0]);
	  TmCopy(tobj[1]->T, cam->stereyes[1]);
	  CamSet(cam, CAM_STEREYES, cam->stereyes,
		 CAM_STERHANDLES, thandle,
		 CAM_END);
	}
	for (i = 0; i < 2; i++) {
	  HandleDelete(thandle[i]);
	  TransDelete(tobj[i]);
	}
      }
	
	break;
      case 11: cam->whicheye = (int)v; break;
      case 12: /* "define" */
	hname = HandleCreateGlobal(iobfdelimtok("(){}", f, 0), &CamOps);
	break;
      case 13: /* "camera" */ break;

      case 14: /* "perspective" */
      case 15: /* "stereo" */
	cam->flag &= ~kw[i].kbit;
	if (v != 0) cam->flag |= kw[i].kbit;
	break;

      case 16: /* "hyperbolic" */
	/* The "hyperbolic" field is obsolete (replaced by the
	   "space" field.  Ignore it for now [ Mon Dec 7 14:05:50
	   1992 ].  After a few months [ say in March 1993 ] add a
	   warning message to be printed out at this point in the
	   code, and after a few more months [ say June 1993 ],
	   remove it completely. -- mbp */
	break;

      case 17: /* "fov" */ CamSet(cam, CAM_FOV, v, CAM_END); break;
      case 18: /* bgcolor */
	/* we always expect RGB values in the range 0..1 as floating
	 * point values.
	 */
	if ((got = iobfgetnf(f, 3, (float *)&cam->bgcolor, 0)) != 3) {
	  OOGLSyntax(f, "Reading camera from \"%s\": \"%s\" expects "
		     "an RGB(A) color specification "
		     "(got only %d values, not 3 or 4)",
		     PoolName(p), "bgcolor", got);
	  CamDelete(cam);
	  return false;
	}
	if (got == 3 && iobfgetnf(f, 1, (float *)&cam->bgcolor+3, 0) != 1) {
	  cam->bgcolor.a = 1.0;
	}
	break;
      case 19: /* bgimage */
	if (!ImgStreamIn(p, &cam->bgimghandle, &cam->bgimage)) {
	  OOGLSyntax(f, "Reading camera from \"%s\": "
		     "unable to read background image",
		     PoolName(p));
	  CamDelete(cam);
	  return false;
	}
	break;
      }
    }
  }

 done:

  if (hname) {
    if (cam) {
      HandleSetObject(hname, (Ref *)cam);
    }
    if (h) {
      /* HandleReferringTo() has passed the ownership to use, so
       * delete h because we do not need it anymore.
       */
      HandleDelete(h);
    }
    h = hname;
  }

  /* Pass the ownership of h and cam to the caller if requested */

  if (hp != NULL) {
    /* pass on ownership of the handle h to the caller of this function */
    if (*hp != NULL) {
      if (*hp != h) {
	HandlePDelete(hp);
      } else {
	HandleDelete(*hp);
      }
    }
    *hp = h;
  } else if (h) {
    /* Otherwise delete h because we are its owner. Note that
     * HandleReferringTo() has passed the ownership of h to us;
     * explicitly defined handles (hdefine and define constructs)
     * will not be deleted by this call.
     */
    HandleDelete(h);
  }

  /* same logic as for hp */
  if (camp != NULL) {
    if (*camp) {
      CamDelete(*camp);
    }
    *camp = cam;
  } else if(cam) {
    CamDelete(cam);
  }

  return (cam != NULL || h != NULL || (empty && braces));
}