static int
tupleprint(PyTupleObject *op, FILE *fp, int flags)
{
	Py_ssize_t i;
	Py_BEGIN_ALLOW_THREADS
	fprintf(fp, "(");
	Py_END_ALLOW_THREADS
	for (i = 0; i < Py_SIZE(op); i++) {
		if (i > 0) {
			Py_BEGIN_ALLOW_THREADS
			fprintf(fp, ", ");
			Py_END_ALLOW_THREADS
		}
		if (PyObject_Print(op->ob_item[i], fp, 0) != 0)
			return -1;
	}
Exemple #2
0
static ExpatStatus
builder_EndElement(void *userState, ExpatName *name)
{
  ParserState *state = (ParserState *)userState;
  Context *context = state->context;
  NodeObject *node;

#ifdef DEBUG_PARSER
  fprintf(stderr, "--- builder_EndElement(name=");
  PyObject_Print(name->qualifiedName, stderr, 0);
  fprintf(stderr, ")\n");
#endif

  /* Get the newly constructed element */
  node = context->node;

  /* Get the working children array */
  context->children = _Container_GetWorkingChildren(node, &context->children_allocated);

  /* Set the element's children */
  switch (_Container_FreezeChildren(node)) {
    case 0:
      break;
    case -1:
      ParserState_FreeContext(state);
    default:
      return EXPAT_STATUS_ERROR;
  }

  /* Mark the current context as free */
  ParserState_FreeContext(state);

  /* ParserState_AddNode steals the reference to the new node */
  if (ParserState_AddNode(state, node) < 0) {
    Py_DECREF(node);
    return EXPAT_STATUS_ERROR;
  }
  /* Hook to send the formed node to any target */

  if (state->rule_matcher) {
    if (RuleMatch_EndElement(state->rule_matcher,(PyObject *) node,name) < 0) {
      return EXPAT_STATUS_ERROR;
    }
  }
  return EXPAT_STATUS_OK;
}
static PyObject * add_to_pointerlist(struct pointerlist *n, struct key_thing *other)
{
    HEX(n);
    HEX(other);
    INT(other->key);
    HEX(other->self);
    XX(print_pointerlist(n));
    if (n == NULL) {
	PyErr_SetString(PyExc_RuntimeError,
			"add_to_pointerlist: null list??");
	return NULL;
    }
    if (other == NULL) {
	PyErr_SetString(PyExc_RuntimeError,
			"add_to_pointerlist: second arg is NULL");
	return NULL;
    }
    if (other->key == 0) {
	printf("BADNESS: ");
	PyObject_Print(other->self, stdout, 0);
	printf("\n");

	PyErr_SetString(PyExc_RuntimeError,
			"add_to_pointerlist: key is zero");
	return NULL;
    }
    /* we already have somebody with the same key, so remove it */
    if (has_key(n, other->key) != NULL) {
	if (remove_from_pointerlist(n, other->key) == NULL)
	    return NULL;
    }
	n->size++;
    if (n->size > n->arraysize) {
	printf("GROW LIST FROM %d to %d\n", n->arraysize, 2 * n->arraysize);
	n->arraysize *= 2;
	n->lst = (struct key_thing **)
	    realloc(n->lst, n->arraysize * sizeof(struct key_thing *));
    }
	n->lst[n->size-1] = other;
	Py_INCREF(other->self);

    MARK();
    XX(print_pointerlist(n));
    Py_INCREF(Py_None);
    return Py_None;
}
Exemple #4
0
int
PyObject_Print(PyObject *op, FILE *fp, int flags)
{
	int ret = 0;
	if (PyErr_CheckSignals())
		return -1;
#ifdef USE_STACKCHECK
	if (PyOS_CheckStack()) {
		PyErr_SetString(PyExc_MemoryError, "stack overflow");
		return -1;
	}
#endif
	clearerr(fp); /* Clear any previous error condition */
	if (op == NULL) {
		fprintf(fp, "<nil>");
	}
	else {
		if (op->ob_refcnt <= 0)
			fprintf(fp, "<refcnt %u at %p>",
				op->ob_refcnt, op);
		else if (op->ob_type->tp_print == NULL) {
			PyObject *s;
			if (flags & Py_PRINT_RAW)
				s = PyObject_Str(op);
			else
				s = PyObject_Repr(op);
			if (s == NULL)
				ret = -1;
			else {
				ret = PyObject_Print(s, fp, Py_PRINT_RAW);
			}
			Py_XDECREF(s);
		}
		else
			ret = (*op->ob_type->tp_print)(op, fp, flags);
	}
	if (ret == 0) {
		if (ferror(fp)) {
			PyErr_SetFromErrno(PyExc_IOError);
			clearerr(fp);
			ret = -1;
		}
	}
	return ret;
}
Exemple #5
0
static PyObject *
xx_bug(PyObject *self, PyObject *args)
{
    PyObject *list, *item;

    if (!PyArg_ParseTuple(args, "O:bug", &list))
        return NULL;

    item = PyList_GetItem(list, 0);
    /* Py_INCREF(item); */
    PyList_SetItem(list, 1, PyInt_FromLong(0L));
    PyObject_Print(item, stdout, 0);
    printf("\n");
    /* Py_DECREF(item); */

    Py_INCREF(Py_None);
    return Py_None;
}
Exemple #6
0
/* For debugging convenience.  See Misc/gdbinit for some useful gdb hooks */
void _PyObject_Dump(PyObject* op)
{
	if (op == NULL)
		fprintf(stderr, "NULL\n");
	else {
		fprintf(stderr, "object  : ");
		(void)PyObject_Print(op, stderr, 0);
		/* XXX(twouters) cast refcount to long until %zd is
		   universally available */
		fprintf(stderr, "\n"
			"type    : %s\n"
			"refcount: %ld\n"
			"address : %p\n",
			op->ob_type==NULL ? "NULL" : op->ob_type->tp_name,
			(long)op->ob_refcnt,
			op);
	}
}
Exemple #7
0
/* for debugging */
void PyC_ObSpit(const char *name, PyObject *var) {
	fprintf(stderr, "<%s> : ", name);
	if (var==NULL) {
		fprintf(stderr, "<NIL>");
	}
	else {
		PyObject_Print(var, stderr, 0);
		fprintf(stderr, " ref:%d ", (int)var->ob_refcnt);
		fprintf(stderr, " ptr:%p", (void *)var);
		
		fprintf(stderr, " type:");
		if(Py_TYPE(var))
			fprintf(stderr, "%s", Py_TYPE(var)->tp_name);
		else
			fprintf(stderr, "<NIL>");
	}
	fprintf(stderr, "\n");
}
static void
handle_system_exit(void)
{
	PyObject *exception, *value, *tb;
	int exitcode = 0;

	PyErr_Fetch(&exception, &value, &tb);
	if (Py_FlushLine())
		PyErr_Clear();
	fflush(stdout);
	if (value == NULL || value == Py_None)
		goto done;
	if (PyExceptionInstance_Check(value)) {
		/* The error code should be in the `code' attribute. */
		PyObject *code = PyObject_GetAttrString(value, "code");
		if (code) {
			Py_DECREF(value);
			value = code;
			if (value == Py_None)
				goto done;
		}
		/* If we failed to dig out the 'code' attribute,
		   just let the else clause below print the error. */
	}
	if (PyInt_Check(value))
		exitcode = (int)PyInt_AsLong(value);
	else {
		PyObject_Print(value, stderr, Py_PRINT_RAW);
		PySys_WriteStderr("\n");
		exitcode = 1;
	}
 done:
	/* Restore and clear the exception info, in order to properly decref
	 * the exception, value, and traceback.	 If we just exit instead,
	 * these leak, which confuses PYTHONDUMPREFS output, and may prevent
	 * some finalizers from running.
	 */
	PyErr_Restore(exception, value, tb);
	PyErr_Clear();
	Py_Exit(exitcode);
	/* NOTREACHED */
}
Exemple #9
0
int Validator_EndElement(PyObject *self)
{
  Context *context;
  int valid;

  if (!Validator_Check(self)) {
    PyErr_BadInternalCall();
    return -1;
  }

#ifdef DEBUG_VALIDATION
  fprintf(stderr, "Validator_EndElement()");
#endif

  context = Validator_Context(self);
  /* context may be NULL if we never encounter a declared element */
  if (context != NULL) {
#ifdef DEBUG_VALIDATION
    fprintf(stderr, " for ");
    if (context->element) {
      PyObject_Print(ElementType_GET_NAME(context->element), stderr, 0);
    } else {
      fprintf(stderr, "undeclared");
    }
    fprintf(stderr, " element\n");
#endif

    /* make sure that we are in the final state */
    valid = Validator_ValidateEvent(self, final_event);

    /* switch the active context to the following one */
    Validator_Context(self) = context->next;

    /* move this one to the free list */
    context->next = Validator_FreeContext(self);
    Validator_FreeContext(self) = context;
  } else {
    valid = 1;
  }

  return valid;
}
Exemple #10
0
int main(int argc, char **argv) {
	
	Py_Initialize();
	PyAutoC_Initialize();
	
	PyAutoStruct_Register(vector3);
	PyAutoStruct_RegisterMember(vector3, x, float);
	PyAutoStruct_RegisterMember(vector3, y, float);
	PyAutoStruct_RegisterMember(vector3, z, float);

	vector3 position = {1.0f, 2.11f, 3.16f};

	PyObject* y = PyAutoStruct_Get(vector3, &position, y);
	PyObject_Print(y, stdout, 0);
	Py_DECREF(y);
  
	PyAutoC_Finalize();
	Py_Finalize();
	
	return 0;
}
Exemple #11
0
static void check_args(int n, int m, int np, int nq,
                       PyArrayObject * beta,
                       PyArrayObject * y, int ldy,
                       PyArrayObject * x, int ldx,
                       PyArrayObject * we, int ldwe, int ld2we,
                       PyArrayObject * wd, int ldwd, int ld2wd,
                       PyArrayObject * ifixb, PyArrayObject * ifixx,
                       int ldifx, int job, int ndigit, double taufac,
                       double sstol, double partol, int maxit,
                       PyArrayObject * stpb, PyArrayObject * stpd,
                       int ldstpd, PyArrayObject * sclb,
                       PyArrayObject * scld, int ldscld,
                       PyArrayObject * work, int lwork,
                       PyArrayObject * iwork, int liwork, int info)
{
  PyObject *printdict;

  printdict =
    Py_BuildValue
    ("{s:i,s:i,s:i,s:i,s:O,s:O,s:i,s:O,s:i,s:O,s:i,s:i,s:O,s:i,s:i,s:O,s:O,s:i,s:i,s:i,s:d,s:d,s:d,s:i,s:O,s:O,s:i,s:O,s:O,s:i,s:O,s:i,s:O,s:i,s:i}",
     "n", n, "m", m, "np", np, "nq", nq, "beta", (PyObject *) beta, "y",
     (PyObject *) y, "ldy", ldy, "x", (PyObject *) x, "ldx", ldx, "we",
     (PyObject *) we, "ldwe", ldwe, "ld2we", ld2we, "wd", (PyObject *) wd,
     "ldwd", ldwd, "ld2wd", ld2wd, "ifixb", (PyObject *) ifixb, "ifixx",
     (PyObject *) ifixx, "ldifx", ldifx, "job", job, "ndigit", ndigit,
     "taufac", taufac, "sstol", sstol, "partol", partol, "maxit", maxit,
     "stpb", (PyObject *) stpb, "stpd", (PyObject *) stpd, "ldstpd", ldstpd,
     "sclb", (PyObject *) sclb, "scld", (PyObject *) scld, "ldscld", ldscld,
     "work", (PyObject *) work, "lwork", lwork, "iwork", (PyObject *) iwork,
     "liwork", liwork, "info", info);
  if (printdict == NULL)
    {
      PyErr_Print();
      return;
    }

  PyObject_Print(printdict, stdout, Py_PRINT_RAW);
  printf("\n");
  Py_XDECREF(printdict);
}
static void
t_bootstrap(void *boot_raw)
{
	struct bootstate *boot = (struct bootstate *) boot_raw;
	PyThreadState *tstate;
	PyObject *res;

	tstate = boot->tstate;
	tstate->thread_id = PyThread_get_thread_ident();
	_PyThreadState_Init(tstate);
	PyEval_AcquireThread(tstate);
	res = PyEval_CallObjectWithKeywords(
		boot->func, boot->args, boot->keyw);
	if (res == NULL) {
		if (PyErr_ExceptionMatches(PyExc_SystemExit))
			PyErr_Clear();
		else {
			PyObject *file;
			PySys_WriteStderr(
				"Unhandled exception in thread started by ");
			file = PySys_GetObject("stderr");
			if (file != NULL && file != Py_None)
				PyFile_WriteObject(boot->func, file, 0);
			else
				PyObject_Print(boot->func, stderr, 0);
			PySys_WriteStderr("\n");
			PyErr_PrintEx(0);
		}
	}
	else
		Py_DECREF(res);
	Py_DECREF(boot->func);
	Py_DECREF(boot->args);
	Py_XDECREF(boot->keyw);
	PyMem_DEL(boot_raw);
	PyThreadState_Clear(tstate);
	PyThreadState_DeleteCurrent();
	PyThread_exit_thread();
}
static int testPointerBeingFreed(void *ptr)
{
    // It is an error for a deleted pointer address to still be registered
    // in the BindingManager
    if (Shiboken::BindingManager::instance().hasWrapper(ptr)) {
        Shiboken::GilState state;

        SbkObject *wrapper = Shiboken::BindingManager::instance().retrieveWrapper(ptr);

        fprintf(stderr, "SbkObject still in binding map when deleted: ");
        PyObject_Print((PyObject*)wrapper, stderr, 0);
        fprintf(stderr, "\n");

#ifdef _WIN32
        DebugBreak();
#else
        assert(0);
#endif
        return FALSE;
    }

    return TRUE;
}
Exemple #14
0
static ExpatStatus
builder_Comment(void *userState, PyObject *data)
{
  ParserState *state = (ParserState *)userState;
  NodeObject *node;

#ifdef DEBUG_PARSER
  fprintf(stderr, "--- builder_Comment(data=");
  PyObject_Print(data, stderr, 0);
  fprintf(stderr, ")\n");
#endif

  if (state->comment_factory) {
    node = (NodeObject *)PyObject_CallFunctionObjArgs(state->comment_factory,
                                                      data, NULL);
    if (node == NULL)
      return EXPAT_STATUS_ERROR;
    if (!Text_Check(node)) {
      PyErr_Format(PyExc_TypeError,
                   "xml_comment_factory should return comment, not %s",
                   node->ob_type->tp_name);
      Py_DECREF(node);
      return EXPAT_STATUS_ERROR;
    }
  } else {
    node = (NodeObject *)Comment_New(data);
    if (node == NULL)
      return EXPAT_STATUS_ERROR;
  }

  /* ParserState_AddNode steals the reference to the new node */
  if (ParserState_AddNode(state, node) < 0) {
    Py_DECREF(node);
    return EXPAT_STATUS_ERROR;
  }
  return EXPAT_STATUS_OK;
}
Exemple #15
0
/* For debugging convenience. */
void _Node_Dump(char *msg, NodeObject *self)
{
  fprintf(stderr, "%s\n"
          "  node    : ", msg);
  if (self == NULL) {
    fprintf(stderr, "NULL\n");
  } else {
    PyObject_Print((PyObject *) self, stderr, 0);
    fprintf(stderr, "\n"
            "  type    : %s\n"
            "  refcount: %" PY_FORMAT_SIZE_T "d\n"
            "  GC refs:  %" PY_FORMAT_SIZE_T "d\n"
            "  parent  : %p\n",
            self->ob_type == NULL ? "NULL" : self->ob_type->tp_name,
            self->ob_refcnt,
            PyObject_IS_GC((PyObject *)self) ? _Py_AS_GC(self)->gc.gc_refs : 0,
            Node_GET_PARENT(self));
    if (Container_Check(self)) {
      fprintf(stderr, "  children: %" PY_FORMAT_SIZE_T "d\n",
              Container_GET_COUNT(self));
    }
  }
  fprintf(stderr, "----------------------\n");
}
Exemple #16
0
static PyObject *builder_parse(PyObject *inputSource, ParseFlags flags,
                               PyObject *entity_factory, int asEntity,
                               PyObject *namespaces, PyObject *rule_handler)
{
  ParserState *state;
  PyObject *result;
  int gc_enabled;
  ExpatStatus status;

#ifdef DEBUG_PARSER
  FILE *stream = PySys_GetFile("stderr", stderr);
  PySys_WriteStderr("builder_parse(source=");
  PyObject_Print(inputSource, stream, 0);
  PySys_WriteStderr(", flags=%d, entity_factory=", flags);
  PyObject_Print(entity_factory, stream, 0);
  PySys_WriteStderr(", asEntity=%d, namespaces=", asEntity);
  PyObject_Print(namespaces, stream, 0);
  PySys_WriteStderr("\n");
#endif
  state = ParserState_New(entity_factory);
  if (state == NULL)
    return NULL;

  state->reader = create_reader(state);
  if (state->reader == NULL) {
    ParserState_Del(state);
    return NULL;
  }

  if (rule_handler) {
    state->rule_matcher = RuleMatchObject_New(rule_handler);
  }

  /* Disable GC (if enabled) while building the DOM tree */
  result = PyObject_Call(gc_isenabled_function, empty_args_tuple, NULL);
  if (result == NULL)
    goto finally;
  gc_enabled = PyObject_IsTrue(result);
  Py_DECREF(result);
  if (gc_enabled) {
    result = PyObject_Call(gc_disable_function, empty_args_tuple, NULL);
    if (result == NULL)
      goto finally;
    Py_DECREF(result);
  }

  Expat_SetValidation(state->reader, flags == PARSE_FLAGS_VALIDATE);
  Expat_SetParamEntityParsing(state->reader, flags != PARSE_FLAGS_STANDALONE);

  if (asEntity)
    status = ExpatReader_ParseEntity(state->reader, inputSource, namespaces);
  else
    status = ExpatReader_Parse(state->reader, inputSource);

  if (gc_enabled) {
    result = PyObject_Call(gc_enable_function, empty_args_tuple, NULL);
    if (result == NULL)
      goto finally;
    Py_DECREF(result);
  }

  /* save off the created document */
  if (status == EXPAT_STATUS_OK)
    result = (PyObject *)state->owner_document;
  else
    result = NULL;

finally:
  ExpatReader_Del(state->reader);
  ParserState_Del(state);
#ifdef DEBUG_PARSER
  PySys_WriteStderr("builder_parse() => ");
  PyObject_Print(result, PySys_GetFile("stderr", stderr), 0);
  PySys_WriteStderr("\n");
#endif
  return result;
}
static PyObject *
newSplitter(PyObject *modinfo, PyObject *args,PyObject *keywds)
{
    Splitter *self=NULL;
    PyObject *doc=NULL, *unicodedoc=NULL,*synstop=NULL;
    char *encoding = "latin1";
    int index_numbers = 0;
    int max_len=64;
    int single_char = 0;
    int casefolding=1;

    if (! (PyArg_ParseTupleAndKeywords(args,keywds,"O|Osiiii",splitter_args,&doc,&synstop,&encoding,&index_numbers,&single_char,&max_len,&casefolding))) return NULL;

#ifdef DEBUG
    puts("got text");
    PyObject_Print(doc,stdout,0);
    fflush(stdout);
#endif

    if (index_numbers<0 || index_numbers>1) {
        PyErr_SetString(PyExc_ValueError,"indexnumbers must be 0 or 1");
        return NULL;
    }

    if (casefolding<0 || casefolding>1) {
        PyErr_SetString(PyExc_ValueError,"casefolding must be 0 or 1");
        return NULL;
    }

    if (single_char<0 || single_char>1) {
        PyErr_SetString(PyExc_ValueError,"singlechar must be 0 or 1");
        return NULL;
    }

    if (max_len<1 || max_len>128) {
        PyErr_SetString(PyExc_ValueError,"maxlen must be between 1 and 128");
        return NULL;
    }

    if (PyString_Check(doc)) {

        unicodedoc = PyUnicode_FromEncodedObject(doc,encoding,"strict");
        if (unicodedoc ==NULL) {
            PyErr_SetString(PyExc_UnicodeError, "Problem converting encoded string");
            return NULL;
        }

    } else if( PyUnicode_Check(doc)) {
        unicodedoc = doc;
        Py_INCREF(unicodedoc);

    } else {
        PyErr_SetString(PyExc_TypeError, "first argument is neither string nor unicode.");
        return NULL;
    }

    if (! (self = PyObject_NEW(Splitter, &SplitterType))) return NULL;

    if (synstop) {
        self->synstop = synstop;
        Py_INCREF(synstop);
    } else  self->synstop=NULL;

    self->index_numbers      = index_numbers;
    self->max_len            = max_len;
    self->allow_single_chars = single_char;
    self->casefolding        = casefolding;

    if ((splitUnicodeString(self,(PyUnicodeObject *)unicodedoc)) < 0)
      goto err;

    Py_DECREF(unicodedoc);
    return (PyObject*)self;

err:
    Py_DECREF(self);
    Py_DECREF(unicodedoc);

    return NULL;
}
Exemple #18
0
static ExpatStatus
builder_StartElement(void *userState, ExpatName *name,
                     ExpatAttribute atts[], size_t natts)
{
  ParserState *state = (ParserState *)userState;
  PyObject *attribute_factory=NULL;
  ElementObject *elem=NULL;
  Py_ssize_t i;
  PyObject *key, *value;

#ifdef DEBUG_PARSER
  fprintf(stderr, "--- builder_StartElement(name=");
  PyObject_Print(name->qualifiedName, stderr, 0);
  fprintf(stderr, ", atts={");
  for (i = 0; i < natts; i++) {
    if (i > 0) {
      fprintf(stderr, ", ");
    }
    PyObject_Print(atts[i].qualifiedName, stderr, 0);
    fprintf(stderr, ", ");
    PyObject_Print(atts[i].value, stderr, 0);
  }
  fprintf(stderr, "})\n");
#endif

  if (state->element_factory) {
    elem = (ElementObject *)
      PyObject_CallFunctionObjArgs(state->element_factory, name->namespaceURI,
                                   name->qualifiedName, NULL);
    if (elem == NULL)
      return EXPAT_STATUS_ERROR;
    if (!Element_Check(elem)) {
      PyErr_Format(PyExc_TypeError,
                   "xml_element_factory should return element, not %s",
                   elem->ob_type->tp_name);
      Py_DECREF(elem);
      return EXPAT_STATUS_ERROR;
    }
  } else {
    elem = Element_New(name->namespaceURI, name->qualifiedName,
                       name->localName);
    if (elem == NULL)
      return EXPAT_STATUS_ERROR;
  }

  /** namespaces *******************************************************/

  /* new_namespaces is a dictionary where key is the prefix and value
   * is the uri.
   */
  if (((PyDictObject *)state->new_namespaces)->ma_used) {
    i = 0;
    while (PyDict_Next(state->new_namespaces, &i, &key, &value)) {
      NamespaceObject *nsnode = Element_AddNamespace(elem, key, value);
      if (nsnode == NULL) {
        Py_DECREF(elem);
        Py_XDECREF(attribute_factory);
        return EXPAT_STATUS_ERROR;
      }
      Py_DECREF(nsnode);
    }
    /* make sure children don't set these namespaces */
    PyDict_Clear(state->new_namespaces);
  }

  /** attributes *******************************************************/

  for (i = 0; i < (Py_ssize_t)natts; i++) {
    AttrObject *attr = Element_AddAttribute(elem, atts[i].namespaceURI,
                                            atts[i].qualifiedName,
                                            atts[i].localName, atts[i].value);
    if (attr == NULL) {
      Py_DECREF(elem);
      return EXPAT_STATUS_ERROR;
    }
    /* save the attribute type as well (for getElementById) */
    Attr_SET_TYPE(attr, atts[i].type);
    Py_DECREF(attr);
  }

  /* Check for rule matching */
  if (state->rule_matcher) {
    if (RuleMatch_StartElement(state->rule_matcher,(PyObject *) elem,name,atts,natts) < 0) {
      Py_DECREF(elem);
      return EXPAT_STATUS_ERROR;
    }
  }

  /* save states on the context */
  if (ParserState_AddContext(state, (NodeObject *) elem) == NULL) {
    Py_DECREF(elem);
    return EXPAT_STATUS_ERROR;
  }
  return EXPAT_STATUS_OK;
}
Exemple #19
0
static PyObject *
eval_frame(PyFrameObject *f)
{
	LOG("> eval_frame\n"); {
	PyObject **stack_pointer; /* Next free slot in value stack */
	register unsigned char *next_instr;
	register int opcode=0;	/* Current opcode */
	register int oparg=0;	/* Current opcode argument, if any */
	register enum why_code why; /* Reason for block stack unwind */
	register int err;	/* Error status -- nonzero if error */
	register PyObject *x;	/* Result object -- NULL if error */
	register PyObject *t, *u, *v;	/* Temporary objects popped off stack */
	register PyObject *w;
	register PyObject **fastlocals, **freevars;
	PyObject *retval = NULL;	/* Return value */
	PyThreadState *tstate = PyThreadState_GET();
	PyCodeObject *co;

	unsigned char *first_instr;
	PyObject *names;
	PyObject *consts;

/* Tuple access macros */

#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))

/* Code access macros */

#define INSTR_OFFSET()	(next_instr - first_instr)
#define NEXTOP()	(*next_instr++)
#define NEXTARG()	(next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
#define JUMPTO(x)	(next_instr = first_instr + (x))
#define JUMPBY(x)	(next_instr += (x))

/* OpCode prediction macros
	Some opcodes tend to come in pairs thus making it possible to predict
	the second code when the first is run.  For example, COMPARE_OP is often
	followed by JUMP_IF_FALSE or JUMP_IF_TRUE.  And, those opcodes are often
	followed by a POP_TOP.

	Verifying the prediction costs a single high-speed test of register
	variable against a constant.  If the pairing was good, then the
	processor has a high likelihood of making its own successful branch
	prediction which results in a nearly zero overhead transition to the
	next opcode.

	A successful prediction saves a trip through the eval-loop including
	its two unpredictable branches, the HASARG test and the switch-case.
*/

#define PREDICT(op)		if (*next_instr == op) goto PRED_##op
#define PREDICTED(op)		PRED_##op: next_instr++
#define PREDICTED_WITH_ARG(op)	PRED_##op: oparg = (next_instr[2]<<8) + \
				next_instr[1]; next_instr += 3

/* Stack manipulation macros */

#define STACK_LEVEL()	(stack_pointer - f->f_valuestack)
#define EMPTY()		(STACK_LEVEL() == 0)
#define TOP()		(stack_pointer[-1])
#define SECOND()	(stack_pointer[-2])
#define THIRD() 	(stack_pointer[-3])
#define FOURTH()	(stack_pointer[-4])
#define SET_TOP(v)	(stack_pointer[-1] = (v))
#define SET_SECOND(v)	(stack_pointer[-2] = (v))
#define SET_THIRD(v)	(stack_pointer[-3] = (v))
#define SET_FOURTH(v)	(stack_pointer[-4] = (v))
#define BASIC_STACKADJ(n)	(stack_pointer += n)
#define BASIC_PUSH(v)	(*stack_pointer++ = (v))
#define BASIC_POP()	(*--stack_pointer)

#define PUSH(v)		BASIC_PUSH(v)
#define POP()		BASIC_POP()
#define STACKADJ(n)	BASIC_STACKADJ(n)

/* Local variable macros */

#define GETLOCAL(i)	(fastlocals[i])

/* The SETLOCAL() macro must not DECREF the local variable in-place and
   then store the new value; it must copy the old value to a temporary
   value, then store the new value, and then DECREF the temporary value.
   This is because it is possible that during the DECREF the frame is
   accessed by other code (e.g. a __del__ method or gc.collect()) and the
   variable would be pointing to already-freed memory. */
#define SETLOCAL(i, value)	do { PyObject *tmp = GETLOCAL(i); \
				     GETLOCAL(i) = value; \
                                     Py_XDECREF(tmp); } while (0)

/* Start of code */

	if (f == NULL)
		return NULL;

	/* push frame */
	if (++tstate->recursion_depth > recursion_limit) {
		--tstate->recursion_depth;
		/* ERROR */
		tstate->frame = f->f_back;
		return NULL;
	}

	tstate->frame = f;

	/* tracing elided */

	co = f->f_code;
	names = co->co_names;
	consts = co->co_consts;
	fastlocals = f->f_localsplus;
	freevars = f->f_localsplus + f->f_nlocals;

	_PyCode_GETCODEPTR(co, &first_instr);

	/* An explanation is in order for the next line.

	   f->f_lasti now refers to the index of the last instruction
	   executed.  You might think this was obvious from the name, but
	   this wasn't always true before 2.3!  PyFrame_New now sets
	   f->f_lasti to -1 (i.e. the index *before* the first instruction)
	   and YIELD_VALUE doesn't fiddle with f_lasti any more.  So this
	   does work.  Promise. */
	next_instr = first_instr + f->f_lasti + 1;
	stack_pointer = f->f_stacktop;

	f->f_stacktop = NULL;	/* remains NULL unless yield suspends frame */

	why = WHY_NOT;
	err = 0;
	x = Py_None;	/* Not a reference, just anything non-NULL */
	w = NULL;

	for (;;) {

		/* Do periodic things.  Doing this every time through
		   the loop would add too much overhead, so we do it
		   only every Nth instruction.  We also do it if
		   ``things_to_do'' is set, i.e. when an asynchronous
		   event needs attention (e.g. a signal handler or
		   async I/O handler); see Py_AddPendingCall() and
		   Py_MakePendingCalls() above. */

		if (--_Py_Ticker < 0) {
			/* @@@ check for SETUP_FINALLY elided */

			_Py_Ticker = _Py_CheckInterval;
			tstate->tick_counter++;
			if (things_to_do) {
				if (Py_MakePendingCalls() < 0) {
					why = WHY_EXCEPTION;
					goto on_error;
				}
			}
		}

	fast_next_opcode:
		f->f_lasti = INSTR_OFFSET();

		/* Extract opcode and argument */

		opcode = NEXTOP();
		if (HAS_ARG(opcode))
			oparg = NEXTARG();

		/* Main switch on opcode */

		switch (opcode) {

		/* BEWARE!
		   It is essential that any operation that fails sets either
		   x to NULL, err to nonzero, or why to anything but WHY_NOT,
		   and that no operation that succeeds does this! */

		/* case STOP_CODE: this is an error! */

		case LOAD_FAST:
			x = GETLOCAL(oparg);
			if (x != NULL) {
				Py_INCREF(x);
				PUSH(x);
				goto fast_next_opcode;
			}
			/* ERROR? */
			break;

                case STORE_FAST:
                        v = POP();
                        SETLOCAL(oparg, v);
                        continue;

		case LOAD_CONST:
			x = GETITEM(consts, oparg);
			Py_INCREF(x);
			PUSH(x);
			goto fast_next_opcode;

		PREDICTED(POP_TOP);
		case POP_TOP:
			v = POP();
			Py_DECREF(v);
			goto fast_next_opcode;

		case UNARY_NOT:
			v = TOP();
			err = PyObject_IsTrue(v);
			Py_DECREF(v);
			if (err == 0) {
				Py_INCREF(Py_True);
				SET_TOP(Py_True);
				continue;
			}
			else if (err > 0) {
				Py_INCREF(Py_False);
				SET_TOP(Py_False);
				err = 0;
				continue;
			}
			STACKADJ(-1);
			break;

		case BINARY_MODULO:
			w = POP();
			v = TOP();
			x = PyNumber_Remainder(v, w);
			Py_DECREF(v);
			Py_DECREF(w);
			SET_TOP(x);
			if (x != NULL) continue;
			break;
			
		case BINARY_ADD:
			w = POP();
			v = TOP();
			if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
				/* INLINE: int + int */
				register long a, b, i;
				a = PyInt_AS_LONG(v);
				b = PyInt_AS_LONG(w);
				i = a + b;
				if ((i^a) < 0 && (i^b) < 0)
					goto slow_add;
				x = PyInt_FromLong(i);
			}
			else {
			  slow_add:
				Py_FatalError("slow add not supported.");
			}
			Py_DECREF(v);
			Py_DECREF(w);
			SET_TOP(x);
			if (x != NULL) continue;
			break;

                case STORE_SLICE+0:
                case STORE_SLICE+1:
                case STORE_SLICE+2:
                case STORE_SLICE+3:
                        if ((opcode-STORE_SLICE) & 2)
                                w = POP();
                        else
                                w = NULL;
                        if ((opcode-STORE_SLICE) & 1)
                                v = POP();
                        else
                                v = NULL;
                        u = POP();
                        t = POP();
                        err = assign_slice(u, v, w, t); /* u[v:w] = t */
                        Py_DECREF(t);
                        Py_DECREF(u);
                        Py_XDECREF(v);
                        Py_XDECREF(w);
                        if (err == 0) continue;
                        break;

                case STORE_SUBSCR:
                        w = POP();
                        v = POP();
                        u = POP();
                        /* v[w] = u */
                        err = PyObject_SetItem(v, w, u);
                        Py_DECREF(u);
                        Py_DECREF(v);
                        Py_DECREF(w);
                        if (err == 0) continue;
                        break;

                case BINARY_SUBSCR:
                        w = POP();
                        v = TOP();
                        if (PyList_CheckExact(v) && PyInt_CheckExact(w)) {
                                /* INLINE: list[int] */
                                long i = PyInt_AsLong(w);
                                if (i < 0)
                                        i += PyList_GET_SIZE(v);
                                if (i < 0 ||
                                    i >= PyList_GET_SIZE(v)) {
                                        /* ERROR */
                                        printf("list index out of range\n");
                                        x = NULL;
                                }
                                else {
                                        x = PyList_GET_ITEM(v, i);
                                        Py_INCREF(x);
                                }
                        }
                        else
                                x = PyObject_GetItem(v, w);
                        Py_DECREF(v);
                        Py_DECREF(w);
                        SET_TOP(x);
                        if (x != NULL) continue;
                        break;

		case BINARY_AND:
			w = POP();
			v = TOP();
			x = PyNumber_And(v, w);
			Py_DECREF(v);
			Py_DECREF(w);
			SET_TOP(x);
			if (x != NULL) continue;
			break;

		case PRINT_ITEM:
			v = POP();

			PyObject_Print(v);
			Py_DECREF(v);
			break;

		case PRINT_NEWLINE:
			printf("\n");
			break;

		case RETURN_VALUE:
			retval = POP();
			why = WHY_RETURN;
			break;

		case POP_BLOCK:
			{
				PyTryBlock *b = PyFrame_BlockPop(f);
				while (STACK_LEVEL() > b->b_level) {
					v = POP();
					Py_DECREF(v);
				}
			}
			break;

		case STORE_NAME:
			w = GETITEM(names, oparg);
			v = POP();
			if ((x = f->f_locals) == NULL) {
				/* ERROR */
				printf("STORE_NAME ERROR\n");
				break;
			}
			err = PyDict_SetItem(x, w, v);
			Py_DECREF(v);
			break;

		case LOAD_NAME:
			w = GETITEM(names, oparg);
			if ((x = f->f_locals) == NULL) {
				/* ERROR */
				printf("LOAD_NAME ERROR\n");
				break;
			}
			x = PyDict_GetItem(x, w);
			if (x == NULL) {
				x = PyDict_GetItem(f->f_globals, w);
				if (x == NULL) {
					x = PyDict_GetItem(f->f_builtins, w);
					if (x == NULL) {
						printf("can't find %s\n", ((PyStringObject *)w)->ob_sval);
						/* format_exc_check_arg */
						break;
					}
				}
			}
			Py_INCREF(x);
			PUSH(x);
			break;
			
		case LOAD_GLOBAL:
			w = GETITEM(names, oparg);
			if (PyString_CheckExact(w)) {
				/* Inline the PyDict_GetItem() calls.
				   WARNING: this is an extreme speed hack.
				   Do not try this at home. */
				long hash = ((PyStringObject *)w)->ob_shash;
				if (hash != -1) {
					PyDictObject *d;
					d = (PyDictObject *)(f->f_globals);
					x = d->ma_lookup(d, w, hash)->me_value;
					if (x != NULL) {
						Py_INCREF(x);
						PUSH(x);
						continue;
					}
					d = (PyDictObject *)(f->f_builtins);
					x = d->ma_lookup(d, w, hash)->me_value;
					if (x != NULL) {
						Py_INCREF(x);
						PUSH(x);
						continue;
					}
					goto load_global_error;
				}
			}
			/* This is the un-inlined version of the code above */
			x = PyDict_GetItem(f->f_globals, w);
			if (x == NULL) {
				x = PyDict_GetItem(f->f_builtins, w);
				if (x == NULL) {
				  load_global_error:
					printf("LOAD_GLOBAL ERROR %s", ((PyStringObject *)w)->ob_sval);
					break;
				}
			}
			Py_INCREF(x);
			PUSH(x);
			break;

		case LOAD_ATTR:
			w = GETITEM(names, oparg);
			v = TOP();
			x = PyObject_GetAttr(v, w);
			Py_DECREF(v);
			SET_TOP(x);
			if (x != NULL) continue;
			break;

		case IMPORT_NAME:
			w = GETITEM(names, oparg);
			x = PyDict_GetItemString(f->f_builtins, "__import__");
			if (x == NULL) {
				printf("__import__ not found");
				break;
			}
			u = TOP();
			w = Py_BuildValue("(O)", w);
			Py_DECREF(u);
			if (w == NULL) {
				u = POP();
				x = NULL;
				break;
			}
			x = PyEval_CallObject(x, w);
			Py_DECREF(w);
			SET_TOP(x);
			if (x != NULL) continue;
			break;

		case JUMP_FORWARD:
			JUMPBY(oparg);
			goto fast_next_opcode;

		PREDICTED_WITH_ARG(JUMP_IF_FALSE);
		case JUMP_IF_FALSE:
			w = TOP();
			if (w == Py_True) {
				PREDICT(POP_TOP);
				goto fast_next_opcode;
			}
			if (w == Py_False) {
				JUMPBY(oparg);
				goto fast_next_opcode;
			}
			err = PyObject_IsTrue(w);
			if (err > 0)
				err = 0;
			else if (err == 0)
				JUMPBY(oparg);
			else
				break;
			continue;
			
		case JUMP_ABSOLUTE:
			JUMPTO(oparg);
			continue;

		case SETUP_LOOP:
			PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg, STACK_LEVEL());
			continue;

		case CALL_FUNCTION:
			x = call_function(&stack_pointer, oparg);
			PUSH(x);
			if (x != NULL)
				continue;
			break;
			
		case MAKE_FUNCTION:
			v = POP(); /* code object */
			x = PyFunction_New(v, f->f_globals);
			Py_DECREF(v);
			/* XXX Maybe this should be a separate opcode? */
			if (x != NULL && oparg > 0) {
				v = PyTuple_New(oparg);
				if (v == NULL) {
					Py_DECREF(x);
					x = NULL;
			break;
				}
				while (--oparg >= 0) {
					w = POP();
					PyTuple_SET_ITEM(v, oparg, w);
				}
				err = PyFunction_SetDefaults(x, v);
				Py_DECREF(v);
			}
			PUSH(x);
			break;
			
		case SET_LINENO:
			break;

		default:
			printf("opcode: %d\n", opcode);
			Py_FatalError("unknown opcode");
		} /* switch */

	  on_error:
		
		if (why == WHY_NOT) {
			if (err == 0 && x != NULL) {
					continue; /* Normal, fast path */
			}
			why = WHY_EXCEPTION;
			x = Py_None;
			err = 0;
		}

		/* End the loop if we still have an error (or return) */

		if (why != WHY_NOT)
			break;

	} /* main loop */

	if (why != WHY_YIELD) {
		/* Pop remaining stack entries -- but when yielding */
		while (!EMPTY()) {
			v = POP();
			Py_XDECREF(v);
		}
	}

	if (why != WHY_RETURN && why != WHY_YIELD)
		retval = NULL;

	/* pop frame */
	--tstate->recursion_depth;
	tstate->frame = f->f_back;

	return retval;
}}
void
PyErr_PrintEx(int set_sys_last_vars)
{
	int err = 0;
	PyObject *exception, *v, *tb, *f;
	PyErr_Fetch(&exception, &v, &tb);
	PyErr_NormalizeException(&exception, &v, &tb);

	if (exception == NULL)
		return;

	if (PyErr_GivenExceptionMatches(exception, PyExc_SystemExit)) {
		if (Py_FlushLine())
			PyErr_Clear();
		fflush(stdout);
		if (v == NULL || v == Py_None)
			Py_Exit(0);
		if (PyInstance_Check(v)) {
			/* we expect the error code to be store in the
			   `code' attribute
			*/
			PyObject *code = PyObject_GetAttrString(v, "code");
			if (code) {
				Py_DECREF(v);
				v = code;
				if (v == Py_None)
					Py_Exit(0);
			}
			/* if we failed to dig out the "code" attribute,
			   then just let the else clause below print the
			   error
			*/
		}
		if (PyInt_Check(v))
			Py_Exit((int)PyInt_AsLong(v));
		else {
			/* OK to use real stderr here */
			PyObject_Print(v, stderr, Py_PRINT_RAW);
			fprintf(stderr, "\n");
			Py_Exit(1);
		}
	}
	if (set_sys_last_vars) {
		PySys_SetObject("last_type", exception);
		PySys_SetObject("last_value", v);
		PySys_SetObject("last_traceback", tb);
	}
	f = PySys_GetObject("stderr");
	if (f == NULL)
		fprintf(stderr, "lost sys.stderr\n");
	else {
		if (Py_FlushLine())
			PyErr_Clear();
		fflush(stdout);
		err = PyTraceBack_Print(tb, f);
		if (err == 0 &&
		    PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError))
		{
			PyObject *message;
			char *filename, *text;
			int lineno, offset;
			if (!parse_syntax_error(v, &message, &filename,
						&lineno, &offset, &text))
				PyErr_Clear();
			else {
				char buf[10];
				PyFile_WriteString("  File \"", f);
				if (filename == NULL)
					PyFile_WriteString("<string>", f);
				else
					PyFile_WriteString(filename, f);
				PyFile_WriteString("\", line ", f);
				sprintf(buf, "%d", lineno);
				PyFile_WriteString(buf, f);
				PyFile_WriteString("\n", f);
				if (text != NULL) {
					char *nl;
					if (offset > 0 &&
					    offset == (int)strlen(text))
						offset--;
					for (;;) {
						nl = strchr(text, '\n');
						if (nl == NULL ||
						    nl-text >= offset)
							break;
						offset -= (nl+1-text);
						text = nl+1;
					}
					while (*text == ' ' || *text == '\t') {
						text++;
						offset--;
					}
					PyFile_WriteString("    ", f);
					PyFile_WriteString(text, f);
					if (*text == '\0' ||
					    text[strlen(text)-1] != '\n')
						PyFile_WriteString("\n", f);
					PyFile_WriteString("    ", f);
					offset--;
					while (offset > 0) {
						PyFile_WriteString(" ", f);
						offset--;
					}
					PyFile_WriteString("^\n", f);
				}
				Py_INCREF(message);
				Py_DECREF(v);
				v = message;
				/* Can't be bothered to check all those
				   PyFile_WriteString() calls */
				if (PyErr_Occurred())
					err = -1;
			}
		}
		if (err) {
			/* Don't do anything else */
		}
		else if (PyClass_Check(exception)) {
			PyClassObject* exc = (PyClassObject*)exception;
			PyObject* className = exc->cl_name;
			PyObject* moduleName =
			      PyDict_GetItemString(exc->cl_dict, "__module__");

			if (moduleName == NULL)
				err = PyFile_WriteString("<unknown>", f);
			else {
				char* modstr = PyString_AsString(moduleName);
				if (modstr && strcmp(modstr, "exceptions")) 
				{
					err = PyFile_WriteString(modstr, f);
					err += PyFile_WriteString(".", f);
				}
			}
			if (err == 0) {
				if (className == NULL)
				      err = PyFile_WriteString("<unknown>", f);
				else
				      err = PyFile_WriteObject(className, f,
							       Py_PRINT_RAW);
			}
		}
		else
			err = PyFile_WriteObject(exception, f, Py_PRINT_RAW);
		if (err == 0) {
			if (v != NULL && v != Py_None) {
				PyObject *s = PyObject_Str(v);
				/* only print colon if the str() of the
				   object is not the empty string
				*/
				if (s == NULL)
					err = -1;
				else if (!PyString_Check(s) ||
					 PyString_GET_SIZE(s) != 0)
					err = PyFile_WriteString(": ", f);
				if (err == 0)
				  err = PyFile_WriteObject(s, f, Py_PRINT_RAW);
				Py_XDECREF(s);
			}
		}
		if (err == 0)
			err = PyFile_WriteString("\n", f);
	}
	Py_XDECREF(exception);
	Py_XDECREF(v);
	Py_XDECREF(tb);
	/* If an error happened here, don't show it.
	   XXX This is wrong, but too many callers rely on this behavior. */
	if (err != 0)
		PyErr_Clear();
}
Exemple #21
0
static void _build_translations_cache(PyObject *py_messages, const char *locale)
{
	PyObject *uuid, *uuid_dict;
	Py_ssize_t pos = 0;
	char *language = NULL, *language_country = NULL, *language_variant = NULL;

	/* For each py dict, we'll search for full locale, then language+country, then language+variant,
	 * then only language keys... */
	BLT_lang_locale_explode(locale, &language, NULL, NULL, &language_country, &language_variant);

	/* Clear the cached ghash if needed, and create a new one. */
	_clear_translations_cache();
	_translations_cache = BLI_ghash_new(_ghashutil_keyhash, _ghashutil_keycmp, __func__);

	/* Iterate over all py dicts. */
	while (PyDict_Next(py_messages, &pos, &uuid, &uuid_dict)) {
		PyObject *lang_dict;

#if 0
		PyObject_Print(uuid_dict, stdout, 0);
		printf("\n");
#endif

		/* Try to get first complete locale, then language+country, then language+variant, then only language */
		lang_dict = PyDict_GetItemString(uuid_dict, locale);
		if (!lang_dict && language_country) {
			lang_dict = PyDict_GetItemString(uuid_dict, language_country);
			locale = language_country;
		}
		if (!lang_dict && language_variant) {
			lang_dict = PyDict_GetItemString(uuid_dict, language_variant);
			locale = language_variant;
		}
		if (!lang_dict && language) {
			lang_dict = PyDict_GetItemString(uuid_dict, language);
			locale = language;
		}

		if (lang_dict) {
			PyObject *pykey, *trans;
			Py_ssize_t ppos = 0;

			if (!PyDict_Check(lang_dict)) {
				printf("WARNING! In translations' dict of \"");
				PyObject_Print(uuid, stdout, Py_PRINT_RAW);
				printf("\":\n");
				printf("    Each language key must have a dictionary as value, \"%s\" is not valid, skipping: ",
				       locale);
				PyObject_Print(lang_dict, stdout, Py_PRINT_RAW);
				printf("\n");
				continue;
			}

			/* Iterate over all translations of the found language dict, and populate our ghash cache. */
			while (PyDict_Next(lang_dict, &ppos, &pykey, &trans)) {
				const char *msgctxt = NULL, *msgid = NULL;
				bool invalid_key = false;

				if ((PyTuple_CheckExact(pykey) == false) || (PyTuple_GET_SIZE(pykey) != 2)) {
					invalid_key = true;
				}
				else {
					PyObject *tmp = PyTuple_GET_ITEM(pykey, 0);
					if (tmp == Py_None) {
						msgctxt = BLT_I18NCONTEXT_DEFAULT_BPYRNA;
					}
					else if (PyUnicode_Check(tmp)) {
						msgctxt = _PyUnicode_AsString(tmp);
					}
					else {
						invalid_key = true;
					}

					tmp = PyTuple_GET_ITEM(pykey, 1);
					if (PyUnicode_Check(tmp)) {
						msgid = _PyUnicode_AsString(tmp);
					}
					else {
						invalid_key = true;
					}
				}

				if (invalid_key) {
					printf("WARNING! In translations' dict of \"");
					PyObject_Print(uuid, stdout, Py_PRINT_RAW);
					printf("\", %s language:\n", locale);
					printf("    Keys must be tuples of (msgctxt [string or None], msgid [string]), "
					       "this one is not valid, skipping: ");
					PyObject_Print(pykey, stdout, Py_PRINT_RAW);
					printf("\n");
					continue;
				}
				if (PyUnicode_Check(trans) == false) {
					printf("WARNING! In translations' dict of \"");
					PyObject_Print(uuid, stdout, Py_PRINT_RAW);
					printf("\":\n");
					printf("    Values must be strings, this one is not valid, skipping: ");
					PyObject_Print(trans, stdout, Py_PRINT_RAW);
					printf("\n");
					continue;
				}

				/* Do not overwrite existing keys! */
				if (BPY_app_translations_py_pgettext(msgctxt, msgid) == msgid) {
					GHashKey *key = _ghashutil_keyalloc(msgctxt, msgid);
					BLI_ghash_insert(_translations_cache, key, BLI_strdup(_PyUnicode_AsString(trans)));
				}
			}
		}
	}

	/* Clean up! */
	MEM_SAFE_FREE(language);
	MEM_SAFE_FREE(language_country);
	MEM_SAFE_FREE(language_variant);
}
Exemple #22
0
static int
_same_vals_helper(PyObject *v1, PyObject *v2)
{
    PyTypeObject *typ1, *typ2;
    if (v1 == v2) return 0;   // 0 -> items are equal
    typ1 = v1->ob_type;
    typ2 = v2->ob_type;
    if (typ1 != typ2) return 1;
    if (typ1 == &PyDict_Type) {
        PyObject *key;
        PyObject *value;
        XXX_Py_ssize_t pos = 0;
        
        if (PyDict_Size(v1) != PyDict_Size(v2)) {
            return 1;
        }
        while (PyDict_Next(v1, &pos, &key, &value)) {
		    // note: when compiling the above line I get the following warning, hopefully harmless:
			// samevalshelp.c:49: warning: passing argument 2 of ‘PyDict_Next’ from incompatible pointer type
			// [bruce 090206, compiling on Mac OS 10.5.6, pyrexc version 0.9.6.4]
            PyObject *value2 = PyDict_GetItem(v2, key);
            if (value2 == NULL) {
                return 1;
            }
            if (_same_vals_helper(value, value2)) {
                return 1;
            }
        }
        return 0;
    } else if (typ1 == &PyList_Type) {
        int i, n;

        n = PyList_Size(v1);
        if (n != PyList_Size(v2)) {
            return 1;
        }
        for (i = 0; i < n; i++)
            if (_same_vals_helper(PyList_GetItem(v1, i),
                                 PyList_GetItem(v2, i)))
                return 1;
        return 0;
    } else if (typ1 == &PyTuple_Type) {
        int i, n;

        n = PyTuple_Size(v1);
        if (n != PyTuple_Size(v2)) {
            return 1;
        }
        for (i = 0; i < n; i++)
            if (_same_vals_helper(PyTuple_GetItem(v1, i),
                                 PyTuple_GetItem(v2, i)))
                return 1;
        return 0;
    } else if (arrayType != NULL && typ1 == arrayType) {
        PyArrayObject *x = (PyArrayObject *) v1;
        PyArrayObject *y = (PyArrayObject *) v2;
        int i;
        int elementSize;
        int *indices;
        int topDimension;
        char *xdata;
        char *ydata;
        int objectCompare = 0;

        // do all quick rejects first (no loops)
        if (x->nd != y->nd) {
            // number of dimensions doesn't match
            return 1;
            // note that a (1 x X) array can never equal a single
            // dimensional array of length X.
        }
        if (x->descr->type_num != y->descr->type_num) {
            // type of elements doesn't match
            return 1;
        }
        if (x->descr->type_num == PyArray_OBJECT) {
            objectCompare = 1;
        }
        elementSize = x->descr->elsize;
        if (elementSize != y->descr->elsize) {
            // size of elements doesn't match (shouldn't happen if
            // types match!)
            return 1;
        }
        for (i = x->nd - 1; i >= 0; i--) {
            if (x->dimensions[i] != y->dimensions[i])
                // shapes don't match
                return 1;
        }
        // we do a lot of these, so handle them early
        if (x->nd == 1 && !objectCompare && x->strides[0]==elementSize && y->strides[0]==elementSize) {
            // contiguous one dimensional array of non-objects
            return memcmp(x->data, y->data, elementSize * x->dimensions[0]) ? 1 : 0;
        }
        if (x->nd == 0) {
            // scalar, just compare one element
            if (objectCompare) {
                return _same_vals_helper(*(PyObject **)x->data, *(PyObject **)y->data);
            } else {
                return memcmp(x->data, y->data, elementSize) ? 1 : 0;
            }
        }
        // If we decide we can't do alloca() for some reason, we can
        // either have a fixed maximum dimensionality, or use alloc
        // and free.
        indices = (int *)alloca(sizeof(int) * x->nd);
        for (i = x->nd - 1; i >= 0; i--) {
            indices[i] = 0;
        }
        topDimension = x->dimensions[0];
        while (indices[0] < topDimension) {
            xdata = x->data;
            ydata = y->data;
            for (i = 0; i < x->nd; i++) {
                xdata += indices[i] * x->strides[i];
                ydata += indices[i] * y->strides[i];
            }
            if (objectCompare) {
                if (_same_vals_helper(*(PyObject **)xdata, *(PyObject **)ydata)) {
                    return 1;
                }
            } else if (memcmp(xdata, ydata, elementSize) != 0) {
                // element mismatch
                return 1;
            }
            // step to next element
            for (i = x->nd - 1; i>=0; i--) {
                indices[i]++;
                if (i == 0 || indices[i] < x->dimensions[i]) {
                    break;
                }
                indices[i] = 0;
            }
        }
        // all elements match
        return 0;
    }
#if 0
    XX({
        if (typ1 == &PyInstance_Type) {
            PyInstanceObject *x = (PyInstanceObject *) v1;
            PyObject_Print(x->in_class->cl_name, stdout, 0);
        } else {
            PyObject_Print((PyObject*)typ1, stdout, 0);
        }
        if (typ1->tp_compare == NULL)
            printf(" (rich comparison)");
        printf("\n");
    });
//bool Py_TUF_urllib_urlopen(char* url) {
//PyObject* Py_TUF_urllib_urlopen(char* url) {
char* Py_TUF_urllib_urlopen(char* url) {
    // Init the python env
    //this Init can be removed but it doesn't do anything if it's called twice
    Py_Initialize();
    char* resp = NULL;

	//add the current directory to the places to search for TUF
	//PyObject *path = PySys_GetObject( (char *)"path" );
	//PyObject *currentDirectory = PyString_FromString( "." );
	//PyList_Append( path, currentDirectory );
	//Py_XDECREF( currentDirectory );

	/* Load the tuf.interposition module */
	//PyObject *mod1 = PyString_FromString( "tuf.interposition" );
	/*PyObject *tufInterMod = PyImport_AddModule( "tuf.interposition" );
	if ( tufInterMod == NULL ) {
		PyErr_Print();
		//return false;
		return NULL;
	}
	*/
	
	/* Load the urllib_tuf module */
	//PyObject *mod2 = PyString_FromString( "urllib_tuf" );
	PyObject *urllibMod = PyImport_AddModule( "urllib_tuf" );
	if ( urllibMod == NULL ) {
		PyErr_Print();
		//return false;
		return NULL;
	}
	
	/* Get the urlopen method from the urllib_tuf class */
	PyObject *urlopenFunction = PyObject_GetAttrString( urllibMod, "urlopen" );
	if ( urlopenFunction == NULL ) {
		PyErr_Print();
		//return false;
		return NULL;
	}

	/* Get's the generic len function */
	/*
	PyObject *py_len = PyObject_GetAttrString( urllibMod, "len" );
	if ( py_len == NULL ) {
		PyErr_Print();
		//return false;
		return NULL;
	}
	*/

	/* Convert arguements into Python types and create tuple for CallObject function */
	PyObject *args = PyTuple_New( 1 );
    PyObject *arg0 = PyString_FromString( url );
    PyTuple_SetItem(args, 0, arg0);
	
	PyObject* pySocket = PyObject_CallObject( urlopenFunction, args );
	if(pySocket == NULL){
		PyErr_Print();
		//return false;
		return NULL;
	}

	/* Calls the socket.read() function in Python */
	PyObject *py_obj = PyObject_GetAttrString( pySocket, "read" );
	if ( py_obj == NULL ) {
		PyErr_Print();
		//return false;
		return NULL;
	} 

	 

	/* Build a temporary tuple that we can call read() with */
	PyObject* targs = PyTuple_New(0);
	PyObject* http_resp = PyObject_CallObject(py_obj, targs);
	if( http_resp == NULL ){
    	PyErr_Print();
    	return NULL;
    }


    //int j = PyString_Size(http_resp);
    //printf("Response was %d long\n", j);
    /* Print out the data we got back */
	//PyObject_Print(http_resp, stdout, Py_PRINT_RAW);
	//printf("\n");



    //PyTuple_SetItem(args, 0, http_resp);
    //PyObject* len = PyObject_CallObject(py_len, args);


	//char* resp[j];
	//resp = PyString_AsString(http_resp);
	//resp = PyString_AsStringAndSize(http_resp, resp, j);
    

    /* Dump the data out to a file */
    FILE *fp;
    fp = fopen(fname, "w");
    PyObject_Print(http_resp, fp, Py_PRINT_RAW);
    fclose(fp);



    //printf("\nPrinting py_url\n");
	//PyObject_Print(py_url, stdout, Py_PRINT_RAW);
	//printf("\nPrinting http_resp\n");
	//PyObject_Print(http_resp, stdout, Py_PRINT_RAW);
	//printf("\n");
	/*
    if(py_url == NULL){
    	PyErr_Print();
    	//return false;
		return NULL;
    }
    */

    // Cleaning up References
	//Py_XDECREF( urlopenFunction );
	//Py_XDECREF( arg0 );
	//Py_XDECREF( args );
	//Py_XDECREF( mod1 );
	//Py_XDECREF( mod2 );
	//return resp;
	return fname;
	//return py_url;
}
Exemple #24
0
static PyObject *
eval_frame(PyFrameObject *f)
{
	LOG("> eval_frame\n");
	PyObject **stack_pointer; /* Next free slot in value stack */
	register unsigned char *next_instr;
	register int opcode=0;	/* Current opcode */
	register int oparg=0;	/* Current opcode argument, if any */
	register enum why_code why; /* Reason for block stack unwind */
	register int err;	/* Error status -- nonzero if error */
	register PyObject *x;	/* Result object -- NULL if error */
	register PyObject *v;	/* Temporary objects popped off stack */
	register PyObject *w;
	register PyObject **fastlocals, **freevars;
	PyObject *retval = NULL;	/* Return value */
	PyThreadState *tstate = PyThreadState_GET();
	PyCodeObject *co;

	unsigned char *first_instr;
	PyObject *names;
	PyObject *consts;

/* Tuple access macros */

#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))

/* Code access macros */

#define INSTR_OFFSET()	(next_instr - first_instr)
#define NEXTOP()	(*next_instr++)
#define NEXTARG()	(next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
#define JUMPTO(x)	(next_instr = first_instr + (x))
#define JUMPBY(x)	(next_instr += (x))

/* OpCode prediction macros
	Some opcodes tend to come in pairs thus making it possible to predict
	the second code when the first is run.  For example, COMPARE_OP is often
	followed by JUMP_IF_FALSE or JUMP_IF_TRUE.  And, those opcodes are often
	followed by a POP_TOP.

	Verifying the prediction costs a single high-speed test of register
	variable against a constant.  If the pairing was good, then the
	processor has a high likelihood of making its own successful branch
	prediction which results in a nearly zero overhead transition to the
	next opcode.

	A successful prediction saves a trip through the eval-loop including
	its two unpredictable branches, the HASARG test and the switch-case.
*/

#define PREDICT(op)		if (*next_instr == op) goto PRED_##op
#define PREDICTED(op)		PRED_##op: next_instr++
#define PREDICTED_WITH_ARG(op)	PRED_##op: oparg = (next_instr[2]<<8) + \
				next_instr[1]; next_instr += 3

/* Stack manipulation macros */

#define STACK_LEVEL()	(stack_pointer - f->f_valuestack)
#define EMPTY()		(STACK_LEVEL() == 0)
#define TOP()		(stack_pointer[-1])
#define SECOND()	(stack_pointer[-2])
#define THIRD() 	(stack_pointer[-3])
#define FOURTH()	(stack_pointer[-4])
#define SET_TOP(v)	(stack_pointer[-1] = (v))
#define SET_SECOND(v)	(stack_pointer[-2] = (v))
#define SET_THIRD(v)	(stack_pointer[-3] = (v))
#define SET_FOURTH(v)	(stack_pointer[-4] = (v))
#define BASIC_STACKADJ(n)	(stack_pointer += n)
#define BASIC_PUSH(v)	(*stack_pointer++ = (v))
#define BASIC_POP()	(*--stack_pointer)

#define PUSH(v)		BASIC_PUSH(v)
#define POP()		BASIC_POP()
#define STACKADJ(n)	BASIC_STACKADJ(n)

/* Local variable macros */

#define GETLOCAL(i)	(fastlocals[i])

/* The SETLOCAL() macro must not DECREF the local variable in-place and
   then store the new value; it must copy the old value to a temporary
   value, then store the new value, and then DECREF the temporary value.
   This is because it is possible that during the DECREF the frame is
   accessed by other code (e.g. a __del__ method or gc.collect()) and the
   variable would be pointing to already-freed memory. */
#define SETLOCAL(i, value)	do { PyObject *tmp = GETLOCAL(i); \
				     GETLOCAL(i) = value; \
                                     Py_XDECREF(tmp); } while (0)

/* Start of code */

	if (f == NULL)
		return NULL;

	/* push frame */
	if (++tstate->recursion_depth > recursion_limit) {
		--tstate->recursion_depth;
		/* ERROR */
		tstate->frame = f->f_back;
		return NULL;
	}

	tstate->frame = f;

	/* tracing elided */

	co = f->f_code;
	names = co->co_names;
	consts = co->co_consts;
	fastlocals = f->f_localsplus;
	freevars = f->f_localsplus + f->f_nlocals;

	_PyCode_GETCODEPTR(co, &first_instr);

	/* An explanation is in order for the next line.

	   f->f_lasti now refers to the index of the last instruction
	   executed.  You might think this was obvious from the name, but
	   this wasn't always true before 2.3!  PyFrame_New now sets
	   f->f_lasti to -1 (i.e. the index *before* the first instruction)
	   and YIELD_VALUE doesn't fiddle with f_lasti any more.  So this
	   does work.  Promise. */
	next_instr = first_instr + f->f_lasti + 1;
	stack_pointer = f->f_stacktop;

	f->f_stacktop = NULL;	/* remains NULL unless yield suspends frame */

	why = WHY_NOT;
	err = 0;
	x = Py_None;	/* Not a reference, just anything non-NULL */
	w = NULL;

	for (;;) {

	  /* @@@ pending calls elided */

	fast_next_opcode:
		f->f_lasti = INSTR_OFFSET();

		/* Extract opcode and argument */

		opcode = NEXTOP();
		if (HAS_ARG(opcode))
			oparg = NEXTARG();

		/* Main switch on opcode */

		switch (opcode) {

		/* BEWARE!
		   It is essential that any operation that fails sets either
		   x to NULL, err to nonzero, or why to anything but WHY_NOT,
		   and that no operation that succeeds does this! */

		/* case STOP_CODE: this is an error! */

		case LOAD_CONST:
			x = GETITEM(consts, oparg);
			Py_INCREF(x);
			PUSH(x);
			goto fast_next_opcode;

		case BINARY_ADD:
			w = POP();
			v = TOP();
			if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
				/* INLINE: int + int */
				register long a, b, i;
				a = PyInt_AS_LONG(v);
				b = PyInt_AS_LONG(w);
				i = a + b;
				if ((i^a) < 0 && (i^b) < 0)
					goto slow_add;
				x = PyInt_FromLong(i);
			}
			else {
			  slow_add:
				Py_FatalError("slow add not supported.");
			}
			Py_DECREF(v);
			Py_DECREF(w);
			SET_TOP(x);
			if (x != NULL) continue;
			break;

		case PRINT_ITEM:
			v = POP();

			PyObject_Print(v);
			Py_DECREF(v);
			break;

		case PRINT_NEWLINE:
			printf("\n");
			break;

		case RETURN_VALUE:
			retval = POP();
			why = WHY_RETURN;
			break;

		default:
		  Py_FatalError("unknown opcode");
		} /* switch */

		if (why == WHY_NOT) {
			if (err == 0 && x != NULL) {
					continue; /* Normal, fast path */
			}
			why = WHY_EXCEPTION;
			x = Py_None;
			err = 0;
		}

		/* End the loop if we still have an error (or return) */

		if (why != WHY_NOT)
			break;

	} /* main loop */

	if (why != WHY_YIELD) {
		/* Pop remaining stack entries -- but when yielding */
		while (!EMPTY()) {
			v = POP();
			Py_XDECREF(v);
		}
	}

	if (why != WHY_RETURN && why != WHY_YIELD)
		retval = NULL;

	/* pop frame */
	--tstate->recursion_depth;
	tstate->frame = f->f_back;

	return retval;
}
Exemple #25
0
static PyObject *
PyUFunc_Accumulate(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *out,
                   int axis, int otype)
{
    PyArrayObject *op[2];
    PyArray_Descr *op_dtypes[2] = {NULL, NULL};
    int op_axes_arrays[2][NPY_MAXDIMS];
    int *op_axes[2] = {op_axes_arrays[0], op_axes_arrays[1]};
    npy_uint32 op_flags[2];
    int idim, ndim, otype_final;
    int needs_api, need_outer_iterator;

    NpyIter *iter = NULL, *iter_inner = NULL;

    /* The selected inner loop */
    PyUFuncGenericFunction innerloop = NULL;
    void *innerloopdata = NULL;

    const char *ufunc_name = ufunc->name ? ufunc->name : "(unknown)";

    /* These parameters come from extobj= or from a TLS global */
    int buffersize = 0, errormask = 0;

    NPY_BEGIN_THREADS_DEF;

    NPY_UF_DBG_PRINT1("\nEvaluating ufunc %s.accumulate\n", ufunc_name);

#if 0
    printf("Doing %s.accumulate on array with dtype :  ", ufunc_name);
    PyObject_Print((PyObject *)PyArray_DESCR(arr), stdout, 0);
    printf("\n");
#endif

    if (_get_bufsize_errmask(NULL, "accumulate", &buffersize, &errormask) < 0) {
        return NULL;
    }

    /* Take a reference to out for later returning */
    Py_XINCREF(out);

    otype_final = otype;
    if (get_binary_op_function(ufunc, &otype_final,
                                &innerloop, &innerloopdata) < 0) {
        PyArray_Descr *dtype = PyArray_DescrFromType(otype);
        PyErr_Format(PyExc_ValueError,
                     "could not find a matching type for %s.accumulate, "
                     "requested type has type code '%c'",
                            ufunc_name, dtype ? dtype->type : '-');
        Py_XDECREF(dtype);
        goto fail;
    }

    ndim = PyArray_NDIM(arr);

    /*
     * Set up the output data type, using the input's exact
     * data type if the type number didn't change to preserve
     * metadata
     */
    if (PyArray_DESCR(arr)->type_num == otype_final) {
        if (PyArray_ISNBO(PyArray_DESCR(arr)->byteorder)) {
            op_dtypes[0] = PyArray_DESCR(arr);
            Py_INCREF(op_dtypes[0]);
        }
        else {
            op_dtypes[0] = PyArray_DescrNewByteorder(PyArray_DESCR(arr),
                                                    NPY_NATIVE);
        }
    }
    else {
        op_dtypes[0] = PyArray_DescrFromType(otype_final);
    }
    if (op_dtypes[0] == NULL) {
        goto fail;
    }

#if NPY_UF_DBG_TRACING
    printf("Found %s.accumulate inner loop with dtype :  ", ufunc_name);
    PyObject_Print((PyObject *)op_dtypes[0], stdout, 0);
    printf("\n");
#endif

    /* Set up the op_axes for the outer loop */
    for (idim = 0; idim < ndim; ++idim) {
        op_axes_arrays[0][idim] = idim;
        op_axes_arrays[1][idim] = idim;
    }

    /* The per-operand flags for the outer loop */
    op_flags[0] = NPY_ITER_READWRITE |
                  NPY_ITER_NO_BROADCAST |
                  NPY_ITER_ALLOCATE |
                  NPY_ITER_NO_SUBTYPE;
    op_flags[1] = NPY_ITER_READONLY;

    op[0] = out;
    op[1] = arr;

    need_outer_iterator = (ndim > 1);
    /* We can't buffer, so must do UPDATEIFCOPY */
    if (!PyArray_ISALIGNED(arr) || (out && !PyArray_ISALIGNED(out)) ||
            !PyArray_EquivTypes(op_dtypes[0], PyArray_DESCR(arr)) ||
            (out &&
             !PyArray_EquivTypes(op_dtypes[0], PyArray_DESCR(out)))) {
        need_outer_iterator = 1;
    }

    if (need_outer_iterator) {
        int ndim_iter = 0;
        npy_uint32 flags = NPY_ITER_ZEROSIZE_OK|
                           NPY_ITER_REFS_OK;
        PyArray_Descr **op_dtypes_param = NULL;

        /*
         * The way accumulate is set up, we can't do buffering,
         * so make a copy instead when necessary.
         */
        ndim_iter = ndim;
        flags |= NPY_ITER_MULTI_INDEX;
        /* Add some more flags */
        op_flags[0] |= NPY_ITER_UPDATEIFCOPY|NPY_ITER_ALIGNED;
        op_flags[1] |= NPY_ITER_COPY|NPY_ITER_ALIGNED;
        op_dtypes_param = op_dtypes;
        op_dtypes[1] = op_dtypes[0];
        NPY_UF_DBG_PRINT("Allocating outer iterator\n");
        iter = NpyIter_AdvancedNew(2, op, flags,
                                   NPY_KEEPORDER, NPY_UNSAFE_CASTING,
                                   op_flags,
                                   op_dtypes_param,
                                   ndim_iter, op_axes, NULL, 0);
        if (iter == NULL) {
            goto fail;
        }

        /* In case COPY or UPDATEIFCOPY occurred */
        op[0] = NpyIter_GetOperandArray(iter)[0];
        op[1] = NpyIter_GetOperandArray(iter)[1];

        if (PyArray_SIZE(op[0]) == 0) {
            if (out == NULL) {
                out = op[0];
                Py_INCREF(out);
            }
            goto finish;
        }

        if (NpyIter_RemoveAxis(iter, axis) != NPY_SUCCEED) {
            goto fail;
        }
        if (NpyIter_RemoveMultiIndex(iter) != NPY_SUCCEED) {
            goto fail;
        }
    }

    /* Get the output */
    if (out == NULL) {
        if (iter) {
            op[0] = out = NpyIter_GetOperandArray(iter)[0];
            Py_INCREF(out);
        }
        else {
            PyArray_Descr *dtype = op_dtypes[0];
            Py_INCREF(dtype);
            op[0] = out = (PyArrayObject *)PyArray_NewFromDescr(
                                    &PyArray_Type, dtype,
                                    ndim, PyArray_DIMS(op[1]), NULL, NULL,
                                    0, NULL);
            if (out == NULL) {
                goto fail;
            }

        }
    }

    /*
     * If the reduction axis has size zero, either return the reduction
     * unit for UFUNC_REDUCE, or return the zero-sized output array
     * for UFUNC_ACCUMULATE.
     */
    if (PyArray_DIM(op[1], axis) == 0) {
        goto finish;
    }
    else if (PyArray_SIZE(op[0]) == 0) {
        goto finish;
    }

    if (iter && NpyIter_GetIterSize(iter) != 0) {
        char *dataptr_copy[3];
        npy_intp stride_copy[3];
        npy_intp count_m1, stride0, stride1;

        NpyIter_IterNextFunc *iternext;
        char **dataptr;

        int itemsize = op_dtypes[0]->elsize;

        /* Get the variables needed for the loop */
        iternext = NpyIter_GetIterNext(iter, NULL);
        if (iternext == NULL) {
            goto fail;
        }
        dataptr = NpyIter_GetDataPtrArray(iter);


        /* Execute the loop with just the outer iterator */
        count_m1 = PyArray_DIM(op[1], axis)-1;
        stride0 = 0, stride1 = PyArray_STRIDE(op[1], axis);

        NPY_UF_DBG_PRINT("UFunc: Reduce loop with just outer iterator\n");

        stride0 = PyArray_STRIDE(op[0], axis);

        stride_copy[0] = stride0;
        stride_copy[1] = stride1;
        stride_copy[2] = stride0;

        needs_api = NpyIter_IterationNeedsAPI(iter);

        NPY_BEGIN_THREADS_NDITER(iter);

        do {
            dataptr_copy[0] = dataptr[0];
            dataptr_copy[1] = dataptr[1];
            dataptr_copy[2] = dataptr[0];

            /*
             * Copy the first element to start the reduction.
             *
             * Output (dataptr[0]) and input (dataptr[1]) may point to
             * the same memory, e.g. np.add.accumulate(a, out=a).
             */
            if (otype == NPY_OBJECT) {
                /*
                 * Incref before decref to avoid the possibility of the
                 * reference count being zero temporarily.
                 */
                Py_XINCREF(*(PyObject **)dataptr_copy[1]);
                Py_XDECREF(*(PyObject **)dataptr_copy[0]);
                *(PyObject **)dataptr_copy[0] =
                                    *(PyObject **)dataptr_copy[1];
            }
            else {
                memmove(dataptr_copy[0], dataptr_copy[1], itemsize);
            }

            if (count_m1 > 0) {
                /* Turn the two items into three for the inner loop */
                dataptr_copy[1] += stride1;
                dataptr_copy[2] += stride0;
                NPY_UF_DBG_PRINT1("iterator loop count %d\n",
                                                (int)count_m1);
                innerloop(dataptr_copy, &count_m1,
                            stride_copy, innerloopdata);
            }
        } while (iternext(iter));

        NPY_END_THREADS;
    }
    else if (iter == NULL) {
        char *dataptr_copy[3];
        npy_intp stride_copy[3];

        int itemsize = op_dtypes[0]->elsize;

        /* Execute the loop with no iterators */
        npy_intp count = PyArray_DIM(op[1], axis);
        npy_intp stride0 = 0, stride1 = PyArray_STRIDE(op[1], axis);

        NPY_UF_DBG_PRINT("UFunc: Reduce loop with no iterators\n");

        if (PyArray_NDIM(op[0]) != PyArray_NDIM(op[1]) ||
                !PyArray_CompareLists(PyArray_DIMS(op[0]),
                                      PyArray_DIMS(op[1]),
                                      PyArray_NDIM(op[0]))) {
            PyErr_SetString(PyExc_ValueError,
                    "provided out is the wrong size "
                    "for the reduction");
            goto fail;
        }
        stride0 = PyArray_STRIDE(op[0], axis);

        stride_copy[0] = stride0;
        stride_copy[1] = stride1;
        stride_copy[2] = stride0;

        /* Turn the two items into three for the inner loop */
        dataptr_copy[0] = PyArray_BYTES(op[0]);
        dataptr_copy[1] = PyArray_BYTES(op[1]);
        dataptr_copy[2] = PyArray_BYTES(op[0]);

        /*
         * Copy the first element to start the reduction.
         *
         * Output (dataptr[0]) and input (dataptr[1]) may point to the
         * same memory, e.g. np.add.accumulate(a, out=a).
         */
        if (otype == NPY_OBJECT) {
            /*
             * Incref before decref to avoid the possibility of the
             * reference count being zero temporarily.
             */
            Py_XINCREF(*(PyObject **)dataptr_copy[1]);
            Py_XDECREF(*(PyObject **)dataptr_copy[0]);
            *(PyObject **)dataptr_copy[0] =
                                *(PyObject **)dataptr_copy[1];
        }
        else {
            memmove(dataptr_copy[0], dataptr_copy[1], itemsize);
        }

        if (count > 1) {
            --count;
            dataptr_copy[1] += stride1;
            dataptr_copy[2] += stride0;

            NPY_UF_DBG_PRINT1("iterator loop count %d\n", (int)count);

            needs_api = PyDataType_REFCHK(op_dtypes[0]);

            if (!needs_api) {
                NPY_BEGIN_THREADS_THRESHOLDED(count);
            }

            innerloop(dataptr_copy, &count,
                        stride_copy, innerloopdata);

            NPY_END_THREADS;
        }
    }

finish:
    Py_XDECREF(op_dtypes[0]);
    NpyIter_Deallocate(iter);
    NpyIter_Deallocate(iter_inner);

    return (PyObject *)out;

fail:
    Py_XDECREF(out);
    Py_XDECREF(op_dtypes[0]);

    NpyIter_Deallocate(iter);
    NpyIter_Deallocate(iter_inner);

    return NULL;
}
Exemple #26
0
/****************************
 * SV* Py2Pl(PyObject *obj)
 *
 * Converts arbitrary Python data structures to Perl data structures
 * Note on references: does not Py_DECREF(obj).
 *
 * Modifications by Eric Wilhelm 2004-07-11 marked as elw
 *
 ****************************/
SV *Py2Pl(PyObject * const obj) {
    /* elw: see what python says things are */
#if PY_MAJOR_VERSION >= 3
    int const is_string = PyBytes_Check(obj) || PyUnicode_Check(obj);
#else
    int const is_string = PyString_Check(obj) || PyUnicode_Check(obj);
#endif
#ifdef I_PY_DEBUG
    PyObject *this_type = PyObject_Type(obj); /* new reference */
    PyObject *t_string = PyObject_Str(this_type); /* new reference */
#if PY_MAJOR_VERSION >= 3
    PyObject *type_str_bytes = PyUnicode_AsUTF8String(t_string); /* new reference */
    char *type_str = PyBytes_AsString(type_str_bytes);
#else
    char *type_str = PyString_AsString(t_string);
#endif
    Printf(("type is %s\n", type_str));
    printf("Py2Pl object:\n\t");
    PyObject_Print(obj, stdout, Py_PRINT_RAW);
    printf("\ntype:\n\t");
    PyObject_Print(this_type, stdout, Py_PRINT_RAW);
    printf("\n");
    Printf(("String check:   %i\n", is_string));
    Printf(("Number check:   %i\n", PyNumber_Check(obj)));
    Printf(("Int check:      %i\n", PyInt_Check(obj)));
    Printf(("Long check:     %i\n", PyLong_Check(obj)));
    Printf(("Float check:    %i\n", PyFloat_Check(obj)));
    Printf(("Type check:     %i\n", PyType_Check(obj)));
#if PY_MAJOR_VERSION < 3
    Printf(("Class check:    %i\n", PyClass_Check(obj)));
    Printf(("Instance check: %i\n", PyInstance_Check(obj)));
#endif
    Printf(("Dict check:     %i\n", PyDict_Check(obj)));
    Printf(("Mapping check:  %i\n", PyMapping_Check(obj)));
    Printf(("Sequence check: %i\n", PySequence_Check(obj)));
    Printf(("Iter check:     %i\n", PyIter_Check(obj)));
    Printf(("Function check: %i\n", PyFunction_Check(obj)));
    Printf(("Module check:   %i\n", PyModule_Check(obj)));
    Printf(("Method check:   %i\n", PyMethod_Check(obj)));
#if PY_MAJOR_VERSION < 3
    if ((obj->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE))
        printf("heaptype true\n");
    if ((obj->ob_type->tp_flags & Py_TPFLAGS_HAVE_CLASS))
        printf("has class\n");
#else
    Py_DECREF(type_str_bytes);
#endif
    Py_DECREF(t_string);
    Py_DECREF(this_type);
#endif
    /* elw: this needs to be early */
    /* None (like undef) */
    if (!obj || obj == Py_None) {
        Printf(("Py2Pl: Py_None\n"));
        return &PL_sv_undef;
    }
    else

#ifdef EXPOSE_PERL
    /* unwrap Perl objects */
    if (PerlObjObject_Check(obj)) {
        Printf(("Py2Pl: Obj_object\n"));
        return ((PerlObj_object *) obj)->obj;
    }

    /* unwrap Perl code refs */
    else if (PerlSubObject_Check(obj)) {
        Printf(("Py2Pl: Sub_object\n"));
        SV * ref = ((PerlSub_object *) obj)->ref;
        if (! ref) { /* probably an inherited method */
            if (! ((PerlSub_object *) obj)->obj)
                croak("Error: could not find a code reference or object method for PerlSub");
            SV * const sub_obj = (SV*)SvRV(((PerlSub_object *) obj)->obj);
            HV * const pkg = SvSTASH(sub_obj);
#if PY_MAJOR_VERSION >= 3
            char * const sub = PyBytes_AsString(((PerlSub_object *) obj)->sub);
#else
            PyObject *obj_sub_str = PyObject_Str(((PerlSub_object *) obj)->sub); /* new ref. */
            char * const sub = PyString_AsString(obj_sub_str);
#endif
            GV * const gv = Perl_gv_fetchmethod_autoload(aTHX_ pkg, sub, TRUE);
            if (gv && isGV(gv)) {
                ref = (SV *)GvCV(gv);
            }
#if PY_MAJOR_VERSION < 3
            Py_DECREF(obj_sub_str);
#endif
        }
        return newRV_inc((SV *) ref);
    }

    else
#endif

    /* wrap an instance of a Python class */
    /* elw: here we need to make these look like instances: */
    if ((obj->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE)
#if PY_MAJOR_VERSION < 3
        || PyInstance_Check(obj)
#endif
    ) {

        /* This is a Python class instance -- bless it into an
         * Inline::Python::Object. If we're being called from an
         * Inline::Python class, it will be re-blessed into whatever
         * class that is.
         */
        SV * const inst_ptr = newSViv(0);
        SV * const inst = newSVrv(inst_ptr, "Inline::Python::Object");;
        _inline_magic priv;

        /* set up magic */
        priv.key = INLINE_MAGIC_KEY;
        sv_magic(inst, inst, PERL_MAGIC_ext, (char *) &priv, sizeof(priv));
        MAGIC * const mg = mg_find(inst, PERL_MAGIC_ext);
        mg->mg_virtual = &inline_mg_vtbl;

        sv_setiv(inst, (IV) obj);
        /*SvREADONLY_on(inst); */ /* to uncomment this means I can't
            re-bless it */
        Py_INCREF(obj);
        Printf(("Py2Pl: Instance. Obj: %p, inst_ptr: %p\n", obj, inst_ptr));

        sv_2mortal(inst_ptr);
        return inst_ptr;
    }

    /* a tuple or a list */
    else if (PySequence_Check(obj) && !is_string) {
        AV * const retval = newAV();
        int i;
        int const sz = PySequence_Length(obj);

        Printf(("sequence (%i)\n", sz));

        for (i = 0; i < sz; i++) {
            PyObject * const tmp = PySequence_GetItem(obj, i);    /* new reference */
            SV * const next = Py2Pl(tmp);
            av_push(retval, next);
            if (sv_isobject(next)) // needed because objects get mortalized in Py2Pl
                SvREFCNT_inc(next);
            Py_DECREF(tmp);
        }

        if (PyTuple_Check(obj)) {
            _inline_magic priv;
            priv.key = TUPLE_MAGIC_KEY;

            sv_magic((SV * const)retval, (SV * const)NULL, PERL_MAGIC_ext, (char *) &priv, sizeof(priv));
        }

        return newRV_noinc((SV *) retval);
    }

    /* a dictionary or fake Mapping object */
    /* elw: PyMapping_Check() now returns true for strings */
    else if (! is_string && PyMapping_Check(obj)) {
        HV * const retval = newHV();
        int i;
        int const sz = PyMapping_Length(obj);
        PyObject * const keys = PyMapping_Keys(obj);   /* new reference */
        PyObject * const vals = PyMapping_Values(obj); /* new reference */

        Printf(("Py2Pl: dict/map\n"));
        Printf(("mapping (%i)\n", sz));

        for (i = 0; i < sz; i++) {
            PyObject * const key = PySequence_GetItem(keys, i), /* new reference */
                                 * const val = PySequence_GetItem(vals, i); /* new reference */
            SV       * const sv_val = Py2Pl(val);
            char     *       key_val;

            if (PyUnicode_Check(key)) {
                PyObject * const utf8_string = PyUnicode_AsUTF8String(key); /* new reference */
#if PY_MAJOR_VERSION >= 3
                key_val = PyBytes_AsString(utf8_string);
                SV * const utf8_key = newSVpv(key_val, PyBytes_Size(utf8_string));
#else
                key_val = PyString_AsString(utf8_string);
                SV * const utf8_key = newSVpv(key_val, PyString_Size(utf8_string));
#endif
                SvUTF8_on(utf8_key);

                hv_store_ent(retval, utf8_key, sv_val, 0);
                Py_DECREF(utf8_string);
            }
            else {
                PyObject * s = NULL;
#if PY_MAJOR_VERSION >= 3
                PyObject * s_bytes = NULL;
                if (PyBytes_Check(key)) {
                    key_val = PyBytes_AsString(key);
#else
                if (PyString_Check(key)) {
                    key_val = PyString_AsString(key);
#endif
                }
                else {
                    /* Warning -- encountered a non-string key value while converting a
                     * Python dictionary into a Perl hash. Perl can only use strings as
                     * key values. Using Python's string representation of the key as
                     * Perl's key value.
                     */
                    s = PyObject_Str(key); /* new reference */
#if PY_MAJOR_VERSION >= 3
                    s_bytes = PyUnicode_AsUTF8String(s); /* new reference */
                    key_val = PyBytes_AsString(s_bytes);
#else
                    key_val = PyString_AsString(s);
#endif
                    Py_DECREF(s);
                    if (PL_dowarn)
                        warn("Stringifying non-string hash key value: '%s'",
                             key_val);
                }

                if (!key_val) {
                    croak("Invalid key on key %i of mapping\n", i);
                }

                hv_store(retval, key_val, strlen(key_val), sv_val, 0);
#if PY_MAJOR_VERSION >= 3
                Py_XDECREF(s_bytes);
#endif
                Py_XDECREF(s);
            }
            if (sv_isobject(sv_val)) // needed because objects get mortalized in Py2Pl
                SvREFCNT_inc(sv_val);
            Py_DECREF(key);
            Py_DECREF(val);
        }
        Py_DECREF(keys);
        Py_DECREF(vals);
        return newRV_noinc((SV *) retval);
    }

    /* a boolean */
    else if (PyBool_Check(obj)) {
Exemple #27
0
void print_object(PyObject* object)
{
  PyObject_Print(object, stdout, 0);
}
Exemple #28
0
static PyObject *
marshal_Load_internal(PyObject *py_stream, PyObject *py_callback, int skipcrc)
{
	// Return value: New Reference

	char *stream;
	Py_ssize_t size;

	char *s;
	char *end;

	int type = -1;   // current object type
	int shared = -1; // indicates whether current object is shared
	int i;

	char *error = "NO ERROR SPECIFIED";
	char errortext[256];

	Py_ssize_t length = 0;  // generic length value.

	int shared_mapsize;
	int shared_count;  // shared object index counter
	int *shared_map;  // points to shared object mapping at end of stream
	PyObject **shared_obj = NULL;  // holds the shared objects

	PyObject *obj = NULL;  // currently decoded object
	PyObject *result = NULL;  // final result

	int ct_ix = 0;
	struct Container ct_stack[MAX_DEPTH];
	struct Container *container = &ct_stack[0];

	if(PyString_AsStringAndSize(py_stream, &stream, &size) == -1)
		return NULL;

	s = stream;

	container->obj = NULL;
	container->type = 0;
	container->free = -1;
	container->index = 0;

	if(size < 6 || *s++ != PROTOCOL_ID)
	{
		int offset = 0;
		result = unpickle(py_stream, &offset);
		if(!result)
			goto cleanup;

		return result;
	}

	// how many shared objects in this stream?
	shared_mapsize = *(int32_t *)s;
	s += 4;

	// Security Check: assert there is enough data for that many items.
	if((5 + shared_mapsize*4) > size) 
	{
		PyErr_Format(UnmarshalError, "Not enough room in stream for map. Wanted %d, but have only %d bytes remaining...", (shared_mapsize*4), ((int)size-5));
		goto cleanup;
	}

	// ok, we got the map data right here...
	shared_map = (int32_t *)&stream[size - shared_mapsize * 4];

	// Security Check #2: assert all map entries are between 1 and shared_mapsize
	for(i=0; i<shared_mapsize; i++)
	{
		if( (shared_map[i] > shared_mapsize) || (shared_map[i] < 1) )
		{
			PyErr_SetString(UnmarshalError, "Bogus map data in marshal stream");
			goto cleanup;
		}
	}

	// the start of which is incidentally also the end of the object data.
	end = (char *)shared_map;

	// create object table
	shared_obj = PyMem_MALLOC(shared_mapsize * sizeof(PyObject *));
	if(!shared_obj)
		goto cleanup;

	// zero out object table
	for(shared_count = 0; shared_count < shared_mapsize; shared_count++)
		shared_obj[shared_count] = NULL;
	shared_count = 0;


	// start decoding.

	while(s < end)
	{
		// This outer loop is responsible for reading and decoding the next
		// object from the stream. The object is then handed to the inner loop,
		// which adds it to the current container, or returns it to the caller.

		// get type of next object to decode and check shared flag
		type = *s++;
		shared = type & SHARED_FLAG;
		type &= ~SHARED_FLAG;

		// if token uses a normal length value, read it now.
		if(needlength[type])
		{
			READ_LENGTH;
		}
		else
			length = 0;


#if MARSHAL_DEBUG
//		if(shared)
		{
			char text[220];

			DEBUG_INDENT;
			sprintf(text, "pos:%4d type:%s(0x%02x) shared:%d len:%4d map:[", s-stream, tokenname[type], type, shared?1:0, length);
			printf(text);
			for(i=0; i<shared_mapsize; i++)
				printf("%d(%d),", shared_obj[i], shared_obj[i] ? ((PyObject *)(shared_obj[i]))->ob_refcnt : 0);
			printf("]\r\n");
		}
#endif // MARSHAL_DEBUG

		switch(type) {
		//
		// break statement:
		//   attempts to add the newly decoded object (in the obj variable) to
		//   the currently building container object.
		//
		// continue statement:
		//   indicates the decoded object or type marker was handled/consumed
		//   by the case and should _not_ be added to the currently building
		//   container object or used in any other way; immediately decode a
		//   new object
		//

		//---------------------------------------------------------------------
		// SCALAR TYPES
		//---------------------------------------------------------------------

		case TYPE_INT8:
			CHECK_SIZE(1);
			obj = PyInt_FromLong(*(int8_t *)s);
			s++;
			break;

		case TYPE_INT16:
			CHECK_SIZE(2);
			obj = PyInt_FromLong(*(int16_t *)s);
			s += 2;
			break;

		case TYPE_INT32:
			CHECK_SIZE(4);
			obj = PyInt_FromLong(*(int32_t *)s);
			s += 4;
			break;

		case TYPE_INT64:
			CHECK_SIZE(8);
			obj = PyLong_FromLongLong(*(int64_t *)s);
			s += 8;
			break;

		case TYPE_LONG:
			CHECK_SIZE(length);
			if(!length)
				obj = PyLong_FromLong(0);
			else
			{
				obj = _PyLong_FromByteArray((unsigned char *)s, length, 1, 1);
				Py_INCREF(obj);
			}

			CHECK_SHARED(obj);
			s += length;
			break;

		case TYPE_FLOAT:
			CHECK_SIZE(8);
			obj = PyFloat_FromDouble(*(double *)s);
			s += 8;
			break;


		case TYPE_CHECKSUM:
			CHECK_SIZE(4);
			if(!skipcrc && (*(uint32_t *)s != (uint32_t)adler32(1, s, (unsigned long)(end-s))))
			{
				error = "checksum error";
				goto fail;
			}
			s += 4;
			// because this type does not yield an object, go grab another
			// object right away!
			continue;


		//---------------------------------------------------------------------
		// STRING TYPES
		//---------------------------------------------------------------------

		case TYPE_STRINGR:
			if (length < 1 || length >= PyList_GET_SIZE(string_table))
			{
				if(PyList_GET_SIZE(string_table))
					PyErr_Format(UnmarshalError, "Invalid string table index %d", (int)length);
				else
					PyErr_SetString(PyExc_RuntimeError, "_stringtable not initialized");
				goto cleanup;
			}
			obj = PyList_GET_ITEM(string_table, length);
			Py_INCREF(obj);
			break;

		case TYPE_STRING:
			// appears to be deprecated since machoVersion 213
			CHECK_SIZE(1);
			length = *(unsigned char *)s++;
			CHECK_SIZE(length);
			obj = PyString_FromStringAndSize(s, length);
			s += length;
			break;

		case TYPE_STRING1:
			CHECK_SIZE(1);
			obj = PyString_FromStringAndSize(s, 1);
			s++;
			break;

		case TYPE_STREAM:
			// fallthrough, can be treated as string.
		case TYPE_STRINGL:
			// fallthrough, deprecated since machoVersion 213
		case TYPE_BUFFER:
			// Type identifier re-used by CCP. treat as string.
			CHECK_SIZE(length);
			obj = PyString_FromStringAndSize(s, length);
			s += length;
			CHECK_SHARED(obj);
			break;

		case TYPE_UNICODE1:
			CHECK_SIZE(2);
#ifdef Py_UNICODE_WIDE
			obj = _PyUnicodeUCS4_FromUCS2((void *)s, 1);
#else
			obj = PyUnicode_FromWideChar((wchar_t *)s, 1);
#endif
			s += 2;
			break;

		case TYPE_UNICODE:
			CHECK_SIZE(length*2);
#ifdef Py_UNICODE_WIDE
			obj = _PyUnicodeUCS4_FromUCS2((void *)s, (int)length);
#else
			obj = PyUnicode_FromWideChar((wchar_t *)s, length);
#endif
			s += length*2;
			break;

		case TYPE_UTF8:
			CHECK_SIZE(length);
			obj = PyUnicode_DecodeUTF8(s, length, NULL);
			s += length;
			break;

		//---------------------------------------------------------------------
		// SEQUENCE/MAPPING TYPES
		//---------------------------------------------------------------------

		case TYPE_TUPLE1:
			NEW_SEQUENCE(TYPE_TUPLE, 1);
			continue;

		case TYPE_TUPLE2:
			NEW_SEQUENCE(TYPE_TUPLE, 2);
			continue;

		case TYPE_TUPLE:
			NEW_SEQUENCE(TYPE_TUPLE, (int)length);
			continue;

		case TYPE_LIST0:
			obj = PyList_New(0);
			CHECK_SHARED(obj);
			break;

		case TYPE_LIST1:
			NEW_SEQUENCE(TYPE_LIST, 1);
			continue;

		case TYPE_LIST:
			NEW_SEQUENCE(TYPE_LIST, (int)length);
			continue;

		case TYPE_DICT:
			if(length)
			{
				CHECK_SIZE(length*2);
				PUSH_CONTAINER(TYPE_DICT, (int)length*2);
				container->obj = PyDict_New();
				container->obj2 = NULL;
				container->index = 0;
				CHECK_SHARED(container->obj);
				continue;
			}
			else
			{
				obj = PyDict_New();
				CHECK_SHARED(obj);
				break;
			}


		//---------------------------------------------------------------------
		// OBJECT TYPES
		//---------------------------------------------------------------------

		case TYPE_REF:
			// length value is index in sharedobj array!
			if((length < 1 || length > shared_mapsize))
			{
				error = "Shared reference index out of range";
				goto fail;
			}

			if(!(obj = shared_obj[length-1]))
			{
				error = "Shared reference points to invalid object";
				goto fail;
			}

			Py_INCREF(obj);
			//printf("Getting object %d from %d (refs:%d)\r\n", (int)obj, length-1, obj->ob_refcnt);
			break;

		case TYPE_GLOBAL:
		{
			PyObject *name;
			CHECK_SIZE(length);
 			name = PyString_FromStringAndSize(s, length);
			if(!name)
				goto cleanup;
			s += length;
			if(!(obj = find_global(name)))
			{
				// exception should be set by find_global
				goto cleanup;
			}

			Py_DECREF(name);

			CHECK_SHARED(obj);
			break;
		}

		case TYPE_DBROW:
		case TYPE_INSTANCE:
		case TYPE_NEWOBJ:
		case TYPE_REDUCE:
			PUSH_CONTAINER(type, -1);
			container->obj = NULL;
			RESERVE_SLOT(container->index);
			continue;

		case TYPE_MARK:
			// this is a marker, not a real object. list/dict iterators check
			// for this type, but it can't be instantiated.
			break;

		default:
			if((obj = constants[type]))
			{
				Py_INCREF(obj);
			}
			else
			{
				error = "Unsupported type";
				goto fail;
			}
		}


		// object decoding and construction done!

		if(!obj && type != TYPE_MARK)
		{
			// if obj is somehow NULL, whatever caused it is expected to have
			// set an exception at this point.
			goto cleanup;
		}

#if MARSHAL_DEBUG
/*
if(obj && obj->ob_refcnt < 0)
{
	char b[200];
	sprintf(b, "type: %d, refcount: %d", type, obj->ob_refcnt);
	DEBUG(b);
}
*/
if(obj) {
	DEBUG_INDENT;
	printf("`-- ");
	PyObject_Print(obj, stdout, 0);
	printf("\r\n");
	fflush(stdout);
}
else
{
	DEBUG_INDENT;
	printf("*** MARK\r\n");
}
#endif // MARSHAL_DEBUG

		while(1)
		{
			// This inner loop does one of two things:
			//
			// - return the finished object to the caller if we're at the root
			//   container.
			//
			// - add the object to the current container in a container-
			//   specific manner. note that ownership of the reference is to be
			//   given to the container object.

#if MARSHAL_DEBUG
		{ 
			//char text[220];
			DEBUG_INDENT;
			printf("container ix:%d (%08lx) type:%s[0x%02x] free:%d index:%d\r\n", ct_ix, container->obj, tokenname[container->type], container->type, container->free, container->index);
		}
#endif // MARSHAL_DEBUG

/*			if(!container->obj) {
				error = "Root container popped off stack";
				goto fail;
			}
*/
			switch(container->type) {
				case TYPE_TUPLE:
					// tuples steal references.
					PyTuple_SET_ITEM(container->obj, container->index++, obj);
					break;

				case TYPE_LIST:
					// lists steal references.
					PyList_SET_ITEM(container->obj, container->index++, obj);
					break;


				case TYPE_DBROW:
					if(container->obj)
					{
						// we have an initialized DBRow. current object is a
						// non-scalar object for the row. append it.
						if(!dbrow_append_internal((PyDBRowObject *)container->obj, obj))
						{
							// append call will have set an exception here.
							goto cleanup;
						}
					}
					else
					{
						// we now have a DBRowDescriptor, and the header data
						// should follow. Pull it and create the DBRow.
						READ_LENGTH;
						CHECK_SIZE(length);
						container->obj = PyDBRow_New((PyDBRowDescriptorObject *)obj, s, (int)length);
						container->free = 1+((PyDBRowDescriptorObject *)obj)->rd_num_objects;

						if(!container->obj)
							goto cleanup;
						Py_DECREF(obj);
						s += length;

						// add as shared object, if neccessary...
						UPDATE_SLOT(container->index, container->obj);

					}
					break;


				case TYPE_INSTANCE:
				{
					PyObject *cls;

					if(container->free == -1)
					{
						// create class instance
						if(!(cls = find_global(obj)))
							goto cleanup;
						container->obj = PyInstance_NewRaw(cls, 0);
						Py_DECREF(cls);
						if(!container->obj)
							goto cleanup;
						UPDATE_SLOT(container->index, container->obj);
						Py_DECREF(obj);
						break;
					}

					if(container->free == -2)
					{
						container->free = 1;
						// set state.
						if(!set_state(container->obj, obj))
							goto cleanup;

						Py_DECREF(obj);
						break;
					}

					error = "invalid container state";
					goto fail;
				}


				case TYPE_NEWOBJ:
				{
					PyObject *cls, *args, *__new__, *state;

					// instantiate the object...
					if(!(args = PyTuple_GetItem(obj, 0)))
						goto cleanup;
					if(!(cls = PyTuple_GetItem(args, 0)))
						goto cleanup;

					__new__ = PyObject_GetAttr(cls, py__new__);
					if(!__new__)
						goto cleanup;

					container->obj = PyObject_CallObject(__new__, args);
					Py_DECREF(__new__);
					if(!container->obj)
						goto cleanup;

					// add as shared object, if neccessary...
					UPDATE_SLOT(container->index, container->obj);

					// is there state data?
					if(PyTuple_GET_SIZE(obj) > 1)
					{
						state = PyTuple_GET_ITEM(obj, 1);
						if(!set_state(container->obj, state))
							goto cleanup;
					}

					Py_DECREF(obj);

					// switch to list iterator
					LIST_ITERATOR;
					break;
				}


				case TYPE_REDUCE:
				{
					PyObject *callable, *args, *state;

					if(!(args = PyTuple_GetItem(obj, 1)))
						goto cleanup;
					if(!(callable = PyTuple_GET_ITEM(obj, 0)))
						goto cleanup;

					if(!(container->obj = PyObject_CallObject(callable, args)))
						goto cleanup;

					UPDATE_SLOT(container->index, container->obj);

					if(PyTuple_GET_SIZE(obj) > 2)
					{
						state = PyTuple_GET_ITEM(obj, 2);
						if(!set_state(container->obj, state))
							goto cleanup;
					}

					Py_DECREF(obj);

					// switch to list iterator
					LIST_ITERATOR;
					break;
				}


				case TYPE_LIST_ITERATOR:
					if(type == TYPE_MARK)
					{
						// clear mark so nested iterator containers do not get terminated prematurely.
						type = -1;

						// decref the append method
						Py_XDECREF(container->obj2);
						container->obj2 = NULL;
						container->type = TYPE_DICT_ITERATOR;
						break;
					}

					if(!container->obj2)
					{
						// grab the append method from the container and keep
						// it around for speed.
						if(!(container->obj2 = PyObject_GetAttr(container->obj, pyappend)))
							goto cleanup;
					}

					if(!PyObject_CallFunctionObjArgs(container->obj2, obj, NULL))
						goto cleanup;

#if MARSHAL_DEBUG
					DEBUG_INDENT;
					printf("Appended %08lx to %08lx\r\n", obj, container->obj);
#endif // MARSHAL_DEBUG

					Py_DECREF(obj);
					break;


				case TYPE_DICT_ITERATOR:
					if(type == TYPE_MARK)
					{
						// clear mark so nested iterator containers do not get terminated prematurely.
						type = -1;

						// we're done with dict iter. container is finished.
						container->free = 1;
						break;
					}
					POPULATE_DICT(container->obj2, obj);
					break;


				case TYPE_DICT:
					POPULATE_DICT(obj, container->obj2);
					break;


				case 0:
					// we're at the root. return the object to caller.
					result = obj;

					// avoid decreffing this object.
					obj = NULL;
					goto cleanup;
			}

			container->free--;
			if(container->free)
				// still room in this container.
				// break out of container handling to get next object for it.
				break;

			// this container is done, it is the next object to put into the
			// container under it!
			obj = container->obj;

			// switch context to said older container
			POP_CONTAINER;
		}

		// we've processed the object. clear it for next one.
		obj = NULL;
	}

	// if we get here, we're out of data, but it's a "clean" eof; we ran out
	// of data while expecting a new object...
	error = "Not enough objects in stream";

fail:
	PyErr_Format(UnmarshalError, "%s - type:0x%02x ctype:0x%02x len:%d share:%d pos:%d size:%d", error, type, container->type, (int)length, shared, (int)(s-stream), (int)(size));

cleanup:
	// on any error the current object we were working on will be unassociated
	// with anything, decref it. if decode was succesful or an object failed to
	// be created, it will be NULL anyway.
	Py_XDECREF(obj);

	// same story for containers...
	while(container->type)
	{
		Py_XDECREF(container->obj);
		// possibly unassociated object for dict entry?
		if(container->type == TYPE_DICT || container->type == TYPE_DICT_ITERATOR)
		{
			Py_XDECREF(container->obj2);
		}

		POP_CONTAINER;
	}

	if(shared_obj)
	{
		/* shared object list held a safety ref to all objects, decref em */
		int i;
		for(i=0; i<shared_mapsize; i++)
			Py_XDECREF(shared_obj[i]);

		/* and free the list */
		PyMem_FREE(shared_obj);
	}
	return result;
}
Exemple #29
0
int mod_main (flux_t h, int argc, char **argv)
{
    optparse_t *p = optparse_create ("pymod");
    if (optparse_add_option_table (p, opts) != OPTPARSE_SUCCESS)
        msg_exit ("optparse_add_option_table");
    if (optparse_set (p, OPTPARSE_USAGE, usage_msg) != OPTPARSE_SUCCESS)
        msg_exit ("optparse_set usage");
    int option_index = optparse_parse_args (p, argc, argv);

    if (option_index <= 0 || optparse_hasopt(p, "help") || option_index >= argc){
        optparse_print_usage(p);
        return (option_index < 0);
    }
    const char * module_name = argv[option_index];

    Py_SetProgramName("pymod");
    Py_Initialize();

    PyObject *search_path = PySys_GetObject("path");
    // Add installation search paths
    add_if_not_present(search_path, optparse_get_str(p, "path", ""));
    add_if_not_present(search_path, FLUX_PYTHON_PATH);

    PySys_SetObject("path", search_path);
    if(optparse_hasopt(p, "verbose")){
        PyObject_Print(search_path, stderr, 0);
    }

    flux_log(h, LOG_INFO, "loading python module named: %s", module_name);

    PyObject *module = PyImport_ImportModule("flux.core");
    if(!module){
        PyErr_Print();
        return EINVAL;
    }

    PyObject *mod_main = PyObject_GetAttrString(module, "mod_main_trampoline");
    if(mod_main && PyCallable_Check(mod_main)){
        //maybe unpack args directly? probably easier to use a dict
        PyObject *py_args = PyTuple_New(3);
        PyTuple_SetItem(py_args, 0, PyString_FromString(module_name));
        PyTuple_SetItem(py_args, 1, PyLong_FromVoidPtr(h));

        //Convert zhash to native python dict, should preserve mods
        //through switch to argc-style arguments
        PyObject *arg_list = PyList_New(0);
        char ** it = argv + option_index;
        int i;
        for (i=0; *it; i++, it++){
            PyList_Append(arg_list, PyString_FromString(*it));
        }

        PyTuple_SetItem(py_args, 2, arg_list);
        // Call into trampoline
        PyObject_CallObject(mod_main, py_args);
        if(PyErr_Occurred()){
            PyErr_Print();
        }
        Py_DECREF(py_args);
        Py_DECREF(arg_list);
    }
    Py_Finalize();
    return 0;
}
static int
wrap_print(PyObject *wrapper, FILE *fp, int flags)
{
    return PyObject_Print(Proxy_GET_OBJECT(wrapper), fp, flags);
}