text:
/*
 * executing Python code
 *
 * src/pl/plpython/plpy_exec.c
 */

#include "postgres.h"

#include "access/htup_details.h"
#include "access/xact.h"
#include "catalog/pg_type.h"
#include "commands/trigger.h"
#include "executor/spi.h"
#include "funcapi.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/typcache.h"

#include "plpython.h"

#include "plpy_exec.h"

#include "plpy_elog.h"
#include "plpy_main.h"
#include "plpy_procedure.h"
#include "plpy_subxactobject.h"

/* saved state for a set-returning function */
typedef struct PLySRFState
{
	PyObject   *iter;			/* Python iterator producing results */
	PLySavedArgs *savedargs;	/* function argument values */
	MemoryContextCallback callback; /* for releasing refcounts when done */
} PLySRFState;

static PyObject *PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc);
static PLySavedArgs *PLy_function_save_args(PLyProcedure *proc);
static void PLy_function_restore_args(PLyProcedure *proc, PLySavedArgs *savedargs);
static void PLy_function_drop_args(PLySavedArgs *savedargs);
static void PLy_global_args_push(PLyProcedure *proc);
static void PLy_global_args_pop(PLyProcedure *proc);
static void plpython_srf_cleanup_callback(void *arg);
static void plpython_return_error_callback(void *arg);

static PyObject *PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc,
										HeapTuple *rv);
static HeapTuple PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd,
								  TriggerData *tdata, HeapTuple otup);
static void plpython_trigger_error_callback(void *arg);

static PyObject *PLy_procedure_call(PLyProcedure *proc, const char *kargs, PyObject *vargs);
static void PLy_abort_open_subtransactions(int save_subxact_level);

/* function subhandler */
Datum
PLy_exec_function(FunctionCallInfo fcinfo, PLyProcedure *proc)
{
	bool		is_setof = proc->is_setof;
	Datum		rv;
	PyObject   *volatile plargs = NULL;
	PyObject   *volatile plrv = NULL;
	FuncCallContext *volatile funcctx = NULL;
	PLySRFState *volatile srfstate = NULL;
	ErrorContextCallback plerrcontext;

	/*
	 * If the function is called recursively, we must push outer-level
	 * arguments into the stack.  This must be immediately before the PG_TRY
	 * to ensure that the corresponding pop happens.
	 */
	PLy_global_args_push(proc);

	PG_TRY();
	{
		if (is_setof)
		{
			/* First Call setup */
			if (SRF_IS_FIRSTCALL())
			{
				funcctx = SRF_FIRSTCALL_INIT();
				srfstate = (PLySRFState *)
					MemoryContextAllocZero(funcctx->multi_call_memory_ctx,
										   sizeof(PLySRFState));
				/* Immediately register cleanup callback */
				srfstate->callback.func = plpython_srf_cleanup_callback;
				srfstate->callback.arg = (void *) srfstate;
				MemoryContextRegisterResetCallback(funcctx->multi_call_memory_ctx,
												   &srfstate->callback);
				funcctx->user_fctx = (void *) srfstate;
			}
			/* Every call setup */
			funcctx = SRF_PERCALL_SETUP();
			Assert(funcctx != NULL);
			srfstate = (PLySRFState *) funcctx->user_fctx;
			Assert(srfstate != NULL);
		}

		if (srfstate == NULL || srfstate->iter == NULL)
		{
			/*
			 * Non-SETOF function or first time for SETOF function: build
			 * args, then actually execute the function.
			 */
			plargs = PLy_function_build_args(fcinfo, proc);
			plrv = PLy_procedure_call(proc, "args", plargs);
			Assert(plrv != NULL);
		}
		else
		{
			/*
			 * Second or later call for a SETOF function: restore arguments in
			 * globals dict to what they were when we left off.  We must do
			 * this in case multiple evaluations of the same SETOF function
			 * are interleaved.  It's a bit annoying, since the iterator may
			 * not look at the arguments at all, but we have no way to know
			 * that.  Fortunately this isn't terribly expensive.
			 */
			if (srfstate->savedargs)
				PLy_function_restore_args(proc, srfstate->savedargs);
			srfstate->savedargs = NULL; /* deleted by restore_args */
		}

		/*
		 * If it returns a set, call the iterator to get the next return item.
		 * We stay in the SPI context while doing this, because PyIter_Next()
		 * calls back into Python code which might contain SPI calls.
		 */
		if (is_setof)
		{
			if (srfstate->iter == NULL)
			{
				/* first time -- do checks and setup */
				ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;

				if (!rsi || !IsA(rsi, ReturnSetInfo) ||
					(rsi->allowedModes & SFRM_ValuePerCall) == 0)
				{
					ereport(ERROR,
							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
							 errmsg("unsupported set function return mode"),
							 errdetail("PL/Python set-returning functions only support returning one value per call.")));
				}
				rsi->returnMode = SFRM_ValuePerCall;

				/* Make iterator out of returned object */
				srfstate->iter = PyObject_GetIter(plrv);

				Py_DECREF(plrv);
				plrv = NULL;

				if (srfstate->iter == NULL)
					ereport(ERROR,
							(errcode(ERRCODE_DATATYPE_MISMATCH),
							 errmsg("returned object cannot be iterated"),
							 errdetail("PL/Python set-returning functions must return an iterable object.")));
			}

			/* Fetch next from iterator */
			plrv = PyIter_Next(srfstate->iter);
			if (plrv == NULL)
			{
				/* Iterator is exhausted or error happened */
				bool		has_error = (PyErr_Occurred() != NULL);

				Py_DECREF(srfstate->iter);
				srfstate->iter = NULL;

				if (has_error)
					PLy_elog(ERROR, "function \"%s\" error fetching next item from iterator", proc->proname);

				/* Pass a null through the data-returning steps below */
				Py_INCREF(Py_None);
				plrv = Py_None;
			}
			else
			{
				/*
				 * This won't be last call, so save argument values.  We do
				 * this again each time in case the iterator is changing those
				 * values.
				 */
				srfstate->savedargs = PLy_function_save_args(proc);
			}
		}

		/*
		 * Disconnect from SPI manager and then create the return values datum
		 * (if the input function does a palloc for it this must not be
		 * allocated in the SPI memory context because SPI_finish would free
		 * it).
		 */
		if (SPI_finish() != SPI_OK_FINISH)
			elog(ERROR, "SPI_finish failed");

		plerrcontext.callback = plpython_return_error_callback;
		plerrcontext.previous = error_context_stack;
		error_context_stack = &plerrcontext;

		/*
		 * For a procedure or function declared to return void, the Python
		 * return value must be None. For void-returning functions, we also
		 * treat a None return value as a special "void datum" rather than
		 * NULL (as is the case for non-void-returning functions).
		 */
		if (proc->result.typoid == VOIDOID)
		{
			if (plrv != Py_None)
			{
				if (proc->is_procedure)
					ereport(ERROR,
							(errcode(ERRCODE_DATATYPE_MISMATCH),
							 errmsg("PL/Python procedure did not return None")));
				else
					ereport(ERROR,
							(errcode(ERRCODE_DATATYPE_MISMATCH),
							 errmsg("PL/Python function with return type \"void\" did not return None")));
			}

			fcinfo->isnull = false;
			rv = (Datum) 0;
		}
		else if (plrv == Py_None &&
				 srfstate && srfstate->iter == NULL)
		{
			/*
			 * In a SETOF function, the iteration-ending null isn't a real
			 * value; don't pass it through the input function, which might
			 * complain.
			 */
			fcinfo->isnull = true;
			rv = (Datum) 0;
		}
		else
		{
			/* Normal conversion of result */
			rv = PLy_output_convert(&proc->result, plrv,
									&fcinfo->isnull);
		}
	}
	PG_CATCH();
	{
		/* Pop old arguments from the stack if they were pushed above */
		PLy_global_args_pop(proc);

		Py_XDECREF(plargs);
		Py_XDECREF(plrv);

		/*
		 * If there was an error within a SRF, the iterator might not have
		 * been exhausted yet.  Clear it so the next invocation of the
		 * function will start the iteration again.  (This code is probably
		 * unnecessary now; plpython_srf_cleanup_callback should take care of
		 * cleanup.  But it doesn't hurt anything to do it here.)
		 */
		if (srfstate)
		{
			Py_XDECREF(srfstate->iter);
			srfstate->iter = NULL;
			/* And drop any saved args; we won't need them */
			if (srfstate->savedargs)
				PLy_function_drop_args(srfstate->savedargs);
			srfstate->savedargs = NULL;
		}

		PG_RE_THROW();
	}
	PG_END_TRY();

	error_context_stack = plerrcontext.previous;

	/* Pop old arguments from the stack if they were pushed above */
	PLy_global_args_pop(proc);

	Py_XDECREF(plargs);
	Py_DECREF(plrv);

	if (srfstate)
	{
		/* We're in a SRF, exit appropriately */
		if (srfstate->iter == NULL)
		{
			/* Iterator exhausted, so we're done */
			SRF_RETURN_DONE(funcctx);
		}
		else if (fcinfo->isnull)
			SRF_RETURN_NEXT_NULL(funcctx);
		else
			SRF_RETURN_NEXT(funcctx, rv);
	}

	/* Plain function, just return the Datum value (possibly null) */
	return rv;
}

/* trigger subhandler
 *
 * the python function is expected to return Py_None if the tuple is
 * acceptable and unmodified.  Otherwise it should return a PyString
 * object who's value is SKIP, or MODIFY.  SKIP means don't perform
 * this action.  MODIFY means the tuple has been modified, so update
 * tuple and perform action.  SKIP and MODIFY assume the trigger fires
 * BEFORE the event and is ROW level.  postgres expects the function
 * to take no arguments and return an argument of type trigger.
 */
HeapTuple
PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc)
{
	HeapTuple	rv = NULL;
	PyObject   *volatile plargs = NULL;
	PyObject   *volatile plrv = NULL;
	TriggerData *tdata;
	TupleDesc	rel_descr;

	Assert(CALLED_AS_TRIGGER(fcinfo));
	tdata = (TriggerData *) fcinfo->context;

	/*
	 * Input/output conversion for trigger tuples.  We use the result and
	 * result_in fields to store the tuple conversion info.  We do this over
	 * again on each call to cover the possibility that the relation's tupdesc
	 * changed since the trigger was last called.  The PLy_xxx_setup_func
	 * calls should only happen once, but PLy_input_setup_tuple and
	 * PLy_output_setup_tuple are responsible for not doing repetitive work.
	 */
	rel_descr = RelationGetDescr(tdata->tg_relation);
	if (proc->result.typoid != rel_descr->tdtypeid)
		PLy_output_setup_func(&proc->result, proc->mcxt,
							  rel_descr->tdtypeid,
							  rel_descr->tdtypmod,
							  proc);
	if (proc->result_in.typoid != rel_descr->tdtypeid)
		PLy_input_setup_func(&proc->result_in, proc->mcxt,
							 rel_descr->tdtypeid,
							 rel_descr->tdtypmod,
							 proc);
	PLy_output_setup_tuple(&proc->result, rel_descr, proc);
	PLy_input_setup_tuple(&proc->result_in, rel_descr, proc);

	PG_TRY();
	{
		int			rc PG_USED_FOR_ASSERTS_ONLY;

		rc = SPI_register_trigger_data(tdata);
		Assert(rc >= 0);

		plargs = PLy_trigger_build_args(fcinfo, proc, &rv);
		plrv = PLy_procedure_call(proc, "TD", plargs);

		Assert(plrv != NULL);

		/*
		 * Disconnect from SPI manager
		 */
		if (SPI_finish() != SPI_OK_FINISH)
			elog(ERROR, "SPI_finish failed");

		/*
		 * return of None means we're happy with the tuple
		 */
		if (plrv != Py_None)
		{
			char	   *srv;

			if (PyString_Check(plrv))
				srv = PyString_AsString(plrv);
			else if (PyUnicode_Check(plrv))
				srv = PLyUnicode_AsString(plrv);
			else
			{
				ereport(ERROR,
						(errcode(ERRCODE_DATA_EXCEPTION),
						 errmsg("unexpected return value from trigger procedure"),
						 errdetail("Expected None or a string.")));
				srv = NULL;		/* keep compiler quiet */
			}

			if (pg_strcasecmp(srv, "SKIP") == 0)
				rv = NULL;
			else if (pg_strcasecmp(srv, "MODIFY") == 0)
			{
				TriggerData *tdata = (TriggerData *) fcinfo->context;

				if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event) ||
					TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
					rv = PLy_modify_tuple(proc, plargs, tdata, rv);
				else
					ereport(WARNING,
							(errmsg("PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored")));
			}
			else if (pg_strcasecmp(srv, "OK") != 0)
			{
				/*
				 * accept "OK" as an alternative to None; otherwise, raise an
				 * error
				 */
				ereport(ERROR,
						(errcode(ERRCODE_DATA_EXCEPTION),
						 errmsg("unexpected return value from trigger procedure"),
						 errdetail("Expected None, \"OK\", \"SKIP\", or \"MODIFY\".")));
			}
		}
	}
	PG_CATCH();
	{
		Py_XDECREF(plargs);
		Py_XDECREF(plrv);

		PG_RE_THROW();
	}
	PG_END_TRY();

	Py_DECREF(plargs);
	Py_DECREF(plrv);

	return rv;
}

/* helper functions for Python code execution */

static PyObject *
PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc)
{
	PyObject   *volatile arg = NULL;
	PyObject   *volatile args = NULL;
	int			i;

	PG_TRY();
	{
		args = PyList_New(proc->nargs);
		if (!args)
			return NULL;

		for (i = 0; i < proc->nargs; i++)
		{
			PLyDatumToOb *arginfo = &proc->args[i];

			if (fcinfo->args[i].isnull)
				arg = NULL;
			else
				arg = PLy_input_convert(arginfo, fcinfo->args[i].value);

			if (arg == NULL)
			{
				Py_INCREF(Py_None);
				arg = Py_None;
			}

			if (PyList_SetItem(args, i, arg) == -1)
				PLy_elog(ERROR, "PyList_SetItem() failed, while setting up arguments");

			if (proc->argnames && proc->argnames[i] &&
				PyDict_SetItemString(proc->globals, proc->argnames[i], arg) == -1)
				PLy_elog(ERROR, "PyDict_SetItemString() failed, while setting up arguments");
			arg = NULL;
		}

		/* Set up output conversion for functions returning RECORD */
		if (proc->result.typoid == RECORDOID)
		{
			TupleDesc	desc;

			if (get_call_result_type(fcinfo, NULL, &desc) != TYPEFUNC_COMPOSITE)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("function returning record called in context "
								"that cannot accept type record")));

			/* cache the output conversion functions */
			PLy_output_setup_record(&proc->result, desc, proc);
		}
	}
	PG_CATCH();
	{
		Py_XDECREF(arg);
		Py_XDECREF(args);

		PG_RE_THROW();
	}
	PG_END_TRY();

	return args;
}

/*
 * Construct a PLySavedArgs struct representing the current values of the
 * procedure's arguments in its globals dict.  This can be used to restore
 * those values when exiting a recursive call level or returning control to a
 * set-returning function.
 *
 * This would not be necessary except for an ancient decision to make args
 * available via the proc's globals :-( ... but we're stuck with that now.
 */
static PLySavedArgs *
PLy_function_save_args(PLyProcedure *proc)
{
	PLySavedArgs *result;

	/* saved args are always allocated in procedure's context */
	result = (PLySavedArgs *)
		MemoryContextAllocZero(proc->mcxt,
							   offsetof(PLySavedArgs, namedargs) +
							   proc->nargs * sizeof(PyObject *));
	result->nargs = proc->nargs;

	/* Fetch the "args" list */
	result->args = PyDict_GetItemString(proc->globals, "args");
	Py_XINCREF(result->args);

	/* Fetch all the named arguments */
	if (proc->argnames)
	{
		int			i;

		for (i = 0; i < result->nargs; i++)
		{
			if (proc->argnames[i])
			{
				result->namedargs[i] = PyDict_GetItemString(proc->globals,
															proc->argnames[i]);
				Py_XINCREF(result->namedargs[i]);
			}
		}
	}

	return result;
}

/*
 * Restore procedure's arguments from a PLySavedArgs struct,
 * then free the struct.
 */
static void
PLy_function_restore_args(PLyProcedure *proc, PLySavedArgs *savedargs)
{
	/* Restore named arguments into their slots in the globals dict */
	if (proc->argnames)
	{
		int			i;

		for (i = 0; i < savedargs->nargs; i++)
		{
			if (proc->argnames[i] && savedargs->namedargs[i])
			{
				PyDict_SetItemString(proc->globals, proc->argnames[i],
									 savedargs->namedargs[i]);
				Py_DECREF(savedargs->namedargs[i]);
			}
		}
	}

	/* Restore the "args" object, too */
	if (savedargs->args)
	{
		PyDict_SetItemString(proc->globals, "args", savedargs->args);
		Py_DECREF(savedargs->args);
	}

	/* And free the PLySavedArgs struct */
	pfree(savedargs);
}

/*
 * Free a PLySavedArgs struct without restoring the values.
 */
static void
PLy_function_drop_args(PLySavedArgs *savedargs)
{
	int			i;

	/* Drop references for named args */
	for (i = 0; i < savedargs->nargs; i++)
	{
		Py_XDECREF(savedargs->namedargs[i]);
	}

	/* Drop ref to the "args" object, too */
	Py_XDECREF(savedargs->args);

	/* And free the PLySavedArgs struct */
	pfree(savedargs);
}

/*
 * Save away any existing arguments for the given procedure, so that we can
 * install new values for a recursive call.  This should be invoked before
 * doing PLy_function_build_args().
 *
 * NB: caller must ensure that PLy_global_args_pop gets invoked once, and
 * only once, per successful completion of PLy_global_args_push.  Otherwise
 * we'll end up out-of-sync between the actual call stack and the contents
 * of proc->argstack.
 */
static void
PLy_global_args_push(PLyProcedure *proc)
{
	/* We only need to push if we are already inside some active call */
	if (proc->calldepth > 0)
	{
		PLySavedArgs *node;

		/* Build a struct containing current argument values */
		node = PLy_function_save_args(proc);

		/*
		 * Push the saved argument values into the procedure's stack.  Once we
		 * modify either proc->argstack or proc->calldepth, we had better
		 * return without the possibility of error.
		 */
		node->next = proc->argstack;
		proc->argstack = node;
	}
	proc->calldepth++;
}

/*
 * Pop old arguments when exiting a recursive call.
 *
 * Note: the idea here is to adjust the proc's callstack state before doing
 * anything that could possibly fail.  In event of any error, we want the
 * callstack to look like we've done the pop.  Leaking a bit of memory is
 * tolerable.
 */
static void
PLy_global_args_pop(PLyProcedure *proc)
{
	Assert(proc->calldepth > 0);
	/* We only need to pop if we were already inside some active call */
	if (proc->calldepth > 1)
	{
		PLySavedArgs *ptr = proc->argstack;

		/* Pop the callstack */
		Assert(ptr != NULL);
		proc->argstack = ptr->next;
		proc->calldepth--;

		/* Restore argument values, then free ptr */
		PLy_function_restore_args(proc, ptr);
	}
	else
	{
		/* Exiting call depth 1 */
		Assert(proc->argstack == NULL);
		proc->calldepth--;

		/*
		 * We used to delete the named arguments (but not "args") from the
		 * proc's globals dict when exiting the outermost call level for a
		 * function.  This seems rather pointless though: nothing can see the
		 * dict until the function is called again, at which time we'll
		 * overwrite those dict entries.  So don't bother with that.
		 */
	}
}

/*
 * Memory context deletion callback for cleaning up a PLySRFState.
 * We need this in case execution of the SRF is terminated early,
 * due to error or the caller simply not running it to completion.
 */
static void
plpython_srf_cleanup_callback(void *arg)
{
	PLySRFState *srfstate = (PLySRFState *) arg;

	/* Release refcount on the iter, if we still have one */
	Py_XDECREF(srfstate->iter);
	srfstate->iter = NULL;
	/* And drop any saved args; we won't need them */
	if (srfstate->savedargs)
		PLy_function_drop_args(srfstate->savedargs);
	srfstate->savedargs = NULL;
}

static void
plpython_return_error_callback(void *arg)
{
	PLyExecutionContext *exec_ctx = PLy_current_execution_context();

	if (exec_ctx->curr_proc &&
		!exec_ctx->curr_proc->is_procedure)
		errcontext("while creating return value");
}

static PyObject *
PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *rv)
{
	TriggerData *tdata = (TriggerData *) fcinfo->context;
	TupleDesc	rel_descr = RelationGetDescr(tdata->tg_relation);
	PyObject   *pltname,
			   *pltevent,
			   *pltwhen,
			   *pltlevel,
			   *pltrelid,
			   *plttablename,
			   *plttableschema;
	PyObject   *pltargs,
			   *pytnew,
			   *pytold;
	PyObject   *volatile pltdata = NULL;
	char	   *stroid;

	PG_TRY();
	{
		pltdata = PyDict_New();
		if (!pltdata)
			return NULL;

		pltname = PyString_FromString(tdata->tg_trigger->tgname);
		PyDict_SetItemString(pltdata, "name", pltname);
		Py_DECREF(pltname);

		stroid = DatumGetCString(DirectFunctionCall1(oidout,
													 ObjectIdGetDatum(tdata->tg_relation->rd_id)));
		pltrelid = PyString_FromString(stroid);
		PyDict_SetItemString(pltdata, "relid", pltrelid);
		Py_DECREF(pltrelid);
		pfree(stroid);

		stroid = SPI_getrelname(tdata->tg_relation);
		plttablename = PyString_FromString(stroid);
		PyDict_SetItemString(pltdata, "table_name", plttablename);
		Py_DECREF(plttablename);
		pfree(stroid);

		stroid = SPI_getnspname(tdata->tg_relation);
		plttableschema = PyString_FromString(stroid);
		PyDict_SetItemString(pltdata, "table_schema", plttableschema);
		Py_DECREF(plttableschema);
		pfree(stroid);

		if (TRIGGER_FIRED_BEFORE(tdata->tg_event))
			pltwhen = PyString_FromString("BEFORE");
		else if (TRIGGER_FIRED_AFTER(tdata->tg_event))
			pltwhen = PyString_FromString("AFTER");
		else if (TRIGGER_FIRED_INSTEAD(tdata->tg_event))
			pltwhen = PyString_FromString("INSTEAD OF");
		else
		{
			elog(ERROR, "unrecognized WHEN tg_event: %u", tdata->tg_event);
			pltwhen = NULL;		/* keep compiler quiet */
		}
		PyDict_SetItemString(pltdata, "when", pltwhen);
		Py_DECREF(pltwhen);

		if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event))
		{
			pltlevel = PyString_FromString("ROW");
			PyDict_SetItemString(pltdata, "level", pltlevel);
			Py_DECREF(pltlevel);

			/*
			 * Note: In BEFORE trigger, stored generated columns are not
			 * computed yet, so don't make them accessible in NEW row.
			 */

			if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event))
			{
				pltevent = PyString_FromString("INSERT");

				PyDict_SetItemString(pltdata, "old", Py_None);
				pytnew = PLy_input_from_tuple(&proc->result_in,
											  tdata->tg_trigtuple,
											  rel_descr,
											  !TRIGGER_FIRED_BEFORE(tdata->tg_event));
				PyDict_SetItemString(pltdata, "new", pytnew);
				Py_DECREF(pytnew);
				*rv = tdata->tg_trigtuple;
			}
			else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event))
			{
				pltevent = PyString_FromString("DELETE");

				PyDict_SetItemString(pltdata, "new", Py_None);
				pytold = PLy_input_from_tuple(&proc->result_in,
											  tdata->tg_trigtuple,
											  rel_descr,
											  true);
				PyDict_SetItemString(pltdata, "old", pytold);
				Py_DECREF(pytold);
				*rv = tdata->tg_trigtuple;
			}
			else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
			{
				pltevent = PyString_FromString("UPDATE");

				pytnew = PLy_input_from_tuple(&proc->result_in,
											  tdata->tg_newtuple,
											  rel_descr,
											  !TRIGGER_FIRED_BEFORE(tdata->tg_event));
				PyDict_SetItemString(pltdata, "new", pytnew);
				Py_DECREF(pytnew);
				pytold = PLy_input_from_tuple(&proc->result_in,
											  tdata->tg_trigtuple,
											  rel_descr,
											  true);
				PyDict_SetItemString(pltdata, "old", pytold);
				Py_DECREF(pytold);
				*rv = tdata->tg_newtuple;
			}
			else
			{
				elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event);
				pltevent = NULL;	/* keep compiler quiet */
			}

			PyDict_SetItemString(pltdata, "event", pltevent);
			Py_DECREF(pltevent);
		}
		else if (TRIGGER_FIRED_FOR_STATEMENT(tdata->tg_event))
		{
			pltlevel = PyString_FromString("STATEMENT");
			PyDict_SetItemString(pltdata, "level", pltlevel);
			Py_DECREF(pltlevel);

			PyDict_SetItemString(pltdata, "old", Py_None);
			PyDict_SetItemString(pltdata, "new", Py_None);
			*rv = NULL;

			if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event))
				pltevent = PyString_FromString("INSERT");
			else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event))
				pltevent = PyString_FromString("DELETE");
			else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event))
				pltevent = PyString_FromString("UPDATE");
			else if (TRIGGER_FIRED_BY_TRUNCATE(tdata->tg_event))
				pltevent = PyString_FromString("TRUNCATE");
			else
			{
				elog(ERROR, "unrecognized OP tg_event: %u", tdata->tg_event);
				pltevent = NULL;	/* keep compiler quiet */
			}

			PyDict_SetItemString(pltdata, "event", pltevent);
			Py_DECREF(pltevent);
		}
		else
			elog(ERROR, "unrecognized LEVEL tg_event: %u", tdata->tg_event);

		if (tdata->tg_trigger->tgnargs)
		{
			/*
			 * all strings...
			 */
			int			i;
			PyObject   *pltarg;

			pltargs = PyList_New(tdata->tg_trigger->tgnargs);
			if (!pltargs)
			{
				Py_DECREF(pltdata);
				return NULL;
			}
			for (i = 0; i < tdata->tg_trigger->tgnargs; i++)
			{
				pltarg = PyString_FromString(tdata->tg_trigger->tgargs[i]);

				/*
				 * stolen, don't Py_DECREF
				 */
				PyList_SetItem(pltargs, i, pltarg);
			}
		}
		else
		{
			Py_INCREF(Py_None);
			pltargs = Py_None;
		}
		PyDict_SetItemString(pltdata, "args", pltargs);
		Py_DECREF(pltargs);
	}
	PG_CATCH();
	{
		Py_XDECREF(pltdata);
		PG_RE_THROW();
	}
	PG_END_TRY();

	return pltdata;
}

/*
 * Apply changes requested by a MODIFY return from a trigger function.
 */
static HeapTuple
PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata,
				 HeapTuple otup)
{
	HeapTuple	rtup;
	PyObject   *volatile plntup;
	PyObject   *volatile plkeys;
	PyObject   *volatile plval;
	Datum	   *volatile modvalues;
	bool	   *volatile modnulls;
	bool	   *volatile modrepls;
	ErrorContextCallback plerrcontext;

	plerrcontext.callback = plpython_trigger_error_callback;
	plerrcontext.previous = error_context_stack;
	error_context_stack = &plerrcontext;

	plntup = plkeys = plval = NULL;
	modvalues = NULL;
	modnulls = NULL;
	modrepls = NULL;

	PG_TRY();
	{
		TupleDesc	tupdesc;
		int			nkeys,
					i;

		if ((plntup = PyDict_GetItemString(pltd, "new")) == NULL)
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
					 errmsg("TD[\"new\"] deleted, cannot modify row")));
		Py_INCREF(plntup);
		if (!PyDict_Check(plntup))
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("TD[\"new\"] is not a dictionary")));

		plkeys = PyDict_Keys(plntup);
		nkeys = PyList_Size(plkeys);

		tupdesc = RelationGetDescr(tdata->tg_relation);

		modvalues = (Datum *) palloc0(tupdesc->natts * sizeof(Datum));
		modnulls = (bool *) palloc0(tupdesc->natts * sizeof(bool));
		modrepls = (bool *) palloc0(tupdesc->natts * sizeof(bool));

		for (i = 0; i < nkeys; i++)
		{
			PyObject   *platt;
			char	   *plattstr;
			int			attn;
			PLyObToDatum *att;

			platt = PyList_GetItem(plkeys, i);
			if (PyString_Check(platt))
				plattstr = PyString_AsString(platt);
			else if (PyUnicode_Check(platt))
				plattstr = PLyUnicode_AsString(platt);
			else
			{
				ereport(ERROR,
						(errcode(ERRCODE_DATATYPE_MISMATCH),
						 errmsg("TD[\"new\"] dictionary key at ordinal position %d is not a string", i)));
				plattstr = NULL;	/* keep compiler quiet */
			}
			attn = SPI_fnumber(tupdesc, plattstr);
			if (attn == SPI_ERROR_NOATTRIBUTE)
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_COLUMN),
						 errmsg("key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row",
								plattstr)));
			if (attn <= 0)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("cannot set system attribute \"%s\"",
								plattstr)));
			if (TupleDescAttr(tupdesc, attn - 1)->attgenerated)
				ereport(ERROR,
						(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
						 errmsg("cannot set generated column \"%s\"",
								plattstr)));

			plval = PyDict_GetItem(plntup, platt);
			if (plval == NULL)
				elog(FATAL, "Python interpreter is probably corrupted");

			Py_INCREF(plval);

			/* We assume proc->result is set up to convert tuples properly */
			att = &proc->result.u.tuple.atts[attn - 1];

			modvalues[attn - 1] = PLy_output_convert(att,
													 plval,
													 &modnulls[attn - 1]);
			modrepls[attn - 1] = true;

			Py_DECREF(plval);
			plval = NULL;
		}

		rtup = heap_modify_tuple(otup, tupdesc, modvalues, modnulls, modrepls);
	}
	PG_CATCH();
	{
		Py_XDECREF(plntup);
		Py_XDECREF(plkeys);
		Py_XDECREF(plval);

		if (modvalues)
			pfree(modvalues);
		if (modnulls)
			pfree(modnulls);
		if (modrepls)
			pfree(modrepls);

		PG_RE_THROW();
	}
	PG_END_TRY();

	Py_DECREF(plntup);
	Py_DECREF(plkeys);

	pfree(modvalues);
	pfree(modnulls);
	pfree(modrepls);

	error_context_stack = plerrcontext.previous;

	return rtup;
}

static void
plpython_trigger_error_callback(void *arg)
{
	PLyExecutionContext *exec_ctx = PLy_current_execution_context();

	if (exec_ctx->curr_proc)
		errcontext("while modifying trigger row");
}

/* execute Python code, propagate Python errors to the backend */
static PyObject *
PLy_procedure_call(PLyProcedure *proc, const char *kargs, PyObject *vargs)
{
	PyObject   *rv;
	int volatile save_subxact_level = list_length(explicit_subtransactions);

	PyDict_SetItemString(proc->globals, kargs, vargs);

	PG_TRY();
	{
		PLy_enter_python_intepreter = true;
#if PY_VERSION_HEX >= 0x03020000
		rv = PyEval_EvalCode(proc->code,
							 proc->globals, proc->globals);
#else
		rv = PyEval_EvalCode((PyCodeObject *) proc->code,
							 proc->globals, proc->globals);
#endif
		PLy_enter_python_intepreter = false;

		/*
		 * Since plpy will only let you close subtransactions that you
		 * started, you cannot *unnest* subtransactions, only *nest* them
		 * without closing.
		 */
		Assert(list_length(explicit_subtransactions) >= save_subxact_level);
	}
	PG_CATCH();
	{
		PLy_enter_python_intepreter = false;
		PLy_abort_open_subtransactions(save_subxact_level);
		PG_RE_THROW();
	}
	PG_END_TRY();

	PLy_abort_open_subtransactions(save_subxact_level);

	/* If the Python code returned an error, propagate it */
	if (rv == NULL)
		PLy_elog(ERROR, NULL);

	return rv;
}

/*
 * Abort lingering subtransactions that have been explicitly started
 * by plpy.subtransaction().start() and not properly closed.
 */
static void
PLy_abort_open_subtransactions(int save_subxact_level)
{
	Assert(save_subxact_level >= 0);

	while (list_length(explicit_subtransactions) > save_subxact_level)
	{
		PLySubtransactionData *subtransactiondata;

		Assert(explicit_subtransactions != NIL);

		ereport(WARNING,
				(errmsg("forcibly aborting a subtransaction that has not been exited")));

		RollbackAndReleaseCurrentSubTransaction();

		subtransactiondata = (PLySubtransactionData *) linitial(explicit_subtransactions);
		explicit_subtransactions = list_delete_first(explicit_subtransactions);

		MemoryContextSwitchTo(subtransactiondata->oldcontext);
		CurrentResourceOwner = subtransactiondata->oldowner;
		pfree(subtransactiondata);
	}
}


text:
#include <zephyr/kernel.h>
#include <zephyr/fff.h>
#include <host/crypto.h>
#include "mocks/hci_core.h"
#include "mocks/hci_core_expects.h"
#include "mocks/hmac_prng.h"
#include "mocks/hmac_prng_expects.h"
#include "mocks/crypto_help_utils.h"

DEFINE_FFF_GLOBALS;

static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
{
	HCI_CORE_FFF_FAKES_LIST(RESET_FAKE);
	HMAC_PRNG_FFF_FAKES_LIST(RESET_FAKE);
}

ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL);

ZTEST_SUITE(prng_init, NULL, NULL, NULL, NULL, NULL);

/*
 *  Test prng_init() succeeds
 *
 *  Constraints:
 *   - bt_hci_le_rand() succeeds and returns 0 (success)
 *   - tc_hmac_prng_init() succeeds and returns 'TC_CRYPTO_SUCCESS'.
 *   - tc_hmac_prng_reseed() succeeds and returns 'TC_CRYPTO_SUCCESS'.
 *
 *  Expected behaviour:
 *   - prng_init() returns 0 (success)
 */
ZTEST(prng_init, test_prng_init_succeeds)
{
	int err;
	uint8_t expected_args_history[] = {8, 32};
	struct tc_hmac_prng_struct *hmac_prng = bt_crypto_get_hmac_prng_instance();

	bt_hci_le_rand_fake.return_val = 0;
	tc_hmac_prng_init_fake.return_val = TC_CRYPTO_SUCCESS;
	tc_hmac_prng_reseed_fake.return_val = TC_CRYPTO_SUCCESS;

	err = prng_init();

	expect_call_count_bt_hci_le_rand(2, expected_args_history);
	expect_single_call_tc_hmac_prng_init(hmac_prng, 8);
	expect_single_call_tc_hmac_prng_reseed(hmac_prng, 32, sizeof(int64_t));

	zassert_ok(err, "'%s()' returned unexpected error code %d", test_unit_name, err);
}

redpajama_set_name: RedPajamaGithub


text:
{% extends "base.html" %}
{% from "helpers/formhelpers.html" import render_pagination %}
{% block title %}{% trans %}Users Administration{% endtrans %}{% endblock %}
{% block header %}{% endblock %}
{% block content %}

{% trans %}Active Users{% endtrans %}

{% trans %}There are {{ users_count }} users registered.{% endtrans %}

      {% for user in users %}

                {{ user }}
                {% if user.deleted %}{% endif %}

              {% if user.is_staff %}{% trans %}Staff Member{% endtrans %}
              {% elif user.is_teacher %}{% trans %}Teacher{% endtrans %}
              {% else %}{% trans %}Student{% endtrans %}
              {% endif %}

               {{ user.email }}

               {{ user.department }}

            {% if not user.deleted %}
            <form action="{{ url_for('admin.users_disable', pk=user.pk) }}" method="post" class="inline-item">
              <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
              <button type="submit" class="btn btn-warning cursor-pointer">{% trans %}Disable{% endtrans %}</button>
            </form>
            {% endif %}
            <form action="{{ url_for('admin.users_delete', pk=user.pk) }}" method="post" class="inline-item">
              <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
              <button type="submit" class="btn btn-danger cursor-pointer">{% trans %}Delete{% endtrans %}</button>
            </form>

      {% endfor %}

    {{ render_pagination(pagination) }}

{% endblock %}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>Renderer</title>
<meta name="date" content="2015-04-17">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

application

Class Renderer

java.lang.Object

application.Renderer

All Implemented Interfaces:

java.util.EventListener, javax.media.opengl.GLEventListener

public class Renderer
extends java.lang.Object
implements javax.media.opengl.GLEventListener

Custom renderer for displaying objects of the type CustomObject to the screen in 3d using OpenGL.
 Requires OpenGL3 support for VBOS.

Author:

Sam Dark

Field Summary

Fields

Modifier and Type
Field and Description

private Camera
cam

The camera object that stores camera position and orientation

private javax.media.opengl.awt.GLCanvas
canvas

The openGL canvas used for drawing on

private boolean
closing

Is the renderer closing?

private java.nio.FloatBuffer
colours

Floatbuffers used for VBO

private FPSSystem
FPSCounter

The FPS counter for displaying fps (and other strings) to the screen

private javax.swing.JFrame
frame

The frame the openGL canvas is in

private javax.media.opengl.glu.GLU
glu

GLU instance

private boolean[]
keyboard

The list of keys and if they are currently pressed (true for pressed but not released yet)

private java.nio.FloatBuffer
normals

Floatbuffers used for VBO

private int
numVerticesInScene

The number of vertices in the scene

private java.util.ArrayList<CustomObject>
objects

The objects to draw to the screen

private java.lang.String
stringForDisplay

The string to display to the screen

private java.nio.FloatBuffer
textures

Floatbuffers used for VBO

private boolean
texturesOn

Are textures enabled?

private long
timeCounter

The time since the last camera update

private long
timeOfLastKeyUpdate

The time the last camera update happened

private boolean
toInitTextures

Are there any textures waiting to be initialised?

private int[]
VBO

The VBO for handing all the information to openGL

private int
VBOSize

Current VBO Size in objects

private boolean
VBOUpdate

Has a VBO update been requested?

private java.nio.FloatBuffer
vertices

Floatbuffers used for VBO

private boolean
vSync

Is vsync on?

private boolean
wireframe

Is wireframe mode on?

Constructor Summary

Constructors

Constructor and Description

Renderer()

Creates a renderer and prepares it for rendering.

Method Summary

All Methods Instance Methods Concrete Methods

Modifier and Type
Method and Description

private void
addKeyListener()

Sets up the hotkeys for turning textures on/off etc and for closing the program

void
checkKeys()

Checks if the camera movement hotkeys are being pressed and updates the camera accordingly
 limits the camera to 60 updates per second

void
display(javax.media.opengl.GLAutoDrawable drawable)

Displays all objects in the scene using the VBO.

private void
displayGUI(javax.media.opengl.GLAutoDrawable drawable)

Displays the GUI to the screen.

private void
displaySetup(javax.media.opengl.GLAutoDrawable drawable)

Sets up the display ready for drawing.

void
dispose(javax.media.opengl.GLAutoDrawable drawable)

Disposes all the OpenGL stuff.

javax.media.opengl.awt.GLCanvas
getCanvas()

Gets the canvas being used for OpenGL

boolean
getClosing()

Returns if the renderer is closing.

java.util.ArrayList<CustomObject>
getObjects()

Gets the objects currently being displayed by the renderer

void
init(javax.media.opengl.GLAutoDrawable drawable)

Initialises OpenGL settings, lighting and VBOs for use later.

private void
initLights(javax.media.opengl.GL2 gl)

Creates and initialises the lights used for lighting

private void
initObjectsTextures()

Creates and set textures on any objects with textures and sets toInitTextures to false.

java.util.ArrayList<CustomObject>
initTextures(java.util.ArrayList<CustomObject> inpObjs)

Requests that the renderer add textures to the input objects, waits until it is done then returns the objects with textures.

private void
initVBO(javax.media.opengl.GLAutoDrawable drawable)

Sets up the VBO used for rendering.

private int
numVertices()

Gets the number of vertices currently in the scene.

void
requestVBOUpdate()

Requests that the renderer redo its VBO.

void
reshape(javax.media.opengl.GLAutoDrawable drawable,
       int x,
       int y,
       int width,
       int height)

Reshapes the canvas.

void
setFrame(javax.swing.JFrame inpFrame)

Sets the frame the canvas is in, used for closing the frame when exit is chosen.

void
setObjects(java.util.ArrayList<CustomObject> inpObjs)

Sets the objects the renderer is to display to the given objects

void
setStringForDisplay(java.lang.String inpString)

Sets an external string to display on the screen.

void
updateVerticesInScene()

Updates the counter that displays the number of vertices in the scene.

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Field Detail

FPSCounter

private FPSSystem FPSCounter

The FPS counter for displaying fps (and other strings) to the screen

canvas

private javax.media.opengl.awt.GLCanvas canvas

The openGL canvas used for drawing on

frame

private javax.swing.JFrame frame

The frame the openGL canvas is in

objects

private java.util.ArrayList<CustomObject> objects

The objects to draw to the screen

glu

private javax.media.opengl.glu.GLU glu

GLU instance

closing

private boolean closing

Is the renderer closing?

VBO

private int[] VBO

The VBO for handing all the information to openGL

vertices

private java.nio.FloatBuffer vertices

Floatbuffers used for VBO

normals

private java.nio.FloatBuffer normals

Floatbuffers used for VBO

textures

private java.nio.FloatBuffer textures

Floatbuffers used for VBO

colours

private java.nio.FloatBuffer colours

Floatbuffers used for VBO

VBOSize

private int VBOSize

Current VBO Size in objects

numVerticesInScene

private int numVerticesInScene

The number of vertices in the scene

vSync

private boolean vSync

Is vsync on?

wireframe

private boolean wireframe

Is wireframe mode on?

texturesOn

private boolean texturesOn

Are textures enabled?

stringForDisplay

private java.lang.String stringForDisplay

The string to display to the screen

toInitTextures

private boolean toInitTextures

Are there any textures waiting to be initialised?

VBOUpdate

private boolean VBOUpdate

Has a VBO update been requested?

cam

private Camera cam

The camera object that stores camera position and orientation

keyboard

private boolean[] keyboard

The list of keys and if they are currently pressed (true for pressed but not released yet)

timeOfLastKeyUpdate

private long timeOfLastKeyUpdate

The time the last camera update happened

timeCounter

private long timeCounter

The time since the last camera update

Constructor Detail

Renderer

Renderer()

Creates a renderer and prepares it for rendering.

Method Detail

getClosing

public boolean getClosing()

Returns if the renderer is closing. When the frame is closed this will change to true.

Returns:

True or false. False if the renderer is not closing

setObjects

public void setObjects(java.util.ArrayList<CustomObject> inpObjs)

Sets the objects the renderer is to display to the given objects

Parameters:

inpObjs - The objects to display

setFrame

public void setFrame(javax.swing.JFrame inpFrame)

Sets the frame the canvas is in, used for closing the frame when exit is chosen.

Parameters:

inpFrame - The frame the canvas is attached to

getCanvas

public javax.media.opengl.awt.GLCanvas getCanvas()

Gets the canvas being used for OpenGL

Returns:

The GLCanvas being used

addKeyListener

private void addKeyListener()

Sets up the hotkeys for turning textures on/off etc and for closing the program

checkKeys

public void checkKeys()

Checks if the camera movement hotkeys are being pressed and updates the camera accordingly
 limits the camera to 60 updates per second

init

public void init(javax.media.opengl.GLAutoDrawable drawable)

Initialises OpenGL settings, lighting and VBOs for use later. Is run once on startup.

Specified by:

init in interface javax.media.opengl.GLEventListener

initLights

private void initLights(javax.media.opengl.GL2 gl)

Creates and initialises the lights used for lighting

Parameters:

gl - The opengl in use

setStringForDisplay

public void setStringForDisplay(java.lang.String inpString)

Sets an external string to display on the screen. Used for displaying physics update time.

Parameters:

inpString - The string to display

initObjectsTextures

private void initObjectsTextures()

Creates and set textures on any objects with textures and sets toInitTextures to false.

initTextures

public java.util.ArrayList<CustomObject> initTextures(java.util.ArrayList<CustomObject> inpObjs)

Requests that the renderer add textures to the input objects, waits until it is done then returns the objects with textures.

Parameters:

inpObjs - The objects to create textures for

Returns:

The objects with textures added

getObjects

public java.util.ArrayList<CustomObject> getObjects()

Gets the objects currently being displayed by the renderer

Returns:

The objects in use

updateVerticesInScene

public void updateVerticesInScene()

Updates the counter that displays the number of vertices in the scene.
 Call once each time a new object or multiple objects are added.
 This method is expensive.

requestVBOUpdate

public void requestVBOUpdate()

Requests that the renderer redo its VBO. Used if the objects materials, textures, vertices (not position/rotation) are changed.
 Expensive, try not to call this, definitely not once per frame.

initVBO

private void initVBO(javax.media.opengl.GLAutoDrawable drawable)

Sets up the VBO used for rendering.
 Expensive method, called only when the vertices in the scene (number of objects, object types etc) are changed.
 Not called on a position/rotation change of objects.

Parameters:

drawable - The drawable object for OpenGL

dispose

public void dispose(javax.media.opengl.GLAutoDrawable drawable)

Disposes all the OpenGL stuff. Called on program exit.

Specified by:

dispose in interface javax.media.opengl.GLEventListener

display

public void display(javax.media.opengl.GLAutoDrawable drawable)

Displays all objects in the scene using the VBO.
 initVBO() must be called some time previously before this works.

Specified by:

display in interface javax.media.opengl.GLEventListener

Parameters:

drawable - The drawable to draw to.

displaySetup

private void displaySetup(javax.media.opengl.GLAutoDrawable drawable)

Sets up the display ready for drawing.
 Inits textures if there are any waiting and enables/disables wireframes, vsync and textures.

Parameters:

drawable - The OpenGL drawable

displayGUI

private void displayGUI(javax.media.opengl.GLAutoDrawable drawable)

Displays the GUI to the screen. Calculates fps and frame time to do this.

Parameters:

drawable - The drawable to draw the GUI to

reshape

public void reshape(javax.media.opengl.GLAutoDrawable drawable,
                    int x,
                    int y,
                    int width,
                    int height)

Reshapes the canvas. Called when the window is resized or resolution changed

Specified by:

reshape in interface javax.media.opengl.GLEventListener

numVertices

private int numVertices()

Gets the number of vertices currently in the scene.
 Note: this is the number of vertices in the object, it does not take into account the duplication of vertices in the VBO

Returns:

The number of vertices in the scene

Skip navigation links

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method


text:
This directory defines tests for the Go runtime builder image.

## Structure Test
The structure test is invoked in the cloud build steps after the builder image is built. It checks the environment setup and the existence of specific files in the image. Failing the structure test will also fail the whole submission.
See the structure tests [README](https://github.com/GoogleCloudPlatform/runtimes-common/blob/master/structure_tests/README.md)
for information on how to write tests.

## Integration Test
The \/integration directory contains a test web application for performing an end to end test.
Refer to integration test framework [README](https://github.com/GoogleCloudPlatform/runtimes-common/tree/master/integration_tests) for the design and requirements. The directory serves as a GOPATH. It also includes all the dependencies for it to be used by the test container. A test.yaml.in is provided as the templated cloudbuild.yaml for deploying the app: the ${STAGING_IMAGE} environment variable will contain the path to the go1-builder staging image to use (this variable must be set). Every newly built image will have the "staging" tag.

To perform the test:
* Manually run a container build of the go1-builder image. Skip this step if you already have an existing image in GCR that you want to test.
* Set `gcloud config set app/use_runtime_builders true`
* Set `gcloud config set app/runtime_builders_root` to the integration/ directory.
* Run test.sh \<project_id>. This will use the generated test.yaml to build and deploy the test app. It will also invoke the test driver to perform the test suite to verify that it is working.
* Optionally pass in the builder image tag name as the second parameter to use a different builder image (default tag is "staging").

### Caveat
There is an issue with the authentication of the test framework.
The test robot of the cloud container build system doesn't have the correct authentication to read the monitoring metrics or log entries.
Affected tests are skipped until the fix made.


text:
@class SFContact;

@implementation SFRemoteUploadRequestParams

@end


text:
..  Titling
    ##++::==~~--''``

Test plan
:::::::::

.. toctree::
   :maxdepth: 1

   tst-integration

.. Unit tests
.. Integration tests
.. Migration tests
.. Functional tests
.. Load tests
.. Monitoring


text:
--------------------------------
-- get view projection matrix
-- @function [parent=#Camera] getViewProjectionMatrix
-- @param self
-- @return mat4_table#mat4_table ret (return value: mat4_table)

--------------------------------
-- Make Camera looks at target

-- param target The target camera is point at

-- param up The up vector, usually it's Y axis
-- @function [parent=#Camera] lookAt
-- @param self
-- @param #vec3_table target
-- @param #vec3_table up
-- @return Camera#Camera self (return value: cc.Camera)

--------------------------------
-- Gets the camera's projection matrix.

-- return The camera projection matrix.
-- @function [parent=#Camera] getProjectionMatrix
-- @param self
-- @return mat4_table#mat4_table ret (return value: mat4_table)

--------------------------------
-- Get object depth towards camera
-- @function [parent=#Camera] getDepthInView
-- @param self
-- @param #mat4_table transform
-- @return float#float ret (return value: float)

--------------------------------
--
-- @function [parent=#Camera] clearBackground
-- @param self
-- @param #float depth
-- @return Camera#Camera self (return value: cc.Camera)

--------------------------------
-- set depth, camera with larger depth is drawn on top of camera with smaller depth, the depth of camera with CameraFlag::DEFAULT is 0, user defined camera is -1 by default
-- @function [parent=#Camera] setDepth
-- @param self
-- @param #int depth
-- @return Camera#Camera self (return value: cc.Camera)

--------------------------------
--  init camera
-- @function [parent=#Camera] initDefault
-- @param self
-- @return bool#bool ret (return value: bool)

--------------------------------
-- get & set Camera flag
-- @function [parent=#Camera] getCameraFlag
-- @param self
-- @return int#int ret (return value: int)

--------------------------------
-- Gets the type of camera.

-- return The camera type.
-- @function [parent=#Camera] getType
-- @param self
-- @return int#int ret (return value: int)

--------------------------------
--
-- @function [parent=#Camera] initOrthographic
-- @param self
-- @param #float zoomX
-- @param #float zoomY
-- @param #float nearPlane
-- @param #float farPlane
-- @return bool#bool ret (return value: bool)

--------------------------------
-- Is this aabb visible in frustum
-- @function [parent=#Camera] isVisibleInFrustum
-- @param self
-- @param #cc.AABB aabb
-- @return bool#bool ret (return value: bool)

--------------------------------
-- set additional matrix for the projection matrix, it multiplys mat to projection matrix when called, used by WP8
-- @function [parent=#Camera] setAdditionalProjection
-- @param self
-- @param #mat4_table mat
-- @return Camera#Camera self (return value: cc.Camera)

--------------------------------
-- Set the scene,this method shall not be invoke manually
-- @function [parent=#Camera] setScene
-- @param self
-- @param #cc.Scene scene
-- @return Camera#Camera self (return value: cc.Camera)

--------------------------------
--
-- @function [parent=#Camera] projectGL
-- @param self
-- @param #vec3_table src
-- @return vec2_table#vec2_table ret (return value: vec2_table)

--------------------------------
-- Gets the camera's view matrix.

-- return The camera view matrix.
-- @function [parent=#Camera] getViewMatrix
-- @param self
-- @return mat4_table#mat4_table ret (return value: mat4_table)

--------------------------------
-- Get the frustum's near plane.
-- @function [parent=#Camera] getNearPlane
-- @param self
-- @return float#float ret (return value: float)

--------------------------------
--
-- @function [parent=#Camera] project
-- @param self
-- @param #vec3_table src
-- @return vec2_table#vec2_table ret (return value: vec2_table)

--------------------------------
--
-- @function [parent=#Camera] setCameraFlag
-- @param self
-- @param #int flag
-- @return Camera#Camera self (return value: cc.Camera)

--------------------------------
-- Get the frustum's far plane.
-- @function [parent=#Camera] getFarPlane
-- @param self
-- @return float#float ret (return value: float)

--------------------------------
--
-- @function [parent=#Camera] initPerspective
-- @param self
-- @param #float fieldOfView
-- @param #float aspectRatio
-- @param #float nearPlane
-- @param #float farPlane
-- @return bool#bool ret (return value: bool)

--------------------------------
--  create default camera, the camera type depends on Director::getProjection, the depth of the default camera is 0
-- @function [parent=#Camera] create
-- @param self
-- @return Camera#Camera ret (return value: cc.Camera)

--------------------------------
-- Creates a perspective camera.

-- param fieldOfView The field of view for the perspective camera (normally in the range of 40-60 degrees).

-- param aspectRatio The aspect ratio of the camera (normally the width of the viewport divided by the height of the viewport).

-- param nearPlane The near plane distance.

-- param farPlane The far plane distance.
-- @function [parent=#Camera] createPerspective
-- @param self
-- @param #float fieldOfView
-- @param #float aspectRatio
-- @param #float nearPlane
-- @param #float farPlane
-- @return Camera#Camera ret (return value: cc.Camera)

--------------------------------
-- Creates an orthographic camera.

-- param zoomX The zoom factor along the X-axis of the orthographic projection (the width of the ortho projection).

-- param zoomY The zoom factor along the Y-axis of the orthographic projection (the height of the ortho projection).

-- param nearPlane The near plane distance.

-- param farPlane The far plane distance.
-- @function [parent=#Camera] createOrthographic
-- @param self
-- @param #float zoomX
-- @param #float zoomY
-- @param #float nearPlane
-- @param #float farPlane
-- @return Camera#Camera ret (return value: cc.Camera)

--------------------------------
-- Get the default camera of the current running scene.
-- @function [parent=#Camera] getDefaultCamera
-- @param self
-- @return Camera#Camera ret (return value: cc.Camera)

--------------------------------
-- Get the visiting camera , the visiting camera shall be set on Scene::render
-- @function [parent=#Camera] getVisitingCamera
-- @param self
-- @return Camera#Camera ret (return value: cc.Camera)

--------------------------------
--
-- @function [parent=#Camera] Camera
-- @param self
-- @return Camera#Camera self (return value: cc.Camera)

return nil


text:
"""
Copyright 2013 Steven Diamond

This file is part of CVXPY.

CVXPY is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

CVXPY is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with CVXPY.  If not, see <http://www.gnu.org/licenses/>.
"""

import cvxpy.interface as intf
import cvxpy.lin_ops as lo
import cvxpy.lin_ops.lin_utils as lu
import cvxpy.lin_ops.lin_to_matrix as op2mat
import scipy.sparse as sp

class MatrixCache(object):
    """A cached version of the matrix and vector pair in an affine constraint.

    Attributes
    ----------
    coo_tup : tuple
            A (V, I, J) triplet for the matrix.
    param_coo_tup : tuple
            A (V, I, J) triplet for the parameterized matrix.
    const_vec : array
        The vector offset.
    constraints : list
        A list of constraints in the matrix.
    size : tuple
        The (rows, cols) dimensions of the matrix.
    """
    def __init__(self, coo_tup, const_vec, constraints, x_length):
        self.coo_tup = coo_tup
        self.const_vec = const_vec
        self.constraints = constraints
        rows = sum([c.size[0] * c.size[1] for c in constraints])
        cols = x_length
        self.size = (rows, cols)
        self.param_coo_tup = ([], [], [])

    def reset_param_data(self):
        """Clear old parameter data.
        """
        self.param_coo_tup = ([], [], [])

class MatrixData(object):
    """The matrices for the conic form convex optimization problem.

    Attributes
    ----------
    sym_data : SymData object
        The symbolic data for the conic form problem.
    matrix_intf : interface
        The matrix interface to use for creating the constraints matrix.
    vec_intf : interface
        The matrix interface to use for creating the constant vector.
    """

    def __init__(self, sym_data, matrix_intf, vec_intf, solver):
        self.sym_data = sym_data
        # A dummy constraint for the objective.
        self.matrix_intf = matrix_intf
        self.vec_intf = vec_intf

        # Cache everything possible.
        self.obj_cache = self._init_matrix_cache(self._dummy_constr(),
                                                 self.sym_data.x_length)
        self._lin_matrix(self.obj_cache, caching=True)
        # Separate constraints based on the solver being used.
        constr_types = solver.split_constr(self.sym_data.constr_map)
        eq_constr, ineq_constr, nonlin_constr = constr_types
        # Equaliy constraints.
        self.eq_cache = self._init_matrix_cache(eq_constr,
                                                self.sym_data.x_length)
        self._lin_matrix(self.eq_cache, caching=True)
        # Inequality constraints.
        self.ineq_cache = self._init_matrix_cache(ineq_constr,
                                                  self.sym_data.x_length)
        self._lin_matrix(self.ineq_cache, caching=True)
        # Nonlinear constraints.
        self.F = self._nonlin_matrix(nonlin_constr)

    def _dummy_constr(self):
        """Returns a dummy constraint for the objective.
        """
        return [lu.create_eq(self.sym_data.objective)]

    def get_objective(self):
        """Returns the linear objective and a scalar offset.
        """
        c, offset = self._cache_to_matrix(self.obj_cache)
        c = self.vec_intf.const_to_matrix(c.T, convert_scalars=True)
        c = intf.from_2D_to_1D(c)
        offset = self.vec_intf.scalar_value(offset)
        # Negate offset because was negated before.
        return c, -offset

    def get_eq_constr(self):
        """Returns the matrix and vector for the equality constraint.
        """
        return self._cache_to_matrix(self.eq_cache)

    def get_ineq_constr(self):
        """Returns the matrix and vector for the inequality constraint.
        """
        return self._cache_to_matrix(self.ineq_cache)

    def get_nonlin_constr(self):
        """Returns the oracle function for the nonlinear constraints.
        """
        return self.F

    def _init_matrix_cache(self, constraints, x_length):
        """Initializes the data structures for the cached matrix.

        Parameters
        ----------
        constraints : list
            A list of constraints in the matrix.
        x_length : int
            The number of columns in the matrix.
        Returns
        -------
        ((V, I, J), array)
        """
        rows = sum([c.size[0] * c.size[1] for c in constraints])
        COO = ([], [], [])
        const_vec = self.vec_intf.zeros(rows, 1)
        return MatrixCache(COO, const_vec, constraints, x_length)

    def _lin_matrix(self, mat_cache, caching=False):
        """Computes a matrix and vector representing a list of constraints.

        In the matrix, each constraint is given a block of rows.
        Each variable coefficient is inserted as a block with upper
        left corner at matrix[variable offset, constraint offset].
        The constant term in the constraint is added to the vector.

        Parameters
        ----------
        mat_cache : MatrixCache
            The cached version of the matrix-vector pair.
        caching : bool
            Is the data being cached?

        Returns
        -------
        tuple
            A (matrix, vector) tuple.
        """
        vert_offset = 0
        for constr in mat_cache.constraints:
            # Process the constraint if it has a parameter and not caching
            # or it doesn't have a parameter and caching.
            has_param = len(lu.get_expr_params(constr.expr)) > 0
            if (has_param and not caching) or (not has_param and caching):
                self._process_constr(constr, mat_cache, vert_offset)
            vert_offset += constr.size[0]*constr.size[1]

    def _cache_to_matrix(self, mat_cache):
        """Converts the cached representation of the constraints matrix.

        Parameters
        ----------
        mat_cache : MatrixCache
            The cached version of the matrix-vector pair.

        Returns
        -------
        A (matrix, vector) tuple.
        """
        # Get parameter values.
        param_cache = self._init_matrix_cache(mat_cache.constraints,
                                              mat_cache.size[0])
        self._lin_matrix(param_cache)
        rows, cols = mat_cache.size
        # Create the constraints matrix.
        # Combine the cached data with the parameter data.
        V, I, J = mat_cache.coo_tup
        Vp, Ip, Jp = param_cache.coo_tup
        if len(V) + len(Vp) > 0:
            matrix = sp.coo_matrix((V + Vp, (I + Ip, J + Jp)), (rows, cols))
            # Convert the constraints matrix to the correct type.
            matrix = self.matrix_intf.const_to_matrix(matrix,
                                                      convert_scalars=True)
        else: # Empty matrix.
            matrix = self.matrix_intf.zeros(rows, cols)
        # Convert 2D ND arrays to 1D
        combo_vec = mat_cache.const_vec + param_cache.const_vec
        const_vec = intf.from_2D_to_1D(combo_vec)
        return (matrix, -const_vec)

    def _process_constr(self, constr, mat_cache, vert_offset):
        """Extract the coefficients from a constraint.

        Parameters
        ----------
        constr : LinConstr
            The linear constraint to process.
        mat_cache : MatrixCache
            The cached version of the matrix-vector pair.
        vert_offset : int
            The row offset of the constraint.
        """
        V, I, J = mat_cache.coo_tup
        coeffs = op2mat.get_coefficients(constr.expr)
        for id_, block in coeffs:
            vert_start = vert_offset
            vert_end = vert_start + constr.size[0]*constr.size[1]
            if id_ is lo.CONSTANT_ID:
                # Flatten the block.
                block = self.vec_intf.const_to_matrix(block)
                block_size = intf.size(block)
                block = self.vec_intf.reshape(
                    block,
                    (block_size[0]*block_size[1], 1)
                )
                mat_cache.const_vec[vert_start:vert_end, :] += block
            else:
                horiz_offset = self.sym_data.var_offsets[id_]
                if intf.is_scalar(block):
                    block = intf.scalar_value(block)
                    V.append(block)
                    I.append(vert_start)
                    J.append(horiz_offset)
                else:
                    # Block is a numpy matrix or
                    # scipy CSC sparse matrix.
                    if not intf.is_sparse(block):
                        block = intf.DEFAULT_SPARSE_INTERFACE.const_to_matrix(
                            block
                        )
                    block = block.tocoo()
                    V.extend(block.data)
                    I.extend(block.row + vert_start)
                    J.extend(block.col + horiz_offset)

    def _nonlin_matrix(self, nonlin_constr):
        """Returns an oracle for the nonlinear constraints.

        The oracle computes the combined function value, gradient, and Hessian.

        Parameters
        ----------
        nonlin_constr : list
            A list of nonlinear constraints represented as oracle functions.

        Returns
        -------
        Oracle function.
        """
        rows = sum([c.size[0] * c.size[1] for c in nonlin_constr])
        cols = self.sym_data.x_length
        var_offsets = self.sym_data.var_offsets

        big_x = self.vec_intf.zeros(cols, 1)
        for constr in nonlin_constr:
            constr.place_x0(big_x, var_offsets, self.vec_intf)

        def F(x=None, z=None):
            """Oracle for function value, gradient, and Hessian.
            """
            if x is None:
                return rows, big_x
            big_f = self.vec_intf.zeros(rows, 1)
            big_Df = self.matrix_intf.zeros(rows, cols)
            if z:
                big_H = self.matrix_intf.zeros(cols, cols)

            offset = 0
            for constr in nonlin_constr:
                constr_entries = constr.size[0]*constr.size[1]
                local_x = constr.extract_variables(x, var_offsets,
                                                   self.vec_intf)
                if z:
                    f, Df, H = constr.f(local_x,
                                        z[offset:offset + constr_entries])
                else:
                    result = constr.f(local_x)
                    if result:
                        f, Df = result
                    else:
                        return None
                big_f[offset:offset + constr_entries] = f
                constr.place_Df(big_Df, Df, var_offsets,
                                offset, self.matrix_intf)
                if z:
                    constr.place_H(big_H, H, var_offsets,
                                   self.matrix_intf)
                offset += constr_entries

            if z is None:
                return big_f, big_Df
            return big_f, big_Df, big_H
        return F


text:
<?php
	declare(strict_types=1);

	namespace Edde\Ext\Application;

	use Edde\Common\Converter\Content;

	class JsonEncodedContent extends Content {
		public function __construct($content) {
			parent::__construct($content, 'json');
		}
	}


text:
datadir := /usr/share
bindir := /usr/bin
systemddir := /usr/lib/systemd/system

PYTHON = python3

####################
all: forward_api_calls
	$(PYTHON) setup.py build

forward_api_calls: forward_api_calls.c
	$(CC) -Wall -Os -o $@ $?
	strip $@

#################### install
install: install-miscell install-startup
	$(PYTHON) setup.py install \
		--install-purelib=$(DESTDIR)/$(datadir)/NodeManager \
		--install-platlib=$(DESTDIR)/$(datadir)/NodeManager
	chmod +x $(DESTDIR)/$(datadir)/NodeManager/conf_files.py

# might be better in setup.py ?
# NOTE: the sliver-initscripts/ and sliver-systemd stuff, being, well, for slivers,
# need to ship on all nodes regardless of WITH_INIT and WITH_SYSTEMD that
# impacts how nodemanager itself gets started
install-miscell:
	install -D -m 755 forward_api_calls $(DESTDIR)/$(bindir)/forward_api_calls
	install -d -m 755 $(DESTDIR)/var/lib/nodemanager
	install -D -m 644 /dev/null $(DESTDIR)/etc/sysconfig/nodemanager
	install -D -m 444 README $(DESTDIR)/$(datadir)/NodeManager/README
	install -D -m 644 logrotate/nodemanager $(DESTDIR)/etc/logrotate.d/nodemanager
	mkdir -p $(DESTDIR)/$(datadir)/NodeManager/sliver-initscripts
	rsync -av sliver-initscripts/ $(DESTDIR)/$(datadir)/NodeManager/sliver-initscripts/
	chmod 755 $(DESTDIR)/$(datadir)/NodeManager/sliver-initscripts/
	mkdir -p $(DESTDIR)/$(datadir)/NodeManager/sliver-systemd
	rsync -av sliver-systemd/ $(DESTDIR)/$(datadir)/NodeManager/sliver-systemd/
	chmod 755 $(DESTDIR)/$(datadir)/NodeManager/sliver-systemd/

install-startup: install-systemd

install-systemd:
	mkdir -p $(DESTDIR)/$(systemddir)
	rsync -av systemd/ $(DESTDIR)/$(systemddir)

#################### clean
clean:
	$(PYTHON) setup.py clean
	rm -f forward_api_calls *.pyc build

.PHONY: all install clean

################################################## devel-oriented
tags:
	git ls-files | xargs etags

.PHONY: tags

########## sync
# for use with the test framework; push local stuff on a test node
# howto use: go on testmaster in the build you want to use and just run
# $ exp
# cut'n paste the result in a terminal in your working dir, e.g. (although all are not required)
# $ export BUILD=2013.07.02--lxc18
# $ export PLCHOSTLXC=gotan.pl.sophia.inria.fr
# $ export GUESTNAME=2013.07.02--lxc18-1-vplc01
# $ export GUESTHOSTNAME=vplc01.pl.sophia.inria.fr
# $ export KVMHOST=kvm64-6.pl.sophia.inria.fr
# $ export NODE=vnode01.pl.sophia.inria.fr
# and then just run
# $ make sync

LOCAL_RSYNC_EXCLUDES	:= --exclude '*.pyc'
RSYNC_EXCLUDES		:= --exclude .git  --exclude .svn --exclude '*~' --exclude TAGS $(LOCAL_RSYNC_EXCLUDES)
RSYNC_COND_DRY_RUN	:= $(if $(findstring n,$(MAKEFLAGS)),--dry-run,)
RSYNC			:= rsync -e "ssh -i $(NODE).key.rsa" -a -v $(RSYNC_COND_DRY_RUN) $(RSYNC_EXCLUDES)

ifdef NODE
NODEURL:=root@$(NODE):/
endif

# this is for lxc only, we need to exclude the vs stuff that otherwise messes up everything on node
# WARNING: keep this in sync with setup.spec
LXC_EXCLUDES= --exclude sliver_vs.py --exclude coresched_vs.py --exclude drl.py

# run with make SYNC_RESTART=false if you want to skip restarting nm
SYNC_RESTART=true

sync:synclxc

synclxc: $(NODE).key.rsa
ifeq (,$(NODEURL))
	@echo "sync: You must define NODE on the command line"
	@echo "  e.g. make sync NODE=vnode01.inria.fr"
	@exit 1
else
	@echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	@echo WARNING : this target might not be very reliable - use with care
	@echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	+$(RSYNC) $(LXC_EXCLUDES) --delete-excluded ./ $(NODEURL)/usr/share/NodeManager/
	+$(RSYNC) ./systemd/ $(NODEURL)/usr/lib/systemd/system/
	-$(SYNC_RESTART) && { ssh -i $(NODE).key.rsa root@$(NODE) service nm restart ; } ||:
endif

### fetching the key

TESTMASTER ?= testmaster.onelab.eu

ifdef BUILD
KEYURL:=root@$(TESTMASTER):$(BUILD)/keys/key_admin.rsa
endif

key: $(NODE).key.rsa

$(NODE).key.rsa:
ifeq (,$(KEYURL))
	@echo "sync: fetching $@ - You must define TESTMASTER, BUILD and NODE on the command line"
	@echo "  e.g. make sync TESTMASTER=testmaster.onelab.eu BUILD=2010.01.22--1l-f8-32 NODE=vnode01.inria.fr"
	@echo "  note that for now all test builds use the same key, so any BUILD would do"
	@exit 1
else
	@echo "FETCHING key"
	+scp $(KEYURL) $@
endif

########## exp. too
SLICE=inri_sl1

syncvinit:
	$(RSYNC) sliver-systemd/vinit.st* $(NODEURL)/vservers/$(SLICE)/usr/bin/
	$(RSYNC) sliver-systemd/vinit.service $(NODEURL)/vservers/$(SLICE)/usr/lib/systemd/system/
	echo "remember to run 'systemctl --system daemon-reload' within this slice"


text:
@implementation MWDeviceInfo

+ (BOOL)isIPhoneXSeries
{
    if ([UIDevice currentDevice].userInterfaceIdiom != UIUserInterfaceIdiomPhone) {
        return NO;
    }
    if (@available(iOS 11.0, *)) {
        UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
        if (mainWindow.safeAreaInsets.bottom > 0.0) {
            return YES;
        }
    }
    return NO;
}

@end


text:
<!DOCTYPE html>

        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

        <title>Example 1 (attester)</title>


text:
#include <llvm/IR/DebugInfo.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/DIBuilder.h>
#include <llvm/IR/DebugInfoMetadata.h>
#include <llvm/IR/Instruction.h>
#include <llvm/Support/Casting.h>
#include "DebugInfoC.h"

/**
 * c++ --std=c++11 llvmDebugInfoC/src/DebugInfoC.cpp -IllvmDebugInfoC/include/ -Idependencies/all/clang+llvm-3.9.0-darwin-macos/include -Ldependencies/all/clang+llvm-3.9.0-darwin-macos/lib  -lLLVMCore -lLLVMSupport -lncurses -shared -o libLLVMDebugInfoC.dylib
 */

namespace llvm {
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBuilder,        DIBuilderRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DICompileUnit,    DICompileUnitRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIFile,           DIFileRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBasicType,      DIBasicTypeRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DICompositeType,  DICompositeTypeRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIType,           DITypeOpaqueRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIDerivedType,    DIDerivedTypeRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIModule,         DIModuleRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIScope,          DIScopeOpaqueRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DISubroutineType, DISubroutineTypeRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DISubprogram,     DISubprogramRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DILocation,       DILocationRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DILocalVariable,  DILocalVariableRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIExpression,     DIExpressionRef)

// from Module.cpp
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module,        LLVMModuleRef)
}

/**
 * see [DIFlags::FlagFwdDecl].
 */
#define DI_FORWARD_DECLARAION (4)
extern "C" {

DIBuilderRef DICreateBuilder(LLVMModuleRef module) {
  return llvm::wrap(new llvm::DIBuilder(* llvm::unwrap(module)));
}

void DIFinalize(DIBuilderRef builder) {
  auto diBuilder = llvm::unwrap(builder);
  diBuilder->finalize();
  delete diBuilder;
}

DICompileUnitRef DICreateCompilationUnit(DIBuilderRef builder, unsigned int lang,
                                         const char *file, const char* dir,
                                         const char * producer, int isOptimized,
                                         const char * flags, unsigned int rv) {
  return llvm::wrap(llvm::unwrap(builder)->createCompileUnit(lang, file, dir, producer, isOptimized, flags, rv));
}

DIFileRef DICreateFile(DIBuilderRef builder, const char *filename, const char *directory) {
  return llvm::wrap(llvm::unwrap(builder)->createFile(filename, directory));
}

DIBasicTypeRef DICreateBasicType(DIBuilderRef builder, const char* name, uint64_t sizeInBits, uint64_t alignment, unsigned encoding) {
  return llvm::wrap(llvm::unwrap(builder)->createBasicType(name, sizeInBits, alignment, encoding));
}

DIModuleRef DICreateModule(DIBuilderRef builder, DIScopeOpaqueRef scope,
                           const char* name, const char* configurationMacro,
                           const char* includePath, const char *iSysRoot) {
  return llvm::wrap(llvm::unwrap(builder)->createModule(llvm::unwrap(scope), name, configurationMacro, includePath, iSysRoot));
}

DISubprogramRef DICreateFunction(DIBuilderRef builder, DIScopeOpaqueRef scope,
                                 const char* name, const char *linkageName,
                                 DIFileRef file, unsigned lineNo,
                                 DISubroutineTypeRef type, int isLocal,
                                 int isDefinition, unsigned scopeLine) {
  return llvm::wrap(llvm::unwrap(builder)->createFunction(llvm::unwrap(scope),
                                                          name,
                                                          linkageName,
                                                          llvm::unwrap(file),
                                                          lineNo,
                                                          llvm::unwrap(type),
                                                          isLocal,
                                                          isDefinition,
                                                          scopeLine));
}

DICompositeTypeRef DICreateStructType(DIBuilderRef refBuilder,
                                      DIScopeOpaqueRef scope, const char *name,
                                      DIFileRef file, unsigned lineNumber,
                                      uint64_t sizeInBits, uint64_t alignInBits,
                                      unsigned flags, DITypeOpaqueRef derivedFrom,
                                      DIDerivedTypeRef *elements,
                                      uint64_t elementsCount,
                                      DICompositeTypeRef refPlace) {
  auto builder = llvm::unwrap(refBuilder);
  if ((flags & DI_FORWARD_DECLARAION) != 0) {
    return llvm::wrap(builder->createStructType(llvm::unwrap(scope), name, NULL, 0, 0, 0, flags, NULL, NULL));
  }
  std::vector<llvm::Metadata *> typeElements;
  for(int i = 0; i < elementsCount; ++i) {
    typeElements.push_back(llvm::unwrap(elements[i]));
  }
  auto elementsArray = builder->getOrCreateArray(typeElements);
  auto composite = builder->createStructType(llvm::unwrap(scope),
                                              name, llvm::unwrap(file),
                                              lineNumber,
                                              sizeInBits, alignInBits, flags,
                                              llvm::unwrap(derivedFrom),
                                              elementsArray);
  builder->replaceTemporary(llvm::TempDIType(llvm::unwrap(refPlace)), composite);
  return llvm::wrap(composite);
}

DICompositeTypeRef DICreateArrayType(DIBuilderRef refBuilder,
                                      uint64_t size, uint64_t alignInBits,
                                      DITypeOpaqueRef refType,
                                     uint64_t elementsCount) {
  auto builder = llvm::unwrap(refBuilder);
  auto range = std::vector<llvm::Metadata*>({llvm::dyn_cast<llvm::Metadata>(builder->getOrCreateSubrange(0, size))});
  return llvm::wrap(builder->createArrayType(size, alignInBits, llvm::unwrap(refType),
                                             builder->getOrCreateArray(range)));
}

DIDerivedTypeRef DICreateMemberType(DIBuilderRef refBuilder,
                                    DIScopeOpaqueRef refScope,
                                    const char *name,
                                    DIFileRef file,
                                    unsigned lineNum,
                                    uint64_t sizeInBits,
                                    uint64_t alignInBits,
                                    uint64_t offsetInBits,
                                    unsigned flags,
                                    DITypeOpaqueRef type) {
  return llvm::wrap(llvm::unwrap(refBuilder)->createMemberType(
                      llvm::unwrap(refScope),
                      name,
                      llvm::unwrap(file),
                      lineNum,
                      sizeInBits,
                      alignInBits,
                      offsetInBits,
                      flags,
                      llvm::unwrap(type)));
}

DICompositeTypeRef DICreateReplaceableCompositeType(DIBuilderRef refBuilder,
                                                    int tag,
                                                    const char *name,
                                                    DIScopeOpaqueRef refScope,
                                                    DIFileRef refFile,
                                                    unsigned line) {
  return llvm::wrap(llvm::unwrap(refBuilder)->createReplaceableCompositeType(
                      tag, name, llvm::unwrap(refScope), llvm::unwrap(refFile), line));
}

DIDerivedTypeRef DICreateReferenceType(DIBuilderRef refBuilder, DITypeOpaqueRef refType) {
  return llvm::wrap(llvm::unwrap(refBuilder)->createReferenceType(
                      llvm::dwarf::DW_TAG_reference_type,
                      llvm::unwrap(refType)));
}

DIDerivedTypeRef DICreatePointerType(DIBuilderRef refBuilder, DITypeOpaqueRef refType) {
  return llvm::wrap(llvm::unwrap(refBuilder)->createReferenceType(
                      llvm::dwarf::DW_TAG_pointer_type,
                      llvm::unwrap(refType)));
}

DISubroutineTypeRef DICreateSubroutineType(DIBuilderRef builder,
                                           DITypeOpaqueRef* types,
                                           unsigned typesCount) {
  std::vector<llvm::Metadata *> parameterTypes;
  for (int i = 0; i != typesCount; ++i) {
    parameterTypes.push_back(llvm::unwrap(types[i]));
  }
  llvm::DIBuilder *b = llvm::unwrap(builder);
  llvm::DITypeRefArray typeArray = b->getOrCreateTypeArray(parameterTypes);
  return llvm::wrap(b->createSubroutineType(typeArray));
}

void DIFunctionAddSubprogram(LLVMValueRef fn, DISubprogramRef sp) {
  auto f = llvm::cast<llvm::Function>(llvm::unwrap(fn));
  auto dsp = llvm::cast<llvm::DISubprogram>(llvm::unwrap(sp));
  f->setSubprogram(dsp);
  if (!dsp->describes(f)) {
    fprintf(stderr, "error!!! f:%s, sp:%s\n", f->getName(), dsp->getLinkageName());
  }
}

DILocalVariableRef DICreateAutoVariable(DIBuilderRef builder, DIScopeOpaqueRef scope, const char *name, DIFileRef file, unsigned line, DITypeOpaqueRef type) {
  return llvm::wrap(llvm::unwrap(builder)->createAutoVariable(
    llvm::unwrap(scope),
    name,
    llvm::unwrap(file),
    line,
    llvm::unwrap(type)));
}

DIExpressionRef DICreateEmptyExpression(DIBuilderRef builder) {
  return llvm::wrap(llvm::unwrap(builder)->createExpression());
}

void DIInsertDeclaration(DIBuilderRef builder, LLVMValueRef value, DILocalVariableRef localVariable, DILocationRef location, LLVMBasicBlockRef bb, int64_t *expr, uint64_t exprCount) {
  auto di_builder = llvm::unwrap(builder);
  std::vector<int64_t> expression;
  for (uint64_t i = 0; i < exprCount; ++i)
    expression.push_back(expr[i]);
  di_builder->insertDeclare(llvm::unwrap(value),
                            llvm::unwrap(localVariable),
                            di_builder->createExpression(expression),
                            llvm::unwrap(location),
                            llvm::unwrap(bb));
}

DILocationRef LLVMBuilderSetDebugLocation(LLVMBuilderRef builder, unsigned line,
                                 unsigned col, DIScopeOpaqueRef scope) {
  auto sp = llvm::unwrap(scope);
  auto llvmBuilder = llvm::unwrap(builder);
  auto location = llvm::DILocation::get(llvmBuilder->getContext(), line, col, sp, nullptr);
  llvmBuilder->SetCurrentDebugLocation(location);
  return llvm::wrap(location);
}

void LLVMBuilderResetDebugLocation(LLVMBuilderRef builder) {
  llvm::unwrap(builder)->SetCurrentDebugLocation(nullptr);
}

LLVMValueRef LLVMBuilderGetCurrentFunction(LLVMBuilderRef builder) {
  return llvm::wrap(llvm::unwrap(builder)->GetInsertBlock()->getParent());
}

const char* LLVMBuilderGetCurrentBbName(LLVMBuilderRef builder) {
  return llvm::unwrap(builder)->GetInsertBlock()->getName().str().c_str();
}

const char *DIGetSubprogramLinkName(DISubprogramRef sp) {
  return llvm::unwrap(sp)->getLinkageName().str().c_str();
}

int DISubprogramDescribesFunction(DISubprogramRef sp, LLVMValueRef fn) {
  return llvm::unwrap(sp)->describes(llvm::cast<llvm::Function>(llvm::unwrap(fn)));
}

void DIScopeDump(DIScopeOpaqueRef scope) {
  llvm::unwrap(scope)->dump();
}
} /* extern "C" */


text:
package io.sunflower.util;

import org.junit.Test;

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;

public class JarLocationTest {
    @Test
    public void isHumanReadable() throws Exception {
        assertThat(new JarLocation(JarLocationTest.class).toString())
                .isEqualTo("project.jar");
    }

    @Test
    public void hasAVersion() throws Exception {
        assertThat(new JarLocation(JarLocationTest.class).getVersion())
                .isEqualTo(Optional.empty());
    }
}