summaryrefslogtreecommitdiff
path: root/sys/src/cmd/python/Python
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2021-06-14 00:00:37 +0000
committerOri Bernstein <ori@eigenstate.org>2021-06-14 00:00:37 +0000
commita73a964e51247ed169d322c725a3a18859f109a3 (patch)
tree3f752d117274d444bda44e85609aeac1acf313f3 /sys/src/cmd/python/Python
parente64efe273fcb921a61bf27d33b230c4e64fcd425 (diff)
python, hg: tow outside the environment.
they've served us well, and can ride off into the sunset.
Diffstat (limited to 'sys/src/cmd/python/Python')
-rw-r--r--sys/src/cmd/python/Python/Python-ast.c3202
-rw-r--r--sys/src/cmd/python/Python/asdl.c36
-rw-r--r--sys/src/cmd/python/Python/ast.c3292
-rw-r--r--sys/src/cmd/python/Python/atof.c50
-rw-r--r--sys/src/cmd/python/Python/bltinmodule.c2620
-rw-r--r--sys/src/cmd/python/Python/ceval.c4351
-rw-r--r--sys/src/cmd/python/Python/codecs.c860
-rw-r--r--sys/src/cmd/python/Python/compile.c4570
-rw-r--r--sys/src/cmd/python/Python/dup2.c30
-rw-r--r--sys/src/cmd/python/Python/dynload_aix.c183
-rw-r--r--sys/src/cmd/python/Python/dynload_atheos.c47
-rw-r--r--sys/src/cmd/python/Python/dynload_beos.c254
-rw-r--r--sys/src/cmd/python/Python/dynload_dl.c26
-rw-r--r--sys/src/cmd/python/Python/dynload_hpux.c58
-rw-r--r--sys/src/cmd/python/Python/dynload_next.c114
-rw-r--r--sys/src/cmd/python/Python/dynload_os2.c46
-rw-r--r--sys/src/cmd/python/Python/dynload_shlib.c143
-rw-r--r--sys/src/cmd/python/Python/dynload_stub.c11
-rw-r--r--sys/src/cmd/python/Python/dynload_win.c263
-rw-r--r--sys/src/cmd/python/Python/errors.c822
-rw-r--r--sys/src/cmd/python/Python/fmod.c27
-rw-r--r--sys/src/cmd/python/Python/frozen.c38
-rw-r--r--sys/src/cmd/python/Python/frozenmain.c68
-rw-r--r--sys/src/cmd/python/Python/future.c136
-rw-r--r--sys/src/cmd/python/Python/getargs.c1771
-rw-r--r--sys/src/cmd/python/Python/getcompiler.c28
-rw-r--r--sys/src/cmd/python/Python/getcopyright.c23
-rw-r--r--sys/src/cmd/python/Python/getcwd.c83
-rw-r--r--sys/src/cmd/python/Python/getmtime.c26
-rw-r--r--sys/src/cmd/python/Python/getopt.c115
-rw-r--r--sys/src/cmd/python/Python/getplatform.c12
-rw-r--r--sys/src/cmd/python/Python/getversion.c15
-rw-r--r--sys/src/cmd/python/Python/hypot.c23
-rw-r--r--sys/src/cmd/python/Python/import.c3033
-rw-r--r--sys/src/cmd/python/Python/importdl.c78
-rw-r--r--sys/src/cmd/python/Python/importdl.h53
-rw-r--r--sys/src/cmd/python/Python/mactoolboxglue.c470
-rw-r--r--sys/src/cmd/python/Python/marshal.c1155
-rw-r--r--sys/src/cmd/python/Python/memmove.c25
-rw-r--r--sys/src/cmd/python/Python/mkfile62
-rw-r--r--sys/src/cmd/python/Python/modsupport.c631
-rw-r--r--sys/src/cmd/python/Python/mysnprintf.c93
-rw-r--r--sys/src/cmd/python/Python/mystrtoul.c232
-rw-r--r--sys/src/cmd/python/Python/pyarena.c220
-rw-r--r--sys/src/cmd/python/Python/pyfpe.c23
-rw-r--r--sys/src/cmd/python/Python/pystate.c632
-rw-r--r--sys/src/cmd/python/Python/pystrtod.c248
-rw-r--r--sys/src/cmd/python/Python/pythonrun.c1857
-rw-r--r--sys/src/cmd/python/Python/sigcheck.c19
-rw-r--r--sys/src/cmd/python/Python/strdup.c14
-rw-r--r--sys/src/cmd/python/Python/strerror.c19
-rw-r--r--sys/src/cmd/python/Python/strtod.c156
-rw-r--r--sys/src/cmd/python/Python/structmember.c312
-rw-r--r--sys/src/cmd/python/Python/symtable.c1425
-rw-r--r--sys/src/cmd/python/Python/sysmodule.c1468
-rw-r--r--sys/src/cmd/python/Python/thread.c384
-rw-r--r--sys/src/cmd/python/Python/thread_atheos.h300
-rw-r--r--sys/src/cmd/python/Python/thread_beos.h287
-rw-r--r--sys/src/cmd/python/Python/thread_cthread.h156
-rw-r--r--sys/src/cmd/python/Python/thread_foobar.h115
-rw-r--r--sys/src/cmd/python/Python/thread_lwp.h149
-rw-r--r--sys/src/cmd/python/Python/thread_nt.h364
-rw-r--r--sys/src/cmd/python/Python/thread_os2.h307
-rw-r--r--sys/src/cmd/python/Python/thread_plan9.h135
-rw-r--r--sys/src/cmd/python/Python/thread_pth.h213
-rw-r--r--sys/src/cmd/python/Python/thread_pthread.h533
-rw-r--r--sys/src/cmd/python/Python/thread_sgi.h375
-rw-r--r--sys/src/cmd/python/Python/thread_solaris.h174
-rw-r--r--sys/src/cmd/python/Python/thread_wince.h171
-rw-r--r--sys/src/cmd/python/Python/traceback.c262
70 files changed, 0 insertions, 39493 deletions
diff --git a/sys/src/cmd/python/Python/Python-ast.c b/sys/src/cmd/python/Python/Python-ast.c
deleted file mode 100644
index 7a0f52825..000000000
--- a/sys/src/cmd/python/Python/Python-ast.c
+++ /dev/null
@@ -1,3202 +0,0 @@
-/* File automatically generated by Parser/asdl_c.py */
-
-#include "Python.h"
-#include "Python-ast.h"
-
-static PyTypeObject* AST_type;
-static PyTypeObject *mod_type;
-static PyObject* ast2obj_mod(void*);
-static PyTypeObject *Module_type;
-static char *Module_fields[]={
- "body",
-};
-static PyTypeObject *Interactive_type;
-static char *Interactive_fields[]={
- "body",
-};
-static PyTypeObject *Expression_type;
-static char *Expression_fields[]={
- "body",
-};
-static PyTypeObject *Suite_type;
-static char *Suite_fields[]={
- "body",
-};
-static PyTypeObject *stmt_type;
-static char *stmt_attributes[] = {
- "lineno",
- "col_offset",
-};
-static PyObject* ast2obj_stmt(void*);
-static PyTypeObject *FunctionDef_type;
-static char *FunctionDef_fields[]={
- "name",
- "args",
- "body",
- "decorators",
-};
-static PyTypeObject *ClassDef_type;
-static char *ClassDef_fields[]={
- "name",
- "bases",
- "body",
-};
-static PyTypeObject *Return_type;
-static char *Return_fields[]={
- "value",
-};
-static PyTypeObject *Delete_type;
-static char *Delete_fields[]={
- "targets",
-};
-static PyTypeObject *Assign_type;
-static char *Assign_fields[]={
- "targets",
- "value",
-};
-static PyTypeObject *AugAssign_type;
-static char *AugAssign_fields[]={
- "target",
- "op",
- "value",
-};
-static PyTypeObject *Print_type;
-static char *Print_fields[]={
- "dest",
- "values",
- "nl",
-};
-static PyTypeObject *For_type;
-static char *For_fields[]={
- "target",
- "iter",
- "body",
- "orelse",
-};
-static PyTypeObject *While_type;
-static char *While_fields[]={
- "test",
- "body",
- "orelse",
-};
-static PyTypeObject *If_type;
-static char *If_fields[]={
- "test",
- "body",
- "orelse",
-};
-static PyTypeObject *With_type;
-static char *With_fields[]={
- "context_expr",
- "optional_vars",
- "body",
-};
-static PyTypeObject *Raise_type;
-static char *Raise_fields[]={
- "type",
- "inst",
- "tback",
-};
-static PyTypeObject *TryExcept_type;
-static char *TryExcept_fields[]={
- "body",
- "handlers",
- "orelse",
-};
-static PyTypeObject *TryFinally_type;
-static char *TryFinally_fields[]={
- "body",
- "finalbody",
-};
-static PyTypeObject *Assert_type;
-static char *Assert_fields[]={
- "test",
- "msg",
-};
-static PyTypeObject *Import_type;
-static char *Import_fields[]={
- "names",
-};
-static PyTypeObject *ImportFrom_type;
-static char *ImportFrom_fields[]={
- "module",
- "names",
- "level",
-};
-static PyTypeObject *Exec_type;
-static char *Exec_fields[]={
- "body",
- "globals",
- "locals",
-};
-static PyTypeObject *Global_type;
-static char *Global_fields[]={
- "names",
-};
-static PyTypeObject *Expr_type;
-static char *Expr_fields[]={
- "value",
-};
-static PyTypeObject *Pass_type;
-static PyTypeObject *Break_type;
-static PyTypeObject *Continue_type;
-static PyTypeObject *expr_type;
-static char *expr_attributes[] = {
- "lineno",
- "col_offset",
-};
-static PyObject* ast2obj_expr(void*);
-static PyTypeObject *BoolOp_type;
-static char *BoolOp_fields[]={
- "op",
- "values",
-};
-static PyTypeObject *BinOp_type;
-static char *BinOp_fields[]={
- "left",
- "op",
- "right",
-};
-static PyTypeObject *UnaryOp_type;
-static char *UnaryOp_fields[]={
- "op",
- "operand",
-};
-static PyTypeObject *Lambda_type;
-static char *Lambda_fields[]={
- "args",
- "body",
-};
-static PyTypeObject *IfExp_type;
-static char *IfExp_fields[]={
- "test",
- "body",
- "orelse",
-};
-static PyTypeObject *Dict_type;
-static char *Dict_fields[]={
- "keys",
- "values",
-};
-static PyTypeObject *ListComp_type;
-static char *ListComp_fields[]={
- "elt",
- "generators",
-};
-static PyTypeObject *GeneratorExp_type;
-static char *GeneratorExp_fields[]={
- "elt",
- "generators",
-};
-static PyTypeObject *Yield_type;
-static char *Yield_fields[]={
- "value",
-};
-static PyTypeObject *Compare_type;
-static char *Compare_fields[]={
- "left",
- "ops",
- "comparators",
-};
-static PyTypeObject *Call_type;
-static char *Call_fields[]={
- "func",
- "args",
- "keywords",
- "starargs",
- "kwargs",
-};
-static PyTypeObject *Repr_type;
-static char *Repr_fields[]={
- "value",
-};
-static PyTypeObject *Num_type;
-static char *Num_fields[]={
- "n",
-};
-static PyTypeObject *Str_type;
-static char *Str_fields[]={
- "s",
-};
-static PyTypeObject *Attribute_type;
-static char *Attribute_fields[]={
- "value",
- "attr",
- "ctx",
-};
-static PyTypeObject *Subscript_type;
-static char *Subscript_fields[]={
- "value",
- "slice",
- "ctx",
-};
-static PyTypeObject *Name_type;
-static char *Name_fields[]={
- "id",
- "ctx",
-};
-static PyTypeObject *List_type;
-static char *List_fields[]={
- "elts",
- "ctx",
-};
-static PyTypeObject *Tuple_type;
-static char *Tuple_fields[]={
- "elts",
- "ctx",
-};
-static PyTypeObject *expr_context_type;
-static PyObject *Load_singleton, *Store_singleton, *Del_singleton,
-*AugLoad_singleton, *AugStore_singleton, *Param_singleton;
-static PyObject* ast2obj_expr_context(expr_context_ty);
-static PyTypeObject *Load_type;
-static PyTypeObject *Store_type;
-static PyTypeObject *Del_type;
-static PyTypeObject *AugLoad_type;
-static PyTypeObject *AugStore_type;
-static PyTypeObject *Param_type;
-static PyTypeObject *slice_type;
-static PyObject* ast2obj_slice(void*);
-static PyTypeObject *Ellipsis_type;
-static PyTypeObject *Slice_type;
-static char *Slice_fields[]={
- "lower",
- "upper",
- "step",
-};
-static PyTypeObject *ExtSlice_type;
-static char *ExtSlice_fields[]={
- "dims",
-};
-static PyTypeObject *Index_type;
-static char *Index_fields[]={
- "value",
-};
-static PyTypeObject *boolop_type;
-static PyObject *And_singleton, *Or_singleton;
-static PyObject* ast2obj_boolop(boolop_ty);
-static PyTypeObject *And_type;
-static PyTypeObject *Or_type;
-static PyTypeObject *operator_type;
-static PyObject *Add_singleton, *Sub_singleton, *Mult_singleton,
-*Div_singleton, *Mod_singleton, *Pow_singleton, *LShift_singleton,
-*RShift_singleton, *BitOr_singleton, *BitXor_singleton, *BitAnd_singleton,
-*FloorDiv_singleton;
-static PyObject* ast2obj_operator(operator_ty);
-static PyTypeObject *Add_type;
-static PyTypeObject *Sub_type;
-static PyTypeObject *Mult_type;
-static PyTypeObject *Div_type;
-static PyTypeObject *Mod_type;
-static PyTypeObject *Pow_type;
-static PyTypeObject *LShift_type;
-static PyTypeObject *RShift_type;
-static PyTypeObject *BitOr_type;
-static PyTypeObject *BitXor_type;
-static PyTypeObject *BitAnd_type;
-static PyTypeObject *FloorDiv_type;
-static PyTypeObject *unaryop_type;
-static PyObject *Invert_singleton, *Not_singleton, *UAdd_singleton,
-*USub_singleton;
-static PyObject* ast2obj_unaryop(unaryop_ty);
-static PyTypeObject *Invert_type;
-static PyTypeObject *Not_type;
-static PyTypeObject *UAdd_type;
-static PyTypeObject *USub_type;
-static PyTypeObject *cmpop_type;
-static PyObject *Eq_singleton, *NotEq_singleton, *Lt_singleton, *LtE_singleton,
-*Gt_singleton, *GtE_singleton, *Is_singleton, *IsNot_singleton, *In_singleton,
-*NotIn_singleton;
-static PyObject* ast2obj_cmpop(cmpop_ty);
-static PyTypeObject *Eq_type;
-static PyTypeObject *NotEq_type;
-static PyTypeObject *Lt_type;
-static PyTypeObject *LtE_type;
-static PyTypeObject *Gt_type;
-static PyTypeObject *GtE_type;
-static PyTypeObject *Is_type;
-static PyTypeObject *IsNot_type;
-static PyTypeObject *In_type;
-static PyTypeObject *NotIn_type;
-static PyTypeObject *comprehension_type;
-static PyObject* ast2obj_comprehension(void*);
-static char *comprehension_fields[]={
- "target",
- "iter",
- "ifs",
-};
-static PyTypeObject *excepthandler_type;
-static PyObject* ast2obj_excepthandler(void*);
-static char *excepthandler_fields[]={
- "type",
- "name",
- "body",
- "lineno",
- "col_offset",
-};
-static PyTypeObject *arguments_type;
-static PyObject* ast2obj_arguments(void*);
-static char *arguments_fields[]={
- "args",
- "vararg",
- "kwarg",
- "defaults",
-};
-static PyTypeObject *keyword_type;
-static PyObject* ast2obj_keyword(void*);
-static char *keyword_fields[]={
- "arg",
- "value",
-};
-static PyTypeObject *alias_type;
-static PyObject* ast2obj_alias(void*);
-static char *alias_fields[]={
- "name",
- "asname",
-};
-
-
-static PyTypeObject* make_type(char *type, PyTypeObject* base, char**fields, int num_fields)
-{
- PyObject *fnames, *result;
- int i;
- if (num_fields) {
- fnames = PyTuple_New(num_fields);
- if (!fnames) return NULL;
- } else {
- fnames = Py_None;
- Py_INCREF(Py_None);
- }
- for(i=0; i < num_fields; i++) {
- PyObject *field = PyString_FromString(fields[i]);
- if (!field) {
- Py_DECREF(fnames);
- return NULL;
- }
- PyTuple_SET_ITEM(fnames, i, field);
- }
- result = PyObject_CallFunction((PyObject*)&PyType_Type, "s(O){sOss}",
- type, base, "_fields", fnames, "__module__", "_ast");
- Py_DECREF(fnames);
- return (PyTypeObject*)result;
-}
-
-static int add_attributes(PyTypeObject* type, char**attrs, int num_fields)
-{
- int i, result;
- PyObject *s, *l = PyList_New(num_fields);
- if (!l) return 0;
- for(i = 0; i < num_fields; i++) {
- s = PyString_FromString(attrs[i]);
- if (!s) {
- Py_DECREF(l);
- return 0;
- }
- PyList_SET_ITEM(l, i, s);
- }
- result = PyObject_SetAttrString((PyObject*)type, "_attributes", l) >= 0;
- Py_DECREF(l);
- return result;
-}
-
-static PyObject* ast2obj_list(asdl_seq *seq, PyObject* (*func)(void*))
-{
- int i, n = asdl_seq_LEN(seq);
- PyObject *result = PyList_New(n);
- PyObject *value;
- if (!result)
- return NULL;
- for (i = 0; i < n; i++) {
- value = func(asdl_seq_GET(seq, i));
- if (!value) {
- Py_DECREF(result);
- return NULL;
- }
- PyList_SET_ITEM(result, i, value);
- }
- return result;
-}
-
-static PyObject* ast2obj_object(void *o)
-{
- if (!o)
- o = Py_None;
- Py_INCREF((PyObject*)o);
- return (PyObject*)o;
-}
-#define ast2obj_identifier ast2obj_object
-#define ast2obj_string ast2obj_object
-static PyObject* ast2obj_bool(bool b)
-{
- return PyBool_FromLong(b);
-}
-
-static PyObject* ast2obj_int(bool b)
-{
- return PyInt_FromLong(b);
-}
-
-static int init_types(void)
-{
- static int initialized;
- if (initialized) return 1;
- AST_type = make_type("AST", &PyBaseObject_Type, NULL, 0);
- mod_type = make_type("mod", AST_type, NULL, 0);
- if (!mod_type) return 0;
- if (!add_attributes(mod_type, NULL, 0)) return 0;
- Module_type = make_type("Module", mod_type, Module_fields, 1);
- if (!Module_type) return 0;
- Interactive_type = make_type("Interactive", mod_type,
- Interactive_fields, 1);
- if (!Interactive_type) return 0;
- Expression_type = make_type("Expression", mod_type, Expression_fields,
- 1);
- if (!Expression_type) return 0;
- Suite_type = make_type("Suite", mod_type, Suite_fields, 1);
- if (!Suite_type) return 0;
- stmt_type = make_type("stmt", AST_type, NULL, 0);
- if (!stmt_type) return 0;
- if (!add_attributes(stmt_type, stmt_attributes, 2)) return 0;
- FunctionDef_type = make_type("FunctionDef", stmt_type,
- FunctionDef_fields, 4);
- if (!FunctionDef_type) return 0;
- ClassDef_type = make_type("ClassDef", stmt_type, ClassDef_fields, 3);
- if (!ClassDef_type) return 0;
- Return_type = make_type("Return", stmt_type, Return_fields, 1);
- if (!Return_type) return 0;
- Delete_type = make_type("Delete", stmt_type, Delete_fields, 1);
- if (!Delete_type) return 0;
- Assign_type = make_type("Assign", stmt_type, Assign_fields, 2);
- if (!Assign_type) return 0;
- AugAssign_type = make_type("AugAssign", stmt_type, AugAssign_fields, 3);
- if (!AugAssign_type) return 0;
- Print_type = make_type("Print", stmt_type, Print_fields, 3);
- if (!Print_type) return 0;
- For_type = make_type("For", stmt_type, For_fields, 4);
- if (!For_type) return 0;
- While_type = make_type("While", stmt_type, While_fields, 3);
- if (!While_type) return 0;
- If_type = make_type("If", stmt_type, If_fields, 3);
- if (!If_type) return 0;
- With_type = make_type("With", stmt_type, With_fields, 3);
- if (!With_type) return 0;
- Raise_type = make_type("Raise", stmt_type, Raise_fields, 3);
- if (!Raise_type) return 0;
- TryExcept_type = make_type("TryExcept", stmt_type, TryExcept_fields, 3);
- if (!TryExcept_type) return 0;
- TryFinally_type = make_type("TryFinally", stmt_type, TryFinally_fields,
- 2);
- if (!TryFinally_type) return 0;
- Assert_type = make_type("Assert", stmt_type, Assert_fields, 2);
- if (!Assert_type) return 0;
- Import_type = make_type("Import", stmt_type, Import_fields, 1);
- if (!Import_type) return 0;
- ImportFrom_type = make_type("ImportFrom", stmt_type, ImportFrom_fields,
- 3);
- if (!ImportFrom_type) return 0;
- Exec_type = make_type("Exec", stmt_type, Exec_fields, 3);
- if (!Exec_type) return 0;
- Global_type = make_type("Global", stmt_type, Global_fields, 1);
- if (!Global_type) return 0;
- Expr_type = make_type("Expr", stmt_type, Expr_fields, 1);
- if (!Expr_type) return 0;
- Pass_type = make_type("Pass", stmt_type, NULL, 0);
- if (!Pass_type) return 0;
- Break_type = make_type("Break", stmt_type, NULL, 0);
- if (!Break_type) return 0;
- Continue_type = make_type("Continue", stmt_type, NULL, 0);
- if (!Continue_type) return 0;
- expr_type = make_type("expr", AST_type, NULL, 0);
- if (!expr_type) return 0;
- if (!add_attributes(expr_type, expr_attributes, 2)) return 0;
- BoolOp_type = make_type("BoolOp", expr_type, BoolOp_fields, 2);
- if (!BoolOp_type) return 0;
- BinOp_type = make_type("BinOp", expr_type, BinOp_fields, 3);
- if (!BinOp_type) return 0;
- UnaryOp_type = make_type("UnaryOp", expr_type, UnaryOp_fields, 2);
- if (!UnaryOp_type) return 0;
- Lambda_type = make_type("Lambda", expr_type, Lambda_fields, 2);
- if (!Lambda_type) return 0;
- IfExp_type = make_type("IfExp", expr_type, IfExp_fields, 3);
- if (!IfExp_type) return 0;
- Dict_type = make_type("Dict", expr_type, Dict_fields, 2);
- if (!Dict_type) return 0;
- ListComp_type = make_type("ListComp", expr_type, ListComp_fields, 2);
- if (!ListComp_type) return 0;
- GeneratorExp_type = make_type("GeneratorExp", expr_type,
- GeneratorExp_fields, 2);
- if (!GeneratorExp_type) return 0;
- Yield_type = make_type("Yield", expr_type, Yield_fields, 1);
- if (!Yield_type) return 0;
- Compare_type = make_type("Compare", expr_type, Compare_fields, 3);
- if (!Compare_type) return 0;
- Call_type = make_type("Call", expr_type, Call_fields, 5);
- if (!Call_type) return 0;
- Repr_type = make_type("Repr", expr_type, Repr_fields, 1);
- if (!Repr_type) return 0;
- Num_type = make_type("Num", expr_type, Num_fields, 1);
- if (!Num_type) return 0;
- Str_type = make_type("Str", expr_type, Str_fields, 1);
- if (!Str_type) return 0;
- Attribute_type = make_type("Attribute", expr_type, Attribute_fields, 3);
- if (!Attribute_type) return 0;
- Subscript_type = make_type("Subscript", expr_type, Subscript_fields, 3);
- if (!Subscript_type) return 0;
- Name_type = make_type("Name", expr_type, Name_fields, 2);
- if (!Name_type) return 0;
- List_type = make_type("List", expr_type, List_fields, 2);
- if (!List_type) return 0;
- Tuple_type = make_type("Tuple", expr_type, Tuple_fields, 2);
- if (!Tuple_type) return 0;
- expr_context_type = make_type("expr_context", AST_type, NULL, 0);
- if (!expr_context_type) return 0;
- if (!add_attributes(expr_context_type, NULL, 0)) return 0;
- Load_type = make_type("Load", expr_context_type, NULL, 0);
- if (!Load_type) return 0;
- Load_singleton = PyType_GenericNew(Load_type, NULL, NULL);
- if (!Load_singleton) return 0;
- Store_type = make_type("Store", expr_context_type, NULL, 0);
- if (!Store_type) return 0;
- Store_singleton = PyType_GenericNew(Store_type, NULL, NULL);
- if (!Store_singleton) return 0;
- Del_type = make_type("Del", expr_context_type, NULL, 0);
- if (!Del_type) return 0;
- Del_singleton = PyType_GenericNew(Del_type, NULL, NULL);
- if (!Del_singleton) return 0;
- AugLoad_type = make_type("AugLoad", expr_context_type, NULL, 0);
- if (!AugLoad_type) return 0;
- AugLoad_singleton = PyType_GenericNew(AugLoad_type, NULL, NULL);
- if (!AugLoad_singleton) return 0;
- AugStore_type = make_type("AugStore", expr_context_type, NULL, 0);
- if (!AugStore_type) return 0;
- AugStore_singleton = PyType_GenericNew(AugStore_type, NULL, NULL);
- if (!AugStore_singleton) return 0;
- Param_type = make_type("Param", expr_context_type, NULL, 0);
- if (!Param_type) return 0;
- Param_singleton = PyType_GenericNew(Param_type, NULL, NULL);
- if (!Param_singleton) return 0;
- slice_type = make_type("slice", AST_type, NULL, 0);
- if (!slice_type) return 0;
- if (!add_attributes(slice_type, NULL, 0)) return 0;
- Ellipsis_type = make_type("Ellipsis", slice_type, NULL, 0);
- if (!Ellipsis_type) return 0;
- Slice_type = make_type("Slice", slice_type, Slice_fields, 3);
- if (!Slice_type) return 0;
- ExtSlice_type = make_type("ExtSlice", slice_type, ExtSlice_fields, 1);
- if (!ExtSlice_type) return 0;
- Index_type = make_type("Index", slice_type, Index_fields, 1);
- if (!Index_type) return 0;
- boolop_type = make_type("boolop", AST_type, NULL, 0);
- if (!boolop_type) return 0;
- if (!add_attributes(boolop_type, NULL, 0)) return 0;
- And_type = make_type("And", boolop_type, NULL, 0);
- if (!And_type) return 0;
- And_singleton = PyType_GenericNew(And_type, NULL, NULL);
- if (!And_singleton) return 0;
- Or_type = make_type("Or", boolop_type, NULL, 0);
- if (!Or_type) return 0;
- Or_singleton = PyType_GenericNew(Or_type, NULL, NULL);
- if (!Or_singleton) return 0;
- operator_type = make_type("operator", AST_type, NULL, 0);
- if (!operator_type) return 0;
- if (!add_attributes(operator_type, NULL, 0)) return 0;
- Add_type = make_type("Add", operator_type, NULL, 0);
- if (!Add_type) return 0;
- Add_singleton = PyType_GenericNew(Add_type, NULL, NULL);
- if (!Add_singleton) return 0;
- Sub_type = make_type("Sub", operator_type, NULL, 0);
- if (!Sub_type) return 0;
- Sub_singleton = PyType_GenericNew(Sub_type, NULL, NULL);
- if (!Sub_singleton) return 0;
- Mult_type = make_type("Mult", operator_type, NULL, 0);
- if (!Mult_type) return 0;
- Mult_singleton = PyType_GenericNew(Mult_type, NULL, NULL);
- if (!Mult_singleton) return 0;
- Div_type = make_type("Div", operator_type, NULL, 0);
- if (!Div_type) return 0;
- Div_singleton = PyType_GenericNew(Div_type, NULL, NULL);
- if (!Div_singleton) return 0;
- Mod_type = make_type("Mod", operator_type, NULL, 0);
- if (!Mod_type) return 0;
- Mod_singleton = PyType_GenericNew(Mod_type, NULL, NULL);
- if (!Mod_singleton) return 0;
- Pow_type = make_type("Pow", operator_type, NULL, 0);
- if (!Pow_type) return 0;
- Pow_singleton = PyType_GenericNew(Pow_type, NULL, NULL);
- if (!Pow_singleton) return 0;
- LShift_type = make_type("LShift", operator_type, NULL, 0);
- if (!LShift_type) return 0;
- LShift_singleton = PyType_GenericNew(LShift_type, NULL, NULL);
- if (!LShift_singleton) return 0;
- RShift_type = make_type("RShift", operator_type, NULL, 0);
- if (!RShift_type) return 0;
- RShift_singleton = PyType_GenericNew(RShift_type, NULL, NULL);
- if (!RShift_singleton) return 0;
- BitOr_type = make_type("BitOr", operator_type, NULL, 0);
- if (!BitOr_type) return 0;
- BitOr_singleton = PyType_GenericNew(BitOr_type, NULL, NULL);
- if (!BitOr_singleton) return 0;
- BitXor_type = make_type("BitXor", operator_type, NULL, 0);
- if (!BitXor_type) return 0;
- BitXor_singleton = PyType_GenericNew(BitXor_type, NULL, NULL);
- if (!BitXor_singleton) return 0;
- BitAnd_type = make_type("BitAnd", operator_type, NULL, 0);
- if (!BitAnd_type) return 0;
- BitAnd_singleton = PyType_GenericNew(BitAnd_type, NULL, NULL);
- if (!BitAnd_singleton) return 0;
- FloorDiv_type = make_type("FloorDiv", operator_type, NULL, 0);
- if (!FloorDiv_type) return 0;
- FloorDiv_singleton = PyType_GenericNew(FloorDiv_type, NULL, NULL);
- if (!FloorDiv_singleton) return 0;
- unaryop_type = make_type("unaryop", AST_type, NULL, 0);
- if (!unaryop_type) return 0;
- if (!add_attributes(unaryop_type, NULL, 0)) return 0;
- Invert_type = make_type("Invert", unaryop_type, NULL, 0);
- if (!Invert_type) return 0;
- Invert_singleton = PyType_GenericNew(Invert_type, NULL, NULL);
- if (!Invert_singleton) return 0;
- Not_type = make_type("Not", unaryop_type, NULL, 0);
- if (!Not_type) return 0;
- Not_singleton = PyType_GenericNew(Not_type, NULL, NULL);
- if (!Not_singleton) return 0;
- UAdd_type = make_type("UAdd", unaryop_type, NULL, 0);
- if (!UAdd_type) return 0;
- UAdd_singleton = PyType_GenericNew(UAdd_type, NULL, NULL);
- if (!UAdd_singleton) return 0;
- USub_type = make_type("USub", unaryop_type, NULL, 0);
- if (!USub_type) return 0;
- USub_singleton = PyType_GenericNew(USub_type, NULL, NULL);
- if (!USub_singleton) return 0;
- cmpop_type = make_type("cmpop", AST_type, NULL, 0);
- if (!cmpop_type) return 0;
- if (!add_attributes(cmpop_type, NULL, 0)) return 0;
- Eq_type = make_type("Eq", cmpop_type, NULL, 0);
- if (!Eq_type) return 0;
- Eq_singleton = PyType_GenericNew(Eq_type, NULL, NULL);
- if (!Eq_singleton) return 0;
- NotEq_type = make_type("NotEq", cmpop_type, NULL, 0);
- if (!NotEq_type) return 0;
- NotEq_singleton = PyType_GenericNew(NotEq_type, NULL, NULL);
- if (!NotEq_singleton) return 0;
- Lt_type = make_type("Lt", cmpop_type, NULL, 0);
- if (!Lt_type) return 0;
- Lt_singleton = PyType_GenericNew(Lt_type, NULL, NULL);
- if (!Lt_singleton) return 0;
- LtE_type = make_type("LtE", cmpop_type, NULL, 0);
- if (!LtE_type) return 0;
- LtE_singleton = PyType_GenericNew(LtE_type, NULL, NULL);
- if (!LtE_singleton) return 0;
- Gt_type = make_type("Gt", cmpop_type, NULL, 0);
- if (!Gt_type) return 0;
- Gt_singleton = PyType_GenericNew(Gt_type, NULL, NULL);
- if (!Gt_singleton) return 0;
- GtE_type = make_type("GtE", cmpop_type, NULL, 0);
- if (!GtE_type) return 0;
- GtE_singleton = PyType_GenericNew(GtE_type, NULL, NULL);
- if (!GtE_singleton) return 0;
- Is_type = make_type("Is", cmpop_type, NULL, 0);
- if (!Is_type) return 0;
- Is_singleton = PyType_GenericNew(Is_type, NULL, NULL);
- if (!Is_singleton) return 0;
- IsNot_type = make_type("IsNot", cmpop_type, NULL, 0);
- if (!IsNot_type) return 0;
- IsNot_singleton = PyType_GenericNew(IsNot_type, NULL, NULL);
- if (!IsNot_singleton) return 0;
- In_type = make_type("In", cmpop_type, NULL, 0);
- if (!In_type) return 0;
- In_singleton = PyType_GenericNew(In_type, NULL, NULL);
- if (!In_singleton) return 0;
- NotIn_type = make_type("NotIn", cmpop_type, NULL, 0);
- if (!NotIn_type) return 0;
- NotIn_singleton = PyType_GenericNew(NotIn_type, NULL, NULL);
- if (!NotIn_singleton) return 0;
- comprehension_type = make_type("comprehension", AST_type,
- comprehension_fields, 3);
- if (!comprehension_type) return 0;
- excepthandler_type = make_type("excepthandler", AST_type,
- excepthandler_fields, 5);
- if (!excepthandler_type) return 0;
- arguments_type = make_type("arguments", AST_type, arguments_fields, 4);
- if (!arguments_type) return 0;
- keyword_type = make_type("keyword", AST_type, keyword_fields, 2);
- if (!keyword_type) return 0;
- alias_type = make_type("alias", AST_type, alias_fields, 2);
- if (!alias_type) return 0;
- initialized = 1;
- return 1;
-}
-
-mod_ty
-Module(asdl_seq * body, PyArena *arena)
-{
- mod_ty p;
- p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Module_kind;
- p->v.Module.body = body;
- return p;
-}
-
-mod_ty
-Interactive(asdl_seq * body, PyArena *arena)
-{
- mod_ty p;
- p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Interactive_kind;
- p->v.Interactive.body = body;
- return p;
-}
-
-mod_ty
-Expression(expr_ty body, PyArena *arena)
-{
- mod_ty p;
- if (!body) {
- PyErr_SetString(PyExc_ValueError,
- "field body is required for Expression");
- return NULL;
- }
- p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Expression_kind;
- p->v.Expression.body = body;
- return p;
-}
-
-mod_ty
-Suite(asdl_seq * body, PyArena *arena)
-{
- mod_ty p;
- p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Suite_kind;
- p->v.Suite.body = body;
- return p;
-}
-
-stmt_ty
-FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
- decorators, int lineno, int col_offset, PyArena *arena)
-{
- stmt_ty p;
- if (!name) {
- PyErr_SetString(PyExc_ValueError,
- "field name is required for FunctionDef");
- return NULL;
- }
- if (!args) {
- PyErr_SetString(PyExc_ValueError,
- "field args is required for FunctionDef");
- return NULL;
- }
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = FunctionDef_kind;
- p->v.FunctionDef.name = name;
- p->v.FunctionDef.args = args;
- p->v.FunctionDef.body = body;
- p->v.FunctionDef.decorators = decorators;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int lineno, int
- col_offset, PyArena *arena)
-{
- stmt_ty p;
- if (!name) {
- PyErr_SetString(PyExc_ValueError,
- "field name is required for ClassDef");
- return NULL;
- }
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = ClassDef_kind;
- p->v.ClassDef.name = name;
- p->v.ClassDef.bases = bases;
- p->v.ClassDef.body = body;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Return(expr_ty value, int lineno, int col_offset, PyArena *arena)
-{
- stmt_ty p;
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Return_kind;
- p->v.Return.value = value;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Delete(asdl_seq * targets, int lineno, int col_offset, PyArena *arena)
-{
- stmt_ty p;
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Delete_kind;
- p->v.Delete.targets = targets;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Assign(asdl_seq * targets, expr_ty value, int lineno, int col_offset, PyArena
- *arena)
-{
- stmt_ty p;
- if (!value) {
- PyErr_SetString(PyExc_ValueError,
- "field value is required for Assign");
- return NULL;
- }
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Assign_kind;
- p->v.Assign.targets = targets;
- p->v.Assign.value = value;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int
- col_offset, PyArena *arena)
-{
- stmt_ty p;
- if (!target) {
- PyErr_SetString(PyExc_ValueError,
- "field target is required for AugAssign");
- return NULL;
- }
- if (!op) {
- PyErr_SetString(PyExc_ValueError,
- "field op is required for AugAssign");
- return NULL;
- }
- if (!value) {
- PyErr_SetString(PyExc_ValueError,
- "field value is required for AugAssign");
- return NULL;
- }
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = AugAssign_kind;
- p->v.AugAssign.target = target;
- p->v.AugAssign.op = op;
- p->v.AugAssign.value = value;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, int col_offset,
- PyArena *arena)
-{
- stmt_ty p;
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Print_kind;
- p->v.Print.dest = dest;
- p->v.Print.values = values;
- p->v.Print.nl = nl;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int
- lineno, int col_offset, PyArena *arena)
-{
- stmt_ty p;
- if (!target) {
- PyErr_SetString(PyExc_ValueError,
- "field target is required for For");
- return NULL;
- }
- if (!iter) {
- PyErr_SetString(PyExc_ValueError,
- "field iter is required for For");
- return NULL;
- }
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = For_kind;
- p->v.For.target = target;
- p->v.For.iter = iter;
- p->v.For.body = body;
- p->v.For.orelse = orelse;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int
- col_offset, PyArena *arena)
-{
- stmt_ty p;
- if (!test) {
- PyErr_SetString(PyExc_ValueError,
- "field test is required for While");
- return NULL;
- }
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = While_kind;
- p->v.While.test = test;
- p->v.While.body = body;
- p->v.While.orelse = orelse;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int
- col_offset, PyArena *arena)
-{
- stmt_ty p;
- if (!test) {
- PyErr_SetString(PyExc_ValueError,
- "field test is required for If");
- return NULL;
- }
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = If_kind;
- p->v.If.test = test;
- p->v.If.body = body;
- p->v.If.orelse = orelse;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, int lineno,
- int col_offset, PyArena *arena)
-{
- stmt_ty p;
- if (!context_expr) {
- PyErr_SetString(PyExc_ValueError,
- "field context_expr is required for With");
- return NULL;
- }
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = With_kind;
- p->v.With.context_expr = context_expr;
- p->v.With.optional_vars = optional_vars;
- p->v.With.body = body;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, int col_offset,
- PyArena *arena)
-{
- stmt_ty p;
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Raise_kind;
- p->v.Raise.type = type;
- p->v.Raise.inst = inst;
- p->v.Raise.tback = tback;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int lineno,
- int col_offset, PyArena *arena)
-{
- stmt_ty p;
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = TryExcept_kind;
- p->v.TryExcept.body = body;
- p->v.TryExcept.handlers = handlers;
- p->v.TryExcept.orelse = orelse;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int col_offset,
- PyArena *arena)
-{
- stmt_ty p;
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = TryFinally_kind;
- p->v.TryFinally.body = body;
- p->v.TryFinally.finalbody = finalbody;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, PyArena *arena)
-{
- stmt_ty p;
- if (!test) {
- PyErr_SetString(PyExc_ValueError,
- "field test is required for Assert");
- return NULL;
- }
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Assert_kind;
- p->v.Assert.test = test;
- p->v.Assert.msg = msg;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Import(asdl_seq * names, int lineno, int col_offset, PyArena *arena)
-{
- stmt_ty p;
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Import_kind;
- p->v.Import.names = names;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-ImportFrom(identifier module, asdl_seq * names, int level, int lineno, int
- col_offset, PyArena *arena)
-{
- stmt_ty p;
- if (!module) {
- PyErr_SetString(PyExc_ValueError,
- "field module is required for ImportFrom");
- return NULL;
- }
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = ImportFrom_kind;
- p->v.ImportFrom.module = module;
- p->v.ImportFrom.names = names;
- p->v.ImportFrom.level = level;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno, int col_offset,
- PyArena *arena)
-{
- stmt_ty p;
- if (!body) {
- PyErr_SetString(PyExc_ValueError,
- "field body is required for Exec");
- return NULL;
- }
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Exec_kind;
- p->v.Exec.body = body;
- p->v.Exec.globals = globals;
- p->v.Exec.locals = locals;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Global(asdl_seq * names, int lineno, int col_offset, PyArena *arena)
-{
- stmt_ty p;
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Global_kind;
- p->v.Global.names = names;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Expr(expr_ty value, int lineno, int col_offset, PyArena *arena)
-{
- stmt_ty p;
- if (!value) {
- PyErr_SetString(PyExc_ValueError,
- "field value is required for Expr");
- return NULL;
- }
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Expr_kind;
- p->v.Expr.value = value;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Pass(int lineno, int col_offset, PyArena *arena)
-{
- stmt_ty p;
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Pass_kind;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Break(int lineno, int col_offset, PyArena *arena)
-{
- stmt_ty p;
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Break_kind;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-stmt_ty
-Continue(int lineno, int col_offset, PyArena *arena)
-{
- stmt_ty p;
- p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Continue_kind;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, PyArena
- *arena)
-{
- expr_ty p;
- if (!op) {
- PyErr_SetString(PyExc_ValueError,
- "field op is required for BoolOp");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = BoolOp_kind;
- p->v.BoolOp.op = op;
- p->v.BoolOp.values = values;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int col_offset,
- PyArena *arena)
-{
- expr_ty p;
- if (!left) {
- PyErr_SetString(PyExc_ValueError,
- "field left is required for BinOp");
- return NULL;
- }
- if (!op) {
- PyErr_SetString(PyExc_ValueError,
- "field op is required for BinOp");
- return NULL;
- }
- if (!right) {
- PyErr_SetString(PyExc_ValueError,
- "field right is required for BinOp");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = BinOp_kind;
- p->v.BinOp.left = left;
- p->v.BinOp.op = op;
- p->v.BinOp.right = right;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, PyArena
- *arena)
-{
- expr_ty p;
- if (!op) {
- PyErr_SetString(PyExc_ValueError,
- "field op is required for UnaryOp");
- return NULL;
- }
- if (!operand) {
- PyErr_SetString(PyExc_ValueError,
- "field operand is required for UnaryOp");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = UnaryOp_kind;
- p->v.UnaryOp.op = op;
- p->v.UnaryOp.operand = operand;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, PyArena
- *arena)
-{
- expr_ty p;
- if (!args) {
- PyErr_SetString(PyExc_ValueError,
- "field args is required for Lambda");
- return NULL;
- }
- if (!body) {
- PyErr_SetString(PyExc_ValueError,
- "field body is required for Lambda");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Lambda_kind;
- p->v.Lambda.args = args;
- p->v.Lambda.body = body;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int col_offset,
- PyArena *arena)
-{
- expr_ty p;
- if (!test) {
- PyErr_SetString(PyExc_ValueError,
- "field test is required for IfExp");
- return NULL;
- }
- if (!body) {
- PyErr_SetString(PyExc_ValueError,
- "field body is required for IfExp");
- return NULL;
- }
- if (!orelse) {
- PyErr_SetString(PyExc_ValueError,
- "field orelse is required for IfExp");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = IfExp_kind;
- p->v.IfExp.test = test;
- p->v.IfExp.body = body;
- p->v.IfExp.orelse = orelse;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Dict(asdl_seq * keys, asdl_seq * values, int lineno, int col_offset, PyArena
- *arena)
-{
- expr_ty p;
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Dict_kind;
- p->v.Dict.keys = keys;
- p->v.Dict.values = values;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-ListComp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
- PyArena *arena)
-{
- expr_ty p;
- if (!elt) {
- PyErr_SetString(PyExc_ValueError,
- "field elt is required for ListComp");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = ListComp_kind;
- p->v.ListComp.elt = elt;
- p->v.ListComp.generators = generators;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset,
- PyArena *arena)
-{
- expr_ty p;
- if (!elt) {
- PyErr_SetString(PyExc_ValueError,
- "field elt is required for GeneratorExp");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = GeneratorExp_kind;
- p->v.GeneratorExp.elt = elt;
- p->v.GeneratorExp.generators = generators;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Yield(expr_ty value, int lineno, int col_offset, PyArena *arena)
-{
- expr_ty p;
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Yield_kind;
- p->v.Yield.value = value;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno,
- int col_offset, PyArena *arena)
-{
- expr_ty p;
- if (!left) {
- PyErr_SetString(PyExc_ValueError,
- "field left is required for Compare");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Compare_kind;
- p->v.Compare.left = left;
- p->v.Compare.ops = ops;
- p->v.Compare.comparators = comparators;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty starargs,
- expr_ty kwargs, int lineno, int col_offset, PyArena *arena)
-{
- expr_ty p;
- if (!func) {
- PyErr_SetString(PyExc_ValueError,
- "field func is required for Call");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Call_kind;
- p->v.Call.func = func;
- p->v.Call.args = args;
- p->v.Call.keywords = keywords;
- p->v.Call.starargs = starargs;
- p->v.Call.kwargs = kwargs;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Repr(expr_ty value, int lineno, int col_offset, PyArena *arena)
-{
- expr_ty p;
- if (!value) {
- PyErr_SetString(PyExc_ValueError,
- "field value is required for Repr");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Repr_kind;
- p->v.Repr.value = value;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Num(object n, int lineno, int col_offset, PyArena *arena)
-{
- expr_ty p;
- if (!n) {
- PyErr_SetString(PyExc_ValueError,
- "field n is required for Num");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Num_kind;
- p->v.Num.n = n;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Str(string s, int lineno, int col_offset, PyArena *arena)
-{
- expr_ty p;
- if (!s) {
- PyErr_SetString(PyExc_ValueError,
- "field s is required for Str");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Str_kind;
- p->v.Str.s = s;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno, int
- col_offset, PyArena *arena)
-{
- expr_ty p;
- if (!value) {
- PyErr_SetString(PyExc_ValueError,
- "field value is required for Attribute");
- return NULL;
- }
- if (!attr) {
- PyErr_SetString(PyExc_ValueError,
- "field attr is required for Attribute");
- return NULL;
- }
- if (!ctx) {
- PyErr_SetString(PyExc_ValueError,
- "field ctx is required for Attribute");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Attribute_kind;
- p->v.Attribute.value = value;
- p->v.Attribute.attr = attr;
- p->v.Attribute.ctx = ctx;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int lineno, int
- col_offset, PyArena *arena)
-{
- expr_ty p;
- if (!value) {
- PyErr_SetString(PyExc_ValueError,
- "field value is required for Subscript");
- return NULL;
- }
- if (!slice) {
- PyErr_SetString(PyExc_ValueError,
- "field slice is required for Subscript");
- return NULL;
- }
- if (!ctx) {
- PyErr_SetString(PyExc_ValueError,
- "field ctx is required for Subscript");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Subscript_kind;
- p->v.Subscript.value = value;
- p->v.Subscript.slice = slice;
- p->v.Subscript.ctx = ctx;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Name(identifier id, expr_context_ty ctx, int lineno, int col_offset, PyArena
- *arena)
-{
- expr_ty p;
- if (!id) {
- PyErr_SetString(PyExc_ValueError,
- "field id is required for Name");
- return NULL;
- }
- if (!ctx) {
- PyErr_SetString(PyExc_ValueError,
- "field ctx is required for Name");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Name_kind;
- p->v.Name.id = id;
- p->v.Name.ctx = ctx;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-List(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, PyArena
- *arena)
-{
- expr_ty p;
- if (!ctx) {
- PyErr_SetString(PyExc_ValueError,
- "field ctx is required for List");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = List_kind;
- p->v.List.elts = elts;
- p->v.List.ctx = ctx;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-expr_ty
-Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int col_offset, PyArena
- *arena)
-{
- expr_ty p;
- if (!ctx) {
- PyErr_SetString(PyExc_ValueError,
- "field ctx is required for Tuple");
- return NULL;
- }
- p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Tuple_kind;
- p->v.Tuple.elts = elts;
- p->v.Tuple.ctx = ctx;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-slice_ty
-Ellipsis(PyArena *arena)
-{
- slice_ty p;
- p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Ellipsis_kind;
- return p;
-}
-
-slice_ty
-Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena)
-{
- slice_ty p;
- p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Slice_kind;
- p->v.Slice.lower = lower;
- p->v.Slice.upper = upper;
- p->v.Slice.step = step;
- return p;
-}
-
-slice_ty
-ExtSlice(asdl_seq * dims, PyArena *arena)
-{
- slice_ty p;
- p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = ExtSlice_kind;
- p->v.ExtSlice.dims = dims;
- return p;
-}
-
-slice_ty
-Index(expr_ty value, PyArena *arena)
-{
- slice_ty p;
- if (!value) {
- PyErr_SetString(PyExc_ValueError,
- "field value is required for Index");
- return NULL;
- }
- p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->kind = Index_kind;
- p->v.Index.value = value;
- return p;
-}
-
-comprehension_ty
-comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, PyArena *arena)
-{
- comprehension_ty p;
- if (!target) {
- PyErr_SetString(PyExc_ValueError,
- "field target is required for comprehension");
- return NULL;
- }
- if (!iter) {
- PyErr_SetString(PyExc_ValueError,
- "field iter is required for comprehension");
- return NULL;
- }
- p = (comprehension_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->target = target;
- p->iter = iter;
- p->ifs = ifs;
- return p;
-}
-
-excepthandler_ty
-excepthandler(expr_ty type, expr_ty name, asdl_seq * body, int lineno, int
- col_offset, PyArena *arena)
-{
- excepthandler_ty p;
- p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->type = type;
- p->name = name;
- p->body = body;
- p->lineno = lineno;
- p->col_offset = col_offset;
- return p;
-}
-
-arguments_ty
-arguments(asdl_seq * args, identifier vararg, identifier kwarg, asdl_seq *
- defaults, PyArena *arena)
-{
- arguments_ty p;
- p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->args = args;
- p->vararg = vararg;
- p->kwarg = kwarg;
- p->defaults = defaults;
- return p;
-}
-
-keyword_ty
-keyword(identifier arg, expr_ty value, PyArena *arena)
-{
- keyword_ty p;
- if (!arg) {
- PyErr_SetString(PyExc_ValueError,
- "field arg is required for keyword");
- return NULL;
- }
- if (!value) {
- PyErr_SetString(PyExc_ValueError,
- "field value is required for keyword");
- return NULL;
- }
- p = (keyword_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->arg = arg;
- p->value = value;
- return p;
-}
-
-alias_ty
-alias(identifier name, identifier asname, PyArena *arena)
-{
- alias_ty p;
- if (!name) {
- PyErr_SetString(PyExc_ValueError,
- "field name is required for alias");
- return NULL;
- }
- p = (alias_ty)PyArena_Malloc(arena, sizeof(*p));
- if (!p) {
- PyErr_NoMemory();
- return NULL;
- }
- p->name = name;
- p->asname = asname;
- return p;
-}
-
-
-PyObject*
-ast2obj_mod(void* _o)
-{
- mod_ty o = (mod_ty)_o;
- PyObject *result = NULL, *value = NULL;
- if (!o) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- switch (o->kind) {
- case Module_kind:
- result = PyType_GenericNew(Module_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.Module.body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Interactive_kind:
- result = PyType_GenericNew(Interactive_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.Interactive.body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Expression_kind:
- result = PyType_GenericNew(Expression_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Expression.body);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Suite_kind:
- result = PyType_GenericNew(Suite_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.Suite.body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- }
- return result;
-failed:
- Py_XDECREF(value);
- Py_XDECREF(result);
- return NULL;
-}
-
-PyObject*
-ast2obj_stmt(void* _o)
-{
- stmt_ty o = (stmt_ty)_o;
- PyObject *result = NULL, *value = NULL;
- if (!o) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- switch (o->kind) {
- case FunctionDef_kind:
- result = PyType_GenericNew(FunctionDef_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_identifier(o->v.FunctionDef.name);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "name", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_arguments(o->v.FunctionDef.args);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "args", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.FunctionDef.body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.FunctionDef.decorators, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "decorators", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case ClassDef_kind:
- result = PyType_GenericNew(ClassDef_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_identifier(o->v.ClassDef.name);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "name", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.ClassDef.bases, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "bases", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.ClassDef.body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Return_kind:
- result = PyType_GenericNew(Return_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Return.value);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "value", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Delete_kind:
- result = PyType_GenericNew(Delete_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.Delete.targets, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "targets", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Assign_kind:
- result = PyType_GenericNew(Assign_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.Assign.targets, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "targets", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.Assign.value);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "value", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case AugAssign_kind:
- result = PyType_GenericNew(AugAssign_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.AugAssign.target);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "target", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_operator(o->v.AugAssign.op);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "op", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.AugAssign.value);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "value", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Print_kind:
- result = PyType_GenericNew(Print_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Print.dest);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "dest", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.Print.values, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "values", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_bool(o->v.Print.nl);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "nl", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case For_kind:
- result = PyType_GenericNew(For_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.For.target);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "target", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.For.iter);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "iter", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.For.body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.For.orelse, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "orelse", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case While_kind:
- result = PyType_GenericNew(While_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.While.test);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "test", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.While.body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.While.orelse, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "orelse", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case If_kind:
- result = PyType_GenericNew(If_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.If.test);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "test", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.If.body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.If.orelse, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "orelse", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case With_kind:
- result = PyType_GenericNew(With_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.With.context_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "context_expr", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.With.optional_vars);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "optional_vars", value) ==
- -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.With.body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Raise_kind:
- result = PyType_GenericNew(Raise_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Raise.type);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "type", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.Raise.inst);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "inst", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.Raise.tback);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "tback", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case TryExcept_kind:
- result = PyType_GenericNew(TryExcept_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.TryExcept.body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.TryExcept.handlers,
- ast2obj_excepthandler);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "handlers", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.TryExcept.orelse, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "orelse", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case TryFinally_kind:
- result = PyType_GenericNew(TryFinally_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.TryFinally.body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.TryFinally.finalbody, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "finalbody", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Assert_kind:
- result = PyType_GenericNew(Assert_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Assert.test);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "test", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.Assert.msg);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "msg", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Import_kind:
- result = PyType_GenericNew(Import_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.Import.names, ast2obj_alias);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "names", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case ImportFrom_kind:
- result = PyType_GenericNew(ImportFrom_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_identifier(o->v.ImportFrom.module);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "module", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.ImportFrom.names, ast2obj_alias);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "names", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_int(o->v.ImportFrom.level);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "level", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Exec_kind:
- result = PyType_GenericNew(Exec_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Exec.body);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.Exec.globals);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "globals", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.Exec.locals);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "locals", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Global_kind:
- result = PyType_GenericNew(Global_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.Global.names, ast2obj_identifier);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "names", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Expr_kind:
- result = PyType_GenericNew(Expr_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Expr.value);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "value", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Pass_kind:
- result = PyType_GenericNew(Pass_type, NULL, NULL);
- if (!result) goto failed;
- break;
- case Break_kind:
- result = PyType_GenericNew(Break_type, NULL, NULL);
- if (!result) goto failed;
- break;
- case Continue_kind:
- result = PyType_GenericNew(Continue_type, NULL, NULL);
- if (!result) goto failed;
- break;
- }
- value = ast2obj_int(o->lineno);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "lineno", value) < 0)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_int(o->col_offset);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "col_offset", value) < 0)
- goto failed;
- Py_DECREF(value);
- return result;
-failed:
- Py_XDECREF(value);
- Py_XDECREF(result);
- return NULL;
-}
-
-PyObject*
-ast2obj_expr(void* _o)
-{
- expr_ty o = (expr_ty)_o;
- PyObject *result = NULL, *value = NULL;
- if (!o) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- switch (o->kind) {
- case BoolOp_kind:
- result = PyType_GenericNew(BoolOp_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_boolop(o->v.BoolOp.op);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "op", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.BoolOp.values, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "values", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case BinOp_kind:
- result = PyType_GenericNew(BinOp_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.BinOp.left);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "left", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_operator(o->v.BinOp.op);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "op", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.BinOp.right);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "right", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case UnaryOp_kind:
- result = PyType_GenericNew(UnaryOp_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_unaryop(o->v.UnaryOp.op);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "op", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.UnaryOp.operand);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "operand", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Lambda_kind:
- result = PyType_GenericNew(Lambda_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_arguments(o->v.Lambda.args);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "args", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.Lambda.body);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case IfExp_kind:
- result = PyType_GenericNew(IfExp_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.IfExp.test);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "test", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.IfExp.body);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.IfExp.orelse);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "orelse", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Dict_kind:
- result = PyType_GenericNew(Dict_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.Dict.keys, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "keys", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.Dict.values, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "values", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case ListComp_kind:
- result = PyType_GenericNew(ListComp_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.ListComp.elt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "elt", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.ListComp.generators,
- ast2obj_comprehension);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "generators", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case GeneratorExp_kind:
- result = PyType_GenericNew(GeneratorExp_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.GeneratorExp.elt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "elt", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.GeneratorExp.generators,
- ast2obj_comprehension);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "generators", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Yield_kind:
- result = PyType_GenericNew(Yield_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Yield.value);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "value", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Compare_kind:
- result = PyType_GenericNew(Compare_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Compare.left);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "left", value) == -1)
- goto failed;
- Py_DECREF(value);
- {
- int i, n = asdl_seq_LEN(o->v.Compare.ops);
- value = PyList_New(n);
- if (!value) goto failed;
- for(i = 0; i < n; i++)
- PyList_SET_ITEM(value, i, ast2obj_cmpop((cmpop_ty)asdl_seq_GET(o->v.Compare.ops, i)));
- }
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "ops", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.Compare.comparators, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "comparators", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Call_kind:
- result = PyType_GenericNew(Call_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Call.func);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "func", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.Call.args, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "args", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->v.Call.keywords, ast2obj_keyword);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "keywords", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.Call.starargs);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "starargs", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.Call.kwargs);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "kwargs", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Repr_kind:
- result = PyType_GenericNew(Repr_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Repr.value);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "value", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Num_kind:
- result = PyType_GenericNew(Num_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_object(o->v.Num.n);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "n", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Str_kind:
- result = PyType_GenericNew(Str_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_string(o->v.Str.s);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "s", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Attribute_kind:
- result = PyType_GenericNew(Attribute_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Attribute.value);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "value", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_identifier(o->v.Attribute.attr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "attr", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr_context(o->v.Attribute.ctx);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "ctx", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Subscript_kind:
- result = PyType_GenericNew(Subscript_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Subscript.value);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "value", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_slice(o->v.Subscript.slice);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "slice", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr_context(o->v.Subscript.ctx);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "ctx", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Name_kind:
- result = PyType_GenericNew(Name_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_identifier(o->v.Name.id);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "id", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr_context(o->v.Name.ctx);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "ctx", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case List_kind:
- result = PyType_GenericNew(List_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.List.elts, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "elts", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr_context(o->v.List.ctx);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "ctx", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Tuple_kind:
- result = PyType_GenericNew(Tuple_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.Tuple.elts, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "elts", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr_context(o->v.Tuple.ctx);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "ctx", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- }
- value = ast2obj_int(o->lineno);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "lineno", value) < 0)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_int(o->col_offset);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "col_offset", value) < 0)
- goto failed;
- Py_DECREF(value);
- return result;
-failed:
- Py_XDECREF(value);
- Py_XDECREF(result);
- return NULL;
-}
-
-PyObject* ast2obj_expr_context(expr_context_ty o)
-{
- switch(o) {
- case Load:
- Py_INCREF(Load_singleton);
- return Load_singleton;
- case Store:
- Py_INCREF(Store_singleton);
- return Store_singleton;
- case Del:
- Py_INCREF(Del_singleton);
- return Del_singleton;
- case AugLoad:
- Py_INCREF(AugLoad_singleton);
- return AugLoad_singleton;
- case AugStore:
- Py_INCREF(AugStore_singleton);
- return AugStore_singleton;
- case Param:
- Py_INCREF(Param_singleton);
- return Param_singleton;
- }
- return NULL; /* cannot happen */
-}
-PyObject*
-ast2obj_slice(void* _o)
-{
- slice_ty o = (slice_ty)_o;
- PyObject *result = NULL, *value = NULL;
- if (!o) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- switch (o->kind) {
- case Ellipsis_kind:
- result = PyType_GenericNew(Ellipsis_type, NULL, NULL);
- if (!result) goto failed;
- break;
- case Slice_kind:
- result = PyType_GenericNew(Slice_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Slice.lower);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "lower", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.Slice.upper);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "upper", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->v.Slice.step);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "step", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case ExtSlice_kind:
- result = PyType_GenericNew(ExtSlice_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_list(o->v.ExtSlice.dims, ast2obj_slice);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "dims", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- case Index_kind:
- result = PyType_GenericNew(Index_type, NULL, NULL);
- if (!result) goto failed;
- value = ast2obj_expr(o->v.Index.value);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "value", value) == -1)
- goto failed;
- Py_DECREF(value);
- break;
- }
- return result;
-failed:
- Py_XDECREF(value);
- Py_XDECREF(result);
- return NULL;
-}
-
-PyObject* ast2obj_boolop(boolop_ty o)
-{
- switch(o) {
- case And:
- Py_INCREF(And_singleton);
- return And_singleton;
- case Or:
- Py_INCREF(Or_singleton);
- return Or_singleton;
- }
- return NULL; /* cannot happen */
-}
-PyObject* ast2obj_operator(operator_ty o)
-{
- switch(o) {
- case Add:
- Py_INCREF(Add_singleton);
- return Add_singleton;
- case Sub:
- Py_INCREF(Sub_singleton);
- return Sub_singleton;
- case Mult:
- Py_INCREF(Mult_singleton);
- return Mult_singleton;
- case Div:
- Py_INCREF(Div_singleton);
- return Div_singleton;
- case Mod:
- Py_INCREF(Mod_singleton);
- return Mod_singleton;
- case Pow:
- Py_INCREF(Pow_singleton);
- return Pow_singleton;
- case LShift:
- Py_INCREF(LShift_singleton);
- return LShift_singleton;
- case RShift:
- Py_INCREF(RShift_singleton);
- return RShift_singleton;
- case BitOr:
- Py_INCREF(BitOr_singleton);
- return BitOr_singleton;
- case BitXor:
- Py_INCREF(BitXor_singleton);
- return BitXor_singleton;
- case BitAnd:
- Py_INCREF(BitAnd_singleton);
- return BitAnd_singleton;
- case FloorDiv:
- Py_INCREF(FloorDiv_singleton);
- return FloorDiv_singleton;
- }
- return NULL; /* cannot happen */
-}
-PyObject* ast2obj_unaryop(unaryop_ty o)
-{
- switch(o) {
- case Invert:
- Py_INCREF(Invert_singleton);
- return Invert_singleton;
- case Not:
- Py_INCREF(Not_singleton);
- return Not_singleton;
- case UAdd:
- Py_INCREF(UAdd_singleton);
- return UAdd_singleton;
- case USub:
- Py_INCREF(USub_singleton);
- return USub_singleton;
- }
- return NULL; /* cannot happen */
-}
-PyObject* ast2obj_cmpop(cmpop_ty o)
-{
- switch(o) {
- case Eq:
- Py_INCREF(Eq_singleton);
- return Eq_singleton;
- case NotEq:
- Py_INCREF(NotEq_singleton);
- return NotEq_singleton;
- case Lt:
- Py_INCREF(Lt_singleton);
- return Lt_singleton;
- case LtE:
- Py_INCREF(LtE_singleton);
- return LtE_singleton;
- case Gt:
- Py_INCREF(Gt_singleton);
- return Gt_singleton;
- case GtE:
- Py_INCREF(GtE_singleton);
- return GtE_singleton;
- case Is:
- Py_INCREF(Is_singleton);
- return Is_singleton;
- case IsNot:
- Py_INCREF(IsNot_singleton);
- return IsNot_singleton;
- case In:
- Py_INCREF(In_singleton);
- return In_singleton;
- case NotIn:
- Py_INCREF(NotIn_singleton);
- return NotIn_singleton;
- }
- return NULL; /* cannot happen */
-}
-PyObject*
-ast2obj_comprehension(void* _o)
-{
- comprehension_ty o = (comprehension_ty)_o;
- PyObject *result = NULL, *value = NULL;
- if (!o) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- result = PyType_GenericNew(comprehension_type, NULL, NULL);
- if (!result) return NULL;
- value = ast2obj_expr(o->target);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "target", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->iter);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "iter", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->ifs, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "ifs", value) == -1)
- goto failed;
- Py_DECREF(value);
- return result;
-failed:
- Py_XDECREF(value);
- Py_XDECREF(result);
- return NULL;
-}
-
-PyObject*
-ast2obj_excepthandler(void* _o)
-{
- excepthandler_ty o = (excepthandler_ty)_o;
- PyObject *result = NULL, *value = NULL;
- if (!o) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- result = PyType_GenericNew(excepthandler_type, NULL, NULL);
- if (!result) return NULL;
- value = ast2obj_expr(o->type);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "type", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->name);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "name", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->body, ast2obj_stmt);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "body", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_int(o->lineno);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "lineno", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_int(o->col_offset);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "col_offset", value) == -1)
- goto failed;
- Py_DECREF(value);
- return result;
-failed:
- Py_XDECREF(value);
- Py_XDECREF(result);
- return NULL;
-}
-
-PyObject*
-ast2obj_arguments(void* _o)
-{
- arguments_ty o = (arguments_ty)_o;
- PyObject *result = NULL, *value = NULL;
- if (!o) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- result = PyType_GenericNew(arguments_type, NULL, NULL);
- if (!result) return NULL;
- value = ast2obj_list(o->args, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "args", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_identifier(o->vararg);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "vararg", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_identifier(o->kwarg);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "kwarg", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_list(o->defaults, ast2obj_expr);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "defaults", value) == -1)
- goto failed;
- Py_DECREF(value);
- return result;
-failed:
- Py_XDECREF(value);
- Py_XDECREF(result);
- return NULL;
-}
-
-PyObject*
-ast2obj_keyword(void* _o)
-{
- keyword_ty o = (keyword_ty)_o;
- PyObject *result = NULL, *value = NULL;
- if (!o) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- result = PyType_GenericNew(keyword_type, NULL, NULL);
- if (!result) return NULL;
- value = ast2obj_identifier(o->arg);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "arg", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_expr(o->value);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "value", value) == -1)
- goto failed;
- Py_DECREF(value);
- return result;
-failed:
- Py_XDECREF(value);
- Py_XDECREF(result);
- return NULL;
-}
-
-PyObject*
-ast2obj_alias(void* _o)
-{
- alias_ty o = (alias_ty)_o;
- PyObject *result = NULL, *value = NULL;
- if (!o) {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- result = PyType_GenericNew(alias_type, NULL, NULL);
- if (!result) return NULL;
- value = ast2obj_identifier(o->name);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "name", value) == -1)
- goto failed;
- Py_DECREF(value);
- value = ast2obj_identifier(o->asname);
- if (!value) goto failed;
- if (PyObject_SetAttrString(result, "asname", value) == -1)
- goto failed;
- Py_DECREF(value);
- return result;
-failed:
- Py_XDECREF(value);
- Py_XDECREF(result);
- return NULL;
-}
-
-
-PyMODINIT_FUNC
-init_ast(void)
-{
- PyObject *m, *d;
- if (!init_types()) return;
- m = Py_InitModule3("_ast", NULL, NULL);
- if (!m) return;
- d = PyModule_GetDict(m);
- if (PyDict_SetItemString(d, "AST", (PyObject*)AST_type) < 0) return;
- if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)
- return;
- if (PyModule_AddStringConstant(m, "__version__", "43614") < 0)
- return;
- if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return;
- if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Interactive", (PyObject*)Interactive_type)
- < 0) return;
- if (PyDict_SetItemString(d, "Expression", (PyObject*)Expression_type) <
- 0) return;
- if (PyDict_SetItemString(d, "Suite", (PyObject*)Suite_type) < 0) return;
- if (PyDict_SetItemString(d, "stmt", (PyObject*)stmt_type) < 0) return;
- if (PyDict_SetItemString(d, "FunctionDef", (PyObject*)FunctionDef_type)
- < 0) return;
- if (PyDict_SetItemString(d, "ClassDef", (PyObject*)ClassDef_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Return", (PyObject*)Return_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Delete", (PyObject*)Delete_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Assign", (PyObject*)Assign_type) < 0)
- return;
- if (PyDict_SetItemString(d, "AugAssign", (PyObject*)AugAssign_type) <
- 0) return;
- if (PyDict_SetItemString(d, "Print", (PyObject*)Print_type) < 0) return;
- if (PyDict_SetItemString(d, "For", (PyObject*)For_type) < 0) return;
- if (PyDict_SetItemString(d, "While", (PyObject*)While_type) < 0) return;
- if (PyDict_SetItemString(d, "If", (PyObject*)If_type) < 0) return;
- if (PyDict_SetItemString(d, "With", (PyObject*)With_type) < 0) return;
- if (PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return;
- if (PyDict_SetItemString(d, "TryExcept", (PyObject*)TryExcept_type) <
- 0) return;
- if (PyDict_SetItemString(d, "TryFinally", (PyObject*)TryFinally_type) <
- 0) return;
- if (PyDict_SetItemString(d, "Assert", (PyObject*)Assert_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Import", (PyObject*)Import_type) < 0)
- return;
- if (PyDict_SetItemString(d, "ImportFrom", (PyObject*)ImportFrom_type) <
- 0) return;
- if (PyDict_SetItemString(d, "Exec", (PyObject*)Exec_type) < 0) return;
- if (PyDict_SetItemString(d, "Global", (PyObject*)Global_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Expr", (PyObject*)Expr_type) < 0) return;
- if (PyDict_SetItemString(d, "Pass", (PyObject*)Pass_type) < 0) return;
- if (PyDict_SetItemString(d, "Break", (PyObject*)Break_type) < 0) return;
- if (PyDict_SetItemString(d, "Continue", (PyObject*)Continue_type) < 0)
- return;
- if (PyDict_SetItemString(d, "expr", (PyObject*)expr_type) < 0) return;
- if (PyDict_SetItemString(d, "BoolOp", (PyObject*)BoolOp_type) < 0)
- return;
- if (PyDict_SetItemString(d, "BinOp", (PyObject*)BinOp_type) < 0) return;
- if (PyDict_SetItemString(d, "UnaryOp", (PyObject*)UnaryOp_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Lambda", (PyObject*)Lambda_type) < 0)
- return;
- if (PyDict_SetItemString(d, "IfExp", (PyObject*)IfExp_type) < 0) return;
- if (PyDict_SetItemString(d, "Dict", (PyObject*)Dict_type) < 0) return;
- if (PyDict_SetItemString(d, "ListComp", (PyObject*)ListComp_type) < 0)
- return;
- if (PyDict_SetItemString(d, "GeneratorExp",
- (PyObject*)GeneratorExp_type) < 0) return;
- if (PyDict_SetItemString(d, "Yield", (PyObject*)Yield_type) < 0) return;
- if (PyDict_SetItemString(d, "Compare", (PyObject*)Compare_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Call", (PyObject*)Call_type) < 0) return;
- if (PyDict_SetItemString(d, "Repr", (PyObject*)Repr_type) < 0) return;
- if (PyDict_SetItemString(d, "Num", (PyObject*)Num_type) < 0) return;
- if (PyDict_SetItemString(d, "Str", (PyObject*)Str_type) < 0) return;
- if (PyDict_SetItemString(d, "Attribute", (PyObject*)Attribute_type) <
- 0) return;
- if (PyDict_SetItemString(d, "Subscript", (PyObject*)Subscript_type) <
- 0) return;
- if (PyDict_SetItemString(d, "Name", (PyObject*)Name_type) < 0) return;
- if (PyDict_SetItemString(d, "List", (PyObject*)List_type) < 0) return;
- if (PyDict_SetItemString(d, "Tuple", (PyObject*)Tuple_type) < 0) return;
- if (PyDict_SetItemString(d, "expr_context",
- (PyObject*)expr_context_type) < 0) return;
- if (PyDict_SetItemString(d, "Load", (PyObject*)Load_type) < 0) return;
- if (PyDict_SetItemString(d, "Store", (PyObject*)Store_type) < 0) return;
- if (PyDict_SetItemString(d, "Del", (PyObject*)Del_type) < 0) return;
- if (PyDict_SetItemString(d, "AugLoad", (PyObject*)AugLoad_type) < 0)
- return;
- if (PyDict_SetItemString(d, "AugStore", (PyObject*)AugStore_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return;
- if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return;
- if (PyDict_SetItemString(d, "Ellipsis", (PyObject*)Ellipsis_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return;
- if (PyDict_SetItemString(d, "ExtSlice", (PyObject*)ExtSlice_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Index", (PyObject*)Index_type) < 0) return;
- if (PyDict_SetItemString(d, "boolop", (PyObject*)boolop_type) < 0)
- return;
- if (PyDict_SetItemString(d, "And", (PyObject*)And_type) < 0) return;
- if (PyDict_SetItemString(d, "Or", (PyObject*)Or_type) < 0) return;
- if (PyDict_SetItemString(d, "operator", (PyObject*)operator_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Add", (PyObject*)Add_type) < 0) return;
- if (PyDict_SetItemString(d, "Sub", (PyObject*)Sub_type) < 0) return;
- if (PyDict_SetItemString(d, "Mult", (PyObject*)Mult_type) < 0) return;
- if (PyDict_SetItemString(d, "Div", (PyObject*)Div_type) < 0) return;
- if (PyDict_SetItemString(d, "Mod", (PyObject*)Mod_type) < 0) return;
- if (PyDict_SetItemString(d, "Pow", (PyObject*)Pow_type) < 0) return;
- if (PyDict_SetItemString(d, "LShift", (PyObject*)LShift_type) < 0)
- return;
- if (PyDict_SetItemString(d, "RShift", (PyObject*)RShift_type) < 0)
- return;
- if (PyDict_SetItemString(d, "BitOr", (PyObject*)BitOr_type) < 0) return;
- if (PyDict_SetItemString(d, "BitXor", (PyObject*)BitXor_type) < 0)
- return;
- if (PyDict_SetItemString(d, "BitAnd", (PyObject*)BitAnd_type) < 0)
- return;
- if (PyDict_SetItemString(d, "FloorDiv", (PyObject*)FloorDiv_type) < 0)
- return;
- if (PyDict_SetItemString(d, "unaryop", (PyObject*)unaryop_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Invert", (PyObject*)Invert_type) < 0)
- return;
- if (PyDict_SetItemString(d, "Not", (PyObject*)Not_type) < 0) return;
- if (PyDict_SetItemString(d, "UAdd", (PyObject*)UAdd_type) < 0) return;
- if (PyDict_SetItemString(d, "USub", (PyObject*)USub_type) < 0) return;
- if (PyDict_SetItemString(d, "cmpop", (PyObject*)cmpop_type) < 0) return;
- if (PyDict_SetItemString(d, "Eq", (PyObject*)Eq_type) < 0) return;
- if (PyDict_SetItemString(d, "NotEq", (PyObject*)NotEq_type) < 0) return;
- if (PyDict_SetItemString(d, "Lt", (PyObject*)Lt_type) < 0) return;
- if (PyDict_SetItemString(d, "LtE", (PyObject*)LtE_type) < 0) return;
- if (PyDict_SetItemString(d, "Gt", (PyObject*)Gt_type) < 0) return;
- if (PyDict_SetItemString(d, "GtE", (PyObject*)GtE_type) < 0) return;
- if (PyDict_SetItemString(d, "Is", (PyObject*)Is_type) < 0) return;
- if (PyDict_SetItemString(d, "IsNot", (PyObject*)IsNot_type) < 0) return;
- if (PyDict_SetItemString(d, "In", (PyObject*)In_type) < 0) return;
- if (PyDict_SetItemString(d, "NotIn", (PyObject*)NotIn_type) < 0) return;
- if (PyDict_SetItemString(d, "comprehension",
- (PyObject*)comprehension_type) < 0) return;
- if (PyDict_SetItemString(d, "excepthandler",
- (PyObject*)excepthandler_type) < 0) return;
- if (PyDict_SetItemString(d, "arguments", (PyObject*)arguments_type) <
- 0) return;
- if (PyDict_SetItemString(d, "keyword", (PyObject*)keyword_type) < 0)
- return;
- if (PyDict_SetItemString(d, "alias", (PyObject*)alias_type) < 0) return;
-}
-
-
-PyObject* PyAST_mod2obj(mod_ty t)
-{
- init_types();
- return ast2obj_mod(t);
-}
-
-
diff --git a/sys/src/cmd/python/Python/asdl.c b/sys/src/cmd/python/Python/asdl.c
deleted file mode 100644
index 72329b9d2..000000000
--- a/sys/src/cmd/python/Python/asdl.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "Python.h"
-#include "asdl.h"
-
-asdl_seq *
-asdl_seq_new(int size, PyArena *arena)
-{
- asdl_seq *seq = NULL;
- size_t n = sizeof(asdl_seq) +
- (size ? (sizeof(void *) * (size - 1)) : 0);
-
- seq = (asdl_seq *)PyArena_Malloc(arena, n);
- if (!seq) {
- PyErr_NoMemory();
- return NULL;
- }
- memset(seq, 0, n);
- seq->size = size;
- return seq;
-}
-
-asdl_int_seq *
-asdl_int_seq_new(int size, PyArena *arena)
-{
- asdl_int_seq *seq = NULL;
- size_t n = sizeof(asdl_seq) +
- (size ? (sizeof(int) * (size - 1)) : 0);
-
- seq = (asdl_int_seq *)PyArena_Malloc(arena, n);
- if (!seq) {
- PyErr_NoMemory();
- return NULL;
- }
- memset(seq, 0, n);
- seq->size = size;
- return seq;
-}
diff --git a/sys/src/cmd/python/Python/ast.c b/sys/src/cmd/python/Python/ast.c
deleted file mode 100644
index 67f45ed06..000000000
--- a/sys/src/cmd/python/Python/ast.c
+++ /dev/null
@@ -1,3292 +0,0 @@
-/*
- * This file includes functions to transform a concrete syntax tree (CST) to
- * an abstract syntax tree (AST). The main function is PyAST_FromNode().
- *
- */
-#include "Python.h"
-#include "Python-ast.h"
-#include "grammar.h"
-#include "node.h"
-#include "pyarena.h"
-#include "ast.h"
-#include "token.h"
-#include "parsetok.h"
-#include "graminit.h"
-
-#include <assert.h>
-
-/* XXX TO DO
- - re-indent this file (should be done)
- - internal error checking (freeing memory, etc.)
- - syntax errors
-*/
-
-/* Data structure used internally */
-struct compiling {
- char *c_encoding; /* source encoding */
- PyArena *c_arena; /* arena for allocating memeory */
-};
-
-static asdl_seq *seq_for_testlist(struct compiling *, const node *);
-static expr_ty ast_for_expr(struct compiling *, const node *);
-static stmt_ty ast_for_stmt(struct compiling *, const node *);
-static asdl_seq *ast_for_suite(struct compiling *, const node *);
-static asdl_seq *ast_for_exprlist(struct compiling *, const node *, expr_context_ty);
-static expr_ty ast_for_testlist(struct compiling *, const node *);
-static expr_ty ast_for_testlist_gexp(struct compiling *, const node *);
-
-/* Note different signature for ast_for_call */
-static expr_ty ast_for_call(struct compiling *, const node *, expr_ty);
-
-static PyObject *parsenumber(const char *);
-static PyObject *parsestr(const char *s, const char *encoding);
-static PyObject *parsestrplus(struct compiling *, const node *n);
-
-#ifndef LINENO
-#define LINENO(n) ((n)->n_lineno)
-#endif
-
-static identifier
-new_identifier(const char* n, PyArena *arena) {
- PyObject* id = PyString_InternFromString(n);
- PyArena_AddPyObject(arena, id);
- return id;
-}
-
-#define NEW_IDENTIFIER(n) new_identifier(STR(n), c->c_arena)
-
-/* This routine provides an invalid object for the syntax error.
- The outermost routine must unpack this error and create the
- proper object. We do this so that we don't have to pass
- the filename to everything function.
-
- XXX Maybe we should just pass the filename...
-*/
-
-static int
-ast_error(const node *n, const char *errstr)
-{
- PyObject *u = Py_BuildValue("zi", errstr, LINENO(n));
- if (!u)
- return 0;
- PyErr_SetObject(PyExc_SyntaxError, u);
- Py_DECREF(u);
- return 0;
-}
-
-static void
-ast_error_finish(const char *filename)
-{
- PyObject *type, *value, *tback, *errstr, *loc, *tmp;
- long lineno;
-
- assert(PyErr_Occurred());
- if (!PyErr_ExceptionMatches(PyExc_SyntaxError))
- return;
-
- PyErr_Fetch(&type, &value, &tback);
- errstr = PyTuple_GetItem(value, 0);
- if (!errstr)
- return;
- Py_INCREF(errstr);
- lineno = PyInt_AsLong(PyTuple_GetItem(value, 1));
- if (lineno == -1) {
- Py_DECREF(errstr);
- return;
- }
- Py_DECREF(value);
-
- loc = PyErr_ProgramText(filename, lineno);
- if (!loc) {
- Py_INCREF(Py_None);
- loc = Py_None;
- }
- tmp = Py_BuildValue("(zlOO)", filename, lineno, Py_None, loc);
- Py_DECREF(loc);
- if (!tmp) {
- Py_DECREF(errstr);
- return;
- }
- value = PyTuple_Pack(2, errstr, tmp);
- Py_DECREF(errstr);
- Py_DECREF(tmp);
- if (!value)
- return;
- PyErr_Restore(type, value, tback);
-}
-
-/* num_stmts() returns number of contained statements.
-
- Use this routine to determine how big a sequence is needed for
- the statements in a parse tree. Its raison d'etre is this bit of
- grammar:
-
- stmt: simple_stmt | compound_stmt
- simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
-
- A simple_stmt can contain multiple small_stmt elements joined
- by semicolons. If the arg is a simple_stmt, the number of
- small_stmt elements is returned.
-*/
-
-static int
-num_stmts(const node *n)
-{
- int i, l;
- node *ch;
-
- switch (TYPE(n)) {
- case single_input:
- if (TYPE(CHILD(n, 0)) == NEWLINE)
- return 0;
- else
- return num_stmts(CHILD(n, 0));
- case file_input:
- l = 0;
- for (i = 0; i < NCH(n); i++) {
- ch = CHILD(n, i);
- if (TYPE(ch) == stmt)
- l += num_stmts(ch);
- }
- return l;
- case stmt:
- return num_stmts(CHILD(n, 0));
- case compound_stmt:
- return 1;
- case simple_stmt:
- return NCH(n) / 2; /* Divide by 2 to remove count of semi-colons */
- case suite:
- if (NCH(n) == 1)
- return num_stmts(CHILD(n, 0));
- else {
- l = 0;
- for (i = 2; i < (NCH(n) - 1); i++)
- l += num_stmts(CHILD(n, i));
- return l;
- }
- default: {
- char buf[128];
-
- sprintf(buf, "Non-statement found: %d %d\n",
- TYPE(n), NCH(n));
- Py_FatalError(buf);
- }
- }
- assert(0);
- return 0;
-}
-
-/* Transform the CST rooted at node * to the appropriate AST
-*/
-
-mod_ty
-PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
- PyArena *arena)
-{
- int i, j, k, num;
- asdl_seq *stmts = NULL;
- stmt_ty s;
- node *ch;
- struct compiling c;
-
- if (flags && flags->cf_flags & PyCF_SOURCE_IS_UTF8) {
- c.c_encoding = "utf-8";
- if (TYPE(n) == encoding_decl) {
- ast_error(n, "encoding declaration in Unicode string");
- goto error;
- }
- } else if (TYPE(n) == encoding_decl) {
- c.c_encoding = STR(n);
- n = CHILD(n, 0);
- } else {
- c.c_encoding = NULL;
- }
- c.c_arena = arena;
-
- k = 0;
- switch (TYPE(n)) {
- case file_input:
- stmts = asdl_seq_new(num_stmts(n), arena);
- if (!stmts)
- return NULL;
- for (i = 0; i < NCH(n) - 1; i++) {
- ch = CHILD(n, i);
- if (TYPE(ch) == NEWLINE)
- continue;
- REQ(ch, stmt);
- num = num_stmts(ch);
- if (num == 1) {
- s = ast_for_stmt(&c, ch);
- if (!s)
- goto error;
- asdl_seq_SET(stmts, k++, s);
- }
- else {
- ch = CHILD(ch, 0);
- REQ(ch, simple_stmt);
- for (j = 0; j < num; j++) {
- s = ast_for_stmt(&c, CHILD(ch, j * 2));
- if (!s)
- goto error;
- asdl_seq_SET(stmts, k++, s);
- }
- }
- }
- return Module(stmts, arena);
- case eval_input: {
- expr_ty testlist_ast;
-
- /* XXX Why not gen_for here? */
- testlist_ast = ast_for_testlist(&c, CHILD(n, 0));
- if (!testlist_ast)
- goto error;
- return Expression(testlist_ast, arena);
- }
- case single_input:
- if (TYPE(CHILD(n, 0)) == NEWLINE) {
- stmts = asdl_seq_new(1, arena);
- if (!stmts)
- goto error;
- asdl_seq_SET(stmts, 0, Pass(n->n_lineno, n->n_col_offset,
- arena));
- return Interactive(stmts, arena);
- }
- else {
- n = CHILD(n, 0);
- num = num_stmts(n);
- stmts = asdl_seq_new(num, arena);
- if (!stmts)
- goto error;
- if (num == 1) {
- s = ast_for_stmt(&c, n);
- if (!s)
- goto error;
- asdl_seq_SET(stmts, 0, s);
- }
- else {
- /* Only a simple_stmt can contain multiple statements. */
- REQ(n, simple_stmt);
- for (i = 0; i < NCH(n); i += 2) {
- if (TYPE(CHILD(n, i)) == NEWLINE)
- break;
- s = ast_for_stmt(&c, CHILD(n, i));
- if (!s)
- goto error;
- asdl_seq_SET(stmts, i / 2, s);
- }
- }
-
- return Interactive(stmts, arena);
- }
- default:
- goto error;
- }
- error:
- ast_error_finish(filename);
- return NULL;
-}
-
-/* Return the AST repr. of the operator represented as syntax (|, ^, etc.)
-*/
-
-static operator_ty
-get_operator(const node *n)
-{
- switch (TYPE(n)) {
- case VBAR:
- return BitOr;
- case CIRCUMFLEX:
- return BitXor;
- case AMPER:
- return BitAnd;
- case LEFTSHIFT:
- return LShift;
- case RIGHTSHIFT:
- return RShift;
- case PLUS:
- return Add;
- case MINUS:
- return Sub;
- case STAR:
- return Mult;
- case SLASH:
- return Div;
- case DOUBLESLASH:
- return FloorDiv;
- case PERCENT:
- return Mod;
- default:
- return (operator_ty)0;
- }
-}
-
-/* Set the context ctx for expr_ty e, recursively traversing e.
-
- Only sets context for expr kinds that "can appear in assignment context"
- (according to ../Parser/Python.asdl). For other expr kinds, it sets
- an appropriate syntax error and returns false.
-*/
-
-static int
-set_context(expr_ty e, expr_context_ty ctx, const node *n)
-{
- asdl_seq *s = NULL;
- /* If a particular expression type can't be used for assign / delete,
- set expr_name to its name and an error message will be generated.
- */
- const char* expr_name = NULL;
-
- /* The ast defines augmented store and load contexts, but the
- implementation here doesn't actually use them. The code may be
- a little more complex than necessary as a result. It also means
- that expressions in an augmented assignment have a Store context.
- Consider restructuring so that augmented assignment uses
- set_context(), too.
- */
- assert(ctx != AugStore && ctx != AugLoad);
-
- switch (e->kind) {
- case Attribute_kind:
- if (ctx == Store &&
- !strcmp(PyString_AS_STRING(e->v.Attribute.attr), "None")) {
- return ast_error(n, "assignment to None");
- }
- e->v.Attribute.ctx = ctx;
- break;
- case Subscript_kind:
- e->v.Subscript.ctx = ctx;
- break;
- case Name_kind:
- if (ctx == Store &&
- !strcmp(PyString_AS_STRING(e->v.Name.id), "None")) {
- return ast_error(n, "assignment to None");
- }
- e->v.Name.ctx = ctx;
- break;
- case List_kind:
- e->v.List.ctx = ctx;
- s = e->v.List.elts;
- break;
- case Tuple_kind:
- if (asdl_seq_LEN(e->v.Tuple.elts) == 0)
- return ast_error(n, "can't assign to ()");
- e->v.Tuple.ctx = ctx;
- s = e->v.Tuple.elts;
- break;
- case Lambda_kind:
- expr_name = "lambda";
- break;
- case Call_kind:
- expr_name = "function call";
- break;
- case BoolOp_kind:
- case BinOp_kind:
- case UnaryOp_kind:
- expr_name = "operator";
- break;
- case GeneratorExp_kind:
- expr_name = "generator expression";
- break;
- case Yield_kind:
- expr_name = "yield expression";
- break;
- case ListComp_kind:
- expr_name = "list comprehension";
- break;
- case Dict_kind:
- case Num_kind:
- case Str_kind:
- expr_name = "literal";
- break;
- case Compare_kind:
- expr_name = "comparison";
- break;
- case Repr_kind:
- expr_name = "repr";
- break;
- case IfExp_kind:
- expr_name = "conditional expression";
- break;
- default:
- PyErr_Format(PyExc_SystemError,
- "unexpected expression in assignment %d (line %d)",
- e->kind, e->lineno);
- return 0;
- }
- /* Check for error string set by switch */
- if (expr_name) {
- char buf[300];
- PyOS_snprintf(buf, sizeof(buf),
- "can't %s %s",
- ctx == Store ? "assign to" : "delete",
- expr_name);
- return ast_error(n, buf);
- }
-
- /* If the LHS is a list or tuple, we need to set the assignment
- context for all the contained elements.
- */
- if (s) {
- int i;
-
- for (i = 0; i < asdl_seq_LEN(s); i++) {
- if (!set_context((expr_ty)asdl_seq_GET(s, i), ctx, n))
- return 0;
- }
- }
- return 1;
-}
-
-static operator_ty
-ast_for_augassign(const node *n)
-{
- REQ(n, augassign);
- n = CHILD(n, 0);
- switch (STR(n)[0]) {
- case '+':
- return Add;
- case '-':
- return Sub;
- case '/':
- if (STR(n)[1] == '/')
- return FloorDiv;
- else
- return Div;
- case '%':
- return Mod;
- case '<':
- return LShift;
- case '>':
- return RShift;
- case '&':
- return BitAnd;
- case '^':
- return BitXor;
- case '|':
- return BitOr;
- case '*':
- if (STR(n)[1] == '*')
- return Pow;
- else
- return Mult;
- default:
- PyErr_Format(PyExc_SystemError, "invalid augassign: %s", STR(n));
- return (operator_ty)0;
- }
-}
-
-static cmpop_ty
-ast_for_comp_op(const node *n)
-{
- /* comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'
- |'is' 'not'
- */
- REQ(n, comp_op);
- if (NCH(n) == 1) {
- n = CHILD(n, 0);
- switch (TYPE(n)) {
- case LESS:
- return Lt;
- case GREATER:
- return Gt;
- case EQEQUAL: /* == */
- return Eq;
- case LESSEQUAL:
- return LtE;
- case GREATEREQUAL:
- return GtE;
- case NOTEQUAL:
- return NotEq;
- case NAME:
- if (strcmp(STR(n), "in") == 0)
- return In;
- if (strcmp(STR(n), "is") == 0)
- return Is;
- default:
- PyErr_Format(PyExc_SystemError, "invalid comp_op: %s",
- STR(n));
- return (cmpop_ty)0;
- }
- }
- else if (NCH(n) == 2) {
- /* handle "not in" and "is not" */
- switch (TYPE(CHILD(n, 0))) {
- case NAME:
- if (strcmp(STR(CHILD(n, 1)), "in") == 0)
- return NotIn;
- if (strcmp(STR(CHILD(n, 0)), "is") == 0)
- return IsNot;
- default:
- PyErr_Format(PyExc_SystemError, "invalid comp_op: %s %s",
- STR(CHILD(n, 0)), STR(CHILD(n, 1)));
- return (cmpop_ty)0;
- }
- }
- PyErr_Format(PyExc_SystemError, "invalid comp_op: has %d children",
- NCH(n));
- return (cmpop_ty)0;
-}
-
-static asdl_seq *
-seq_for_testlist(struct compiling *c, const node *n)
-{
- /* testlist: test (',' test)* [','] */
- asdl_seq *seq;
- expr_ty expression;
- int i;
- assert(TYPE(n) == testlist
- || TYPE(n) == listmaker
- || TYPE(n) == testlist_gexp
- || TYPE(n) == testlist_safe
- || TYPE(n) == testlist1
- );
-
- seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
- if (!seq)
- return NULL;
-
- for (i = 0; i < NCH(n); i += 2) {
- assert(TYPE(CHILD(n, i)) == test || TYPE(CHILD(n, i)) == old_test);
-
- expression = ast_for_expr(c, CHILD(n, i));
- if (!expression)
- return NULL;
-
- assert(i / 2 < seq->size);
- asdl_seq_SET(seq, i / 2, expression);
- }
- return seq;
-}
-
-static expr_ty
-compiler_complex_args(struct compiling *c, const node *n)
-{
- int i, len = (NCH(n) + 1) / 2;
- expr_ty result;
- asdl_seq *args = asdl_seq_new(len, c->c_arena);
- if (!args)
- return NULL;
-
- /* fpdef: NAME | '(' fplist ')'
- fplist: fpdef (',' fpdef)* [',']
- */
- REQ(n, fplist);
- for (i = 0; i < len; i++) {
- const node *fpdef_node = CHILD(n, 2*i);
- const node *child;
- expr_ty arg;
-set_name:
- /* fpdef_node is either a NAME or an fplist */
- child = CHILD(fpdef_node, 0);
- if (TYPE(child) == NAME) {
- if (!strcmp(STR(child), "None")) {
- ast_error(child, "assignment to None");
- return NULL;
- }
- arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child),
- child->n_col_offset, c->c_arena);
- }
- else {
- assert(TYPE(fpdef_node) == fpdef);
- /* fpdef_node[0] is not a name, so it must be a '(', get CHILD[1] */
- child = CHILD(fpdef_node, 1);
- assert(TYPE(child) == fplist);
- /* NCH == 1 means we have (x), we need to elide the extra parens */
- if (NCH(child) == 1) {
- fpdef_node = CHILD(child, 0);
- assert(TYPE(fpdef_node) == fpdef);
- goto set_name;
- }
- arg = compiler_complex_args(c, child);
- }
- asdl_seq_SET(args, i, arg);
- }
-
- result = Tuple(args, Store, LINENO(n), n->n_col_offset, c->c_arena);
- if (!set_context(result, Store, n))
- return NULL;
- return result;
-}
-
-
-/* Create AST for argument list. */
-
-static arguments_ty
-ast_for_arguments(struct compiling *c, const node *n)
-{
- /* parameters: '(' [varargslist] ')'
- varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME]
- | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
- */
- int i, j, k, n_args = 0, n_defaults = 0, found_default = 0;
- asdl_seq *args, *defaults;
- identifier vararg = NULL, kwarg = NULL;
- node *ch;
-
- if (TYPE(n) == parameters) {
- if (NCH(n) == 2) /* () as argument list */
- return arguments(NULL, NULL, NULL, NULL, c->c_arena);
- n = CHILD(n, 1);
- }
- REQ(n, varargslist);
-
- /* first count the number of normal args & defaults */
- for (i = 0; i < NCH(n); i++) {
- ch = CHILD(n, i);
- if (TYPE(ch) == fpdef)
- n_args++;
- if (TYPE(ch) == EQUAL)
- n_defaults++;
- }
- args = (n_args ? asdl_seq_new(n_args, c->c_arena) : NULL);
- if (!args && n_args)
- return NULL; /* Don't need to goto error; no objects allocated */
- defaults = (n_defaults ? asdl_seq_new(n_defaults, c->c_arena) : NULL);
- if (!defaults && n_defaults)
- return NULL; /* Don't need to goto error; no objects allocated */
-
- /* fpdef: NAME | '(' fplist ')'
- fplist: fpdef (',' fpdef)* [',']
- */
- i = 0;
- j = 0; /* index for defaults */
- k = 0; /* index for args */
- while (i < NCH(n)) {
- ch = CHILD(n, i);
- switch (TYPE(ch)) {
- case fpdef:
- handle_fpdef:
- /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is
- anything other than EQUAL or a comma? */
- /* XXX Should NCH(n) check be made a separate check? */
- if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) {
- expr_ty expression = ast_for_expr(c, CHILD(n, i + 2));
- if (!expression)
- goto error;
- assert(defaults != NULL);
- asdl_seq_SET(defaults, j++, expression);
- i += 2;
- found_default = 1;
- }
- else if (found_default) {
- ast_error(n,
- "non-default argument follows default argument");
- goto error;
- }
- if (NCH(ch) == 3) {
- ch = CHILD(ch, 1);
- /* def foo((x)): is not complex, special case. */
- if (NCH(ch) != 1) {
- /* We have complex arguments, setup for unpacking. */
- asdl_seq_SET(args, k++, compiler_complex_args(c, ch));
- } else {
- /* def foo((x)): setup for checking NAME below. */
- /* Loop because there can be many parens and tuple
- upacking mixed in. */
- ch = CHILD(ch, 0);
- assert(TYPE(ch) == fpdef);
- goto handle_fpdef;
- }
- }
- if (TYPE(CHILD(ch, 0)) == NAME) {
- expr_ty name;
- if (!strcmp(STR(CHILD(ch, 0)), "None")) {
- ast_error(CHILD(ch, 0), "assignment to None");
- goto error;
- }
- name = Name(NEW_IDENTIFIER(CHILD(ch, 0)),
- Param, LINENO(ch), ch->n_col_offset,
- c->c_arena);
- if (!name)
- goto error;
- asdl_seq_SET(args, k++, name);
-
- }
- i += 2; /* the name and the comma */
- break;
- case STAR:
- if (!strcmp(STR(CHILD(n, i+1)), "None")) {
- ast_error(CHILD(n, i+1), "assignment to None");
- goto error;
- }
- vararg = NEW_IDENTIFIER(CHILD(n, i+1));
- i += 3;
- break;
- case DOUBLESTAR:
- if (!strcmp(STR(CHILD(n, i+1)), "None")) {
- ast_error(CHILD(n, i+1), "assignment to None");
- goto error;
- }
- kwarg = NEW_IDENTIFIER(CHILD(n, i+1));
- i += 3;
- break;
- default:
- PyErr_Format(PyExc_SystemError,
- "unexpected node in varargslist: %d @ %d",
- TYPE(ch), i);
- goto error;
- }
- }
-
- return arguments(args, vararg, kwarg, defaults, c->c_arena);
-
- error:
- Py_XDECREF(vararg);
- Py_XDECREF(kwarg);
- return NULL;
-}
-
-static expr_ty
-ast_for_dotted_name(struct compiling *c, const node *n)
-{
- expr_ty e;
- identifier id;
- int lineno, col_offset;
- int i;
-
- REQ(n, dotted_name);
-
- lineno = LINENO(n);
- col_offset = n->n_col_offset;
-
- id = NEW_IDENTIFIER(CHILD(n, 0));
- if (!id)
- return NULL;
- e = Name(id, Load, lineno, col_offset, c->c_arena);
- if (!e)
- return NULL;
-
- for (i = 2; i < NCH(n); i+=2) {
- id = NEW_IDENTIFIER(CHILD(n, i));
- if (!id)
- return NULL;
- e = Attribute(e, id, Load, lineno, col_offset, c->c_arena);
- if (!e)
- return NULL;
- }
-
- return e;
-}
-
-static expr_ty
-ast_for_decorator(struct compiling *c, const node *n)
-{
- /* decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE */
- expr_ty d = NULL;
- expr_ty name_expr;
-
- REQ(n, decorator);
- REQ(CHILD(n, 0), AT);
- REQ(RCHILD(n, -1), NEWLINE);
-
- name_expr = ast_for_dotted_name(c, CHILD(n, 1));
- if (!name_expr)
- return NULL;
-
- if (NCH(n) == 3) { /* No arguments */
- d = name_expr;
- name_expr = NULL;
- }
- else if (NCH(n) == 5) { /* Call with no arguments */
- d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n),
- n->n_col_offset, c->c_arena);
- if (!d)
- return NULL;
- name_expr = NULL;
- }
- else {
- d = ast_for_call(c, CHILD(n, 3), name_expr);
- if (!d)
- return NULL;
- name_expr = NULL;
- }
-
- return d;
-}
-
-static asdl_seq*
-ast_for_decorators(struct compiling *c, const node *n)
-{
- asdl_seq* decorator_seq;
- expr_ty d;
- int i;
-
- REQ(n, decorators);
- decorator_seq = asdl_seq_new(NCH(n), c->c_arena);
- if (!decorator_seq)
- return NULL;
-
- for (i = 0; i < NCH(n); i++) {
- d = ast_for_decorator(c, CHILD(n, i));
- if (!d)
- return NULL;
- asdl_seq_SET(decorator_seq, i, d);
- }
- return decorator_seq;
-}
-
-static stmt_ty
-ast_for_funcdef(struct compiling *c, const node *n)
-{
- /* funcdef: 'def' [decorators] NAME parameters ':' suite */
- identifier name;
- arguments_ty args;
- asdl_seq *body;
- asdl_seq *decorator_seq = NULL;
- int name_i;
-
- REQ(n, funcdef);
-
- if (NCH(n) == 6) { /* decorators are present */
- decorator_seq = ast_for_decorators(c, CHILD(n, 0));
- if (!decorator_seq)
- return NULL;
- name_i = 2;
- }
- else {
- name_i = 1;
- }
-
- name = NEW_IDENTIFIER(CHILD(n, name_i));
- if (!name)
- return NULL;
- else if (!strcmp(STR(CHILD(n, name_i)), "None")) {
- ast_error(CHILD(n, name_i), "assignment to None");
- return NULL;
- }
- args = ast_for_arguments(c, CHILD(n, name_i + 1));
- if (!args)
- return NULL;
- body = ast_for_suite(c, CHILD(n, name_i + 3));
- if (!body)
- return NULL;
-
- return FunctionDef(name, args, body, decorator_seq, LINENO(n),
- n->n_col_offset, c->c_arena);
-}
-
-static expr_ty
-ast_for_lambdef(struct compiling *c, const node *n)
-{
- /* lambdef: 'lambda' [varargslist] ':' test */
- arguments_ty args;
- expr_ty expression;
-
- if (NCH(n) == 3) {
- args = arguments(NULL, NULL, NULL, NULL, c->c_arena);
- if (!args)
- return NULL;
- expression = ast_for_expr(c, CHILD(n, 2));
- if (!expression)
- return NULL;
- }
- else {
- args = ast_for_arguments(c, CHILD(n, 1));
- if (!args)
- return NULL;
- expression = ast_for_expr(c, CHILD(n, 3));
- if (!expression)
- return NULL;
- }
-
- return Lambda(args, expression, LINENO(n), n->n_col_offset, c->c_arena);
-}
-
-static expr_ty
-ast_for_ifexpr(struct compiling *c, const node *n)
-{
- /* test: or_test 'if' or_test 'else' test */
- expr_ty expression, body, orelse;
-
- assert(NCH(n) == 5);
- body = ast_for_expr(c, CHILD(n, 0));
- if (!body)
- return NULL;
- expression = ast_for_expr(c, CHILD(n, 2));
- if (!expression)
- return NULL;
- orelse = ast_for_expr(c, CHILD(n, 4));
- if (!orelse)
- return NULL;
- return IfExp(expression, body, orelse, LINENO(n), n->n_col_offset,
- c->c_arena);
-}
-
-/* Count the number of 'for' loop in a list comprehension.
-
- Helper for ast_for_listcomp().
-*/
-
-static int
-count_list_fors(const node *n)
-{
- int n_fors = 0;
- node *ch = CHILD(n, 1);
-
- count_list_for:
- n_fors++;
- REQ(ch, list_for);
- if (NCH(ch) == 5)
- ch = CHILD(ch, 4);
- else
- return n_fors;
- count_list_iter:
- REQ(ch, list_iter);
- ch = CHILD(ch, 0);
- if (TYPE(ch) == list_for)
- goto count_list_for;
- else if (TYPE(ch) == list_if) {
- if (NCH(ch) == 3) {
- ch = CHILD(ch, 2);
- goto count_list_iter;
- }
- else
- return n_fors;
- }
-
- /* Should never be reached */
- PyErr_SetString(PyExc_SystemError, "logic error in count_list_fors");
- return -1;
-}
-
-/* Count the number of 'if' statements in a list comprehension.
-
- Helper for ast_for_listcomp().
-*/
-
-static int
-count_list_ifs(const node *n)
-{
- int n_ifs = 0;
-
- count_list_iter:
- REQ(n, list_iter);
- if (TYPE(CHILD(n, 0)) == list_for)
- return n_ifs;
- n = CHILD(n, 0);
- REQ(n, list_if);
- n_ifs++;
- if (NCH(n) == 2)
- return n_ifs;
- n = CHILD(n, 2);
- goto count_list_iter;
-}
-
-static expr_ty
-ast_for_listcomp(struct compiling *c, const node *n)
-{
- /* listmaker: test ( list_for | (',' test)* [','] )
- list_for: 'for' exprlist 'in' testlist_safe [list_iter]
- list_iter: list_for | list_if
- list_if: 'if' test [list_iter]
- testlist_safe: test [(',' test)+ [',']]
- */
- expr_ty elt;
- asdl_seq *listcomps;
- int i, n_fors;
- node *ch;
-
- REQ(n, listmaker);
- assert(NCH(n) > 1);
-
- elt = ast_for_expr(c, CHILD(n, 0));
- if (!elt)
- return NULL;
-
- n_fors = count_list_fors(n);
- if (n_fors == -1)
- return NULL;
-
- listcomps = asdl_seq_new(n_fors, c->c_arena);
- if (!listcomps)
- return NULL;
-
- ch = CHILD(n, 1);
- for (i = 0; i < n_fors; i++) {
- comprehension_ty lc;
- asdl_seq *t;
- expr_ty expression;
- node *for_ch;
-
- REQ(ch, list_for);
-
- for_ch = CHILD(ch, 1);
- t = ast_for_exprlist(c, for_ch, Store);
- if (!t)
- return NULL;
- expression = ast_for_testlist(c, CHILD(ch, 3));
- if (!expression)
- return NULL;
-
- /* Check the # of children rather than the length of t, since
- [x for x, in ... ] has 1 element in t, but still requires a Tuple. */
- if (NCH(for_ch) == 1)
- lc = comprehension((expr_ty)asdl_seq_GET(t, 0), expression, NULL,
- c->c_arena);
- else
- lc = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
- c->c_arena),
- expression, NULL, c->c_arena);
- if (!lc)
- return NULL;
-
- if (NCH(ch) == 5) {
- int j, n_ifs;
- asdl_seq *ifs;
- expr_ty list_for_expr;
-
- ch = CHILD(ch, 4);
- n_ifs = count_list_ifs(ch);
- if (n_ifs == -1)
- return NULL;
-
- ifs = asdl_seq_new(n_ifs, c->c_arena);
- if (!ifs)
- return NULL;
-
- for (j = 0; j < n_ifs; j++) {
- REQ(ch, list_iter);
- ch = CHILD(ch, 0);
- REQ(ch, list_if);
-
- list_for_expr = ast_for_expr(c, CHILD(ch, 1));
- if (!list_for_expr)
- return NULL;
-
- asdl_seq_SET(ifs, j, list_for_expr);
- if (NCH(ch) == 3)
- ch = CHILD(ch, 2);
- }
- /* on exit, must guarantee that ch is a list_for */
- if (TYPE(ch) == list_iter)
- ch = CHILD(ch, 0);
- lc->ifs = ifs;
- }
- asdl_seq_SET(listcomps, i, lc);
- }
-
- return ListComp(elt, listcomps, LINENO(n), n->n_col_offset, c->c_arena);
-}
-
-/*
- Count the number of 'for' loops in a generator expression.
-
- Helper for ast_for_genexp().
-*/
-
-static int
-count_gen_fors(const node *n)
-{
- int n_fors = 0;
- node *ch = CHILD(n, 1);
-
- count_gen_for:
- n_fors++;
- REQ(ch, gen_for);
- if (NCH(ch) == 5)
- ch = CHILD(ch, 4);
- else
- return n_fors;
- count_gen_iter:
- REQ(ch, gen_iter);
- ch = CHILD(ch, 0);
- if (TYPE(ch) == gen_for)
- goto count_gen_for;
- else if (TYPE(ch) == gen_if) {
- if (NCH(ch) == 3) {
- ch = CHILD(ch, 2);
- goto count_gen_iter;
- }
- else
- return n_fors;
- }
-
- /* Should never be reached */
- PyErr_SetString(PyExc_SystemError,
- "logic error in count_gen_fors");
- return -1;
-}
-
-/* Count the number of 'if' statements in a generator expression.
-
- Helper for ast_for_genexp().
-*/
-
-static int
-count_gen_ifs(const node *n)
-{
- int n_ifs = 0;
-
- while (1) {
- REQ(n, gen_iter);
- if (TYPE(CHILD(n, 0)) == gen_for)
- return n_ifs;
- n = CHILD(n, 0);
- REQ(n, gen_if);
- n_ifs++;
- if (NCH(n) == 2)
- return n_ifs;
- n = CHILD(n, 2);
- }
-}
-
-/* TODO(jhylton): Combine with list comprehension code? */
-static expr_ty
-ast_for_genexp(struct compiling *c, const node *n)
-{
- /* testlist_gexp: test ( gen_for | (',' test)* [','] )
- argument: [test '='] test [gen_for] # Really [keyword '='] test */
- expr_ty elt;
- asdl_seq *genexps;
- int i, n_fors;
- node *ch;
-
- assert(TYPE(n) == (testlist_gexp) || TYPE(n) == (argument));
- assert(NCH(n) > 1);
-
- elt = ast_for_expr(c, CHILD(n, 0));
- if (!elt)
- return NULL;
-
- n_fors = count_gen_fors(n);
- if (n_fors == -1)
- return NULL;
-
- genexps = asdl_seq_new(n_fors, c->c_arena);
- if (!genexps)
- return NULL;
-
- ch = CHILD(n, 1);
- for (i = 0; i < n_fors; i++) {
- comprehension_ty ge;
- asdl_seq *t;
- expr_ty expression;
- node *for_ch;
-
- REQ(ch, gen_for);
-
- for_ch = CHILD(ch, 1);
- t = ast_for_exprlist(c, for_ch, Store);
- if (!t)
- return NULL;
- expression = ast_for_expr(c, CHILD(ch, 3));
- if (!expression)
- return NULL;
-
- /* Check the # of children rather than the length of t, since
- (x for x, in ...) has 1 element in t, but still requires a Tuple. */
- if (NCH(for_ch) == 1)
- ge = comprehension((expr_ty)asdl_seq_GET(t, 0), expression,
- NULL, c->c_arena);
- else
- ge = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,
- c->c_arena),
- expression, NULL, c->c_arena);
-
- if (!ge)
- return NULL;
-
- if (NCH(ch) == 5) {
- int j, n_ifs;
- asdl_seq *ifs;
-
- ch = CHILD(ch, 4);
- n_ifs = count_gen_ifs(ch);
- if (n_ifs == -1)
- return NULL;
-
- ifs = asdl_seq_new(n_ifs, c->c_arena);
- if (!ifs)
- return NULL;
-
- for (j = 0; j < n_ifs; j++) {
- REQ(ch, gen_iter);
- ch = CHILD(ch, 0);
- REQ(ch, gen_if);
-
- expression = ast_for_expr(c, CHILD(ch, 1));
- if (!expression)
- return NULL;
- asdl_seq_SET(ifs, j, expression);
- if (NCH(ch) == 3)
- ch = CHILD(ch, 2);
- }
- /* on exit, must guarantee that ch is a gen_for */
- if (TYPE(ch) == gen_iter)
- ch = CHILD(ch, 0);
- ge->ifs = ifs;
- }
- asdl_seq_SET(genexps, i, ge);
- }
-
- return GeneratorExp(elt, genexps, LINENO(n), n->n_col_offset, c->c_arena);
-}
-
-static expr_ty
-ast_for_atom(struct compiling *c, const node *n)
-{
- /* atom: '(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']'
- | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+
- */
- node *ch = CHILD(n, 0);
-
- switch (TYPE(ch)) {
- case NAME:
- /* All names start in Load context, but may later be
- changed. */
- return Name(NEW_IDENTIFIER(ch), Load, LINENO(n), n->n_col_offset, c->c_arena);
- case STRING: {
- PyObject *str = parsestrplus(c, n);
- if (!str)
- return NULL;
-
- PyArena_AddPyObject(c->c_arena, str);
- return Str(str, LINENO(n), n->n_col_offset, c->c_arena);
- }
- case NUMBER: {
- PyObject *pynum = parsenumber(STR(ch));
- if (!pynum)
- return NULL;
-
- PyArena_AddPyObject(c->c_arena, pynum);
- return Num(pynum, LINENO(n), n->n_col_offset, c->c_arena);
- }
- case LPAR: /* some parenthesized expressions */
- ch = CHILD(n, 1);
-
- if (TYPE(ch) == RPAR)
- return Tuple(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena);
-
- if (TYPE(ch) == yield_expr)
- return ast_for_expr(c, ch);
-
- if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == gen_for))
- return ast_for_genexp(c, ch);
-
- return ast_for_testlist_gexp(c, ch);
- case LSQB: /* list (or list comprehension) */
- ch = CHILD(n, 1);
-
- if (TYPE(ch) == RSQB)
- return List(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena);
-
- REQ(ch, listmaker);
- if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
- asdl_seq *elts = seq_for_testlist(c, ch);
- if (!elts)
- return NULL;
-
- return List(elts, Load, LINENO(n), n->n_col_offset, c->c_arena);
- }
- else
- return ast_for_listcomp(c, ch);
- case LBRACE: {
- /* dictmaker: test ':' test (',' test ':' test)* [','] */
- int i, size;
- asdl_seq *keys, *values;
-
- ch = CHILD(n, 1);
- size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
- keys = asdl_seq_new(size, c->c_arena);
- if (!keys)
- return NULL;
-
- values = asdl_seq_new(size, c->c_arena);
- if (!values)
- return NULL;
-
- for (i = 0; i < NCH(ch); i += 4) {
- expr_ty expression;
-
- expression = ast_for_expr(c, CHILD(ch, i));
- if (!expression)
- return NULL;
-
- asdl_seq_SET(keys, i / 4, expression);
-
- expression = ast_for_expr(c, CHILD(ch, i + 2));
- if (!expression)
- return NULL;
-
- asdl_seq_SET(values, i / 4, expression);
- }
- return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);
- }
- case BACKQUOTE: { /* repr */
- expr_ty expression = ast_for_testlist(c, CHILD(n, 1));
- if (!expression)
- return NULL;
-
- return Repr(expression, LINENO(n), n->n_col_offset, c->c_arena);
- }
- default:
- PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch));
- return NULL;
- }
-}
-
-static slice_ty
-ast_for_slice(struct compiling *c, const node *n)
-{
- node *ch;
- expr_ty lower = NULL, upper = NULL, step = NULL;
-
- REQ(n, subscript);
-
- /*
- subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
- sliceop: ':' [test]
- */
- ch = CHILD(n, 0);
- if (TYPE(ch) == DOT)
- return Ellipsis(c->c_arena);
-
- if (NCH(n) == 1 && TYPE(ch) == test) {
- /* 'step' variable hold no significance in terms of being used over
- other vars */
- step = ast_for_expr(c, ch);
- if (!step)
- return NULL;
-
- return Index(step, c->c_arena);
- }
-
- if (TYPE(ch) == test) {
- lower = ast_for_expr(c, ch);
- if (!lower)
- return NULL;
- }
-
- /* If there's an upper bound it's in the second or third position. */
- if (TYPE(ch) == COLON) {
- if (NCH(n) > 1) {
- node *n2 = CHILD(n, 1);
-
- if (TYPE(n2) == test) {
- upper = ast_for_expr(c, n2);
- if (!upper)
- return NULL;
- }
- }
- } else if (NCH(n) > 2) {
- node *n2 = CHILD(n, 2);
-
- if (TYPE(n2) == test) {
- upper = ast_for_expr(c, n2);
- if (!upper)
- return NULL;
- }
- }
-
- ch = CHILD(n, NCH(n) - 1);
- if (TYPE(ch) == sliceop) {
- if (NCH(ch) == 1) {
- /* No expression, so step is None */
- ch = CHILD(ch, 0);
- step = Name(new_identifier("None", c->c_arena), Load,
- LINENO(ch), ch->n_col_offset, c->c_arena);
- if (!step)
- return NULL;
- } else {
- ch = CHILD(ch, 1);
- if (TYPE(ch) == test) {
- step = ast_for_expr(c, ch);
- if (!step)
- return NULL;
- }
- }
- }
-
- return Slice(lower, upper, step, c->c_arena);
-}
-
-static expr_ty
-ast_for_binop(struct compiling *c, const node *n)
-{
- /* Must account for a sequence of expressions.
- How should A op B op C by represented?
- BinOp(BinOp(A, op, B), op, C).
- */
-
- int i, nops;
- expr_ty expr1, expr2, result;
- operator_ty newoperator;
-
- expr1 = ast_for_expr(c, CHILD(n, 0));
- if (!expr1)
- return NULL;
-
- expr2 = ast_for_expr(c, CHILD(n, 2));
- if (!expr2)
- return NULL;
-
- newoperator = get_operator(CHILD(n, 1));
- if (!newoperator)
- return NULL;
-
- result = BinOp(expr1, newoperator, expr2, LINENO(n), n->n_col_offset,
- c->c_arena);
- if (!result)
- return NULL;
-
- nops = (NCH(n) - 1) / 2;
- for (i = 1; i < nops; i++) {
- expr_ty tmp_result, tmp;
- const node* next_oper = CHILD(n, i * 2 + 1);
-
- newoperator = get_operator(next_oper);
- if (!newoperator)
- return NULL;
-
- tmp = ast_for_expr(c, CHILD(n, i * 2 + 2));
- if (!tmp)
- return NULL;
-
- tmp_result = BinOp(result, newoperator, tmp,
- LINENO(next_oper), next_oper->n_col_offset,
- c->c_arena);
- if (!tmp)
- return NULL;
- result = tmp_result;
- }
- return result;
-}
-
-static expr_ty
-ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr)
-{
- /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
- subscriptlist: subscript (',' subscript)* [',']
- subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]
- */
- REQ(n, trailer);
- if (TYPE(CHILD(n, 0)) == LPAR) {
- if (NCH(n) == 2)
- return Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n),
- n->n_col_offset, c->c_arena);
- else
- return ast_for_call(c, CHILD(n, 1), left_expr);
- }
- else if (TYPE(CHILD(n, 0)) == DOT ) {
- return Attribute(left_expr, NEW_IDENTIFIER(CHILD(n, 1)), Load,
- LINENO(n), n->n_col_offset, c->c_arena);
- }
- else {
- REQ(CHILD(n, 0), LSQB);
- REQ(CHILD(n, 2), RSQB);
- n = CHILD(n, 1);
- if (NCH(n) == 1) {
- slice_ty slc = ast_for_slice(c, CHILD(n, 0));
- if (!slc)
- return NULL;
- return Subscript(left_expr, slc, Load, LINENO(n), n->n_col_offset,
- c->c_arena);
- }
- else {
- /* The grammar is ambiguous here. The ambiguity is resolved
- by treating the sequence as a tuple literal if there are
- no slice features.
- */
- int j;
- slice_ty slc;
- expr_ty e;
- bool simple = true;
- asdl_seq *slices, *elts;
- slices = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
- if (!slices)
- return NULL;
- for (j = 0; j < NCH(n); j += 2) {
- slc = ast_for_slice(c, CHILD(n, j));
- if (!slc)
- return NULL;
- if (slc->kind != Index_kind)
- simple = false;
- asdl_seq_SET(slices, j / 2, slc);
- }
- if (!simple) {
- return Subscript(left_expr, ExtSlice(slices, c->c_arena),
- Load, LINENO(n), n->n_col_offset, c->c_arena);
- }
- /* extract Index values and put them in a Tuple */
- elts = asdl_seq_new(asdl_seq_LEN(slices), c->c_arena);
- if (!elts)
- return NULL;
- for (j = 0; j < asdl_seq_LEN(slices); ++j) {
- slc = (slice_ty)asdl_seq_GET(slices, j);
- assert(slc->kind == Index_kind && slc->v.Index.value);
- asdl_seq_SET(elts, j, slc->v.Index.value);
- }
- e = Tuple(elts, Load, LINENO(n), n->n_col_offset, c->c_arena);
- if (!e)
- return NULL;
- return Subscript(left_expr, Index(e, c->c_arena),
- Load, LINENO(n), n->n_col_offset, c->c_arena);
- }
- }
-}
-
-static expr_ty
-ast_for_factor(struct compiling *c, const node *n)
-{
- node *pfactor, *ppower, *patom, *pnum;
- expr_ty expression;
-
- /* If the unary - operator is applied to a constant, don't generate
- a UNARY_NEGATIVE opcode. Just store the approriate value as a
- constant. The peephole optimizer already does something like
- this but it doesn't handle the case where the constant is
- (sys.maxint - 1). In that case, we want a PyIntObject, not a
- PyLongObject.
- */
- if (TYPE(CHILD(n, 0)) == MINUS
- && NCH(n) == 2
- && TYPE((pfactor = CHILD(n, 1))) == factor
- && NCH(pfactor) == 1
- && TYPE((ppower = CHILD(pfactor, 0))) == power
- && NCH(ppower) == 1
- && TYPE((patom = CHILD(ppower, 0))) == atom
- && TYPE((pnum = CHILD(patom, 0))) == NUMBER) {
- char *s = PyObject_MALLOC(strlen(STR(pnum)) + 2);
- if (s == NULL)
- return NULL;
- s[0] = '-';
- strcpy(s + 1, STR(pnum));
- PyObject_FREE(STR(pnum));
- STR(pnum) = s;
- return ast_for_atom(c, patom);
- }
-
- expression = ast_for_expr(c, CHILD(n, 1));
- if (!expression)
- return NULL;
-
- switch (TYPE(CHILD(n, 0))) {
- case PLUS:
- return UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset,
- c->c_arena);
- case MINUS:
- return UnaryOp(USub, expression, LINENO(n), n->n_col_offset,
- c->c_arena);
- case TILDE:
- return UnaryOp(Invert, expression, LINENO(n),
- n->n_col_offset, c->c_arena);
- }
- PyErr_Format(PyExc_SystemError, "unhandled factor: %d",
- TYPE(CHILD(n, 0)));
- return NULL;
-}
-
-static expr_ty
-ast_for_power(struct compiling *c, const node *n)
-{
- /* power: atom trailer* ('**' factor)*
- */
- int i;
- expr_ty e, tmp;
- REQ(n, power);
- e = ast_for_atom(c, CHILD(n, 0));
- if (!e)
- return NULL;
- if (NCH(n) == 1)
- return e;
- for (i = 1; i < NCH(n); i++) {
- node *ch = CHILD(n, i);
- if (TYPE(ch) != trailer)
- break;
- tmp = ast_for_trailer(c, ch, e);
- if (!tmp)
- return NULL;
- tmp->lineno = e->lineno;
- tmp->col_offset = e->col_offset;
- e = tmp;
- }
- if (TYPE(CHILD(n, NCH(n) - 1)) == factor) {
- expr_ty f = ast_for_expr(c, CHILD(n, NCH(n) - 1));
- if (!f)
- return NULL;
- tmp = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, c->c_arena);
- if (!tmp)
- return NULL;
- e = tmp;
- }
- return e;
-}
-
-/* Do not name a variable 'expr'! Will cause a compile error.
-*/
-
-static expr_ty
-ast_for_expr(struct compiling *c, const node *n)
-{
- /* handle the full range of simple expressions
- test: or_test ['if' or_test 'else' test] | lambdef
- or_test: and_test ('or' and_test)*
- and_test: not_test ('and' not_test)*
- not_test: 'not' not_test | comparison
- comparison: expr (comp_op expr)*
- expr: xor_expr ('|' xor_expr)*
- xor_expr: and_expr ('^' and_expr)*
- and_expr: shift_expr ('&' shift_expr)*
- shift_expr: arith_expr (('<<'|'>>') arith_expr)*
- arith_expr: term (('+'|'-') term)*
- term: factor (('*'|'/'|'%'|'//') factor)*
- factor: ('+'|'-'|'~') factor | power
- power: atom trailer* ('**' factor)*
-
- As well as modified versions that exist for backward compatibility,
- to explicitly allow:
- [ x for x in lambda: 0, lambda: 1 ]
- (which would be ambiguous without these extra rules)
-
- old_test: or_test | old_lambdef
- old_lambdef: 'lambda' [vararglist] ':' old_test
-
- */
-
- asdl_seq *seq;
- int i;
-
- loop:
- switch (TYPE(n)) {
- case test:
- case old_test:
- if (TYPE(CHILD(n, 0)) == lambdef ||
- TYPE(CHILD(n, 0)) == old_lambdef)
- return ast_for_lambdef(c, CHILD(n, 0));
- else if (NCH(n) > 1)
- return ast_for_ifexpr(c, n);
- /* Fallthrough */
- case or_test:
- case and_test:
- if (NCH(n) == 1) {
- n = CHILD(n, 0);
- goto loop;
- }
- seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
- if (!seq)
- return NULL;
- for (i = 0; i < NCH(n); i += 2) {
- expr_ty e = ast_for_expr(c, CHILD(n, i));
- if (!e)
- return NULL;
- asdl_seq_SET(seq, i / 2, e);
- }
- if (!strcmp(STR(CHILD(n, 1)), "and"))
- return BoolOp(And, seq, LINENO(n), n->n_col_offset,
- c->c_arena);
- assert(!strcmp(STR(CHILD(n, 1)), "or"));
- return BoolOp(Or, seq, LINENO(n), n->n_col_offset, c->c_arena);
- case not_test:
- if (NCH(n) == 1) {
- n = CHILD(n, 0);
- goto loop;
- }
- else {
- expr_ty expression = ast_for_expr(c, CHILD(n, 1));
- if (!expression)
- return NULL;
-
- return UnaryOp(Not, expression, LINENO(n), n->n_col_offset,
- c->c_arena);
- }
- case comparison:
- if (NCH(n) == 1) {
- n = CHILD(n, 0);
- goto loop;
- }
- else {
- expr_ty expression;
- asdl_int_seq *ops;
- asdl_seq *cmps;
- ops = asdl_int_seq_new(NCH(n) / 2, c->c_arena);
- if (!ops)
- return NULL;
- cmps = asdl_seq_new(NCH(n) / 2, c->c_arena);
- if (!cmps) {
- return NULL;
- }
- for (i = 1; i < NCH(n); i += 2) {
- cmpop_ty newoperator;
-
- newoperator = ast_for_comp_op(CHILD(n, i));
- if (!newoperator) {
- return NULL;
- }
-
- expression = ast_for_expr(c, CHILD(n, i + 1));
- if (!expression) {
- return NULL;
- }
-
- asdl_seq_SET(ops, i / 2, newoperator);
- asdl_seq_SET(cmps, i / 2, expression);
- }
- expression = ast_for_expr(c, CHILD(n, 0));
- if (!expression) {
- return NULL;
- }
-
- return Compare(expression, ops, cmps, LINENO(n),
- n->n_col_offset, c->c_arena);
- }
- break;
-
- /* The next five cases all handle BinOps. The main body of code
- is the same in each case, but the switch turned inside out to
- reuse the code for each type of operator.
- */
- case expr:
- case xor_expr:
- case and_expr:
- case shift_expr:
- case arith_expr:
- case term:
- if (NCH(n) == 1) {
- n = CHILD(n, 0);
- goto loop;
- }
- return ast_for_binop(c, n);
- case yield_expr: {
- expr_ty exp = NULL;
- if (NCH(n) == 2) {
- exp = ast_for_testlist(c, CHILD(n, 1));
- if (!exp)
- return NULL;
- }
- return Yield(exp, LINENO(n), n->n_col_offset, c->c_arena);
- }
- case factor:
- if (NCH(n) == 1) {
- n = CHILD(n, 0);
- goto loop;
- }
- return ast_for_factor(c, n);
- case power:
- return ast_for_power(c, n);
- default:
- PyErr_Format(PyExc_SystemError, "unhandled expr: %d", TYPE(n));
- return NULL;
- }
- /* should never get here unless if error is set */
- return NULL;
-}
-
-static expr_ty
-ast_for_call(struct compiling *c, const node *n, expr_ty func)
-{
- /*
- arglist: (argument ',')* (argument [',']| '*' test [',' '**' test]
- | '**' test)
- argument: [test '='] test [gen_for] # Really [keyword '='] test
- */
-
- int i, nargs, nkeywords, ngens;
- asdl_seq *args;
- asdl_seq *keywords;
- expr_ty vararg = NULL, kwarg = NULL;
-
- REQ(n, arglist);
-
- nargs = 0;
- nkeywords = 0;
- ngens = 0;
- for (i = 0; i < NCH(n); i++) {
- node *ch = CHILD(n, i);
- if (TYPE(ch) == argument) {
- if (NCH(ch) == 1)
- nargs++;
- else if (TYPE(CHILD(ch, 1)) == gen_for)
- ngens++;
- else
- nkeywords++;
- }
- }
- if (ngens > 1 || (ngens && (nargs || nkeywords))) {
- ast_error(n, "Generator expression must be parenthesized "
- "if not sole argument");
- return NULL;
- }
-
- if (nargs + nkeywords + ngens > 255) {
- ast_error(n, "more than 255 arguments");
- return NULL;
- }
-
- args = asdl_seq_new(nargs + ngens, c->c_arena);
- if (!args)
- return NULL;
- keywords = asdl_seq_new(nkeywords, c->c_arena);
- if (!keywords)
- return NULL;
- nargs = 0;
- nkeywords = 0;
- for (i = 0; i < NCH(n); i++) {
- node *ch = CHILD(n, i);
- if (TYPE(ch) == argument) {
- expr_ty e;
- if (NCH(ch) == 1) {
- if (nkeywords) {
- ast_error(CHILD(ch, 0),
- "non-keyword arg after keyword arg");
- return NULL;
- }
- e = ast_for_expr(c, CHILD(ch, 0));
- if (!e)
- return NULL;
- asdl_seq_SET(args, nargs++, e);
- }
- else if (TYPE(CHILD(ch, 1)) == gen_for) {
- e = ast_for_genexp(c, ch);
- if (!e)
- return NULL;
- asdl_seq_SET(args, nargs++, e);
- }
- else {
- keyword_ty kw;
- identifier key;
-
- /* CHILD(ch, 0) is test, but must be an identifier? */
- e = ast_for_expr(c, CHILD(ch, 0));
- if (!e)
- return NULL;
- /* f(lambda x: x[0] = 3) ends up getting parsed with
- * LHS test = lambda x: x[0], and RHS test = 3.
- * SF bug 132313 points out that complaining about a keyword
- * then is very confusing.
- */
- if (e->kind == Lambda_kind) {
- ast_error(CHILD(ch, 0), "lambda cannot contain assignment");
- return NULL;
- } else if (e->kind != Name_kind) {
- ast_error(CHILD(ch, 0), "keyword can't be an expression");
- return NULL;
- }
- key = e->v.Name.id;
- e = ast_for_expr(c, CHILD(ch, 2));
- if (!e)
- return NULL;
- kw = keyword(key, e, c->c_arena);
- if (!kw)
- return NULL;
- asdl_seq_SET(keywords, nkeywords++, kw);
- }
- }
- else if (TYPE(ch) == STAR) {
- vararg = ast_for_expr(c, CHILD(n, i+1));
- i++;
- }
- else if (TYPE(ch) == DOUBLESTAR) {
- kwarg = ast_for_expr(c, CHILD(n, i+1));
- i++;
- }
- }
-
- return Call(func, args, keywords, vararg, kwarg, func->lineno, func->col_offset, c->c_arena);
-}
-
-static expr_ty
-ast_for_testlist(struct compiling *c, const node* n)
-{
- /* testlist_gexp: test (',' test)* [','] */
- /* testlist: test (',' test)* [','] */
- /* testlist_safe: test (',' test)+ [','] */
- /* testlist1: test (',' test)* */
- assert(NCH(n) > 0);
- if (TYPE(n) == testlist_gexp) {
- if (NCH(n) > 1)
- assert(TYPE(CHILD(n, 1)) != gen_for);
- }
- else {
- assert(TYPE(n) == testlist ||
- TYPE(n) == testlist_safe ||
- TYPE(n) == testlist1);
- }
- if (NCH(n) == 1)
- return ast_for_expr(c, CHILD(n, 0));
- else {
- asdl_seq *tmp = seq_for_testlist(c, n);
- if (!tmp)
- return NULL;
- return Tuple(tmp, Load, LINENO(n), n->n_col_offset, c->c_arena);
- }
-}
-
-static expr_ty
-ast_for_testlist_gexp(struct compiling *c, const node* n)
-{
- /* testlist_gexp: test ( gen_for | (',' test)* [','] ) */
- /* argument: test [ gen_for ] */
- assert(TYPE(n) == testlist_gexp || TYPE(n) == argument);
- if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == gen_for)
- return ast_for_genexp(c, n);
- return ast_for_testlist(c, n);
-}
-
-/* like ast_for_testlist() but returns a sequence */
-static asdl_seq*
-ast_for_class_bases(struct compiling *c, const node* n)
-{
- /* testlist: test (',' test)* [','] */
- assert(NCH(n) > 0);
- REQ(n, testlist);
- if (NCH(n) == 1) {
- expr_ty base;
- asdl_seq *bases = asdl_seq_new(1, c->c_arena);
- if (!bases)
- return NULL;
- base = ast_for_expr(c, CHILD(n, 0));
- if (!base)
- return NULL;
- asdl_seq_SET(bases, 0, base);
- return bases;
- }
-
- return seq_for_testlist(c, n);
-}
-
-static stmt_ty
-ast_for_expr_stmt(struct compiling *c, const node *n)
-{
- REQ(n, expr_stmt);
- /* expr_stmt: testlist (augassign (yield_expr|testlist)
- | ('=' (yield_expr|testlist))*)
- testlist: test (',' test)* [',']
- augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^='
- | '<<=' | '>>=' | '**=' | '//='
- test: ... here starts the operator precendence dance
- */
-
- if (NCH(n) == 1) {
- expr_ty e = ast_for_testlist(c, CHILD(n, 0));
- if (!e)
- return NULL;
-
- return Expr(e, LINENO(n), n->n_col_offset, c->c_arena);
- }
- else if (TYPE(CHILD(n, 1)) == augassign) {
- expr_ty expr1, expr2;
- operator_ty newoperator;
- node *ch = CHILD(n, 0);
-
- expr1 = ast_for_testlist(c, ch);
- if (!expr1)
- return NULL;
- /* TODO(nas): Remove duplicated error checks (set_context does it) */
- switch (expr1->kind) {
- case GeneratorExp_kind:
- ast_error(ch, "augmented assignment to generator "
- "expression not possible");
- return NULL;
- case Yield_kind:
- ast_error(ch, "augmented assignment to yield "
- "expression not possible");
- return NULL;
- case Name_kind: {
- const char *var_name = PyString_AS_STRING(expr1->v.Name.id);
- if (var_name[0] == 'N' && !strcmp(var_name, "None")) {
- ast_error(ch, "assignment to None");
- return NULL;
- }
- break;
- }
- case Attribute_kind:
- case Subscript_kind:
- break;
- default:
- ast_error(ch, "illegal expression for augmented "
- "assignment");
- return NULL;
- }
- if (!set_context(expr1, Store, ch))
- return NULL;
-
- ch = CHILD(n, 2);
- if (TYPE(ch) == testlist)
- expr2 = ast_for_testlist(c, ch);
- else
- expr2 = ast_for_expr(c, ch);
- if (!expr2)
- return NULL;
-
- newoperator = ast_for_augassign(CHILD(n, 1));
- if (!newoperator)
- return NULL;
-
- return AugAssign(expr1, newoperator, expr2, LINENO(n), n->n_col_offset, c->c_arena);
- }
- else {
- int i;
- asdl_seq *targets;
- node *value;
- expr_ty expression;
-
- /* a normal assignment */
- REQ(CHILD(n, 1), EQUAL);
- targets = asdl_seq_new(NCH(n) / 2, c->c_arena);
- if (!targets)
- return NULL;
- for (i = 0; i < NCH(n) - 2; i += 2) {
- expr_ty e;
- node *ch = CHILD(n, i);
- if (TYPE(ch) == yield_expr) {
- ast_error(ch, "assignment to yield expression not possible");
- return NULL;
- }
- e = ast_for_testlist(c, ch);
-
- /* set context to assign */
- if (!e)
- return NULL;
-
- if (!set_context(e, Store, CHILD(n, i)))
- return NULL;
-
- asdl_seq_SET(targets, i / 2, e);
- }
- value = CHILD(n, NCH(n) - 1);
- if (TYPE(value) == testlist)
- expression = ast_for_testlist(c, value);
- else
- expression = ast_for_expr(c, value);
- if (!expression)
- return NULL;
- return Assign(targets, expression, LINENO(n), n->n_col_offset, c->c_arena);
- }
-}
-
-static stmt_ty
-ast_for_print_stmt(struct compiling *c, const node *n)
-{
- /* print_stmt: 'print' ( [ test (',' test)* [','] ]
- | '>>' test [ (',' test)+ [','] ] )
- */
- expr_ty dest = NULL, expression;
- asdl_seq *seq;
- bool nl;
- int i, j, start = 1;
-
- REQ(n, print_stmt);
- if (NCH(n) >= 2 && TYPE(CHILD(n, 1)) == RIGHTSHIFT) {
- dest = ast_for_expr(c, CHILD(n, 2));
- if (!dest)
- return NULL;
- start = 4;
- }
- seq = asdl_seq_new((NCH(n) + 1 - start) / 2, c->c_arena);
- if (!seq)
- return NULL;
- for (i = start, j = 0; i < NCH(n); i += 2, ++j) {
- expression = ast_for_expr(c, CHILD(n, i));
- if (!expression)
- return NULL;
- asdl_seq_SET(seq, j, expression);
- }
- nl = (TYPE(CHILD(n, NCH(n) - 1)) == COMMA) ? false : true;
- return Print(dest, seq, nl, LINENO(n), n->n_col_offset, c->c_arena);
-}
-
-static asdl_seq *
-ast_for_exprlist(struct compiling *c, const node *n, expr_context_ty context)
-{
- asdl_seq *seq;
- int i;
- expr_ty e;
-
- REQ(n, exprlist);
-
- seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
- if (!seq)
- return NULL;
- for (i = 0; i < NCH(n); i += 2) {
- e = ast_for_expr(c, CHILD(n, i));
- if (!e)
- return NULL;
- asdl_seq_SET(seq, i / 2, e);
- if (context && !set_context(e, context, CHILD(n, i)))
- return NULL;
- }
- return seq;
-}
-
-static stmt_ty
-ast_for_del_stmt(struct compiling *c, const node *n)
-{
- asdl_seq *expr_list;
-
- /* del_stmt: 'del' exprlist */
- REQ(n, del_stmt);
-
- expr_list = ast_for_exprlist(c, CHILD(n, 1), Del);
- if (!expr_list)
- return NULL;
- return Delete(expr_list, LINENO(n), n->n_col_offset, c->c_arena);
-}
-
-static stmt_ty
-ast_for_flow_stmt(struct compiling *c, const node *n)
-{
- /*
- flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt
- | yield_stmt
- break_stmt: 'break'
- continue_stmt: 'continue'
- return_stmt: 'return' [testlist]
- yield_stmt: yield_expr
- yield_expr: 'yield' testlist
- raise_stmt: 'raise' [test [',' test [',' test]]]
- */
- node *ch;
-
- REQ(n, flow_stmt);
- ch = CHILD(n, 0);
- switch (TYPE(ch)) {
- case break_stmt:
- return Break(LINENO(n), n->n_col_offset, c->c_arena);
- case continue_stmt:
- return Continue(LINENO(n), n->n_col_offset, c->c_arena);
- case yield_stmt: { /* will reduce to yield_expr */
- expr_ty exp = ast_for_expr(c, CHILD(ch, 0));
- if (!exp)
- return NULL;
- return Expr(exp, LINENO(n), n->n_col_offset, c->c_arena);
- }
- case return_stmt:
- if (NCH(ch) == 1)
- return Return(NULL, LINENO(n), n->n_col_offset, c->c_arena);
- else {
- expr_ty expression = ast_for_testlist(c, CHILD(ch, 1));
- if (!expression)
- return NULL;
- return Return(expression, LINENO(n), n->n_col_offset, c->c_arena);
- }
- case raise_stmt:
- if (NCH(ch) == 1)
- return Raise(NULL, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena);
- else if (NCH(ch) == 2) {
- expr_ty expression = ast_for_expr(c, CHILD(ch, 1));
- if (!expression)
- return NULL;
- return Raise(expression, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena);
- }
- else if (NCH(ch) == 4) {
- expr_ty expr1, expr2;
-
- expr1 = ast_for_expr(c, CHILD(ch, 1));
- if (!expr1)
- return NULL;
- expr2 = ast_for_expr(c, CHILD(ch, 3));
- if (!expr2)
- return NULL;
-
- return Raise(expr1, expr2, NULL, LINENO(n), n->n_col_offset, c->c_arena);
- }
- else if (NCH(ch) == 6) {
- expr_ty expr1, expr2, expr3;
-
- expr1 = ast_for_expr(c, CHILD(ch, 1));
- if (!expr1)
- return NULL;
- expr2 = ast_for_expr(c, CHILD(ch, 3));
- if (!expr2)
- return NULL;
- expr3 = ast_for_expr(c, CHILD(ch, 5));
- if (!expr3)
- return NULL;
-
- return Raise(expr1, expr2, expr3, LINENO(n), n->n_col_offset, c->c_arena);
- }
- default:
- PyErr_Format(PyExc_SystemError,
- "unexpected flow_stmt: %d", TYPE(ch));
- return NULL;
- }
-
- PyErr_SetString(PyExc_SystemError, "unhandled flow statement");
- return NULL;
-}
-
-static alias_ty
-alias_for_import_name(struct compiling *c, const node *n)
-{
- /*
- import_as_name: NAME ['as' NAME]
- dotted_as_name: dotted_name ['as' NAME]
- dotted_name: NAME ('.' NAME)*
- */
- PyObject *str;
-
- loop:
- switch (TYPE(n)) {
- case import_as_name:
- str = NULL;
- if (NCH(n) == 3) {
- if (strcmp(STR(CHILD(n, 1)), "as") != 0) {
- ast_error(n, "must use 'as' in import");
- return NULL;
- }
- str = NEW_IDENTIFIER(CHILD(n, 2));
- }
- return alias(NEW_IDENTIFIER(CHILD(n, 0)), str, c->c_arena);
- case dotted_as_name:
- if (NCH(n) == 1) {
- n = CHILD(n, 0);
- goto loop;
- }
- else {
- alias_ty a = alias_for_import_name(c, CHILD(n, 0));
- if (!a)
- return NULL;
- if (strcmp(STR(CHILD(n, 1)), "as") != 0) {
- ast_error(n, "must use 'as' in import");
- return NULL;
- }
- assert(!a->asname);
- a->asname = NEW_IDENTIFIER(CHILD(n, 2));
- return a;
- }
- break;
- case dotted_name:
- if (NCH(n) == 1)
- return alias(NEW_IDENTIFIER(CHILD(n, 0)), NULL, c->c_arena);
- else {
- /* Create a string of the form "a.b.c" */
- int i;
- size_t len;
- char *s;
-
- len = 0;
- for (i = 0; i < NCH(n); i += 2)
- /* length of string plus one for the dot */
- len += strlen(STR(CHILD(n, i))) + 1;
- len--; /* the last name doesn't have a dot */
- str = PyString_FromStringAndSize(NULL, len);
- if (!str)
- return NULL;
- s = PyString_AS_STRING(str);
- if (!s)
- return NULL;
- for (i = 0; i < NCH(n); i += 2) {
- char *sch = STR(CHILD(n, i));
- strcpy(s, STR(CHILD(n, i)));
- s += strlen(sch);
- *s++ = '.';
- }
- --s;
- *s = '\0';
- PyString_InternInPlace(&str);
- PyArena_AddPyObject(c->c_arena, str);
- return alias(str, NULL, c->c_arena);
- }
- break;
- case STAR:
- str = PyString_InternFromString("*");
- PyArena_AddPyObject(c->c_arena, str);
- return alias(str, NULL, c->c_arena);
- default:
- PyErr_Format(PyExc_SystemError,
- "unexpected import name: %d", TYPE(n));
- return NULL;
- }
-
- PyErr_SetString(PyExc_SystemError, "unhandled import name condition");
- return NULL;
-}
-
-static stmt_ty
-ast_for_import_stmt(struct compiling *c, const node *n)
-{
- /*
- import_stmt: import_name | import_from
- import_name: 'import' dotted_as_names
- import_from: 'from' ('.'* dotted_name | '.') 'import'
- ('*' | '(' import_as_names ')' | import_as_names)
- */
- int lineno;
- int col_offset;
- int i;
- asdl_seq *aliases;
-
- REQ(n, import_stmt);
- lineno = LINENO(n);
- col_offset = n->n_col_offset;
- n = CHILD(n, 0);
- if (TYPE(n) == import_name) {
- n = CHILD(n, 1);
- REQ(n, dotted_as_names);
- aliases = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
- if (!aliases)
- return NULL;
- for (i = 0; i < NCH(n); i += 2) {
- alias_ty import_alias = alias_for_import_name(c, CHILD(n, i));
- if (!import_alias)
- return NULL;
- asdl_seq_SET(aliases, i / 2, import_alias);
- }
- return Import(aliases, lineno, col_offset, c->c_arena);
- }
- else if (TYPE(n) == import_from) {
- int n_children;
- int idx, ndots = 0;
- alias_ty mod = NULL;
- identifier modname;
-
- /* Count the number of dots (for relative imports) and check for the
- optional module name */
- for (idx = 1; idx < NCH(n); idx++) {
- if (TYPE(CHILD(n, idx)) == dotted_name) {
- mod = alias_for_import_name(c, CHILD(n, idx));
- idx++;
- break;
- } else if (TYPE(CHILD(n, idx)) != DOT) {
- break;
- }
- ndots++;
- }
- idx++; /* skip over the 'import' keyword */
- switch (TYPE(CHILD(n, idx))) {
- case STAR:
- /* from ... import * */
- n = CHILD(n, idx);
- n_children = 1;
- if (ndots) {
- ast_error(n, "'import *' not allowed with 'from .'");
- return NULL;
- }
- break;
- case LPAR:
- /* from ... import (x, y, z) */
- n = CHILD(n, idx + 1);
- n_children = NCH(n);
- break;
- case import_as_names:
- /* from ... import x, y, z */
- n = CHILD(n, idx);
- n_children = NCH(n);
- if (n_children % 2 == 0) {
- ast_error(n, "trailing comma not allowed without"
- " surrounding parentheses");
- return NULL;
- }
- break;
- default:
- ast_error(n, "Unexpected node-type in from-import");
- return NULL;
- }
-
- aliases = asdl_seq_new((n_children + 1) / 2, c->c_arena);
- if (!aliases)
- return NULL;
-
- /* handle "from ... import *" special b/c there's no children */
- if (TYPE(n) == STAR) {
- alias_ty import_alias = alias_for_import_name(c, n);
- if (!import_alias)
- return NULL;
- asdl_seq_SET(aliases, 0, import_alias);
- }
- else {
- for (i = 0; i < NCH(n); i += 2) {
- alias_ty import_alias = alias_for_import_name(c, CHILD(n, i));
- if (!import_alias)
- return NULL;
- asdl_seq_SET(aliases, i / 2, import_alias);
- }
- }
- if (mod != NULL)
- modname = mod->name;
- else
- modname = new_identifier("", c->c_arena);
- return ImportFrom(modname, aliases, ndots, lineno, col_offset,
- c->c_arena);
- }
- PyErr_Format(PyExc_SystemError,
- "unknown import statement: starts with command '%s'",
- STR(CHILD(n, 0)));
- return NULL;
-}
-
-static stmt_ty
-ast_for_global_stmt(struct compiling *c, const node *n)
-{
- /* global_stmt: 'global' NAME (',' NAME)* */
- identifier name;
- asdl_seq *s;
- int i;
-
- REQ(n, global_stmt);
- s = asdl_seq_new(NCH(n) / 2, c->c_arena);
- if (!s)
- return NULL;
- for (i = 1; i < NCH(n); i += 2) {
- name = NEW_IDENTIFIER(CHILD(n, i));
- if (!name)
- return NULL;
- asdl_seq_SET(s, i / 2, name);
- }
- return Global(s, LINENO(n), n->n_col_offset, c->c_arena);
-}
-
-static stmt_ty
-ast_for_exec_stmt(struct compiling *c, const node *n)
-{
- expr_ty expr1, globals = NULL, locals = NULL;
- int n_children = NCH(n);
- if (n_children != 2 && n_children != 4 && n_children != 6) {
- PyErr_Format(PyExc_SystemError,
- "poorly formed 'exec' statement: %d parts to statement",
- n_children);
- return NULL;
- }
-
- /* exec_stmt: 'exec' expr ['in' test [',' test]] */
- REQ(n, exec_stmt);
- expr1 = ast_for_expr(c, CHILD(n, 1));
- if (!expr1)
- return NULL;
- if (n_children >= 4) {
- globals = ast_for_expr(c, CHILD(n, 3));
- if (!globals)
- return NULL;
- }
- if (n_children == 6) {
- locals = ast_for_expr(c, CHILD(n, 5));
- if (!locals)
- return NULL;
- }
-
- return Exec(expr1, globals, locals, LINENO(n), n->n_col_offset, c->c_arena);
-}
-
-static stmt_ty
-ast_for_assert_stmt(struct compiling *c, const node *n)
-{
- /* assert_stmt: 'assert' test [',' test] */
- REQ(n, assert_stmt);
- if (NCH(n) == 2) {
- expr_ty expression = ast_for_expr(c, CHILD(n, 1));
- if (!expression)
- return NULL;
- return Assert(expression, NULL, LINENO(n), n->n_col_offset, c->c_arena);
- }
- else if (NCH(n) == 4) {
- expr_ty expr1, expr2;
-
- expr1 = ast_for_expr(c, CHILD(n, 1));
- if (!expr1)
- return NULL;
- expr2 = ast_for_expr(c, CHILD(n, 3));
- if (!expr2)
- return NULL;
-
- return Assert(expr1, expr2, LINENO(n), n->n_col_offset, c->c_arena);
- }
- PyErr_Format(PyExc_SystemError,
- "improper number of parts to 'assert' statement: %d",
- NCH(n));
- return NULL;
-}
-
-static asdl_seq *
-ast_for_suite(struct compiling *c, const node *n)
-{
- /* suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT */
- asdl_seq *seq;
- stmt_ty s;
- int i, total, num, end, pos = 0;
- node *ch;
-
- REQ(n, suite);
-
- total = num_stmts(n);
- seq = asdl_seq_new(total, c->c_arena);
- if (!seq)
- return NULL;
- if (TYPE(CHILD(n, 0)) == simple_stmt) {
- n = CHILD(n, 0);
- /* simple_stmt always ends with a NEWLINE,
- and may have a trailing SEMI
- */
- end = NCH(n) - 1;
- if (TYPE(CHILD(n, end - 1)) == SEMI)
- end--;
- /* loop by 2 to skip semi-colons */
- for (i = 0; i < end; i += 2) {
- ch = CHILD(n, i);
- s = ast_for_stmt(c, ch);
- if (!s)
- return NULL;
- asdl_seq_SET(seq, pos++, s);
- }
- }
- else {
- for (i = 2; i < (NCH(n) - 1); i++) {
- ch = CHILD(n, i);
- REQ(ch, stmt);
- num = num_stmts(ch);
- if (num == 1) {
- /* small_stmt or compound_stmt with only one child */
- s = ast_for_stmt(c, ch);
- if (!s)
- return NULL;
- asdl_seq_SET(seq, pos++, s);
- }
- else {
- int j;
- ch = CHILD(ch, 0);
- REQ(ch, simple_stmt);
- for (j = 0; j < NCH(ch); j += 2) {
- /* statement terminates with a semi-colon ';' */
- if (NCH(CHILD(ch, j)) == 0) {
- assert((j + 1) == NCH(ch));
- break;
- }
- s = ast_for_stmt(c, CHILD(ch, j));
- if (!s)
- return NULL;
- asdl_seq_SET(seq, pos++, s);
- }
- }
- }
- }
- assert(pos == seq->size);
- return seq;
-}
-
-static stmt_ty
-ast_for_if_stmt(struct compiling *c, const node *n)
-{
- /* if_stmt: 'if' test ':' suite ('elif' test ':' suite)*
- ['else' ':' suite]
- */
- char *s;
-
- REQ(n, if_stmt);
-
- if (NCH(n) == 4) {
- expr_ty expression;
- asdl_seq *suite_seq;
-
- expression = ast_for_expr(c, CHILD(n, 1));
- if (!expression)
- return NULL;
- suite_seq = ast_for_suite(c, CHILD(n, 3));
- if (!suite_seq)
- return NULL;
-
- return If(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, c->c_arena);
- }
-
- s = STR(CHILD(n, 4));
- /* s[2], the third character in the string, will be
- 's' for el_s_e, or
- 'i' for el_i_f
- */
- if (s[2] == 's') {
- expr_ty expression;
- asdl_seq *seq1, *seq2;
-
- expression = ast_for_expr(c, CHILD(n, 1));
- if (!expression)
- return NULL;
- seq1 = ast_for_suite(c, CHILD(n, 3));
- if (!seq1)
- return NULL;
- seq2 = ast_for_suite(c, CHILD(n, 6));
- if (!seq2)
- return NULL;
-
- return If(expression, seq1, seq2, LINENO(n), n->n_col_offset, c->c_arena);
- }
- else if (s[2] == 'i') {
- int i, n_elif, has_else = 0;
- expr_ty expression;
- asdl_seq *suite_seq;
- asdl_seq *orelse = NULL;
- n_elif = NCH(n) - 4;
- /* must reference the child n_elif+1 since 'else' token is third,
- not fourth, child from the end. */
- if (TYPE(CHILD(n, (n_elif + 1))) == NAME
- && STR(CHILD(n, (n_elif + 1)))[2] == 's') {
- has_else = 1;
- n_elif -= 3;
- }
- n_elif /= 4;
-
- if (has_else) {
- asdl_seq *suite_seq2;
-
- orelse = asdl_seq_new(1, c->c_arena);
- if (!orelse)
- return NULL;
- expression = ast_for_expr(c, CHILD(n, NCH(n) - 6));
- if (!expression)
- return NULL;
- suite_seq = ast_for_suite(c, CHILD(n, NCH(n) - 4));
- if (!suite_seq)
- return NULL;
- suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
- if (!suite_seq2)
- return NULL;
-
- asdl_seq_SET(orelse, 0, If(expression, suite_seq, suite_seq2,
- LINENO(CHILD(n, NCH(n) - 6)), CHILD(n, NCH(n) - 6)->n_col_offset,
- c->c_arena));
- /* the just-created orelse handled the last elif */
- n_elif--;
- }
-
- for (i = 0; i < n_elif; i++) {
- int off = 5 + (n_elif - i - 1) * 4;
- asdl_seq *newobj = asdl_seq_new(1, c->c_arena);
- if (!newobj)
- return NULL;
- expression = ast_for_expr(c, CHILD(n, off));
- if (!expression)
- return NULL;
- suite_seq = ast_for_suite(c, CHILD(n, off + 2));
- if (!suite_seq)
- return NULL;
-
- asdl_seq_SET(newobj, 0,
- If(expression, suite_seq, orelse,
- LINENO(CHILD(n, off)), CHILD(n, off)->n_col_offset, c->c_arena));
- orelse = newobj;
- }
- expression = ast_for_expr(c, CHILD(n, 1));
- if (!expression)
- return NULL;
- suite_seq = ast_for_suite(c, CHILD(n, 3));
- if (!suite_seq)
- return NULL;
- return If(expression, suite_seq, orelse,
- LINENO(n), n->n_col_offset, c->c_arena);
- }
-
- PyErr_Format(PyExc_SystemError,
- "unexpected token in 'if' statement: %s", s);
- return NULL;
-}
-
-static stmt_ty
-ast_for_while_stmt(struct compiling *c, const node *n)
-{
- /* while_stmt: 'while' test ':' suite ['else' ':' suite] */
- REQ(n, while_stmt);
-
- if (NCH(n) == 4) {
- expr_ty expression;
- asdl_seq *suite_seq;
-
- expression = ast_for_expr(c, CHILD(n, 1));
- if (!expression)
- return NULL;
- suite_seq = ast_for_suite(c, CHILD(n, 3));
- if (!suite_seq)
- return NULL;
- return While(expression, suite_seq, NULL, LINENO(n), n->n_col_offset, c->c_arena);
- }
- else if (NCH(n) == 7) {
- expr_ty expression;
- asdl_seq *seq1, *seq2;
-
- expression = ast_for_expr(c, CHILD(n, 1));
- if (!expression)
- return NULL;
- seq1 = ast_for_suite(c, CHILD(n, 3));
- if (!seq1)
- return NULL;
- seq2 = ast_for_suite(c, CHILD(n, 6));
- if (!seq2)
- return NULL;
-
- return While(expression, seq1, seq2, LINENO(n), n->n_col_offset, c->c_arena);
- }
-
- PyErr_Format(PyExc_SystemError,
- "wrong number of tokens for 'while' statement: %d",
- NCH(n));
- return NULL;
-}
-
-static stmt_ty
-ast_for_for_stmt(struct compiling *c, const node *n)
-{
- asdl_seq *_target, *seq = NULL, *suite_seq;
- expr_ty expression;
- expr_ty target;
- const node *node_target;
- /* for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] */
- REQ(n, for_stmt);
-
- if (NCH(n) == 9) {
- seq = ast_for_suite(c, CHILD(n, 8));
- if (!seq)
- return NULL;
- }
-
- node_target = CHILD(n, 1);
- _target = ast_for_exprlist(c, node_target, Store);
- if (!_target)
- return NULL;
- /* Check the # of children rather than the length of _target, since
- for x, in ... has 1 element in _target, but still requires a Tuple. */
- if (NCH(node_target) == 1)
- target = (expr_ty)asdl_seq_GET(_target, 0);
- else
- target = Tuple(_target, Store, LINENO(n), n->n_col_offset, c->c_arena);
-
- expression = ast_for_testlist(c, CHILD(n, 3));
- if (!expression)
- return NULL;
- suite_seq = ast_for_suite(c, CHILD(n, 5));
- if (!suite_seq)
- return NULL;
-
- return For(target, expression, suite_seq, seq, LINENO(n), n->n_col_offset,
- c->c_arena);
-}
-
-static excepthandler_ty
-ast_for_except_clause(struct compiling *c, const node *exc, node *body)
-{
- /* except_clause: 'except' [test [',' test]] */
- REQ(exc, except_clause);
- REQ(body, suite);
-
- if (NCH(exc) == 1) {
- asdl_seq *suite_seq = ast_for_suite(c, body);
- if (!suite_seq)
- return NULL;
-
- return excepthandler(NULL, NULL, suite_seq, LINENO(exc),
- exc->n_col_offset, c->c_arena);
- }
- else if (NCH(exc) == 2) {
- expr_ty expression;
- asdl_seq *suite_seq;
-
- expression = ast_for_expr(c, CHILD(exc, 1));
- if (!expression)
- return NULL;
- suite_seq = ast_for_suite(c, body);
- if (!suite_seq)
- return NULL;
-
- return excepthandler(expression, NULL, suite_seq, LINENO(exc),
- exc->n_col_offset, c->c_arena);
- }
- else if (NCH(exc) == 4) {
- asdl_seq *suite_seq;
- expr_ty expression;
- expr_ty e = ast_for_expr(c, CHILD(exc, 3));
- if (!e)
- return NULL;
- if (!set_context(e, Store, CHILD(exc, 3)))
- return NULL;
- expression = ast_for_expr(c, CHILD(exc, 1));
- if (!expression)
- return NULL;
- suite_seq = ast_for_suite(c, body);
- if (!suite_seq)
- return NULL;
-
- return excepthandler(expression, e, suite_seq, LINENO(exc),
- exc->n_col_offset, c->c_arena);
- }
-
- PyErr_Format(PyExc_SystemError,
- "wrong number of children for 'except' clause: %d",
- NCH(exc));
- return NULL;
-}
-
-static stmt_ty
-ast_for_try_stmt(struct compiling *c, const node *n)
-{
- const int nch = NCH(n);
- int n_except = (nch - 3)/3;
- asdl_seq *body, *orelse = NULL, *finally = NULL;
-
- REQ(n, try_stmt);
-
- body = ast_for_suite(c, CHILD(n, 2));
- if (body == NULL)
- return NULL;
-
- if (TYPE(CHILD(n, nch - 3)) == NAME) {
- if (strcmp(STR(CHILD(n, nch - 3)), "finally") == 0) {
- if (nch >= 9 && TYPE(CHILD(n, nch - 6)) == NAME) {
- /* we can assume it's an "else",
- because nch >= 9 for try-else-finally and
- it would otherwise have a type of except_clause */
- orelse = ast_for_suite(c, CHILD(n, nch - 4));
- if (orelse == NULL)
- return NULL;
- n_except--;
- }
-
- finally = ast_for_suite(c, CHILD(n, nch - 1));
- if (finally == NULL)
- return NULL;
- n_except--;
- }
- else {
- /* we can assume it's an "else",
- otherwise it would have a type of except_clause */
- orelse = ast_for_suite(c, CHILD(n, nch - 1));
- if (orelse == NULL)
- return NULL;
- n_except--;
- }
- }
- else if (TYPE(CHILD(n, nch - 3)) != except_clause) {
- ast_error(n, "malformed 'try' statement");
- return NULL;
- }
-
- if (n_except > 0) {
- int i;
- stmt_ty except_st;
- /* process except statements to create a try ... except */
- asdl_seq *handlers = asdl_seq_new(n_except, c->c_arena);
- if (handlers == NULL)
- return NULL;
-
- for (i = 0; i < n_except; i++) {
- excepthandler_ty e = ast_for_except_clause(c, CHILD(n, 3 + i * 3),
- CHILD(n, 5 + i * 3));
- if (!e)
- return NULL;
- asdl_seq_SET(handlers, i, e);
- }
-
- except_st = TryExcept(body, handlers, orelse, LINENO(n),
- n->n_col_offset, c->c_arena);
- if (!finally)
- return except_st;
-
- /* if a 'finally' is present too, we nest the TryExcept within a
- TryFinally to emulate try ... except ... finally */
- body = asdl_seq_new(1, c->c_arena);
- if (body == NULL)
- return NULL;
- asdl_seq_SET(body, 0, except_st);
- }
-
- /* must be a try ... finally (except clauses are in body, if any exist) */
- assert(finally != NULL);
- return TryFinally(body, finally, LINENO(n), n->n_col_offset, c->c_arena);
-}
-
-static expr_ty
-ast_for_with_var(struct compiling *c, const node *n)
-{
- REQ(n, with_var);
- if (strcmp(STR(CHILD(n, 0)), "as") != 0) {
- ast_error(n, "expected \"with [expr] as [var]\"");
- return NULL;
- }
- return ast_for_expr(c, CHILD(n, 1));
-}
-
-/* with_stmt: 'with' test [ with_var ] ':' suite */
-static stmt_ty
-ast_for_with_stmt(struct compiling *c, const node *n)
-{
- expr_ty context_expr, optional_vars = NULL;
- int suite_index = 3; /* skip 'with', test, and ':' */
- asdl_seq *suite_seq;
-
- assert(TYPE(n) == with_stmt);
- context_expr = ast_for_expr(c, CHILD(n, 1));
- if (!context_expr)
- return NULL;
- if (TYPE(CHILD(n, 2)) == with_var) {
- optional_vars = ast_for_with_var(c, CHILD(n, 2));
-
- if (!optional_vars) {
- return NULL;
- }
- if (!set_context(optional_vars, Store, n)) {
- return NULL;
- }
- suite_index = 4;
- }
-
- suite_seq = ast_for_suite(c, CHILD(n, suite_index));
- if (!suite_seq) {
- return NULL;
- }
- return With(context_expr, optional_vars, suite_seq, LINENO(n),
- n->n_col_offset, c->c_arena);
-}
-
-static stmt_ty
-ast_for_classdef(struct compiling *c, const node *n)
-{
- /* classdef: 'class' NAME ['(' testlist ')'] ':' suite */
- asdl_seq *bases, *s;
-
- REQ(n, classdef);
-
- if (!strcmp(STR(CHILD(n, 1)), "None")) {
- ast_error(n, "assignment to None");
- return NULL;
- }
-
- if (NCH(n) == 4) {
- s = ast_for_suite(c, CHILD(n, 3));
- if (!s)
- return NULL;
- return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n),
- n->n_col_offset, c->c_arena);
- }
- /* check for empty base list */
- if (TYPE(CHILD(n,3)) == RPAR) {
- s = ast_for_suite(c, CHILD(n,5));
- if (!s)
- return NULL;
- return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n),
- n->n_col_offset, c->c_arena);
- }
-
- /* else handle the base class list */
- bases = ast_for_class_bases(c, CHILD(n, 3));
- if (!bases)
- return NULL;
-
- s = ast_for_suite(c, CHILD(n, 6));
- if (!s)
- return NULL;
- return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), bases, s, LINENO(n),
- n->n_col_offset, c->c_arena);
-}
-
-static stmt_ty
-ast_for_stmt(struct compiling *c, const node *n)
-{
- if (TYPE(n) == stmt) {
- assert(NCH(n) == 1);
- n = CHILD(n, 0);
- }
- if (TYPE(n) == simple_stmt) {
- assert(num_stmts(n) == 1);
- n = CHILD(n, 0);
- }
- if (TYPE(n) == small_stmt) {
- REQ(n, small_stmt);
- n = CHILD(n, 0);
- /* small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt
- | flow_stmt | import_stmt | global_stmt | exec_stmt
- | assert_stmt
- */
- switch (TYPE(n)) {
- case expr_stmt:
- return ast_for_expr_stmt(c, n);
- case print_stmt:
- return ast_for_print_stmt(c, n);
- case del_stmt:
- return ast_for_del_stmt(c, n);
- case pass_stmt:
- return Pass(LINENO(n), n->n_col_offset, c->c_arena);
- case flow_stmt:
- return ast_for_flow_stmt(c, n);
- case import_stmt:
- return ast_for_import_stmt(c, n);
- case global_stmt:
- return ast_for_global_stmt(c, n);
- case exec_stmt:
- return ast_for_exec_stmt(c, n);
- case assert_stmt:
- return ast_for_assert_stmt(c, n);
- default:
- PyErr_Format(PyExc_SystemError,
- "unhandled small_stmt: TYPE=%d NCH=%d\n",
- TYPE(n), NCH(n));
- return NULL;
- }
- }
- else {
- /* compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt
- | funcdef | classdef
- */
- node *ch = CHILD(n, 0);
- REQ(n, compound_stmt);
- switch (TYPE(ch)) {
- case if_stmt:
- return ast_for_if_stmt(c, ch);
- case while_stmt:
- return ast_for_while_stmt(c, ch);
- case for_stmt:
- return ast_for_for_stmt(c, ch);
- case try_stmt:
- return ast_for_try_stmt(c, ch);
- case with_stmt:
- return ast_for_with_stmt(c, ch);
- case funcdef:
- return ast_for_funcdef(c, ch);
- case classdef:
- return ast_for_classdef(c, ch);
- default:
- PyErr_Format(PyExc_SystemError,
- "unhandled small_stmt: TYPE=%d NCH=%d\n",
- TYPE(n), NCH(n));
- return NULL;
- }
- }
-}
-
-static PyObject *
-parsenumber(const char *s)
-{
- const char *end;
- long x;
- double dx;
-#ifndef WITHOUT_COMPLEX
- Py_complex c;
- int imflag;
-#endif
-
- errno = 0;
- end = s + strlen(s) - 1;
-#ifndef WITHOUT_COMPLEX
- imflag = *end == 'j' || *end == 'J';
-#endif
- if (*end == 'l' || *end == 'L')
- return PyLong_FromString((char *)s, (char **)0, 0);
- if (s[0] == '0') {
- x = (long) PyOS_strtoul((char *)s, (char **)&end, 0);
- if (x < 0 && errno == 0) {
- return PyLong_FromString((char *)s,
- (char **)0,
- 0);
- }
- }
- else
- x = PyOS_strtol((char *)s, (char **)&end, 0);
- if (*end == '\0') {
- if (errno != 0)
- return PyLong_FromString((char *)s, (char **)0, 0);
- return PyInt_FromLong(x);
- }
- /* XXX Huge floats may silently fail */
-#ifndef WITHOUT_COMPLEX
- if (imflag) {
- c.real = 0.;
- PyFPE_START_PROTECT("atof", return 0)
- c.imag = PyOS_ascii_atof(s);
- PyFPE_END_PROTECT(c)
- return PyComplex_FromCComplex(c);
- }
- else
-#endif
- {
- PyFPE_START_PROTECT("atof", return 0)
- dx = PyOS_ascii_atof(s);
- PyFPE_END_PROTECT(dx)
- return PyFloat_FromDouble(dx);
- }
-}
-
-static PyObject *
-decode_utf8(const char **sPtr, const char *end, char* encoding)
-{
-#ifndef Py_USING_UNICODE
- Py_FatalError("decode_utf8 should not be called in this build.");
- return NULL;
-#else
- PyObject *u, *v;
- char *s, *t;
- t = s = (char *)*sPtr;
- /* while (s < end && *s != '\\') s++; */ /* inefficient for u".." */
- while (s < end && (*s & 0x80)) s++;
- *sPtr = s;
- u = PyUnicode_DecodeUTF8(t, s - t, NULL);
- if (u == NULL)
- return NULL;
- v = PyUnicode_AsEncodedString(u, encoding, NULL);
- Py_DECREF(u);
- return v;
-#endif
-}
-
-static PyObject *
-decode_unicode(const char *s, size_t len, int rawmode, const char *encoding)
-{
- PyObject *v, *u;
- char *buf;
- char *p;
- const char *end;
- if (encoding == NULL) {
- buf = (char *)s;
- u = NULL;
- } else if (strcmp(encoding, "iso-8859-1") == 0) {
- buf = (char *)s;
- u = NULL;
- } else {
- /* "\XX" may become "\u005c\uHHLL" (12 bytes) */
- u = PyString_FromStringAndSize((char *)NULL, len * 4);
- if (u == NULL)
- return NULL;
- p = buf = PyString_AsString(u);
- end = s + len;
- while (s < end) {
- if (*s == '\\') {
- *p++ = *s++;
- if (*s & 0x80) {
- strcpy(p, "u005c");
- p += 5;
- }
- }
- if (*s & 0x80) { /* XXX inefficient */
- PyObject *w;
- char *r;
- Py_ssize_t rn, i;
- w = decode_utf8(&s, end, "utf-16-be");
- if (w == NULL) {
- Py_DECREF(u);
- return NULL;
- }
- r = PyString_AsString(w);
- rn = PyString_Size(w);
- assert(rn % 2 == 0);
- for (i = 0; i < rn; i += 2) {
- sprintf(p, "\\u%02x%02x",
- r[i + 0] & 0xFF,
- r[i + 1] & 0xFF);
- p += 6;
- }
- Py_DECREF(w);
- } else {
- *p++ = *s++;
- }
- }
- len = p - buf;
- s = buf;
- }
- if (rawmode)
- v = PyUnicode_DecodeRawUnicodeEscape(s, len, NULL);
- else
- v = PyUnicode_DecodeUnicodeEscape(s, len, NULL);
- Py_XDECREF(u);
- return v;
-}
-
-/* s is a Python string literal, including the bracketing quote characters,
- * and r &/or u prefixes (if any), and embedded escape sequences (if any).
- * parsestr parses it, and returns the decoded Python string object.
- */
-static PyObject *
-parsestr(const char *s, const char *encoding)
-{
- size_t len;
- int quote = Py_CHARMASK(*s);
- int rawmode = 0;
- int need_encoding;
- int unicode = 0;
-
- if (isalpha(quote) || quote == '_') {
- if (quote == 'u' || quote == 'U') {
- quote = *++s;
- unicode = 1;
- }
- if (quote == 'r' || quote == 'R') {
- quote = *++s;
- rawmode = 1;
- }
- }
- if (quote != '\'' && quote != '\"') {
- PyErr_BadInternalCall();
- return NULL;
- }
- s++;
- len = strlen(s);
- if (len > INT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "string to parse is too long");
- return NULL;
- }
- if (s[--len] != quote) {
- PyErr_BadInternalCall();
- return NULL;
- }
- if (len >= 4 && s[0] == quote && s[1] == quote) {
- s += 2;
- len -= 2;
- if (s[--len] != quote || s[--len] != quote) {
- PyErr_BadInternalCall();
- return NULL;
- }
- }
-#ifdef Py_USING_UNICODE
- if (unicode || Py_UnicodeFlag) {
- return decode_unicode(s, len, rawmode, encoding);
- }
-#endif
- need_encoding = (encoding != NULL &&
- strcmp(encoding, "utf-8") != 0 &&
- strcmp(encoding, "iso-8859-1") != 0);
- if (rawmode || strchr(s, '\\') == NULL) {
- if (need_encoding) {
-#ifndef Py_USING_UNICODE
- /* This should not happen - we never see any other
- encoding. */
- Py_FatalError(
- "cannot deal with encodings in this build.");
-#else
- PyObject *v, *u = PyUnicode_DecodeUTF8(s, len, NULL);
- if (u == NULL)
- return NULL;
- v = PyUnicode_AsEncodedString(u, encoding, NULL);
- Py_DECREF(u);
- return v;
-#endif
- } else {
- return PyString_FromStringAndSize(s, len);
- }
- }
-
- return PyString_DecodeEscape(s, len, NULL, unicode,
- need_encoding ? encoding : NULL);
-}
-
-/* Build a Python string object out of a STRING atom. This takes care of
- * compile-time literal catenation, calling parsestr() on each piece, and
- * pasting the intermediate results together.
- */
-static PyObject *
-parsestrplus(struct compiling *c, const node *n)
-{
- PyObject *v;
- int i;
- REQ(CHILD(n, 0), STRING);
- if ((v = parsestr(STR(CHILD(n, 0)), c->c_encoding)) != NULL) {
- /* String literal concatenation */
- for (i = 1; i < NCH(n); i++) {
- PyObject *s;
- s = parsestr(STR(CHILD(n, i)), c->c_encoding);
- if (s == NULL)
- goto onError;
- if (PyString_Check(v) && PyString_Check(s)) {
- PyString_ConcatAndDel(&v, s);
- if (v == NULL)
- goto onError;
- }
-#ifdef Py_USING_UNICODE
- else {
- PyObject *temp = PyUnicode_Concat(v, s);
- Py_DECREF(s);
- Py_DECREF(v);
- v = temp;
- if (v == NULL)
- goto onError;
- }
-#endif
- }
- }
- return v;
-
- onError:
- Py_XDECREF(v);
- return NULL;
-}
diff --git a/sys/src/cmd/python/Python/atof.c b/sys/src/cmd/python/Python/atof.c
deleted file mode 100644
index 8fbde3847..000000000
--- a/sys/src/cmd/python/Python/atof.c
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/* Just in case you haven't got an atof() around...
- This one doesn't check for bad syntax or overflow,
- and is slow and inaccurate.
- But it's good enough for the occasional string literal... */
-
-#include "pyconfig.h"
-
-#include <ctype.h>
-
-double atof(char *s)
-{
- double a = 0.0;
- int e = 0;
- int c;
- while ((c = *s++) != '\0' && isdigit(c)) {
- a = a*10.0 + (c - '0');
- }
- if (c == '.') {
- while ((c = *s++) != '\0' && isdigit(c)) {
- a = a*10.0 + (c - '0');
- e = e-1;
- }
- }
- if (c == 'e' || c == 'E') {
- int sign = 1;
- int i = 0;
- c = *s++;
- if (c == '+')
- c = *s++;
- else if (c == '-') {
- c = *s++;
- sign = -1;
- }
- while (isdigit(c)) {
- i = i*10 + (c - '0');
- c = *s++;
- }
- e += i*sign;
- }
- while (e > 0) {
- a *= 10.0;
- e--;
- }
- while (e < 0) {
- a *= 0.1;
- e++;
- }
- return a;
-}
diff --git a/sys/src/cmd/python/Python/bltinmodule.c b/sys/src/cmd/python/Python/bltinmodule.c
deleted file mode 100644
index ceb2fc77f..000000000
--- a/sys/src/cmd/python/Python/bltinmodule.c
+++ /dev/null
@@ -1,2620 +0,0 @@
-/* Built-in functions */
-
-#include "Python.h"
-
-#include "node.h"
-#include "code.h"
-#include "eval.h"
-
-#include <ctype.h>
-
-#ifdef RISCOS
-#include "unixstuff.h"
-#endif
-
-/* The default encoding used by the platform file system APIs
- Can remain NULL for all platforms that don't have such a concept
-*/
-#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
-const char *Py_FileSystemDefaultEncoding = "mbcs";
-#elif defined(__APPLE__)
-const char *Py_FileSystemDefaultEncoding = "utf-8";
-#else
-const char *Py_FileSystemDefaultEncoding = NULL; /* use default */
-#endif
-
-/* Forward */
-static PyObject *filterstring(PyObject *, PyObject *);
-#ifdef Py_USING_UNICODE
-static PyObject *filterunicode(PyObject *, PyObject *);
-#endif
-static PyObject *filtertuple (PyObject *, PyObject *);
-
-static PyObject *
-builtin___import__(PyObject *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"name", "globals", "locals", "fromlist",
- "level", 0};
- char *name;
- PyObject *globals = NULL;
- PyObject *locals = NULL;
- PyObject *fromlist = NULL;
- int level = -1;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|OOOi:__import__",
- kwlist, &name, &globals, &locals, &fromlist, &level))
- return NULL;
- return PyImport_ImportModuleLevel(name, globals, locals,
- fromlist, level);
-}
-
-PyDoc_STRVAR(import_doc,
-"__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module\n\
-\n\
-Import a module. The globals are only used to determine the context;\n\
-they are not modified. The locals are currently unused. The fromlist\n\
-should be a list of names to emulate ``from name import ...'', or an\n\
-empty list to emulate ``import name''.\n\
-When importing a module from a package, note that __import__('A.B', ...)\n\
-returns package A when fromlist is empty, but its submodule B when\n\
-fromlist is not empty. Level is used to determine whether to perform \n\
-absolute or relative imports. -1 is the original strategy of attempting\n\
-both absolute and relative imports, 0 is absolute, a positive number\n\
-is the number of parent directories to search relative to the current module.");
-
-
-static PyObject *
-builtin_abs(PyObject *self, PyObject *v)
-{
- return PyNumber_Absolute(v);
-}
-
-PyDoc_STRVAR(abs_doc,
-"abs(number) -> number\n\
-\n\
-Return the absolute value of the argument.");
-
-static PyObject *
-builtin_all(PyObject *self, PyObject *v)
-{
- PyObject *it, *item;
-
- it = PyObject_GetIter(v);
- if (it == NULL)
- return NULL;
-
- while ((item = PyIter_Next(it)) != NULL) {
- int cmp = PyObject_IsTrue(item);
- Py_DECREF(item);
- if (cmp < 0) {
- Py_DECREF(it);
- return NULL;
- }
- if (cmp == 0) {
- Py_DECREF(it);
- Py_RETURN_FALSE;
- }
- }
- Py_DECREF(it);
- if (PyErr_Occurred())
- return NULL;
- Py_RETURN_TRUE;
-}
-
-PyDoc_STRVAR(all_doc,
-"all(iterable) -> bool\n\
-\n\
-Return True if bool(x) is True for all values x in the iterable.");
-
-static PyObject *
-builtin_any(PyObject *self, PyObject *v)
-{
- PyObject *it, *item;
-
- it = PyObject_GetIter(v);
- if (it == NULL)
- return NULL;
-
- while ((item = PyIter_Next(it)) != NULL) {
- int cmp = PyObject_IsTrue(item);
- Py_DECREF(item);
- if (cmp < 0) {
- Py_DECREF(it);
- return NULL;
- }
- if (cmp == 1) {
- Py_DECREF(it);
- Py_RETURN_TRUE;
- }
- }
- Py_DECREF(it);
- if (PyErr_Occurred())
- return NULL;
- Py_RETURN_FALSE;
-}
-
-PyDoc_STRVAR(any_doc,
-"any(iterable) -> bool\n\
-\n\
-Return True if bool(x) is True for any x in the iterable.");
-
-static PyObject *
-builtin_apply(PyObject *self, PyObject *args)
-{
- PyObject *func, *alist = NULL, *kwdict = NULL;
- PyObject *t = NULL, *retval = NULL;
-
- if (!PyArg_UnpackTuple(args, "apply", 1, 3, &func, &alist, &kwdict))
- return NULL;
- if (alist != NULL) {
- if (!PyTuple_Check(alist)) {
- if (!PySequence_Check(alist)) {
- PyErr_Format(PyExc_TypeError,
- "apply() arg 2 expected sequence, found %s",
- alist->ob_type->tp_name);
- return NULL;
- }
- t = PySequence_Tuple(alist);
- if (t == NULL)
- return NULL;
- alist = t;
- }
- }
- if (kwdict != NULL && !PyDict_Check(kwdict)) {
- PyErr_Format(PyExc_TypeError,
- "apply() arg 3 expected dictionary, found %s",
- kwdict->ob_type->tp_name);
- goto finally;
- }
- retval = PyEval_CallObjectWithKeywords(func, alist, kwdict);
- finally:
- Py_XDECREF(t);
- return retval;
-}
-
-PyDoc_STRVAR(apply_doc,
-"apply(object[, args[, kwargs]]) -> value\n\
-\n\
-Call a callable object with positional arguments taken from the tuple args,\n\
-and keyword arguments taken from the optional dictionary kwargs.\n\
-Note that classes are callable, as are instances with a __call__() method.\n\
-\n\
-Deprecated since release 2.3. Instead, use the extended call syntax:\n\
- function(*args, **keywords).");
-
-
-static PyObject *
-builtin_callable(PyObject *self, PyObject *v)
-{
- return PyBool_FromLong((long)PyCallable_Check(v));
-}
-
-PyDoc_STRVAR(callable_doc,
-"callable(object) -> bool\n\
-\n\
-Return whether the object is callable (i.e., some kind of function).\n\
-Note that classes are callable, as are instances with a __call__() method.");
-
-
-static PyObject *
-builtin_filter(PyObject *self, PyObject *args)
-{
- PyObject *func, *seq, *result, *it, *arg;
- Py_ssize_t len; /* guess for result list size */
- register Py_ssize_t j;
-
- if (!PyArg_UnpackTuple(args, "filter", 2, 2, &func, &seq))
- return NULL;
-
- /* Strings and tuples return a result of the same type. */
- if (PyString_Check(seq))
- return filterstring(func, seq);
-#ifdef Py_USING_UNICODE
- if (PyUnicode_Check(seq))
- return filterunicode(func, seq);
-#endif
- if (PyTuple_Check(seq))
- return filtertuple(func, seq);
-
- /* Pre-allocate argument list tuple. */
- arg = PyTuple_New(1);
- if (arg == NULL)
- return NULL;
-
- /* Get iterator. */
- it = PyObject_GetIter(seq);
- if (it == NULL)
- goto Fail_arg;
-
- /* Guess a result list size. */
- len = _PyObject_LengthHint(seq);
- if (len < 0) {
- if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
- !PyErr_ExceptionMatches(PyExc_AttributeError)) {
- goto Fail_it;
- }
- PyErr_Clear();
- len = 8; /* arbitrary */
- }
-
- /* Get a result list. */
- if (PyList_Check(seq) && seq->ob_refcnt == 1) {
- /* Eww - can modify the list in-place. */
- Py_INCREF(seq);
- result = seq;
- }
- else {
- result = PyList_New(len);
- if (result == NULL)
- goto Fail_it;
- }
-
- /* Build the result list. */
- j = 0;
- for (;;) {
- PyObject *item;
- int ok;
-
- item = PyIter_Next(it);
- if (item == NULL) {
- if (PyErr_Occurred())
- goto Fail_result_it;
- break;
- }
-
- if (func == (PyObject *)&PyBool_Type || func == Py_None) {
- ok = PyObject_IsTrue(item);
- }
- else {
- PyObject *good;
- PyTuple_SET_ITEM(arg, 0, item);
- good = PyObject_Call(func, arg, NULL);
- PyTuple_SET_ITEM(arg, 0, NULL);
- if (good == NULL) {
- Py_DECREF(item);
- goto Fail_result_it;
- }
- ok = PyObject_IsTrue(good);
- Py_DECREF(good);
- }
- if (ok) {
- if (j < len)
- PyList_SET_ITEM(result, j, item);
- else {
- int status = PyList_Append(result, item);
- Py_DECREF(item);
- if (status < 0)
- goto Fail_result_it;
- }
- ++j;
- }
- else
- Py_DECREF(item);
- }
-
-
- /* Cut back result list if len is too big. */
- if (j < len && PyList_SetSlice(result, j, len, NULL) < 0)
- goto Fail_result_it;
-
- Py_DECREF(it);
- Py_DECREF(arg);
- return result;
-
-Fail_result_it:
- Py_DECREF(result);
-Fail_it:
- Py_DECREF(it);
-Fail_arg:
- Py_DECREF(arg);
- return NULL;
-}
-
-PyDoc_STRVAR(filter_doc,
-"filter(function or None, sequence) -> list, tuple, or string\n"
-"\n"
-"Return those items of sequence for which function(item) is true. If\n"
-"function is None, return the items that are true. If sequence is a tuple\n"
-"or string, return the same type, else return a list.");
-
-static PyObject *
-builtin_chr(PyObject *self, PyObject *args)
-{
- long x;
- char s[1];
-
- if (!PyArg_ParseTuple(args, "l:chr", &x))
- return NULL;
- if (x < 0 || x >= 256) {
- PyErr_SetString(PyExc_ValueError,
- "chr() arg not in range(256)");
- return NULL;
- }
- s[0] = (char)x;
- return PyString_FromStringAndSize(s, 1);
-}
-
-PyDoc_STRVAR(chr_doc,
-"chr(i) -> character\n\
-\n\
-Return a string of one character with ordinal i; 0 <= i < 256.");
-
-
-#ifdef Py_USING_UNICODE
-static PyObject *
-builtin_unichr(PyObject *self, PyObject *args)
-{
- long x;
-
- if (!PyArg_ParseTuple(args, "l:unichr", &x))
- return NULL;
-
- return PyUnicode_FromOrdinal(x);
-}
-
-PyDoc_STRVAR(unichr_doc,
-"unichr(i) -> Unicode character\n\
-\n\
-Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.");
-#endif
-
-
-static PyObject *
-builtin_cmp(PyObject *self, PyObject *args)
-{
- PyObject *a, *b;
- int c;
-
- if (!PyArg_UnpackTuple(args, "cmp", 2, 2, &a, &b))
- return NULL;
- if (PyObject_Cmp(a, b, &c) < 0)
- return NULL;
- return PyInt_FromLong((long)c);
-}
-
-PyDoc_STRVAR(cmp_doc,
-"cmp(x, y) -> integer\n\
-\n\
-Return negative if x<y, zero if x==y, positive if x>y.");
-
-
-static PyObject *
-builtin_coerce(PyObject *self, PyObject *args)
-{
- PyObject *v, *w;
- PyObject *res;
-
- if (!PyArg_UnpackTuple(args, "coerce", 2, 2, &v, &w))
- return NULL;
- if (PyNumber_Coerce(&v, &w) < 0)
- return NULL;
- res = PyTuple_Pack(2, v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- return res;
-}
-
-PyDoc_STRVAR(coerce_doc,
-"coerce(x, y) -> (x1, y1)\n\
-\n\
-Return a tuple consisting of the two numeric arguments converted to\n\
-a common type, using the same rules as used by arithmetic operations.\n\
-If coercion is not possible, raise TypeError.");
-
-static PyObject *
-builtin_compile(PyObject *self, PyObject *args)
-{
- char *str;
- char *filename;
- char *startstr;
- int start;
- int dont_inherit = 0;
- int supplied_flags = 0;
- PyCompilerFlags cf;
- PyObject *result = NULL, *cmd, *tmp = NULL;
- Py_ssize_t length;
-
- if (!PyArg_ParseTuple(args, "Oss|ii:compile", &cmd, &filename,
- &startstr, &supplied_flags, &dont_inherit))
- return NULL;
-
- cf.cf_flags = supplied_flags;
-
-#ifdef Py_USING_UNICODE
- if (PyUnicode_Check(cmd)) {
- tmp = PyUnicode_AsUTF8String(cmd);
- if (tmp == NULL)
- return NULL;
- cmd = tmp;
- cf.cf_flags |= PyCF_SOURCE_IS_UTF8;
- }
-#endif
- if (PyObject_AsReadBuffer(cmd, (const void **)&str, &length))
- return NULL;
- if ((size_t)length != strlen(str)) {
- PyErr_SetString(PyExc_TypeError,
- "compile() expected string without null bytes");
- goto cleanup;
- }
-
- if (strcmp(startstr, "exec") == 0)
- start = Py_file_input;
- else if (strcmp(startstr, "eval") == 0)
- start = Py_eval_input;
- else if (strcmp(startstr, "single") == 0)
- start = Py_single_input;
- else {
- PyErr_SetString(PyExc_ValueError,
- "compile() arg 3 must be 'exec' or 'eval' or 'single'");
- goto cleanup;
- }
-
- if (supplied_flags &
- ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST))
- {
- PyErr_SetString(PyExc_ValueError,
- "compile(): unrecognised flags");
- goto cleanup;
- }
- /* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */
-
- if (!dont_inherit) {
- PyEval_MergeCompilerFlags(&cf);
- }
- result = Py_CompileStringFlags(str, filename, start, &cf);
-cleanup:
- Py_XDECREF(tmp);
- return result;
-}
-
-PyDoc_STRVAR(compile_doc,
-"compile(source, filename, mode[, flags[, dont_inherit]]) -> code object\n\
-\n\
-Compile the source string (a Python module, statement or expression)\n\
-into a code object that can be executed by the exec statement or eval().\n\
-The filename will be used for run-time error messages.\n\
-The mode must be 'exec' to compile a module, 'single' to compile a\n\
-single (interactive) statement, or 'eval' to compile an expression.\n\
-The flags argument, if present, controls which future statements influence\n\
-the compilation of the code.\n\
-The dont_inherit argument, if non-zero, stops the compilation inheriting\n\
-the effects of any future statements in effect in the code calling\n\
-compile; if absent or zero these statements do influence the compilation,\n\
-in addition to any features explicitly specified.");
-
-static PyObject *
-builtin_dir(PyObject *self, PyObject *args)
-{
- PyObject *arg = NULL;
-
- if (!PyArg_UnpackTuple(args, "dir", 0, 1, &arg))
- return NULL;
- return PyObject_Dir(arg);
-}
-
-PyDoc_STRVAR(dir_doc,
-"dir([object]) -> list of strings\n"
-"\n"
-"Return an alphabetized list of names comprising (some of) the attributes\n"
-"of the given object, and of attributes reachable from it:\n"
-"\n"
-"No argument: the names in the current scope.\n"
-"Module object: the module attributes.\n"
-"Type or class object: its attributes, and recursively the attributes of\n"
-" its bases.\n"
-"Otherwise: its attributes, its class's attributes, and recursively the\n"
-" attributes of its class's base classes.");
-
-static PyObject *
-builtin_divmod(PyObject *self, PyObject *args)
-{
- PyObject *v, *w;
-
- if (!PyArg_UnpackTuple(args, "divmod", 2, 2, &v, &w))
- return NULL;
- return PyNumber_Divmod(v, w);
-}
-
-PyDoc_STRVAR(divmod_doc,
-"divmod(x, y) -> (div, mod)\n\
-\n\
-Return the tuple ((x-x%y)/y, x%y). Invariant: div*y + mod == x.");
-
-
-static PyObject *
-builtin_eval(PyObject *self, PyObject *args)
-{
- PyObject *cmd, *result, *tmp = NULL;
- PyObject *globals = Py_None, *locals = Py_None;
- char *str;
- PyCompilerFlags cf;
-
- if (!PyArg_UnpackTuple(args, "eval", 1, 3, &cmd, &globals, &locals))
- return NULL;
- if (locals != Py_None && !PyMapping_Check(locals)) {
- PyErr_SetString(PyExc_TypeError, "locals must be a mapping");
- return NULL;
- }
- if (globals != Py_None && !PyDict_Check(globals)) {
- PyErr_SetString(PyExc_TypeError, PyMapping_Check(globals) ?
- "globals must be a real dict; try eval(expr, {}, mapping)"
- : "globals must be a dict");
- return NULL;
- }
- if (globals == Py_None) {
- globals = PyEval_GetGlobals();
- if (locals == Py_None)
- locals = PyEval_GetLocals();
- }
- else if (locals == Py_None)
- locals = globals;
-
- if (globals == NULL || locals == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "eval must be given globals and locals "
- "when called without a frame");
- return NULL;
- }
-
- if (PyDict_GetItemString(globals, "__builtins__") == NULL) {
- if (PyDict_SetItemString(globals, "__builtins__",
- PyEval_GetBuiltins()) != 0)
- return NULL;
- }
-
- if (PyCode_Check(cmd)) {
- if (PyCode_GetNumFree((PyCodeObject *)cmd) > 0) {
- PyErr_SetString(PyExc_TypeError,
- "code object passed to eval() may not contain free variables");
- return NULL;
- }
- return PyEval_EvalCode((PyCodeObject *) cmd, globals, locals);
- }
-
- if (!PyString_Check(cmd) &&
- !PyUnicode_Check(cmd)) {
- PyErr_SetString(PyExc_TypeError,
- "eval() arg 1 must be a string or code object");
- return NULL;
- }
- cf.cf_flags = 0;
-
-#ifdef Py_USING_UNICODE
- if (PyUnicode_Check(cmd)) {
- tmp = PyUnicode_AsUTF8String(cmd);
- if (tmp == NULL)
- return NULL;
- cmd = tmp;
- cf.cf_flags |= PyCF_SOURCE_IS_UTF8;
- }
-#endif
- if (PyString_AsStringAndSize(cmd, &str, NULL)) {
- Py_XDECREF(tmp);
- return NULL;
- }
- while (*str == ' ' || *str == '\t')
- str++;
-
- (void)PyEval_MergeCompilerFlags(&cf);
- result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf);
- Py_XDECREF(tmp);
- return result;
-}
-
-PyDoc_STRVAR(eval_doc,
-"eval(source[, globals[, locals]]) -> value\n\
-\n\
-Evaluate the source in the context of globals and locals.\n\
-The source may be a string representing a Python expression\n\
-or a code object as returned by compile().\n\
-The globals must be a dictionary and locals can be any mapping,\n\
-defaulting to the current globals and locals.\n\
-If only globals is given, locals defaults to it.\n");
-
-
-static PyObject *
-builtin_execfile(PyObject *self, PyObject *args)
-{
- char *filename;
- PyObject *globals = Py_None, *locals = Py_None;
- PyObject *res;
- FILE* fp = NULL;
- PyCompilerFlags cf;
- int exists;
-
- if (!PyArg_ParseTuple(args, "s|O!O:execfile",
- &filename,
- &PyDict_Type, &globals,
- &locals))
- return NULL;
- if (locals != Py_None && !PyMapping_Check(locals)) {
- PyErr_SetString(PyExc_TypeError, "locals must be a mapping");
- return NULL;
- }
- if (globals == Py_None) {
- globals = PyEval_GetGlobals();
- if (locals == Py_None)
- locals = PyEval_GetLocals();
- }
- else if (locals == Py_None)
- locals = globals;
- if (PyDict_GetItemString(globals, "__builtins__") == NULL) {
- if (PyDict_SetItemString(globals, "__builtins__",
- PyEval_GetBuiltins()) != 0)
- return NULL;
- }
-
- exists = 0;
- /* Test for existence or directory. */
-#if defined(PLAN9)
- {
- Dir *d;
-
- if ((d = dirstat(filename))!=nil) {
- if(d->mode & DMDIR)
- werrstr("is a directory");
- else
- exists = 1;
- free(d);
- }
- }
-#elif defined(RISCOS)
- if (object_exists(filename)) {
- if (isdir(filename))
- errno = EISDIR;
- else
- exists = 1;
- }
-#else /* standard Posix */
- {
- struct stat s;
- if (stat(filename, &s) == 0) {
- if (S_ISDIR(s.st_mode))
-# if defined(PYOS_OS2) && defined(PYCC_VACPP)
- errno = EOS2ERR;
-# else
- errno = EISDIR;
-# endif
- else
- exists = 1;
- }
- }
-#endif
-
- if (exists) {
- Py_BEGIN_ALLOW_THREADS
- fp = fopen(filename, "r" PY_STDIOTEXTMODE);
- Py_END_ALLOW_THREADS
-
- if (fp == NULL) {
- exists = 0;
- }
- }
-
- if (!exists) {
- PyErr_SetFromErrnoWithFilename(PyExc_IOError, filename);
- return NULL;
- }
- cf.cf_flags = 0;
- if (PyEval_MergeCompilerFlags(&cf))
- res = PyRun_FileExFlags(fp, filename, Py_file_input, globals,
- locals, 1, &cf);
- else
- res = PyRun_FileEx(fp, filename, Py_file_input, globals,
- locals, 1);
- return res;
-}
-
-PyDoc_STRVAR(execfile_doc,
-"execfile(filename[, globals[, locals]])\n\
-\n\
-Read and execute a Python script from a file.\n\
-The globals and locals are dictionaries, defaulting to the current\n\
-globals and locals. If only globals is given, locals defaults to it.");
-
-
-static PyObject *
-builtin_getattr(PyObject *self, PyObject *args)
-{
- PyObject *v, *result, *dflt = NULL;
- PyObject *name;
-
- if (!PyArg_UnpackTuple(args, "getattr", 2, 3, &v, &name, &dflt))
- return NULL;
-#ifdef Py_USING_UNICODE
- if (PyUnicode_Check(name)) {
- name = _PyUnicode_AsDefaultEncodedString(name, NULL);
- if (name == NULL)
- return NULL;
- }
-#endif
-
- if (!PyString_Check(name)) {
- PyErr_SetString(PyExc_TypeError,
- "getattr(): attribute name must be string");
- return NULL;
- }
- result = PyObject_GetAttr(v, name);
- if (result == NULL && dflt != NULL &&
- PyErr_ExceptionMatches(PyExc_AttributeError))
- {
- PyErr_Clear();
- Py_INCREF(dflt);
- result = dflt;
- }
- return result;
-}
-
-PyDoc_STRVAR(getattr_doc,
-"getattr(object, name[, default]) -> value\n\
-\n\
-Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\
-When a default argument is given, it is returned when the attribute doesn't\n\
-exist; without it, an exception is raised in that case.");
-
-
-static PyObject *
-builtin_globals(PyObject *self)
-{
- PyObject *d;
-
- d = PyEval_GetGlobals();
- Py_XINCREF(d);
- return d;
-}
-
-PyDoc_STRVAR(globals_doc,
-"globals() -> dictionary\n\
-\n\
-Return the dictionary containing the current scope's global variables.");
-
-
-static PyObject *
-builtin_hasattr(PyObject *self, PyObject *args)
-{
- PyObject *v;
- PyObject *name;
-
- if (!PyArg_UnpackTuple(args, "hasattr", 2, 2, &v, &name))
- return NULL;
-#ifdef Py_USING_UNICODE
- if (PyUnicode_Check(name)) {
- name = _PyUnicode_AsDefaultEncodedString(name, NULL);
- if (name == NULL)
- return NULL;
- }
-#endif
-
- if (!PyString_Check(name)) {
- PyErr_SetString(PyExc_TypeError,
- "hasattr(): attribute name must be string");
- return NULL;
- }
- v = PyObject_GetAttr(v, name);
- if (v == NULL) {
- PyErr_Clear();
- Py_INCREF(Py_False);
- return Py_False;
- }
- Py_DECREF(v);
- Py_INCREF(Py_True);
- return Py_True;
-}
-
-PyDoc_STRVAR(hasattr_doc,
-"hasattr(object, name) -> bool\n\
-\n\
-Return whether the object has an attribute with the given name.\n\
-(This is done by calling getattr(object, name) and catching exceptions.)");
-
-
-static PyObject *
-builtin_id(PyObject *self, PyObject *v)
-{
- return PyLong_FromVoidPtr(v);
-}
-
-PyDoc_STRVAR(id_doc,
-"id(object) -> integer\n\
-\n\
-Return the identity of an object. This is guaranteed to be unique among\n\
-simultaneously existing objects. (Hint: it's the object's memory address.)");
-
-
-static PyObject *
-builtin_map(PyObject *self, PyObject *args)
-{
- typedef struct {
- PyObject *it; /* the iterator object */
- int saw_StopIteration; /* bool: did the iterator end? */
- } sequence;
-
- PyObject *func, *result;
- sequence *seqs = NULL, *sqp;
- Py_ssize_t n, len;
- register int i, j;
-
- n = PyTuple_Size(args);
- if (n < 2) {
- PyErr_SetString(PyExc_TypeError,
- "map() requires at least two args");
- return NULL;
- }
-
- func = PyTuple_GetItem(args, 0);
- n--;
-
- if (func == Py_None && n == 1) {
- /* map(None, S) is the same as list(S). */
- return PySequence_List(PyTuple_GetItem(args, 1));
- }
-
- /* Get space for sequence descriptors. Must NULL out the iterator
- * pointers so that jumping to Fail_2 later doesn't see trash.
- */
- if ((seqs = PyMem_NEW(sequence, n)) == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
- for (i = 0; i < n; ++i) {
- seqs[i].it = (PyObject*)NULL;
- seqs[i].saw_StopIteration = 0;
- }
-
- /* Do a first pass to obtain iterators for the arguments, and set len
- * to the largest of their lengths.
- */
- len = 0;
- for (i = 0, sqp = seqs; i < n; ++i, ++sqp) {
- PyObject *curseq;
- Py_ssize_t curlen;
-
- /* Get iterator. */
- curseq = PyTuple_GetItem(args, i+1);
- sqp->it = PyObject_GetIter(curseq);
- if (sqp->it == NULL) {
- static char errmsg[] =
- "argument %d to map() must support iteration";
- char errbuf[sizeof(errmsg) + 25];
- PyOS_snprintf(errbuf, sizeof(errbuf), errmsg, i+2);
- PyErr_SetString(PyExc_TypeError, errbuf);
- goto Fail_2;
- }
-
- /* Update len. */
- curlen = _PyObject_LengthHint(curseq);
- if (curlen < 0) {
- if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
- !PyErr_ExceptionMatches(PyExc_AttributeError)) {
- goto Fail_2;
- }
- PyErr_Clear();
- curlen = 8; /* arbitrary */
- }
- if (curlen > len)
- len = curlen;
- }
-
- /* Get space for the result list. */
- if ((result = (PyObject *) PyList_New(len)) == NULL)
- goto Fail_2;
-
- /* Iterate over the sequences until all have stopped. */
- for (i = 0; ; ++i) {
- PyObject *alist, *item=NULL, *value;
- int numactive = 0;
-
- if (func == Py_None && n == 1)
- alist = NULL;
- else if ((alist = PyTuple_New(n)) == NULL)
- goto Fail_1;
-
- for (j = 0, sqp = seqs; j < n; ++j, ++sqp) {
- if (sqp->saw_StopIteration) {
- Py_INCREF(Py_None);
- item = Py_None;
- }
- else {
- item = PyIter_Next(sqp->it);
- if (item)
- ++numactive;
- else {
- if (PyErr_Occurred()) {
- Py_XDECREF(alist);
- goto Fail_1;
- }
- Py_INCREF(Py_None);
- item = Py_None;
- sqp->saw_StopIteration = 1;
- }
- }
- if (alist)
- PyTuple_SET_ITEM(alist, j, item);
- else
- break;
- }
-
- if (!alist)
- alist = item;
-
- if (numactive == 0) {
- Py_DECREF(alist);
- break;
- }
-
- if (func == Py_None)
- value = alist;
- else {
- value = PyEval_CallObject(func, alist);
- Py_DECREF(alist);
- if (value == NULL)
- goto Fail_1;
- }
- if (i >= len) {
- int status = PyList_Append(result, value);
- Py_DECREF(value);
- if (status < 0)
- goto Fail_1;
- }
- else if (PyList_SetItem(result, i, value) < 0)
- goto Fail_1;
- }
-
- if (i < len && PyList_SetSlice(result, i, len, NULL) < 0)
- goto Fail_1;
-
- goto Succeed;
-
-Fail_1:
- Py_DECREF(result);
-Fail_2:
- result = NULL;
-Succeed:
- assert(seqs);
- for (i = 0; i < n; ++i)
- Py_XDECREF(seqs[i].it);
- PyMem_DEL(seqs);
- return result;
-}
-
-PyDoc_STRVAR(map_doc,
-"map(function, sequence[, sequence, ...]) -> list\n\
-\n\
-Return a list of the results of applying the function to the items of\n\
-the argument sequence(s). If more than one sequence is given, the\n\
-function is called with an argument list consisting of the corresponding\n\
-item of each sequence, substituting None for missing values when not all\n\
-sequences have the same length. If the function is None, return a list of\n\
-the items of the sequence (or a list of tuples if more than one sequence).");
-
-
-static PyObject *
-builtin_setattr(PyObject *self, PyObject *args)
-{
- PyObject *v;
- PyObject *name;
- PyObject *value;
-
- if (!PyArg_UnpackTuple(args, "setattr", 3, 3, &v, &name, &value))
- return NULL;
- if (PyObject_SetAttr(v, name, value) != 0)
- return NULL;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(setattr_doc,
-"setattr(object, name, value)\n\
-\n\
-Set a named attribute on an object; setattr(x, 'y', v) is equivalent to\n\
-``x.y = v''.");
-
-
-static PyObject *
-builtin_delattr(PyObject *self, PyObject *args)
-{
- PyObject *v;
- PyObject *name;
-
- if (!PyArg_UnpackTuple(args, "delattr", 2, 2, &v, &name))
- return NULL;
- if (PyObject_SetAttr(v, name, (PyObject *)NULL) != 0)
- return NULL;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(delattr_doc,
-"delattr(object, name)\n\
-\n\
-Delete a named attribute on an object; delattr(x, 'y') is equivalent to\n\
-``del x.y''.");
-
-
-static PyObject *
-builtin_hash(PyObject *self, PyObject *v)
-{
- long x;
-
- x = PyObject_Hash(v);
- if (x == -1)
- return NULL;
- return PyInt_FromLong(x);
-}
-
-PyDoc_STRVAR(hash_doc,
-"hash(object) -> integer\n\
-\n\
-Return a hash value for the object. Two objects with the same value have\n\
-the same hash value. The reverse is not necessarily true, but likely.");
-
-
-static PyObject *
-builtin_hex(PyObject *self, PyObject *v)
-{
- PyNumberMethods *nb;
- PyObject *res;
-
- if ((nb = v->ob_type->tp_as_number) == NULL ||
- nb->nb_hex == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "hex() argument can't be converted to hex");
- return NULL;
- }
- res = (*nb->nb_hex)(v);
- if (res && !PyString_Check(res)) {
- PyErr_Format(PyExc_TypeError,
- "__hex__ returned non-string (type %.200s)",
- res->ob_type->tp_name);
- Py_DECREF(res);
- return NULL;
- }
- return res;
-}
-
-PyDoc_STRVAR(hex_doc,
-"hex(number) -> string\n\
-\n\
-Return the hexadecimal representation of an integer or long integer.");
-
-
-static PyObject *builtin_raw_input(PyObject *, PyObject *);
-
-static PyObject *
-builtin_input(PyObject *self, PyObject *args)
-{
- PyObject *line;
- char *str;
- PyObject *res;
- PyObject *globals, *locals;
- PyCompilerFlags cf;
-
- line = builtin_raw_input(self, args);
- if (line == NULL)
- return line;
- if (!PyArg_Parse(line, "s;embedded '\\0' in input line", &str))
- return NULL;
- while (*str == ' ' || *str == '\t')
- str++;
- globals = PyEval_GetGlobals();
- locals = PyEval_GetLocals();
- if (PyDict_GetItemString(globals, "__builtins__") == NULL) {
- if (PyDict_SetItemString(globals, "__builtins__",
- PyEval_GetBuiltins()) != 0)
- return NULL;
- }
- cf.cf_flags = 0;
- PyEval_MergeCompilerFlags(&cf);
- res = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf);
- Py_DECREF(line);
- return res;
-}
-
-PyDoc_STRVAR(input_doc,
-"input([prompt]) -> value\n\
-\n\
-Equivalent to eval(raw_input(prompt)).");
-
-
-static PyObject *
-builtin_intern(PyObject *self, PyObject *args)
-{
- PyObject *s;
- if (!PyArg_ParseTuple(args, "S:intern", &s))
- return NULL;
- if (!PyString_CheckExact(s)) {
- PyErr_SetString(PyExc_TypeError,
- "can't intern subclass of string");
- return NULL;
- }
- Py_INCREF(s);
- PyString_InternInPlace(&s);
- return s;
-}
-
-PyDoc_STRVAR(intern_doc,
-"intern(string) -> string\n\
-\n\
-``Intern'' the given string. This enters the string in the (global)\n\
-table of interned strings whose purpose is to speed up dictionary lookups.\n\
-Return the string itself or the previously interned string object with the\n\
-same value.");
-
-
-static PyObject *
-builtin_iter(PyObject *self, PyObject *args)
-{
- PyObject *v, *w = NULL;
-
- if (!PyArg_UnpackTuple(args, "iter", 1, 2, &v, &w))
- return NULL;
- if (w == NULL)
- return PyObject_GetIter(v);
- if (!PyCallable_Check(v)) {
- PyErr_SetString(PyExc_TypeError,
- "iter(v, w): v must be callable");
- return NULL;
- }
- return PyCallIter_New(v, w);
-}
-
-PyDoc_STRVAR(iter_doc,
-"iter(collection) -> iterator\n\
-iter(callable, sentinel) -> iterator\n\
-\n\
-Get an iterator from an object. In the first form, the argument must\n\
-supply its own iterator, or be a sequence.\n\
-In the second form, the callable is called until it returns the sentinel.");
-
-
-static PyObject *
-builtin_len(PyObject *self, PyObject *v)
-{
- Py_ssize_t res;
-
- res = PyObject_Size(v);
- if (res < 0 && PyErr_Occurred())
- return NULL;
- return PyInt_FromSsize_t(res);
-}
-
-PyDoc_STRVAR(len_doc,
-"len(object) -> integer\n\
-\n\
-Return the number of items of a sequence or mapping.");
-
-
-static PyObject *
-builtin_locals(PyObject *self)
-{
- PyObject *d;
-
- d = PyEval_GetLocals();
- Py_XINCREF(d);
- return d;
-}
-
-PyDoc_STRVAR(locals_doc,
-"locals() -> dictionary\n\
-\n\
-Update and return a dictionary containing the current scope's local variables.");
-
-
-static PyObject *
-min_max(PyObject *args, PyObject *kwds, int op)
-{
- PyObject *v, *it, *item, *val, *maxitem, *maxval, *keyfunc=NULL;
- const char *name = op == Py_LT ? "min" : "max";
-
- if (PyTuple_Size(args) > 1)
- v = args;
- else if (!PyArg_UnpackTuple(args, (char *)name, 1, 1, &v))
- return NULL;
-
- if (kwds != NULL && PyDict_Check(kwds) && PyDict_Size(kwds)) {
- keyfunc = PyDict_GetItemString(kwds, "key");
- if (PyDict_Size(kwds)!=1 || keyfunc == NULL) {
- PyErr_Format(PyExc_TypeError,
- "%s() got an unexpected keyword argument", name);
- return NULL;
- }
- }
-
- it = PyObject_GetIter(v);
- if (it == NULL)
- return NULL;
-
- maxitem = NULL; /* the result */
- maxval = NULL; /* the value associated with the result */
- while (( item = PyIter_Next(it) )) {
- /* get the value from the key function */
- if (keyfunc != NULL) {
- val = PyObject_CallFunctionObjArgs(keyfunc, item, NULL);
- if (val == NULL)
- goto Fail_it_item;
- }
- /* no key function; the value is the item */
- else {
- val = item;
- Py_INCREF(val);
- }
-
- /* maximum value and item are unset; set them */
- if (maxval == NULL) {
- maxitem = item;
- maxval = val;
- }
- /* maximum value and item are set; update them as necessary */
- else {
- int cmp = PyObject_RichCompareBool(val, maxval, op);
- if (cmp < 0)
- goto Fail_it_item_and_val;
- else if (cmp > 0) {
- Py_DECREF(maxval);
- Py_DECREF(maxitem);
- maxval = val;
- maxitem = item;
- }
- else {
- Py_DECREF(item);
- Py_DECREF(val);
- }
- }
- }
- if (PyErr_Occurred())
- goto Fail_it;
- if (maxval == NULL) {
- PyErr_Format(PyExc_ValueError,
- "%s() arg is an empty sequence", name);
- assert(maxitem == NULL);
- }
- else
- Py_DECREF(maxval);
- Py_DECREF(it);
- return maxitem;
-
-Fail_it_item_and_val:
- Py_DECREF(val);
-Fail_it_item:
- Py_DECREF(item);
-Fail_it:
- Py_XDECREF(maxval);
- Py_XDECREF(maxitem);
- Py_DECREF(it);
- return NULL;
-}
-
-static PyObject *
-builtin_min(PyObject *self, PyObject *args, PyObject *kwds)
-{
- return min_max(args, kwds, Py_LT);
-}
-
-PyDoc_STRVAR(min_doc,
-"min(iterable[, key=func]) -> value\n\
-min(a, b, c, ...[, key=func]) -> value\n\
-\n\
-With a single iterable argument, return its smallest item.\n\
-With two or more arguments, return the smallest argument.");
-
-
-static PyObject *
-builtin_max(PyObject *self, PyObject *args, PyObject *kwds)
-{
- return min_max(args, kwds, Py_GT);
-}
-
-PyDoc_STRVAR(max_doc,
-"max(iterable[, key=func]) -> value\n\
-max(a, b, c, ...[, key=func]) -> value\n\
-\n\
-With a single iterable argument, return its largest item.\n\
-With two or more arguments, return the largest argument.");
-
-
-static PyObject *
-builtin_oct(PyObject *self, PyObject *v)
-{
- PyNumberMethods *nb;
- PyObject *res;
-
- if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
- nb->nb_oct == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "oct() argument can't be converted to oct");
- return NULL;
- }
- res = (*nb->nb_oct)(v);
- if (res && !PyString_Check(res)) {
- PyErr_Format(PyExc_TypeError,
- "__oct__ returned non-string (type %.200s)",
- res->ob_type->tp_name);
- Py_DECREF(res);
- return NULL;
- }
- return res;
-}
-
-PyDoc_STRVAR(oct_doc,
-"oct(number) -> string\n\
-\n\
-Return the octal representation of an integer or long integer.");
-
-
-static PyObject *
-builtin_open(PyObject *self, PyObject *args, PyObject *kwds)
-{
- return PyObject_Call((PyObject*)&PyFile_Type, args, kwds);
-}
-
-PyDoc_STRVAR(open_doc,
-"open(name[, mode[, buffering]]) -> file object\n\
-\n\
-Open a file using the file() type, returns a file object.");
-
-
-static PyObject *
-builtin_ord(PyObject *self, PyObject* obj)
-{
- long ord;
- Py_ssize_t size;
-
- if (PyString_Check(obj)) {
- size = PyString_GET_SIZE(obj);
- if (size == 1) {
- ord = (long)((unsigned char)*PyString_AS_STRING(obj));
- return PyInt_FromLong(ord);
- }
-#ifdef Py_USING_UNICODE
- } else if (PyUnicode_Check(obj)) {
- size = PyUnicode_GET_SIZE(obj);
- if (size == 1) {
- ord = (long)*PyUnicode_AS_UNICODE(obj);
- return PyInt_FromLong(ord);
- }
-#endif
- } else {
- PyErr_Format(PyExc_TypeError,
- "ord() expected string of length 1, but " \
- "%.200s found", obj->ob_type->tp_name);
- return NULL;
- }
-
- PyErr_Format(PyExc_TypeError,
- "ord() expected a character, "
- "but string of length %zd found",
- size);
- return NULL;
-}
-
-PyDoc_STRVAR(ord_doc,
-"ord(c) -> integer\n\
-\n\
-Return the integer ordinal of a one-character string.");
-
-
-static PyObject *
-builtin_pow(PyObject *self, PyObject *args)
-{
- PyObject *v, *w, *z = Py_None;
-
- if (!PyArg_UnpackTuple(args, "pow", 2, 3, &v, &w, &z))
- return NULL;
- return PyNumber_Power(v, w, z);
-}
-
-PyDoc_STRVAR(pow_doc,
-"pow(x, y[, z]) -> number\n\
-\n\
-With two arguments, equivalent to x**y. With three arguments,\n\
-equivalent to (x**y) % z, but may be more efficient (e.g. for longs).");
-
-
-
-/* Return number of items in range (lo, hi, step), when arguments are
- * PyInt or PyLong objects. step > 0 required. Return a value < 0 if
- * & only if the true value is too large to fit in a signed long.
- * Arguments MUST return 1 with either PyInt_Check() or
- * PyLong_Check(). Return -1 when there is an error.
- */
-static long
-get_len_of_range_longs(PyObject *lo, PyObject *hi, PyObject *step)
-{
- /* -------------------------------------------------------------
- Algorithm is equal to that of get_len_of_range(), but it operates
- on PyObjects (which are assumed to be PyLong or PyInt objects).
- ---------------------------------------------------------------*/
- long n;
- PyObject *diff = NULL;
- PyObject *one = NULL;
- PyObject *tmp1 = NULL, *tmp2 = NULL, *tmp3 = NULL;
- /* holds sub-expression evaluations */
-
- /* if (lo >= hi), return length of 0. */
- if (PyObject_Compare(lo, hi) >= 0)
- return 0;
-
- if ((one = PyLong_FromLong(1L)) == NULL)
- goto Fail;
-
- if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
- goto Fail;
-
- if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
- goto Fail;
-
- if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
- goto Fail;
-
- if ((tmp3 = PyNumber_Add(tmp2, one)) == NULL)
- goto Fail;
-
- n = PyLong_AsLong(tmp3);
- if (PyErr_Occurred()) { /* Check for Overflow */
- PyErr_Clear();
- goto Fail;
- }
-
- Py_DECREF(tmp3);
- Py_DECREF(tmp2);
- Py_DECREF(diff);
- Py_DECREF(tmp1);
- Py_DECREF(one);
- return n;
-
- Fail:
- Py_XDECREF(tmp3);
- Py_XDECREF(tmp2);
- Py_XDECREF(diff);
- Py_XDECREF(tmp1);
- Py_XDECREF(one);
- return -1;
-}
-
-/* An extension of builtin_range() that handles the case when PyLong
- * arguments are given. */
-static PyObject *
-handle_range_longs(PyObject *self, PyObject *args)
-{
- PyObject *ilow;
- PyObject *ihigh = NULL;
- PyObject *istep = NULL;
-
- PyObject *curnum = NULL;
- PyObject *v = NULL;
- long bign;
- int i, n;
- int cmp_result;
-
- PyObject *zero = PyLong_FromLong(0);
-
- if (zero == NULL)
- return NULL;
-
- if (!PyArg_UnpackTuple(args, "range", 1, 3, &ilow, &ihigh, &istep)) {
- Py_DECREF(zero);
- return NULL;
- }
-
- /* Figure out which way we were called, supply defaults, and be
- * sure to incref everything so that the decrefs at the end
- * are correct.
- */
- assert(ilow != NULL);
- if (ihigh == NULL) {
- /* only 1 arg -- it's the upper limit */
- ihigh = ilow;
- ilow = NULL;
- }
- assert(ihigh != NULL);
- Py_INCREF(ihigh);
-
- /* ihigh correct now; do ilow */
- if (ilow == NULL)
- ilow = zero;
- Py_INCREF(ilow);
-
- /* ilow and ihigh correct now; do istep */
- if (istep == NULL) {
- istep = PyLong_FromLong(1L);
- if (istep == NULL)
- goto Fail;
- }
- else {
- Py_INCREF(istep);
- }
-
- if (!PyInt_Check(ilow) && !PyLong_Check(ilow)) {
- PyErr_Format(PyExc_TypeError,
- "range() integer start argument expected, got %s.",
- ilow->ob_type->tp_name);
- goto Fail;
- }
-
- if (!PyInt_Check(ihigh) && !PyLong_Check(ihigh)) {
- PyErr_Format(PyExc_TypeError,
- "range() integer end argument expected, got %s.",
- ihigh->ob_type->tp_name);
- goto Fail;
- }
-
- if (!PyInt_Check(istep) && !PyLong_Check(istep)) {
- PyErr_Format(PyExc_TypeError,
- "range() integer step argument expected, got %s.",
- istep->ob_type->tp_name);
- goto Fail;
- }
-
- if (PyObject_Cmp(istep, zero, &cmp_result) == -1)
- goto Fail;
- if (cmp_result == 0) {
- PyErr_SetString(PyExc_ValueError,
- "range() step argument must not be zero");
- goto Fail;
- }
-
- if (cmp_result > 0)
- bign = get_len_of_range_longs(ilow, ihigh, istep);
- else {
- PyObject *neg_istep = PyNumber_Negative(istep);
- if (neg_istep == NULL)
- goto Fail;
- bign = get_len_of_range_longs(ihigh, ilow, neg_istep);
- Py_DECREF(neg_istep);
- }
-
- n = (int)bign;
- if (bign < 0 || (long)n != bign) {
- PyErr_SetString(PyExc_OverflowError,
- "range() result has too many items");
- goto Fail;
- }
-
- v = PyList_New(n);
- if (v == NULL)
- goto Fail;
-
- curnum = ilow;
- Py_INCREF(curnum);
-
- for (i = 0; i < n; i++) {
- PyObject *w = PyNumber_Long(curnum);
- PyObject *tmp_num;
- if (w == NULL)
- goto Fail;
-
- PyList_SET_ITEM(v, i, w);
-
- tmp_num = PyNumber_Add(curnum, istep);
- if (tmp_num == NULL)
- goto Fail;
-
- Py_DECREF(curnum);
- curnum = tmp_num;
- }
- Py_DECREF(ilow);
- Py_DECREF(ihigh);
- Py_DECREF(istep);
- Py_DECREF(zero);
- Py_DECREF(curnum);
- return v;
-
- Fail:
- Py_DECREF(ilow);
- Py_DECREF(ihigh);
- Py_XDECREF(istep);
- Py_DECREF(zero);
- Py_XDECREF(curnum);
- Py_XDECREF(v);
- return NULL;
-}
-
-/* Return number of items in range/xrange (lo, hi, step). step > 0
- * required. Return a value < 0 if & only if the true value is too
- * large to fit in a signed long.
- */
-static long
-get_len_of_range(long lo, long hi, long step)
-{
- /* -------------------------------------------------------------
- If lo >= hi, the range is empty.
- Else if n values are in the range, the last one is
- lo + (n-1)*step, which must be <= hi-1. Rearranging,
- n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
- the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
- the RHS is non-negative and so truncation is the same as the
- floor. Letting M be the largest positive long, the worst case
- for the RHS numerator is hi=M, lo=-M-1, and then
- hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
- precision to compute the RHS exactly.
- ---------------------------------------------------------------*/
- long n = 0;
- if (lo < hi) {
- unsigned long uhi = (unsigned long)hi;
- unsigned long ulo = (unsigned long)lo;
- unsigned long diff = uhi - ulo - 1;
- n = (long)(diff / (unsigned long)step + 1);
- }
- return n;
-}
-
-static PyObject *
-builtin_range(PyObject *self, PyObject *args)
-{
- long ilow = 0, ihigh = 0, istep = 1;
- long bign;
- int i, n;
-
- PyObject *v;
-
- if (PyTuple_Size(args) <= 1) {
- if (!PyArg_ParseTuple(args,
- "l;range() requires 1-3 int arguments",
- &ihigh)) {
- PyErr_Clear();
- return handle_range_longs(self, args);
- }
- }
- else {
- if (!PyArg_ParseTuple(args,
- "ll|l;range() requires 1-3 int arguments",
- &ilow, &ihigh, &istep)) {
- PyErr_Clear();
- return handle_range_longs(self, args);
- }
- }
- if (istep == 0) {
- PyErr_SetString(PyExc_ValueError,
- "range() step argument must not be zero");
- return NULL;
- }
- if (istep > 0)
- bign = get_len_of_range(ilow, ihigh, istep);
- else
- bign = get_len_of_range(ihigh, ilow, -istep);
- n = (int)bign;
- if (bign < 0 || (long)n != bign) {
- PyErr_SetString(PyExc_OverflowError,
- "range() result has too many items");
- return NULL;
- }
- v = PyList_New(n);
- if (v == NULL)
- return NULL;
- for (i = 0; i < n; i++) {
- PyObject *w = PyInt_FromLong(ilow);
- if (w == NULL) {
- Py_DECREF(v);
- return NULL;
- }
- PyList_SET_ITEM(v, i, w);
- ilow += istep;
- }
- return v;
-}
-
-PyDoc_STRVAR(range_doc,
-"range([start,] stop[, step]) -> list of integers\n\
-\n\
-Return a list containing an arithmetic progression of integers.\n\
-range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.\n\
-When step is given, it specifies the increment (or decrement).\n\
-For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!\n\
-These are exactly the valid indices for a list of 4 elements.");
-
-
-static PyObject *
-builtin_raw_input(PyObject *self, PyObject *args)
-{
- PyObject *v = NULL;
- PyObject *fin = PySys_GetObject("stdin");
- PyObject *fout = PySys_GetObject("stdout");
-
- if (!PyArg_UnpackTuple(args, "[raw_]input", 0, 1, &v))
- return NULL;
-
- if (fin == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "[raw_]input: lost sys.stdin");
- return NULL;
- }
- if (fout == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "[raw_]input: lost sys.stdout");
- return NULL;
- }
- if (PyFile_SoftSpace(fout, 0)) {
- if (PyFile_WriteString(" ", fout) != 0)
- return NULL;
- }
- if (PyFile_AsFile(fin) && PyFile_AsFile(fout)
- && isatty(fileno(PyFile_AsFile(fin)))
- && isatty(fileno(PyFile_AsFile(fout)))) {
- PyObject *po;
- char *prompt;
- char *s;
- PyObject *result;
- if (v != NULL) {
- po = PyObject_Str(v);
- if (po == NULL)
- return NULL;
- prompt = PyString_AsString(po);
- if (prompt == NULL)
- return NULL;
- }
- else {
- po = NULL;
- prompt = "";
- }
- s = PyOS_Readline(PyFile_AsFile(fin), PyFile_AsFile(fout),
- prompt);
- Py_XDECREF(po);
- if (s == NULL) {
- if (!PyErr_Occurred())
- PyErr_SetNone(PyExc_KeyboardInterrupt);
- return NULL;
- }
- if (*s == '\0') {
- PyErr_SetNone(PyExc_EOFError);
- result = NULL;
- }
- else { /* strip trailing '\n' */
- size_t len = strlen(s);
- if (len > PY_SSIZE_T_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "[raw_]input: input too long");
- result = NULL;
- }
- else {
- result = PyString_FromStringAndSize(s, len-1);
- }
- }
- PyMem_FREE(s);
- return result;
- }
- if (v != NULL) {
- if (PyFile_WriteObject(v, fout, Py_PRINT_RAW) != 0)
- return NULL;
- }
- return PyFile_GetLine(fin, -1);
-}
-
-PyDoc_STRVAR(raw_input_doc,
-"raw_input([prompt]) -> string\n\
-\n\
-Read a string from standard input. The trailing newline is stripped.\n\
-If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return), raise EOFError.\n\
-On Unix, GNU readline is used if enabled. The prompt string, if given,\n\
-is printed without a trailing newline before reading.");
-
-
-static PyObject *
-builtin_reduce(PyObject *self, PyObject *args)
-{
- PyObject *seq, *func, *result = NULL, *it;
-
- if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result))
- return NULL;
- if (result != NULL)
- Py_INCREF(result);
-
- it = PyObject_GetIter(seq);
- if (it == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "reduce() arg 2 must support iteration");
- Py_XDECREF(result);
- return NULL;
- }
-
- if ((args = PyTuple_New(2)) == NULL)
- goto Fail;
-
- for (;;) {
- PyObject *op2;
-
- if (args->ob_refcnt > 1) {
- Py_DECREF(args);
- if ((args = PyTuple_New(2)) == NULL)
- goto Fail;
- }
-
- op2 = PyIter_Next(it);
- if (op2 == NULL) {
- if (PyErr_Occurred())
- goto Fail;
- break;
- }
-
- if (result == NULL)
- result = op2;
- else {
- PyTuple_SetItem(args, 0, result);
- PyTuple_SetItem(args, 1, op2);
- if ((result = PyEval_CallObject(func, args)) == NULL)
- goto Fail;
- }
- }
-
- Py_DECREF(args);
-
- if (result == NULL)
- PyErr_SetString(PyExc_TypeError,
- "reduce() of empty sequence with no initial value");
-
- Py_DECREF(it);
- return result;
-
-Fail:
- Py_XDECREF(args);
- Py_XDECREF(result);
- Py_DECREF(it);
- return NULL;
-}
-
-PyDoc_STRVAR(reduce_doc,
-"reduce(function, sequence[, initial]) -> value\n\
-\n\
-Apply a function of two arguments cumulatively to the items of a sequence,\n\
-from left to right, so as to reduce the sequence to a single value.\n\
-For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\
-((((1+2)+3)+4)+5). If initial is present, it is placed before the items\n\
-of the sequence in the calculation, and serves as a default when the\n\
-sequence is empty.");
-
-
-static PyObject *
-builtin_reload(PyObject *self, PyObject *v)
-{
- return PyImport_ReloadModule(v);
-}
-
-PyDoc_STRVAR(reload_doc,
-"reload(module) -> module\n\
-\n\
-Reload the module. The module must have been successfully imported before.");
-
-
-static PyObject *
-builtin_repr(PyObject *self, PyObject *v)
-{
- return PyObject_Repr(v);
-}
-
-PyDoc_STRVAR(repr_doc,
-"repr(object) -> string\n\
-\n\
-Return the canonical string representation of the object.\n\
-For most object types, eval(repr(object)) == object.");
-
-
-static PyObject *
-builtin_round(PyObject *self, PyObject *args, PyObject *kwds)
-{
- double number;
- double f;
- int ndigits = 0;
- int i;
- static char *kwlist[] = {"number", "ndigits", 0};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "d|i:round",
- kwlist, &number, &ndigits))
- return NULL;
- f = 1.0;
- i = abs(ndigits);
- while (--i >= 0)
- f = f*10.0;
- if (ndigits < 0)
- number /= f;
- else
- number *= f;
- if (number >= 0.0)
- number = floor(number + 0.5);
- else
- number = ceil(number - 0.5);
- if (ndigits < 0)
- number *= f;
- else
- number /= f;
- return PyFloat_FromDouble(number);
-}
-
-PyDoc_STRVAR(round_doc,
-"round(number[, ndigits]) -> floating point number\n\
-\n\
-Round a number to a given precision in decimal digits (default 0 digits).\n\
-This always returns a floating point number. Precision may be negative.");
-
-static PyObject *
-builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds)
-{
- PyObject *newlist, *v, *seq, *compare=NULL, *keyfunc=NULL, *newargs;
- PyObject *callable;
- static char *kwlist[] = {"iterable", "cmp", "key", "reverse", 0};
- int reverse;
-
- /* args 1-4 should match listsort in Objects/listobject.c */
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOi:sorted",
- kwlist, &seq, &compare, &keyfunc, &reverse))
- return NULL;
-
- newlist = PySequence_List(seq);
- if (newlist == NULL)
- return NULL;
-
- callable = PyObject_GetAttrString(newlist, "sort");
- if (callable == NULL) {
- Py_DECREF(newlist);
- return NULL;
- }
-
- newargs = PyTuple_GetSlice(args, 1, 4);
- if (newargs == NULL) {
- Py_DECREF(newlist);
- Py_DECREF(callable);
- return NULL;
- }
-
- v = PyObject_Call(callable, newargs, kwds);
- Py_DECREF(newargs);
- Py_DECREF(callable);
- if (v == NULL) {
- Py_DECREF(newlist);
- return NULL;
- }
- Py_DECREF(v);
- return newlist;
-}
-
-PyDoc_STRVAR(sorted_doc,
-"sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list");
-
-static PyObject *
-builtin_vars(PyObject *self, PyObject *args)
-{
- PyObject *v = NULL;
- PyObject *d;
-
- if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v))
- return NULL;
- if (v == NULL) {
- d = PyEval_GetLocals();
- if (d == NULL) {
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_SystemError,
- "vars(): no locals!?");
- }
- else
- Py_INCREF(d);
- }
- else {
- d = PyObject_GetAttrString(v, "__dict__");
- if (d == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "vars() argument must have __dict__ attribute");
- return NULL;
- }
- }
- return d;
-}
-
-PyDoc_STRVAR(vars_doc,
-"vars([object]) -> dictionary\n\
-\n\
-Without arguments, equivalent to locals().\n\
-With an argument, equivalent to object.__dict__.");
-
-
-static PyObject*
-builtin_sum(PyObject *self, PyObject *args)
-{
- PyObject *seq;
- PyObject *result = NULL;
- PyObject *temp, *item, *iter;
-
- if (!PyArg_UnpackTuple(args, "sum", 1, 2, &seq, &result))
- return NULL;
-
- iter = PyObject_GetIter(seq);
- if (iter == NULL)
- return NULL;
-
- if (result == NULL) {
- result = PyInt_FromLong(0);
- if (result == NULL) {
- Py_DECREF(iter);
- return NULL;
- }
- } else {
- /* reject string values for 'start' parameter */
- if (PyObject_TypeCheck(result, &PyBaseString_Type)) {
- PyErr_SetString(PyExc_TypeError,
- "sum() can't sum strings [use ''.join(seq) instead]");
- Py_DECREF(iter);
- return NULL;
- }
- Py_INCREF(result);
- }
-
- for(;;) {
- item = PyIter_Next(iter);
- if (item == NULL) {
- /* error, or end-of-sequence */
- if (PyErr_Occurred()) {
- Py_DECREF(result);
- result = NULL;
- }
- break;
- }
- temp = PyNumber_Add(result, item);
- Py_DECREF(result);
- Py_DECREF(item);
- result = temp;
- if (result == NULL)
- break;
- }
- Py_DECREF(iter);
- return result;
-}
-
-PyDoc_STRVAR(sum_doc,
-"sum(sequence, start=0) -> value\n\
-\n\
-Returns the sum of a sequence of numbers (NOT strings) plus the value\n\
-of parameter 'start'. When the sequence is empty, returns start.");
-
-
-static PyObject *
-builtin_isinstance(PyObject *self, PyObject *args)
-{
- PyObject *inst;
- PyObject *cls;
- int retval;
-
- if (!PyArg_UnpackTuple(args, "isinstance", 2, 2, &inst, &cls))
- return NULL;
-
- retval = PyObject_IsInstance(inst, cls);
- if (retval < 0)
- return NULL;
- return PyBool_FromLong(retval);
-}
-
-PyDoc_STRVAR(isinstance_doc,
-"isinstance(object, class-or-type-or-tuple) -> bool\n\
-\n\
-Return whether an object is an instance of a class or of a subclass thereof.\n\
-With a type as second argument, return whether that is the object's type.\n\
-The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for\n\
-isinstance(x, A) or isinstance(x, B) or ... (etc.).");
-
-
-static PyObject *
-builtin_issubclass(PyObject *self, PyObject *args)
-{
- PyObject *derived;
- PyObject *cls;
- int retval;
-
- if (!PyArg_UnpackTuple(args, "issubclass", 2, 2, &derived, &cls))
- return NULL;
-
- retval = PyObject_IsSubclass(derived, cls);
- if (retval < 0)
- return NULL;
- return PyBool_FromLong(retval);
-}
-
-PyDoc_STRVAR(issubclass_doc,
-"issubclass(C, B) -> bool\n\
-\n\
-Return whether class C is a subclass (i.e., a derived class) of class B.\n\
-When using a tuple as the second argument issubclass(X, (A, B, ...)),\n\
-is a shortcut for issubclass(X, A) or issubclass(X, B) or ... (etc.).");
-
-
-static PyObject*
-builtin_zip(PyObject *self, PyObject *args)
-{
- PyObject *ret;
- const Py_ssize_t itemsize = PySequence_Length(args);
- Py_ssize_t i;
- PyObject *itlist; /* tuple of iterators */
- Py_ssize_t len; /* guess at result length */
-
- if (itemsize == 0)
- return PyList_New(0);
-
- /* args must be a tuple */
- assert(PyTuple_Check(args));
-
- /* Guess at result length: the shortest of the input lengths.
- If some argument refuses to say, we refuse to guess too, lest
- an argument like xrange(sys.maxint) lead us astray.*/
- len = -1; /* unknown */
- for (i = 0; i < itemsize; ++i) {
- PyObject *item = PyTuple_GET_ITEM(args, i);
- Py_ssize_t thislen = _PyObject_LengthHint(item);
- if (thislen < 0) {
- if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
- !PyErr_ExceptionMatches(PyExc_AttributeError)) {
- return NULL;
- }
- PyErr_Clear();
- len = -1;
- break;
- }
- else if (len < 0 || thislen < len)
- len = thislen;
- }
-
- /* allocate result list */
- if (len < 0)
- len = 10; /* arbitrary */
- if ((ret = PyList_New(len)) == NULL)
- return NULL;
-
- /* obtain iterators */
- itlist = PyTuple_New(itemsize);
- if (itlist == NULL)
- goto Fail_ret;
- for (i = 0; i < itemsize; ++i) {
- PyObject *item = PyTuple_GET_ITEM(args, i);
- PyObject *it = PyObject_GetIter(item);
- if (it == NULL) {
- if (PyErr_ExceptionMatches(PyExc_TypeError))
- PyErr_Format(PyExc_TypeError,
- "zip argument #%zd must support iteration",
- i+1);
- goto Fail_ret_itlist;
- }
- PyTuple_SET_ITEM(itlist, i, it);
- }
-
- /* build result into ret list */
- for (i = 0; ; ++i) {
- int j;
- PyObject *next = PyTuple_New(itemsize);
- if (!next)
- goto Fail_ret_itlist;
-
- for (j = 0; j < itemsize; j++) {
- PyObject *it = PyTuple_GET_ITEM(itlist, j);
- PyObject *item = PyIter_Next(it);
- if (!item) {
- if (PyErr_Occurred()) {
- Py_DECREF(ret);
- ret = NULL;
- }
- Py_DECREF(next);
- Py_DECREF(itlist);
- goto Done;
- }
- PyTuple_SET_ITEM(next, j, item);
- }
-
- if (i < len)
- PyList_SET_ITEM(ret, i, next);
- else {
- int status = PyList_Append(ret, next);
- Py_DECREF(next);
- ++len;
- if (status < 0)
- goto Fail_ret_itlist;
- }
- }
-
-Done:
- if (ret != NULL && i < len) {
- /* The list is too big. */
- if (PyList_SetSlice(ret, i, len, NULL) < 0)
- return NULL;
- }
- return ret;
-
-Fail_ret_itlist:
- Py_DECREF(itlist);
-Fail_ret:
- Py_DECREF(ret);
- return NULL;
-}
-
-
-PyDoc_STRVAR(zip_doc,
-"zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]\n\
-\n\
-Return a list of tuples, where each tuple contains the i-th element\n\
-from each of the argument sequences. The returned list is truncated\n\
-in length to the length of the shortest argument sequence.");
-
-
-static PyMethodDef builtin_methods[] = {
- {"__import__", (PyCFunction)builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc},
- {"abs", builtin_abs, METH_O, abs_doc},
- {"all", builtin_all, METH_O, all_doc},
- {"any", builtin_any, METH_O, any_doc},
- {"apply", builtin_apply, METH_VARARGS, apply_doc},
- {"callable", builtin_callable, METH_O, callable_doc},
- {"chr", builtin_chr, METH_VARARGS, chr_doc},
- {"cmp", builtin_cmp, METH_VARARGS, cmp_doc},
- {"coerce", builtin_coerce, METH_VARARGS, coerce_doc},
- {"compile", builtin_compile, METH_VARARGS, compile_doc},
- {"delattr", builtin_delattr, METH_VARARGS, delattr_doc},
- {"dir", builtin_dir, METH_VARARGS, dir_doc},
- {"divmod", builtin_divmod, METH_VARARGS, divmod_doc},
- {"eval", builtin_eval, METH_VARARGS, eval_doc},
- {"execfile", builtin_execfile, METH_VARARGS, execfile_doc},
- {"filter", builtin_filter, METH_VARARGS, filter_doc},
- {"getattr", builtin_getattr, METH_VARARGS, getattr_doc},
- {"globals", (PyCFunction)builtin_globals, METH_NOARGS, globals_doc},
- {"hasattr", builtin_hasattr, METH_VARARGS, hasattr_doc},
- {"hash", builtin_hash, METH_O, hash_doc},
- {"hex", builtin_hex, METH_O, hex_doc},
- {"id", builtin_id, METH_O, id_doc},
- {"input", builtin_input, METH_VARARGS, input_doc},
- {"intern", builtin_intern, METH_VARARGS, intern_doc},
- {"isinstance", builtin_isinstance, METH_VARARGS, isinstance_doc},
- {"issubclass", builtin_issubclass, METH_VARARGS, issubclass_doc},
- {"iter", builtin_iter, METH_VARARGS, iter_doc},
- {"len", builtin_len, METH_O, len_doc},
- {"locals", (PyCFunction)builtin_locals, METH_NOARGS, locals_doc},
- {"map", builtin_map, METH_VARARGS, map_doc},
- {"max", (PyCFunction)builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc},
- {"min", (PyCFunction)builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc},
- {"oct", builtin_oct, METH_O, oct_doc},
- {"open", (PyCFunction)builtin_open, METH_VARARGS | METH_KEYWORDS, open_doc},
- {"ord", builtin_ord, METH_O, ord_doc},
- {"pow", builtin_pow, METH_VARARGS, pow_doc},
- {"range", builtin_range, METH_VARARGS, range_doc},
- {"raw_input", builtin_raw_input, METH_VARARGS, raw_input_doc},
- {"reduce", builtin_reduce, METH_VARARGS, reduce_doc},
- {"reload", builtin_reload, METH_O, reload_doc},
- {"repr", builtin_repr, METH_O, repr_doc},
- {"round", (PyCFunction)builtin_round, METH_VARARGS | METH_KEYWORDS, round_doc},
- {"setattr", builtin_setattr, METH_VARARGS, setattr_doc},
- {"sorted", (PyCFunction)builtin_sorted, METH_VARARGS | METH_KEYWORDS, sorted_doc},
- {"sum", builtin_sum, METH_VARARGS, sum_doc},
-#ifdef Py_USING_UNICODE
- {"unichr", builtin_unichr, METH_VARARGS, unichr_doc},
-#endif
- {"vars", builtin_vars, METH_VARARGS, vars_doc},
- {"zip", builtin_zip, METH_VARARGS, zip_doc},
- {NULL, NULL},
-};
-
-PyDoc_STRVAR(builtin_doc,
-"Built-in functions, exceptions, and other objects.\n\
-\n\
-Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices.");
-
-PyObject *
-_PyBuiltin_Init(void)
-{
- PyObject *mod, *dict, *debug;
- mod = Py_InitModule4("__builtin__", builtin_methods,
- builtin_doc, (PyObject *)NULL,
- PYTHON_API_VERSION);
- if (mod == NULL)
- return NULL;
- dict = PyModule_GetDict(mod);
-
-#ifdef Py_TRACE_REFS
- /* __builtin__ exposes a number of statically allocated objects
- * that, before this code was added in 2.3, never showed up in
- * the list of "all objects" maintained by Py_TRACE_REFS. As a
- * result, programs leaking references to None and False (etc)
- * couldn't be diagnosed by examining sys.getobjects(0).
- */
-#define ADD_TO_ALL(OBJECT) _Py_AddToAllObjects((PyObject *)(OBJECT), 0)
-#else
-#define ADD_TO_ALL(OBJECT) (void)0
-#endif
-
-#define SETBUILTIN(NAME, OBJECT) \
- if (PyDict_SetItemString(dict, NAME, (PyObject *)OBJECT) < 0) \
- return NULL; \
- ADD_TO_ALL(OBJECT)
-
- SETBUILTIN("None", Py_None);
- SETBUILTIN("Ellipsis", Py_Ellipsis);
- SETBUILTIN("NotImplemented", Py_NotImplemented);
- SETBUILTIN("False", Py_False);
- SETBUILTIN("True", Py_True);
- SETBUILTIN("basestring", &PyBaseString_Type);
- SETBUILTIN("bool", &PyBool_Type);
- SETBUILTIN("buffer", &PyBuffer_Type);
- SETBUILTIN("classmethod", &PyClassMethod_Type);
-#ifndef WITHOUT_COMPLEX
- SETBUILTIN("complex", &PyComplex_Type);
-#endif
- SETBUILTIN("dict", &PyDict_Type);
- SETBUILTIN("enumerate", &PyEnum_Type);
- SETBUILTIN("file", &PyFile_Type);
- SETBUILTIN("float", &PyFloat_Type);
- SETBUILTIN("frozenset", &PyFrozenSet_Type);
- SETBUILTIN("property", &PyProperty_Type);
- SETBUILTIN("int", &PyInt_Type);
- SETBUILTIN("list", &PyList_Type);
- SETBUILTIN("long", &PyLong_Type);
- SETBUILTIN("object", &PyBaseObject_Type);
- SETBUILTIN("reversed", &PyReversed_Type);
- SETBUILTIN("set", &PySet_Type);
- SETBUILTIN("slice", &PySlice_Type);
- SETBUILTIN("staticmethod", &PyStaticMethod_Type);
- SETBUILTIN("str", &PyString_Type);
- SETBUILTIN("super", &PySuper_Type);
- SETBUILTIN("tuple", &PyTuple_Type);
- SETBUILTIN("type", &PyType_Type);
- SETBUILTIN("xrange", &PyRange_Type);
-#ifdef Py_USING_UNICODE
- SETBUILTIN("unicode", &PyUnicode_Type);
-#endif
- debug = PyBool_FromLong(Py_OptimizeFlag == 0);
- if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {
- Py_XDECREF(debug);
- return NULL;
- }
- Py_XDECREF(debug);
-
- return mod;
-#undef ADD_TO_ALL
-#undef SETBUILTIN
-}
-
-/* Helper for filter(): filter a tuple through a function */
-
-static PyObject *
-filtertuple(PyObject *func, PyObject *tuple)
-{
- PyObject *result;
- Py_ssize_t i, j;
- Py_ssize_t len = PyTuple_Size(tuple);
-
- if (len == 0) {
- if (PyTuple_CheckExact(tuple))
- Py_INCREF(tuple);
- else
- tuple = PyTuple_New(0);
- return tuple;
- }
-
- if ((result = PyTuple_New(len)) == NULL)
- return NULL;
-
- for (i = j = 0; i < len; ++i) {
- PyObject *item, *good;
- int ok;
-
- if (tuple->ob_type->tp_as_sequence &&
- tuple->ob_type->tp_as_sequence->sq_item) {
- item = tuple->ob_type->tp_as_sequence->sq_item(tuple, i);
- if (item == NULL)
- goto Fail_1;
- } else {
- PyErr_SetString(PyExc_TypeError, "filter(): unsubscriptable tuple");
- goto Fail_1;
- }
- if (func == Py_None) {
- Py_INCREF(item);
- good = item;
- }
- else {
- PyObject *arg = PyTuple_Pack(1, item);
- if (arg == NULL) {
- Py_DECREF(item);
- goto Fail_1;
- }
- good = PyEval_CallObject(func, arg);
- Py_DECREF(arg);
- if (good == NULL) {
- Py_DECREF(item);
- goto Fail_1;
- }
- }
- ok = PyObject_IsTrue(good);
- Py_DECREF(good);
- if (ok) {
- if (PyTuple_SetItem(result, j++, item) < 0)
- goto Fail_1;
- }
- else
- Py_DECREF(item);
- }
-
- if (_PyTuple_Resize(&result, j) < 0)
- return NULL;
-
- return result;
-
-Fail_1:
- Py_DECREF(result);
- return NULL;
-}
-
-
-/* Helper for filter(): filter a string through a function */
-
-static PyObject *
-filterstring(PyObject *func, PyObject *strobj)
-{
- PyObject *result;
- Py_ssize_t i, j;
- Py_ssize_t len = PyString_Size(strobj);
- Py_ssize_t outlen = len;
-
- if (func == Py_None) {
- /* If it's a real string we can return the original,
- * as no character is ever false and __getitem__
- * does return this character. If it's a subclass
- * we must go through the __getitem__ loop */
- if (PyString_CheckExact(strobj)) {
- Py_INCREF(strobj);
- return strobj;
- }
- }
- if ((result = PyString_FromStringAndSize(NULL, len)) == NULL)
- return NULL;
-
- for (i = j = 0; i < len; ++i) {
- PyObject *item;
- int ok;
-
- item = (*strobj->ob_type->tp_as_sequence->sq_item)(strobj, i);
- if (item == NULL)
- goto Fail_1;
- if (func==Py_None) {
- ok = 1;
- } else {
- PyObject *arg, *good;
- arg = PyTuple_Pack(1, item);
- if (arg == NULL) {
- Py_DECREF(item);
- goto Fail_1;
- }
- good = PyEval_CallObject(func, arg);
- Py_DECREF(arg);
- if (good == NULL) {
- Py_DECREF(item);
- goto Fail_1;
- }
- ok = PyObject_IsTrue(good);
- Py_DECREF(good);
- }
- if (ok) {
- Py_ssize_t reslen;
- if (!PyString_Check(item)) {
- PyErr_SetString(PyExc_TypeError, "can't filter str to str:"
- " __getitem__ returned different type");
- Py_DECREF(item);
- goto Fail_1;
- }
- reslen = PyString_GET_SIZE(item);
- if (reslen == 1) {
- PyString_AS_STRING(result)[j++] =
- PyString_AS_STRING(item)[0];
- } else {
- /* do we need more space? */
- Py_ssize_t need = j + reslen + len-i-1;
- if (need > outlen) {
- /* overallocate, to avoid reallocations */
- if (need<2*outlen)
- need = 2*outlen;
- if (_PyString_Resize(&result, need)) {
- Py_DECREF(item);
- return NULL;
- }
- outlen = need;
- }
- memcpy(
- PyString_AS_STRING(result) + j,
- PyString_AS_STRING(item),
- reslen
- );
- j += reslen;
- }
- }
- Py_DECREF(item);
- }
-
- if (j < outlen)
- _PyString_Resize(&result, j);
-
- return result;
-
-Fail_1:
- Py_DECREF(result);
- return NULL;
-}
-
-#ifdef Py_USING_UNICODE
-/* Helper for filter(): filter a Unicode object through a function */
-
-static PyObject *
-filterunicode(PyObject *func, PyObject *strobj)
-{
- PyObject *result;
- register Py_ssize_t i, j;
- Py_ssize_t len = PyUnicode_GetSize(strobj);
- Py_ssize_t outlen = len;
-
- if (func == Py_None) {
- /* If it's a real string we can return the original,
- * as no character is ever false and __getitem__
- * does return this character. If it's a subclass
- * we must go through the __getitem__ loop */
- if (PyUnicode_CheckExact(strobj)) {
- Py_INCREF(strobj);
- return strobj;
- }
- }
- if ((result = PyUnicode_FromUnicode(NULL, len)) == NULL)
- return NULL;
-
- for (i = j = 0; i < len; ++i) {
- PyObject *item, *arg, *good;
- int ok;
-
- item = (*strobj->ob_type->tp_as_sequence->sq_item)(strobj, i);
- if (item == NULL)
- goto Fail_1;
- if (func == Py_None) {
- ok = 1;
- } else {
- arg = PyTuple_Pack(1, item);
- if (arg == NULL) {
- Py_DECREF(item);
- goto Fail_1;
- }
- good = PyEval_CallObject(func, arg);
- Py_DECREF(arg);
- if (good == NULL) {
- Py_DECREF(item);
- goto Fail_1;
- }
- ok = PyObject_IsTrue(good);
- Py_DECREF(good);
- }
- if (ok) {
- Py_ssize_t reslen;
- if (!PyUnicode_Check(item)) {
- PyErr_SetString(PyExc_TypeError,
- "can't filter unicode to unicode:"
- " __getitem__ returned different type");
- Py_DECREF(item);
- goto Fail_1;
- }
- reslen = PyUnicode_GET_SIZE(item);
- if (reslen == 1)
- PyUnicode_AS_UNICODE(result)[j++] =
- PyUnicode_AS_UNICODE(item)[0];
- else {
- /* do we need more space? */
- Py_ssize_t need = j + reslen + len - i - 1;
- if (need > outlen) {
- /* overallocate,
- to avoid reallocations */
- if (need < 2 * outlen)
- need = 2 * outlen;
- if (PyUnicode_Resize(
- &result, need) < 0) {
- Py_DECREF(item);
- goto Fail_1;
- }
- outlen = need;
- }
- memcpy(PyUnicode_AS_UNICODE(result) + j,
- PyUnicode_AS_UNICODE(item),
- reslen*sizeof(Py_UNICODE));
- j += reslen;
- }
- }
- Py_DECREF(item);
- }
-
- if (j < outlen)
- PyUnicode_Resize(&result, j);
-
- return result;
-
-Fail_1:
- Py_DECREF(result);
- return NULL;
-}
-#endif
diff --git a/sys/src/cmd/python/Python/ceval.c b/sys/src/cmd/python/Python/ceval.c
deleted file mode 100644
index 597ae481f..000000000
--- a/sys/src/cmd/python/Python/ceval.c
+++ /dev/null
@@ -1,4351 +0,0 @@
-
-/* Execute compiled code */
-
-/* XXX TO DO:
- XXX speed up searching for keywords by using a dictionary
- XXX document it!
- */
-
-/* enable more aggressive intra-module optimizations, where available */
-#define PY_LOCAL_AGGRESSIVE
-
-#include "Python.h"
-
-#include "code.h"
-#include "frameobject.h"
-#include "eval.h"
-#include "opcode.h"
-#include "structmember.h"
-
-#include <ctype.h>
-
-#ifndef WITH_TSC
-
-#define READ_TIMESTAMP(var)
-
-#else
-
-typedef unsigned long long uint64;
-
-#if defined(__ppc__) /* <- Don't know if this is the correct symbol; this
- section should work for GCC on any PowerPC platform,
- irrespective of OS. POWER? Who knows :-) */
-
-#define READ_TIMESTAMP(var) ppc_getcounter(&var)
-
-static void
-ppc_getcounter(uint64 *v)
-{
- register unsigned long tbu, tb, tbu2;
-
- loop:
- asm volatile ("mftbu %0" : "=r" (tbu) );
- asm volatile ("mftb %0" : "=r" (tb) );
- asm volatile ("mftbu %0" : "=r" (tbu2));
- if (__builtin_expect(tbu != tbu2, 0)) goto loop;
-
- /* The slightly peculiar way of writing the next lines is
- compiled better by GCC than any other way I tried. */
- ((long*)(v))[0] = tbu;
- ((long*)(v))[1] = tb;
-}
-
-#else /* this is for linux/x86 (and probably any other GCC/x86 combo) */
-
-#define READ_TIMESTAMP(val) \
- __asm__ __volatile__("rdtsc" : "=A" (val))
-
-#endif
-
-void dump_tsc(int opcode, int ticked, uint64 inst0, uint64 inst1,
- uint64 loop0, uint64 loop1, uint64 intr0, uint64 intr1)
-{
- uint64 intr, inst, loop;
- PyThreadState *tstate = PyThreadState_Get();
- if (!tstate->interp->tscdump)
- return;
- intr = intr1 - intr0;
- inst = inst1 - inst0 - intr;
- loop = loop1 - loop0 - intr;
- fprintf(stderr, "opcode=%03d t=%d inst=%06lld loop=%06lld\n",
- opcode, ticked, inst, loop);
-}
-
-#endif
-
-/* Turn this on if your compiler chokes on the big switch: */
-/* #define CASE_TOO_BIG 1 */
-
-#ifdef Py_DEBUG
-/* For debugging the interpreter: */
-#define LLTRACE 1 /* Low-level trace feature */
-#define CHECKEXC 1 /* Double-check exception checking */
-#endif
-
-typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);
-
-/* Forward declarations */
-#ifdef WITH_TSC
-static PyObject * call_function(PyObject ***, int, uint64*, uint64*);
-#else
-static PyObject * call_function(PyObject ***, int);
-#endif
-static PyObject * fast_function(PyObject *, PyObject ***, int, int, int);
-static PyObject * do_call(PyObject *, PyObject ***, int, int);
-static PyObject * ext_do_call(PyObject *, PyObject ***, int, int, int);
-static PyObject * update_keyword_args(PyObject *, int, PyObject ***,PyObject *);
-static PyObject * update_star_args(int, int, PyObject *, PyObject ***);
-static PyObject * load_args(PyObject ***, int);
-#define CALL_FLAG_VAR 1
-#define CALL_FLAG_KW 2
-
-#ifdef LLTRACE
-static int lltrace;
-static int prtrace(PyObject *, char *);
-#endif
-static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *,
- int, PyObject *);
-static void call_trace_protected(Py_tracefunc, PyObject *,
- PyFrameObject *, int, PyObject *);
-static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *);
-static int maybe_call_line_trace(Py_tracefunc, PyObject *,
- PyFrameObject *, int *, int *, int *);
-
-static PyObject * apply_slice(PyObject *, PyObject *, PyObject *);
-static int assign_slice(PyObject *, PyObject *,
- PyObject *, PyObject *);
-static PyObject * cmp_outcome(int, PyObject *, PyObject *);
-static PyObject * import_from(PyObject *, PyObject *);
-static int import_all_from(PyObject *, PyObject *);
-static PyObject * build_class(PyObject *, PyObject *, PyObject *);
-static int exec_statement(PyFrameObject *,
- PyObject *, PyObject *, PyObject *);
-static void set_exc_info(PyThreadState *, PyObject *, PyObject *, PyObject *);
-static void reset_exc_info(PyThreadState *);
-static void format_exc_check_arg(PyObject *, char *, PyObject *);
-static PyObject * string_concatenate(PyObject *, PyObject *,
- PyFrameObject *, unsigned char *);
-
-#define NAME_ERROR_MSG \
- "name '%.200s' is not defined"
-#define GLOBAL_NAME_ERROR_MSG \
- "global name '%.200s' is not defined"
-#define UNBOUNDLOCAL_ERROR_MSG \
- "local variable '%.200s' referenced before assignment"
-#define UNBOUNDFREE_ERROR_MSG \
- "free variable '%.200s' referenced before assignment" \
- " in enclosing scope"
-
-/* Dynamic execution profile */
-#ifdef DYNAMIC_EXECUTION_PROFILE
-#ifdef DXPAIRS
-static long dxpairs[257][256];
-#define dxp dxpairs[256]
-#else
-static long dxp[256];
-#endif
-#endif
-
-/* Function call profile */
-#ifdef CALL_PROFILE
-#define PCALL_NUM 11
-static int pcall[PCALL_NUM];
-
-#define PCALL_ALL 0
-#define PCALL_FUNCTION 1
-#define PCALL_FAST_FUNCTION 2
-#define PCALL_FASTER_FUNCTION 3
-#define PCALL_METHOD 4
-#define PCALL_BOUND_METHOD 5
-#define PCALL_CFUNCTION 6
-#define PCALL_TYPE 7
-#define PCALL_GENERATOR 8
-#define PCALL_OTHER 9
-#define PCALL_POP 10
-
-/* Notes about the statistics
-
- PCALL_FAST stats
-
- FAST_FUNCTION means no argument tuple needs to be created.
- FASTER_FUNCTION means that the fast-path frame setup code is used.
-
- If there is a method call where the call can be optimized by changing
- the argument tuple and calling the function directly, it gets recorded
- twice.
-
- As a result, the relationship among the statistics appears to be
- PCALL_ALL == PCALL_FUNCTION + PCALL_METHOD - PCALL_BOUND_METHOD +
- PCALL_CFUNCTION + PCALL_TYPE + PCALL_GENERATOR + PCALL_OTHER
- PCALL_FUNCTION > PCALL_FAST_FUNCTION > PCALL_FASTER_FUNCTION
- PCALL_METHOD > PCALL_BOUND_METHOD
-*/
-
-#define PCALL(POS) pcall[POS]++
-
-PyObject *
-PyEval_GetCallStats(PyObject *self)
-{
- return Py_BuildValue("iiiiiiiiiii",
- pcall[0], pcall[1], pcall[2], pcall[3],
- pcall[4], pcall[5], pcall[6], pcall[7],
- pcall[8], pcall[9], pcall[10]);
-}
-#else
-#define PCALL(O)
-
-PyObject *
-PyEval_GetCallStats(PyObject *self)
-{
- Py_INCREF(Py_None);
- return Py_None;
-}
-#endif
-
-
-#ifdef WITH_THREAD
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include "pythread.h"
-
-static PyThread_type_lock interpreter_lock = 0; /* This is the GIL */
-static long main_thread = 0;
-
-int
-PyEval_ThreadsInitialized(void)
-{
- return interpreter_lock != 0;
-}
-
-void
-PyEval_InitThreads(void)
-{
- if (interpreter_lock)
- return;
- interpreter_lock = PyThread_allocate_lock();
- PyThread_acquire_lock(interpreter_lock, 1);
- main_thread = PyThread_get_thread_ident();
-}
-
-void
-PyEval_AcquireLock(void)
-{
- PyThread_acquire_lock(interpreter_lock, 1);
-}
-
-void
-PyEval_ReleaseLock(void)
-{
- PyThread_release_lock(interpreter_lock);
-}
-
-void
-PyEval_AcquireThread(PyThreadState *tstate)
-{
- if (tstate == NULL)
- Py_FatalError("PyEval_AcquireThread: NULL new thread state");
- /* Check someone has called PyEval_InitThreads() to create the lock */
- assert(interpreter_lock);
- PyThread_acquire_lock(interpreter_lock, 1);
- if (PyThreadState_Swap(tstate) != NULL)
- Py_FatalError(
- "PyEval_AcquireThread: non-NULL old thread state");
-}
-
-void
-PyEval_ReleaseThread(PyThreadState *tstate)
-{
- if (tstate == NULL)
- Py_FatalError("PyEval_ReleaseThread: NULL thread state");
- if (PyThreadState_Swap(NULL) != tstate)
- Py_FatalError("PyEval_ReleaseThread: wrong thread state");
- PyThread_release_lock(interpreter_lock);
-}
-
-/* This function is called from PyOS_AfterFork to ensure that newly
- created child processes don't hold locks referring to threads which
- are not running in the child process. (This could also be done using
- pthread_atfork mechanism, at least for the pthreads implementation.) */
-
-void
-PyEval_ReInitThreads(void)
-{
- if (!interpreter_lock)
- return;
- /*XXX Can't use PyThread_free_lock here because it does too
- much error-checking. Doing this cleanly would require
- adding a new function to each thread_*.h. Instead, just
- create a new lock and waste a little bit of memory */
- interpreter_lock = PyThread_allocate_lock();
- PyThread_acquire_lock(interpreter_lock, 1);
- main_thread = PyThread_get_thread_ident();
-}
-#endif
-
-/* Functions save_thread and restore_thread are always defined so
- dynamically loaded modules needn't be compiled separately for use
- with and without threads: */
-
-PyThreadState *
-PyEval_SaveThread(void)
-{
- PyThreadState *tstate = PyThreadState_Swap(NULL);
- if (tstate == NULL)
- Py_FatalError("PyEval_SaveThread: NULL tstate");
-#ifdef WITH_THREAD
- if (interpreter_lock)
- PyThread_release_lock(interpreter_lock);
-#endif
- return tstate;
-}
-
-void
-PyEval_RestoreThread(PyThreadState *tstate)
-{
- if (tstate == NULL)
- Py_FatalError("PyEval_RestoreThread: NULL tstate");
-#ifdef WITH_THREAD
- if (interpreter_lock) {
- int err = errno;
- PyThread_acquire_lock(interpreter_lock, 1);
- errno = err;
- }
-#endif
- PyThreadState_Swap(tstate);
-}
-
-
-/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX
- signal handlers or Mac I/O completion routines) can schedule calls
- to a function to be called synchronously.
- The synchronous function is called with one void* argument.
- It should return 0 for success or -1 for failure -- failure should
- be accompanied by an exception.
-
- If registry succeeds, the registry function returns 0; if it fails
- (e.g. due to too many pending calls) it returns -1 (without setting
- an exception condition).
-
- Note that because registry may occur from within signal handlers,
- or other asynchronous events, calling malloc() is unsafe!
-
-#ifdef WITH_THREAD
- Any thread can schedule pending calls, but only the main thread
- will execute them.
-#endif
-
- XXX WARNING! ASYNCHRONOUSLY EXECUTING CODE!
- There are two possible race conditions:
- (1) nested asynchronous registry calls;
- (2) registry calls made while pending calls are being processed.
- While (1) is very unlikely, (2) is a real possibility.
- The current code is safe against (2), but not against (1).
- The safety against (2) is derived from the fact that only one
- thread (the main thread) ever takes things out of the queue.
-
- XXX Darn! With the advent of thread state, we should have an array
- of pending calls per thread in the thread state! Later...
-*/
-
-#define NPENDINGCALLS 32
-static struct {
- int (*func)(void *);
- void *arg;
-} pendingcalls[NPENDINGCALLS];
-static volatile int pendingfirst = 0;
-static volatile int pendinglast = 0;
-static volatile int things_to_do = 0;
-
-int
-Py_AddPendingCall(int (*func)(void *), void *arg)
-{
- static int busy = 0;
- int i, j;
- /* XXX Begin critical section */
- /* XXX If you want this to be safe against nested
- XXX asynchronous calls, you'll have to work harder! */
- if (busy)
- return -1;
- busy = 1;
- i = pendinglast;
- j = (i + 1) % NPENDINGCALLS;
- if (j == pendingfirst) {
- busy = 0;
- return -1; /* Queue full */
- }
- pendingcalls[i].func = func;
- pendingcalls[i].arg = arg;
- pendinglast = j;
-
- _Py_Ticker = 0;
- things_to_do = 1; /* Signal main loop */
- busy = 0;
- /* XXX End critical section */
- return 0;
-}
-
-int
-Py_MakePendingCalls(void)
-{
- static int busy = 0;
-#ifdef WITH_THREAD
- if (main_thread && PyThread_get_thread_ident() != main_thread)
- return 0;
-#endif
- if (busy)
- return 0;
- busy = 1;
- things_to_do = 0;
- for (;;) {
- int i;
- int (*func)(void *);
- void *arg;
- i = pendingfirst;
- if (i == pendinglast)
- break; /* Queue empty */
- func = pendingcalls[i].func;
- arg = pendingcalls[i].arg;
- pendingfirst = (i + 1) % NPENDINGCALLS;
- if (func(arg) < 0) {
- busy = 0;
- things_to_do = 1; /* We're not done yet */
- return -1;
- }
- }
- busy = 0;
- return 0;
-}
-
-
-/* The interpreter's recursion limit */
-
-#ifndef Py_DEFAULT_RECURSION_LIMIT
-#define Py_DEFAULT_RECURSION_LIMIT 1000
-#endif
-static int recursion_limit = Py_DEFAULT_RECURSION_LIMIT;
-int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
-
-int
-Py_GetRecursionLimit(void)
-{
- return recursion_limit;
-}
-
-void
-Py_SetRecursionLimit(int new_limit)
-{
- recursion_limit = new_limit;
- _Py_CheckRecursionLimit = recursion_limit;
-}
-
-/* the macro Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
- if the recursion_depth reaches _Py_CheckRecursionLimit.
- If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit
- to guarantee that _Py_CheckRecursiveCall() is regularly called.
- Without USE_STACKCHECK, there is no need for this. */
-int
-_Py_CheckRecursiveCall(char *where)
-{
- PyThreadState *tstate = PyThreadState_GET();
-
-#ifdef USE_STACKCHECK
- if (PyOS_CheckStack()) {
- --tstate->recursion_depth;
- PyErr_SetString(PyExc_MemoryError, "Stack overflow");
- return -1;
- }
-#endif
- if (tstate->recursion_depth > recursion_limit) {
- --tstate->recursion_depth;
- PyErr_Format(PyExc_RuntimeError,
- "maximum recursion depth exceeded%s",
- where);
- return -1;
- }
- _Py_CheckRecursionLimit = recursion_limit;
- return 0;
-}
-
-/* Status code for main loop (reason for stack unwind) */
-enum why_code {
- WHY_NOT = 0x0001, /* No error */
- WHY_EXCEPTION = 0x0002, /* Exception occurred */
- WHY_RERAISE = 0x0004, /* Exception re-raised by 'finally' */
- WHY_RETURN = 0x0008, /* 'return' statement */
- WHY_BREAK = 0x0010, /* 'break' statement */
- WHY_CONTINUE = 0x0020, /* 'continue' statement */
- WHY_YIELD = 0x0040 /* 'yield' operator */
-};
-
-static enum why_code do_raise(PyObject *, PyObject *, PyObject *);
-static int unpack_iterable(PyObject *, int, PyObject **);
-
-/* for manipulating the thread switch and periodic "stuff" - used to be
- per thread, now just a pair o' globals */
-int _Py_CheckInterval = 100;
-volatile int _Py_Ticker = 100;
-
-PyObject *
-PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
-{
- /* XXX raise SystemError if globals is NULL */
- return PyEval_EvalCodeEx(co,
- globals, locals,
- (PyObject **)NULL, 0,
- (PyObject **)NULL, 0,
- (PyObject **)NULL, 0,
- NULL);
-}
-
-
-/* Interpreter main loop */
-
-PyObject *
-PyEval_EvalFrame(PyFrameObject *f) {
- /* This is for backward compatibility with extension modules that
- used this API; core interpreter code should call PyEval_EvalFrameEx() */
- return PyEval_EvalFrameEx(f, 0);
-}
-
-PyObject *
-PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
-{
-#ifdef DXPAIRS
- int lastopcode = 0;
-#endif
- register PyObject **stack_pointer; /* Next free slot in value stack */
- register unsigned char *next_instr;
- register int opcode; /* Current opcode */
- register int oparg; /* 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 *u;
- register PyObject *t;
- register PyObject *stream = NULL; /* for PRINT opcodes */
- register PyObject **fastlocals, **freevars;
- PyObject *retval = NULL; /* Return value */
- PyThreadState *tstate = PyThreadState_GET();
- PyCodeObject *co;
-
- /* when tracing we set things up so that
-
- not (instr_lb <= current_bytecode_offset < instr_ub)
-
- is true when the line being executed has changed. The
- initial values are such as to make this false the first
- time it is tested. */
- int instr_ub = -1, instr_lb = 0, instr_prev = -1;
-
- unsigned char *first_instr;
- PyObject *names;
- PyObject *consts;
-#if defined(Py_DEBUG) || defined(LLTRACE)
- /* Make it easier to find out where we are with a debugger */
- char *filename;
-#endif
-
-/* Tuple access macros */
-
-#ifndef Py_DEBUG
-#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))
-#else
-#define GETITEM(v, i) PyTuple_GetItem((v), (i))
-#endif
-
-#ifdef WITH_TSC
-/* Use Pentium timestamp counter to mark certain events:
- inst0 -- beginning of switch statement for opcode dispatch
- inst1 -- end of switch statement (may be skipped)
- loop0 -- the top of the mainloop
- loop1 -- place where control returns again to top of mainloop
- (may be skipped)
- intr1 -- beginning of long interruption
- intr2 -- end of long interruption
-
- Many opcodes call out to helper C functions. In some cases, the
- time in those functions should be counted towards the time for the
- opcode, but not in all cases. For example, a CALL_FUNCTION opcode
- calls another Python function; there's no point in charge all the
- bytecode executed by the called function to the caller.
-
- It's hard to make a useful judgement statically. In the presence
- of operator overloading, it's impossible to tell if a call will
- execute new Python code or not.
-
- It's a case-by-case judgement. I'll use intr1 for the following
- cases:
-
- EXEC_STMT
- IMPORT_STAR
- IMPORT_FROM
- CALL_FUNCTION (and friends)
-
- */
- uint64 inst0, inst1, loop0, loop1, intr0 = 0, intr1 = 0;
- int ticked = 0;
-
- READ_TIMESTAMP(inst0);
- READ_TIMESTAMP(inst1);
- READ_TIMESTAMP(loop0);
- READ_TIMESTAMP(loop1);
-
- /* shut up the compiler */
- opcode = 0;
-#endif
-
-/* Code access macros */
-
-#define INSTR_OFFSET() ((int)(next_instr - first_instr))
-#define NEXTOP() (*next_instr++)
-#define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
-#define PEEKARG() ((next_instr[2]<<8) + next_instr[1])
-#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.
-
- If collecting opcode statistics, turn off prediction so that
- statistics are accurately maintained (the predictions bypass
- the opcode frequency counter updates).
-*/
-
-#ifdef DYNAMIC_EXECUTION_PROFILE
-#define PREDICT(op) if (0) goto PRED_##op
-#else
-#define PREDICT(op) if (*next_instr == op) goto PRED_##op
-#endif
-
-#define PREDICTED(op) PRED_##op: next_instr++
-#define PREDICTED_WITH_ARG(op) PRED_##op: oparg = PEEKARG(); next_instr += 3
-
-/* Stack manipulation macros */
-
-/* The stack can grow at most MAXINT deep, as co_nlocals and
- co_stacksize are ints. */
-#define STACK_LEVEL() ((int)(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)
-
-#ifdef LLTRACE
-#define PUSH(v) { (void)(BASIC_PUSH(v), \
- lltrace && prtrace(TOP(), "push")); \
- assert(STACK_LEVEL() <= co->co_stacksize); }
-#define POP() ((void)(lltrace && prtrace(TOP(), "pop")), BASIC_POP())
-#define STACKADJ(n) { (void)(BASIC_STACKADJ(n), \
- lltrace && prtrace(TOP(), "stackadj")); \
- assert(STACK_LEVEL() <= co->co_stacksize); }
-#define EXT_POP(STACK_POINTER) (lltrace && prtrace(*(STACK_POINTER), "ext_pop"), *--(STACK_POINTER))
-#else
-#define PUSH(v) BASIC_PUSH(v)
-#define POP() BASIC_POP()
-#define STACKADJ(n) BASIC_STACKADJ(n)
-#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
-#endif
-
-/* 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 (Py_EnterRecursiveCall(""))
- return NULL;
-
- tstate->frame = f;
-
- if (tstate->use_tracing) {
- if (tstate->c_tracefunc != NULL) {
- /* tstate->c_tracefunc, if defined, is a
- function that will be called on *every* entry
- to a code block. Its return value, if not
- None, is a function that will be called at
- the start of each executed line of code.
- (Actually, the function must return itself
- in order to continue tracing.) The trace
- functions are called with three arguments:
- a pointer to the current frame, a string
- indicating why the function is called, and
- an argument which depends on the situation.
- The global trace function is also called
- whenever an exception is detected. */
- if (call_trace(tstate->c_tracefunc, tstate->c_traceobj,
- f, PyTrace_CALL, Py_None)) {
- /* Trace function raised an error */
- goto exit_eval_frame;
- }
- }
- if (tstate->c_profilefunc != NULL) {
- /* Similar for c_profilefunc, except it needn't
- return itself and isn't called for "line" events */
- if (call_trace(tstate->c_profilefunc,
- tstate->c_profileobj,
- f, PyTrace_CALL, Py_None)) {
- /* Profile function raised an error */
- goto exit_eval_frame;
- }
- }
- }
-
- co = f->f_code;
- names = co->co_names;
- consts = co->co_consts;
- fastlocals = f->f_localsplus;
- freevars = f->f_localsplus + co->co_nlocals;
- first_instr = (unsigned char*) PyString_AS_STRING(co->co_code);
- /* 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;
- assert(stack_pointer != NULL);
- f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */
-
-#ifdef LLTRACE
- lltrace = PyDict_GetItemString(f->f_globals, "__lltrace__") != NULL;
-#endif
-#if defined(Py_DEBUG) || defined(LLTRACE)
- filename = PyString_AsString(co->co_filename);
-#endif
-
- why = WHY_NOT;
- err = 0;
- x = Py_None; /* Not a reference, just anything non-NULL */
- w = NULL;
-
- if (throwflag) { /* support for generator.throw() */
- why = WHY_EXCEPTION;
- goto on_error;
- }
-
- for (;;) {
-#ifdef WITH_TSC
- if (inst1 == 0) {
- /* Almost surely, the opcode executed a break
- or a continue, preventing inst1 from being set
- on the way out of the loop.
- */
- READ_TIMESTAMP(inst1);
- loop1 = inst1;
- }
- dump_tsc(opcode, ticked, inst0, inst1, loop0, loop1,
- intr0, intr1);
- ticked = 0;
- inst1 = 0;
- intr0 = 0;
- intr1 = 0;
- READ_TIMESTAMP(loop0);
-#endif
- assert(stack_pointer >= f->f_valuestack); /* else underflow */
- assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */
-
- /* 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) {
- if (*next_instr == SETUP_FINALLY) {
- /* Make the last opcode before
- a try: finally: block uninterruptable. */
- goto fast_next_opcode;
- }
- _Py_Ticker = _Py_CheckInterval;
- tstate->tick_counter++;
-#ifdef WITH_TSC
- ticked = 1;
-#endif
- if (things_to_do) {
- if (Py_MakePendingCalls() < 0) {
- why = WHY_EXCEPTION;
- goto on_error;
- }
- if (things_to_do)
- /* MakePendingCalls() didn't succeed.
- Force early re-execution of this
- "periodic" code, possibly after
- a thread switch */
- _Py_Ticker = 0;
- }
-#ifdef WITH_THREAD
- if (interpreter_lock) {
- /* Give another thread a chance */
-
- if (PyThreadState_Swap(NULL) != tstate)
- Py_FatalError("ceval: tstate mix-up");
- PyThread_release_lock(interpreter_lock);
-
- /* Other threads may run now */
-
- PyThread_acquire_lock(interpreter_lock, 1);
- if (PyThreadState_Swap(tstate) != NULL)
- Py_FatalError("ceval: orphan tstate");
-
- /* Check for thread interrupts */
-
- if (tstate->async_exc != NULL) {
- x = tstate->async_exc;
- tstate->async_exc = NULL;
- PyErr_SetNone(x);
- Py_DECREF(x);
- why = WHY_EXCEPTION;
- goto on_error;
- }
- }
-#endif
- }
-
- fast_next_opcode:
- f->f_lasti = INSTR_OFFSET();
-
- /* line-by-line tracing support */
-
- if (tstate->c_tracefunc != NULL && !tstate->tracing) {
- /* see maybe_call_line_trace
- for expository comments */
- f->f_stacktop = stack_pointer;
-
- err = maybe_call_line_trace(tstate->c_tracefunc,
- tstate->c_traceobj,
- f, &instr_lb, &instr_ub,
- &instr_prev);
- /* Reload possibly changed frame fields */
- JUMPTO(f->f_lasti);
- if (f->f_stacktop != NULL) {
- stack_pointer = f->f_stacktop;
- f->f_stacktop = NULL;
- }
- if (err) {
- /* trace function raised an exception */
- goto on_error;
- }
- }
-
- /* Extract opcode and argument */
-
- opcode = NEXTOP();
- oparg = 0; /* allows oparg to be stored in a register because
- it doesn't have to be remembered across a full loop */
- if (HAS_ARG(opcode))
- oparg = NEXTARG();
- dispatch_opcode:
-#ifdef DYNAMIC_EXECUTION_PROFILE
-#ifdef DXPAIRS
- dxpairs[lastopcode][opcode]++;
- lastopcode = opcode;
-#endif
- dxp[opcode]++;
-#endif
-
-#ifdef LLTRACE
- /* Instruction tracing */
-
- if (lltrace) {
- if (HAS_ARG(opcode)) {
- printf("%d: %d, %d\n",
- f->f_lasti, opcode, oparg);
- }
- else {
- printf("%d: %d\n",
- f->f_lasti, opcode);
- }
- }
-#endif
-
- /* Main switch on opcode */
- READ_TIMESTAMP(inst0);
-
- 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 NOP:
- goto fast_next_opcode;
-
- case LOAD_FAST:
- x = GETLOCAL(oparg);
- if (x != NULL) {
- Py_INCREF(x);
- PUSH(x);
- goto fast_next_opcode;
- }
- format_exc_check_arg(PyExc_UnboundLocalError,
- UNBOUNDLOCAL_ERROR_MSG,
- PyTuple_GetItem(co->co_varnames, oparg));
- break;
-
- case LOAD_CONST:
- x = GETITEM(consts, oparg);
- Py_INCREF(x);
- PUSH(x);
- goto fast_next_opcode;
-
- PREDICTED_WITH_ARG(STORE_FAST);
- case STORE_FAST:
- v = POP();
- SETLOCAL(oparg, v);
- goto fast_next_opcode;
-
- PREDICTED(POP_TOP);
- case POP_TOP:
- v = POP();
- Py_DECREF(v);
- goto fast_next_opcode;
-
- case ROT_TWO:
- v = TOP();
- w = SECOND();
- SET_TOP(w);
- SET_SECOND(v);
- goto fast_next_opcode;
-
- case ROT_THREE:
- v = TOP();
- w = SECOND();
- x = THIRD();
- SET_TOP(w);
- SET_SECOND(x);
- SET_THIRD(v);
- goto fast_next_opcode;
-
- case ROT_FOUR:
- u = TOP();
- v = SECOND();
- w = THIRD();
- x = FOURTH();
- SET_TOP(v);
- SET_SECOND(w);
- SET_THIRD(x);
- SET_FOURTH(u);
- goto fast_next_opcode;
-
- case DUP_TOP:
- v = TOP();
- Py_INCREF(v);
- PUSH(v);
- goto fast_next_opcode;
-
- case DUP_TOPX:
- if (oparg == 2) {
- x = TOP();
- Py_INCREF(x);
- w = SECOND();
- Py_INCREF(w);
- STACKADJ(2);
- SET_TOP(x);
- SET_SECOND(w);
- goto fast_next_opcode;
- } else if (oparg == 3) {
- x = TOP();
- Py_INCREF(x);
- w = SECOND();
- Py_INCREF(w);
- v = THIRD();
- Py_INCREF(v);
- STACKADJ(3);
- SET_TOP(x);
- SET_SECOND(w);
- SET_THIRD(v);
- goto fast_next_opcode;
- }
- Py_FatalError("invalid argument to DUP_TOPX"
- " (bytecode corruption?)");
- break;
-
- case UNARY_POSITIVE:
- v = TOP();
- x = PyNumber_Positive(v);
- Py_DECREF(v);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case UNARY_NEGATIVE:
- v = TOP();
- x = PyNumber_Negative(v);
- Py_DECREF(v);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- 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 UNARY_CONVERT:
- v = TOP();
- x = PyObject_Repr(v);
- Py_DECREF(v);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case UNARY_INVERT:
- v = TOP();
- x = PyNumber_Invert(v);
- Py_DECREF(v);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case BINARY_POWER:
- w = POP();
- v = TOP();
- x = PyNumber_Power(v, w, Py_None);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case BINARY_MULTIPLY:
- w = POP();
- v = TOP();
- x = PyNumber_Multiply(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case BINARY_DIVIDE:
- if (!_Py_QnewFlag) {
- w = POP();
- v = TOP();
- x = PyNumber_Divide(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
- }
- /* -Qnew is in effect: fall through to
- BINARY_TRUE_DIVIDE */
- case BINARY_TRUE_DIVIDE:
- w = POP();
- v = TOP();
- x = PyNumber_TrueDivide(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case BINARY_FLOOR_DIVIDE:
- w = POP();
- v = TOP();
- x = PyNumber_FloorDivide(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- 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 if (PyString_CheckExact(v) &&
- PyString_CheckExact(w)) {
- x = string_concatenate(v, w, f, next_instr);
- /* string_concatenate consumed the ref to v */
- goto skip_decref_vx;
- }
- else {
- slow_add:
- x = PyNumber_Add(v, w);
- }
- Py_DECREF(v);
- skip_decref_vx:
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case BINARY_SUBTRACT:
- 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_sub;
- x = PyInt_FromLong(i);
- }
- else {
- slow_sub:
- x = PyNumber_Subtract(v, w);
- }
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case BINARY_SUBSCR:
- w = POP();
- v = TOP();
- if (PyList_CheckExact(v) && PyInt_CheckExact(w)) {
- /* INLINE: list[int] */
- Py_ssize_t i = PyInt_AsSsize_t(w);
- if (i < 0)
- i += PyList_GET_SIZE(v);
- if (i >= 0 && i < PyList_GET_SIZE(v)) {
- x = PyList_GET_ITEM(v, i);
- Py_INCREF(x);
- }
- else
- goto slow_get;
- }
- else
- slow_get:
- x = PyObject_GetItem(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case BINARY_LSHIFT:
- w = POP();
- v = TOP();
- x = PyNumber_Lshift(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case BINARY_RSHIFT:
- w = POP();
- v = TOP();
- x = PyNumber_Rshift(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 BINARY_XOR:
- w = POP();
- v = TOP();
- x = PyNumber_Xor(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case BINARY_OR:
- w = POP();
- v = TOP();
- x = PyNumber_Or(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case LIST_APPEND:
- w = POP();
- v = POP();
- err = PyList_Append(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- if (err == 0) {
- PREDICT(JUMP_ABSOLUTE);
- continue;
- }
- break;
-
- case INPLACE_POWER:
- w = POP();
- v = TOP();
- x = PyNumber_InPlacePower(v, w, Py_None);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case INPLACE_MULTIPLY:
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceMultiply(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case INPLACE_DIVIDE:
- if (!_Py_QnewFlag) {
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceDivide(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
- }
- /* -Qnew is in effect: fall through to
- INPLACE_TRUE_DIVIDE */
- case INPLACE_TRUE_DIVIDE:
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceTrueDivide(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case INPLACE_FLOOR_DIVIDE:
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceFloorDivide(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case INPLACE_MODULO:
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceRemainder(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case INPLACE_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_iadd;
- x = PyInt_FromLong(i);
- }
- else if (PyString_CheckExact(v) &&
- PyString_CheckExact(w)) {
- x = string_concatenate(v, w, f, next_instr);
- /* string_concatenate consumed the ref to v */
- goto skip_decref_v;
- }
- else {
- slow_iadd:
- x = PyNumber_InPlaceAdd(v, w);
- }
- Py_DECREF(v);
- skip_decref_v:
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case INPLACE_SUBTRACT:
- 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_isub;
- x = PyInt_FromLong(i);
- }
- else {
- slow_isub:
- x = PyNumber_InPlaceSubtract(v, w);
- }
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case INPLACE_LSHIFT:
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceLshift(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case INPLACE_RSHIFT:
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceRshift(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case INPLACE_AND:
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceAnd(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case INPLACE_XOR:
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceXor(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case INPLACE_OR:
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceOr(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case SLICE+0:
- case SLICE+1:
- case SLICE+2:
- case SLICE+3:
- if ((opcode-SLICE) & 2)
- w = POP();
- else
- w = NULL;
- if ((opcode-SLICE) & 1)
- v = POP();
- else
- v = NULL;
- u = TOP();
- x = apply_slice(u, v, w);
- Py_DECREF(u);
- Py_XDECREF(v);
- Py_XDECREF(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 DELETE_SLICE+0:
- case DELETE_SLICE+1:
- case DELETE_SLICE+2:
- case DELETE_SLICE+3:
- if ((opcode-DELETE_SLICE) & 2)
- w = POP();
- else
- w = NULL;
- if ((opcode-DELETE_SLICE) & 1)
- v = POP();
- else
- v = NULL;
- u = POP();
- err = assign_slice(u, v, w, (PyObject *)NULL);
- /* del u[v:w] */
- Py_DECREF(u);
- Py_XDECREF(v);
- Py_XDECREF(w);
- if (err == 0) continue;
- break;
-
- case STORE_SUBSCR:
- w = TOP();
- v = SECOND();
- u = THIRD();
- STACKADJ(-3);
- /* v[w] = u */
- err = PyObject_SetItem(v, w, u);
- Py_DECREF(u);
- Py_DECREF(v);
- Py_DECREF(w);
- if (err == 0) continue;
- break;
-
- case DELETE_SUBSCR:
- w = TOP();
- v = SECOND();
- STACKADJ(-2);
- /* del v[w] */
- err = PyObject_DelItem(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- if (err == 0) continue;
- break;
-
- case PRINT_EXPR:
- v = POP();
- w = PySys_GetObject("displayhook");
- if (w == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "lost sys.displayhook");
- err = -1;
- x = NULL;
- }
- if (err == 0) {
- x = PyTuple_Pack(1, v);
- if (x == NULL)
- err = -1;
- }
- if (err == 0) {
- w = PyEval_CallObject(w, x);
- Py_XDECREF(w);
- if (w == NULL)
- err = -1;
- }
- Py_DECREF(v);
- Py_XDECREF(x);
- break;
-
- case PRINT_ITEM_TO:
- w = stream = POP();
- /* fall through to PRINT_ITEM */
-
- case PRINT_ITEM:
- v = POP();
- if (stream == NULL || stream == Py_None) {
- w = PySys_GetObject("stdout");
- if (w == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "lost sys.stdout");
- err = -1;
- }
- }
- /* PyFile_SoftSpace() can exececute arbitrary code
- if sys.stdout is an instance with a __getattr__.
- If __getattr__ raises an exception, w will
- be freed, so we need to prevent that temporarily. */
- Py_XINCREF(w);
- if (w != NULL && PyFile_SoftSpace(w, 0))
- err = PyFile_WriteString(" ", w);
- if (err == 0)
- err = PyFile_WriteObject(v, w, Py_PRINT_RAW);
- if (err == 0) {
- /* XXX move into writeobject() ? */
- if (PyString_Check(v)) {
- char *s = PyString_AS_STRING(v);
- Py_ssize_t len = PyString_GET_SIZE(v);
- if (len == 0 ||
- !isspace(Py_CHARMASK(s[len-1])) ||
- s[len-1] == ' ')
- PyFile_SoftSpace(w, 1);
- }
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(v)) {
- Py_UNICODE *s = PyUnicode_AS_UNICODE(v);
- Py_ssize_t len = PyUnicode_GET_SIZE(v);
- if (len == 0 ||
- !Py_UNICODE_ISSPACE(s[len-1]) ||
- s[len-1] == ' ')
- PyFile_SoftSpace(w, 1);
- }
-#endif
- else
- PyFile_SoftSpace(w, 1);
- }
- Py_XDECREF(w);
- Py_DECREF(v);
- Py_XDECREF(stream);
- stream = NULL;
- if (err == 0)
- continue;
- break;
-
- case PRINT_NEWLINE_TO:
- w = stream = POP();
- /* fall through to PRINT_NEWLINE */
-
- case PRINT_NEWLINE:
- if (stream == NULL || stream == Py_None) {
- w = PySys_GetObject("stdout");
- if (w == NULL)
- PyErr_SetString(PyExc_RuntimeError,
- "lost sys.stdout");
- }
- if (w != NULL) {
- err = PyFile_WriteString("\n", w);
- if (err == 0)
- PyFile_SoftSpace(w, 0);
- }
- Py_XDECREF(stream);
- stream = NULL;
- break;
-
-
-#ifdef CASE_TOO_BIG
- default: switch (opcode) {
-#endif
- case RAISE_VARARGS:
- u = v = w = NULL;
- switch (oparg) {
- case 3:
- u = POP(); /* traceback */
- /* Fallthrough */
- case 2:
- v = POP(); /* value */
- /* Fallthrough */
- case 1:
- w = POP(); /* exc */
- case 0: /* Fallthrough */
- why = do_raise(w, v, u);
- break;
- default:
- PyErr_SetString(PyExc_SystemError,
- "bad RAISE_VARARGS oparg");
- why = WHY_EXCEPTION;
- break;
- }
- break;
-
- case LOAD_LOCALS:
- if ((x = f->f_locals) != NULL) {
- Py_INCREF(x);
- PUSH(x);
- continue;
- }
- PyErr_SetString(PyExc_SystemError, "no locals");
- break;
-
- case RETURN_VALUE:
- retval = POP();
- why = WHY_RETURN;
- goto fast_block_end;
-
- case YIELD_VALUE:
- retval = POP();
- f->f_stacktop = stack_pointer;
- why = WHY_YIELD;
- goto fast_yield;
-
- case EXEC_STMT:
- w = TOP();
- v = SECOND();
- u = THIRD();
- STACKADJ(-3);
- READ_TIMESTAMP(intr0);
- err = exec_statement(f, u, v, w);
- READ_TIMESTAMP(intr1);
- Py_DECREF(u);
- Py_DECREF(v);
- Py_DECREF(w);
- break;
-
- case POP_BLOCK:
- {
- PyTryBlock *b = PyFrame_BlockPop(f);
- while (STACK_LEVEL() > b->b_level) {
- v = POP();
- Py_DECREF(v);
- }
- }
- continue;
-
- case END_FINALLY:
- v = POP();
- if (PyInt_Check(v)) {
- why = (enum why_code) PyInt_AS_LONG(v);
- assert(why != WHY_YIELD);
- if (why == WHY_RETURN ||
- why == WHY_CONTINUE)
- retval = POP();
- }
- else if (PyExceptionClass_Check(v) || PyString_Check(v)) {
- w = POP();
- u = POP();
- PyErr_Restore(v, w, u);
- why = WHY_RERAISE;
- break;
- }
- else if (v != Py_None) {
- PyErr_SetString(PyExc_SystemError,
- "'finally' pops bad exception");
- why = WHY_EXCEPTION;
- }
- Py_DECREF(v);
- break;
-
- case BUILD_CLASS:
- u = TOP();
- v = SECOND();
- w = THIRD();
- STACKADJ(-2);
- x = build_class(u, v, w);
- SET_TOP(x);
- Py_DECREF(u);
- Py_DECREF(v);
- Py_DECREF(w);
- break;
-
- case STORE_NAME:
- w = GETITEM(names, oparg);
- v = POP();
- if ((x = f->f_locals) != NULL) {
- if (PyDict_CheckExact(x))
- err = PyDict_SetItem(x, w, v);
- else
- err = PyObject_SetItem(x, w, v);
- Py_DECREF(v);
- if (err == 0) continue;
- break;
- }
- PyErr_Format(PyExc_SystemError,
- "no locals found when storing %s",
- PyObject_REPR(w));
- break;
-
- case DELETE_NAME:
- w = GETITEM(names, oparg);
- if ((x = f->f_locals) != NULL) {
- if ((err = PyObject_DelItem(x, w)) != 0)
- format_exc_check_arg(PyExc_NameError,
- NAME_ERROR_MSG ,w);
- break;
- }
- PyErr_Format(PyExc_SystemError,
- "no locals when deleting %s",
- PyObject_REPR(w));
- break;
-
- PREDICTED_WITH_ARG(UNPACK_SEQUENCE);
- case UNPACK_SEQUENCE:
- v = POP();
- if (PyTuple_CheckExact(v) && PyTuple_GET_SIZE(v) == oparg) {
- PyObject **items = ((PyTupleObject *)v)->ob_item;
- while (oparg--) {
- w = items[oparg];
- Py_INCREF(w);
- PUSH(w);
- }
- Py_DECREF(v);
- continue;
- } else if (PyList_CheckExact(v) && PyList_GET_SIZE(v) == oparg) {
- PyObject **items = ((PyListObject *)v)->ob_item;
- while (oparg--) {
- w = items[oparg];
- Py_INCREF(w);
- PUSH(w);
- }
- } else if (unpack_iterable(v, oparg,
- stack_pointer + oparg)) {
- stack_pointer += oparg;
- } else {
- /* unpack_iterable() raised an exception */
- why = WHY_EXCEPTION;
- }
- Py_DECREF(v);
- break;
-
- case STORE_ATTR:
- w = GETITEM(names, oparg);
- v = TOP();
- u = SECOND();
- STACKADJ(-2);
- err = PyObject_SetAttr(v, w, u); /* v.w = u */
- Py_DECREF(v);
- Py_DECREF(u);
- if (err == 0) continue;
- break;
-
- case DELETE_ATTR:
- w = GETITEM(names, oparg);
- v = POP();
- err = PyObject_SetAttr(v, w, (PyObject *)NULL);
- /* del v.w */
- Py_DECREF(v);
- break;
-
- case STORE_GLOBAL:
- w = GETITEM(names, oparg);
- v = POP();
- err = PyDict_SetItem(f->f_globals, w, v);
- Py_DECREF(v);
- if (err == 0) continue;
- break;
-
- case DELETE_GLOBAL:
- w = GETITEM(names, oparg);
- if ((err = PyDict_DelItem(f->f_globals, w)) != 0)
- format_exc_check_arg(
- PyExc_NameError, GLOBAL_NAME_ERROR_MSG, w);
- break;
-
- case LOAD_NAME:
- w = GETITEM(names, oparg);
- if ((v = f->f_locals) == NULL) {
- PyErr_Format(PyExc_SystemError,
- "no locals when loading %s",
- PyObject_REPR(w));
- break;
- }
- if (PyDict_CheckExact(v)) {
- x = PyDict_GetItem(v, w);
- Py_XINCREF(x);
- }
- else {
- x = PyObject_GetItem(v, w);
- if (x == NULL && PyErr_Occurred()) {
- if (!PyErr_ExceptionMatches(PyExc_KeyError))
- break;
- PyErr_Clear();
- }
- }
- if (x == NULL) {
- x = PyDict_GetItem(f->f_globals, w);
- if (x == NULL) {
- x = PyDict_GetItem(f->f_builtins, w);
- if (x == NULL) {
- format_exc_check_arg(
- PyExc_NameError,
- NAME_ERROR_MSG ,w);
- break;
- }
- }
- Py_INCREF(x);
- }
- PUSH(x);
- continue;
-
- 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;
- PyDictEntry *e;
- d = (PyDictObject *)(f->f_globals);
- e = d->ma_lookup(d, w, hash);
- if (e == NULL) {
- x = NULL;
- break;
- }
- x = e->me_value;
- if (x != NULL) {
- Py_INCREF(x);
- PUSH(x);
- continue;
- }
- d = (PyDictObject *)(f->f_builtins);
- e = d->ma_lookup(d, w, hash);
- if (e == NULL) {
- x = NULL;
- break;
- }
- x = e->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:
- format_exc_check_arg(
- PyExc_NameError,
- GLOBAL_NAME_ERROR_MSG, w);
- break;
- }
- }
- Py_INCREF(x);
- PUSH(x);
- continue;
-
- case DELETE_FAST:
- x = GETLOCAL(oparg);
- if (x != NULL) {
- SETLOCAL(oparg, NULL);
- continue;
- }
- format_exc_check_arg(
- PyExc_UnboundLocalError,
- UNBOUNDLOCAL_ERROR_MSG,
- PyTuple_GetItem(co->co_varnames, oparg)
- );
- break;
-
- case LOAD_CLOSURE:
- x = freevars[oparg];
- Py_INCREF(x);
- PUSH(x);
- if (x != NULL) continue;
- break;
-
- case LOAD_DEREF:
- x = freevars[oparg];
- w = PyCell_Get(x);
- if (w != NULL) {
- PUSH(w);
- continue;
- }
- err = -1;
- /* Don't stomp existing exception */
- if (PyErr_Occurred())
- break;
- if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) {
- v = PyTuple_GET_ITEM(co->co_cellvars,
- oparg);
- format_exc_check_arg(
- PyExc_UnboundLocalError,
- UNBOUNDLOCAL_ERROR_MSG,
- v);
- } else {
- v = PyTuple_GET_ITEM(
- co->co_freevars,
- oparg - PyTuple_GET_SIZE(co->co_cellvars));
- format_exc_check_arg(
- PyExc_NameError,
- UNBOUNDFREE_ERROR_MSG,
- v);
- }
- break;
-
- case STORE_DEREF:
- w = POP();
- x = freevars[oparg];
- PyCell_Set(x, w);
- Py_DECREF(w);
- continue;
-
- case BUILD_TUPLE:
- x = PyTuple_New(oparg);
- if (x != NULL) {
- for (; --oparg >= 0;) {
- w = POP();
- PyTuple_SET_ITEM(x, oparg, w);
- }
- PUSH(x);
- continue;
- }
- break;
-
- case BUILD_LIST:
- x = PyList_New(oparg);
- if (x != NULL) {
- for (; --oparg >= 0;) {
- w = POP();
- PyList_SET_ITEM(x, oparg, w);
- }
- PUSH(x);
- continue;
- }
- break;
-
- case BUILD_MAP:
- x = PyDict_New();
- PUSH(x);
- if (x != NULL) continue;
- 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 COMPARE_OP:
- w = POP();
- v = TOP();
- if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) {
- /* INLINE: cmp(int, int) */
- register long a, b;
- register int res;
- a = PyInt_AS_LONG(v);
- b = PyInt_AS_LONG(w);
- switch (oparg) {
- case PyCmp_LT: res = a < b; break;
- case PyCmp_LE: res = a <= b; break;
- case PyCmp_EQ: res = a == b; break;
- case PyCmp_NE: res = a != b; break;
- case PyCmp_GT: res = a > b; break;
- case PyCmp_GE: res = a >= b; break;
- case PyCmp_IS: res = v == w; break;
- case PyCmp_IS_NOT: res = v != w; break;
- default: goto slow_compare;
- }
- x = res ? Py_True : Py_False;
- Py_INCREF(x);
- }
- else {
- slow_compare:
- x = cmp_outcome(oparg, v, w);
- }
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x == NULL) break;
- PREDICT(JUMP_IF_FALSE);
- PREDICT(JUMP_IF_TRUE);
- continue;
-
- case IMPORT_NAME:
- w = GETITEM(names, oparg);
- x = PyDict_GetItemString(f->f_builtins, "__import__");
- if (x == NULL) {
- PyErr_SetString(PyExc_ImportError,
- "__import__ not found");
- break;
- }
- v = POP();
- u = TOP();
- if (PyInt_AsLong(u) != -1 || PyErr_Occurred())
- w = PyTuple_Pack(5,
- w,
- f->f_globals,
- f->f_locals == NULL ?
- Py_None : f->f_locals,
- v,
- u);
- else
- w = PyTuple_Pack(4,
- w,
- f->f_globals,
- f->f_locals == NULL ?
- Py_None : f->f_locals,
- v);
- Py_DECREF(v);
- Py_DECREF(u);
- if (w == NULL) {
- u = POP();
- x = NULL;
- break;
- }
- READ_TIMESTAMP(intr0);
- x = PyEval_CallObject(x, w);
- READ_TIMESTAMP(intr1);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case IMPORT_STAR:
- v = POP();
- PyFrame_FastToLocals(f);
- if ((x = f->f_locals) == NULL) {
- PyErr_SetString(PyExc_SystemError,
- "no locals found during 'import *'");
- break;
- }
- READ_TIMESTAMP(intr0);
- err = import_all_from(x, v);
- READ_TIMESTAMP(intr1);
- PyFrame_LocalsToFast(f, 0);
- Py_DECREF(v);
- if (err == 0) continue;
- break;
-
- case IMPORT_FROM:
- w = GETITEM(names, oparg);
- v = TOP();
- READ_TIMESTAMP(intr0);
- x = import_from(v, w);
- READ_TIMESTAMP(intr1);
- PUSH(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;
-
- PREDICTED_WITH_ARG(JUMP_IF_TRUE);
- case JUMP_IF_TRUE:
- w = TOP();
- if (w == Py_False) {
- PREDICT(POP_TOP);
- goto fast_next_opcode;
- }
- if (w == Py_True) {
- JUMPBY(oparg);
- goto fast_next_opcode;
- }
- err = PyObject_IsTrue(w);
- if (err > 0) {
- err = 0;
- JUMPBY(oparg);
- }
- else if (err == 0)
- ;
- else
- break;
- continue;
-
- PREDICTED_WITH_ARG(JUMP_ABSOLUTE);
- case JUMP_ABSOLUTE:
- JUMPTO(oparg);
- continue;
-
- case GET_ITER:
- /* before: [obj]; after [getiter(obj)] */
- v = TOP();
- x = PyObject_GetIter(v);
- Py_DECREF(v);
- if (x != NULL) {
- SET_TOP(x);
- PREDICT(FOR_ITER);
- continue;
- }
- STACKADJ(-1);
- break;
-
- PREDICTED_WITH_ARG(FOR_ITER);
- case FOR_ITER:
- /* before: [iter]; after: [iter, iter()] *or* [] */
- v = TOP();
- x = (*v->ob_type->tp_iternext)(v);
- if (x != NULL) {
- PUSH(x);
- PREDICT(STORE_FAST);
- PREDICT(UNPACK_SEQUENCE);
- continue;
- }
- if (PyErr_Occurred()) {
- if (!PyErr_ExceptionMatches(PyExc_StopIteration))
- break;
- PyErr_Clear();
- }
- /* iterator ended normally */
- x = v = POP();
- Py_DECREF(v);
- JUMPBY(oparg);
- continue;
-
- case BREAK_LOOP:
- why = WHY_BREAK;
- goto fast_block_end;
-
- case CONTINUE_LOOP:
- retval = PyInt_FromLong(oparg);
- if (!retval) {
- x = NULL;
- break;
- }
- why = WHY_CONTINUE;
- goto fast_block_end;
-
- case SETUP_LOOP:
- case SETUP_EXCEPT:
- case SETUP_FINALLY:
- /* NOTE: If you add any new block-setup opcodes that are not try/except/finally
- handlers, you may need to update the PyGen_NeedsFinalizing() function. */
-
- PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg,
- STACK_LEVEL());
- continue;
-
- case WITH_CLEANUP:
- {
- /* TOP is the context.__exit__ bound method.
- Below that are 1-3 values indicating how/why
- we entered the finally clause:
- - SECOND = None
- - (SECOND, THIRD) = (WHY_{RETURN,CONTINUE}), retval
- - SECOND = WHY_*; no retval below it
- - (SECOND, THIRD, FOURTH) = exc_info()
- In the last case, we must call
- TOP(SECOND, THIRD, FOURTH)
- otherwise we must call
- TOP(None, None, None)
-
- In addition, if the stack represents an exception,
- *and* the function call returns a 'true' value, we
- "zap" this information, to prevent END_FINALLY from
- re-raising the exception. (But non-local gotos
- should still be resumed.)
- */
-
- x = TOP();
- u = SECOND();
- if (PyInt_Check(u) || u == Py_None) {
- u = v = w = Py_None;
- }
- else {
- v = THIRD();
- w = FOURTH();
- }
- /* XXX Not the fastest way to call it... */
- x = PyObject_CallFunctionObjArgs(x, u, v, w, NULL);
- if (x == NULL)
- break; /* Go to error exit */
- if (u != Py_None && PyObject_IsTrue(x)) {
- /* There was an exception and a true return */
- Py_DECREF(x);
- x = TOP(); /* Again */
- STACKADJ(-3);
- Py_INCREF(Py_None);
- SET_TOP(Py_None);
- Py_DECREF(x);
- Py_DECREF(u);
- Py_DECREF(v);
- Py_DECREF(w);
- } else {
- /* Let END_FINALLY do its thing */
- Py_DECREF(x);
- x = POP();
- Py_DECREF(x);
- }
- break;
- }
-
- case CALL_FUNCTION:
- {
- PyObject **sp;
- PCALL(PCALL_ALL);
- sp = stack_pointer;
-#ifdef WITH_TSC
- x = call_function(&sp, oparg, &intr0, &intr1);
-#else
- x = call_function(&sp, oparg);
-#endif
- stack_pointer = sp;
- PUSH(x);
- if (x != NULL)
- continue;
- break;
- }
-
- case CALL_FUNCTION_VAR:
- case CALL_FUNCTION_KW:
- case CALL_FUNCTION_VAR_KW:
- {
- int na = oparg & 0xff;
- int nk = (oparg>>8) & 0xff;
- int flags = (opcode - CALL_FUNCTION) & 3;
- int n = na + 2 * nk;
- PyObject **pfunc, *func, **sp;
- PCALL(PCALL_ALL);
- if (flags & CALL_FLAG_VAR)
- n++;
- if (flags & CALL_FLAG_KW)
- n++;
- pfunc = stack_pointer - n - 1;
- func = *pfunc;
-
- if (PyMethod_Check(func)
- && PyMethod_GET_SELF(func) != NULL) {
- PyObject *self = PyMethod_GET_SELF(func);
- Py_INCREF(self);
- func = PyMethod_GET_FUNCTION(func);
- Py_INCREF(func);
- Py_DECREF(*pfunc);
- *pfunc = self;
- na++;
- n++;
- } else
- Py_INCREF(func);
- sp = stack_pointer;
- READ_TIMESTAMP(intr0);
- x = ext_do_call(func, &sp, flags, na, nk);
- READ_TIMESTAMP(intr1);
- stack_pointer = sp;
- Py_DECREF(func);
-
- while (stack_pointer > pfunc) {
- w = POP();
- Py_DECREF(w);
- }
- 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 MAKE_CLOSURE:
- {
- v = POP(); /* code object */
- x = PyFunction_New(v, f->f_globals);
- Py_DECREF(v);
- if (x != NULL) {
- v = POP();
- err = PyFunction_SetClosure(x, v);
- Py_DECREF(v);
- }
- 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 BUILD_SLICE:
- if (oparg == 3)
- w = POP();
- else
- w = NULL;
- v = POP();
- u = TOP();
- x = PySlice_New(u, v, w);
- Py_DECREF(u);
- Py_DECREF(v);
- Py_XDECREF(w);
- SET_TOP(x);
- if (x != NULL) continue;
- break;
-
- case EXTENDED_ARG:
- opcode = NEXTOP();
- oparg = oparg<<16 | NEXTARG();
- goto dispatch_opcode;
-
- default:
- fprintf(stderr,
- "XXX lineno: %d, opcode: %d\n",
- PyCode_Addr2Line(f->f_code, f->f_lasti),
- opcode);
- PyErr_SetString(PyExc_SystemError, "unknown opcode");
- why = WHY_EXCEPTION;
- break;
-
-#ifdef CASE_TOO_BIG
- }
-#endif
-
- } /* switch */
-
- on_error:
-
- READ_TIMESTAMP(inst1);
-
- /* Quickly continue if no error occurred */
-
- if (why == WHY_NOT) {
- if (err == 0 && x != NULL) {
-#ifdef CHECKEXC
- /* This check is expensive! */
- if (PyErr_Occurred())
- fprintf(stderr,
- "XXX undetected error\n");
- else {
-#endif
- READ_TIMESTAMP(loop1);
- continue; /* Normal, fast path */
-#ifdef CHECKEXC
- }
-#endif
- }
- why = WHY_EXCEPTION;
- x = Py_None;
- err = 0;
- }
-
- /* Double-check exception status */
-
- if (why == WHY_EXCEPTION || why == WHY_RERAISE) {
- if (!PyErr_Occurred()) {
- PyErr_SetString(PyExc_SystemError,
- "error return without exception set");
- why = WHY_EXCEPTION;
- }
- }
-#ifdef CHECKEXC
- else {
- /* This check is expensive! */
- if (PyErr_Occurred()) {
- char buf[1024];
- sprintf(buf, "Stack unwind with exception "
- "set and why=%d", why);
- Py_FatalError(buf);
- }
- }
-#endif
-
- /* Log traceback info if this is a real exception */
-
- if (why == WHY_EXCEPTION) {
- PyTraceBack_Here(f);
-
- if (tstate->c_tracefunc != NULL)
- call_exc_trace(tstate->c_tracefunc,
- tstate->c_traceobj, f);
- }
-
- /* For the rest, treat WHY_RERAISE as WHY_EXCEPTION */
-
- if (why == WHY_RERAISE)
- why = WHY_EXCEPTION;
-
- /* Unwind stacks if a (pseudo) exception occurred */
-
-fast_block_end:
- while (why != WHY_NOT && f->f_iblock > 0) {
- PyTryBlock *b = PyFrame_BlockPop(f);
-
- assert(why != WHY_YIELD);
- if (b->b_type == SETUP_LOOP && why == WHY_CONTINUE) {
- /* For a continue inside a try block,
- don't pop the block for the loop. */
- PyFrame_BlockSetup(f, b->b_type, b->b_handler,
- b->b_level);
- why = WHY_NOT;
- JUMPTO(PyInt_AS_LONG(retval));
- Py_DECREF(retval);
- break;
- }
-
- while (STACK_LEVEL() > b->b_level) {
- v = POP();
- Py_XDECREF(v);
- }
- if (b->b_type == SETUP_LOOP && why == WHY_BREAK) {
- why = WHY_NOT;
- JUMPTO(b->b_handler);
- break;
- }
- if (b->b_type == SETUP_FINALLY ||
- (b->b_type == SETUP_EXCEPT &&
- why == WHY_EXCEPTION)) {
- if (why == WHY_EXCEPTION) {
- PyObject *exc, *val, *tb;
- PyErr_Fetch(&exc, &val, &tb);
- if (val == NULL) {
- val = Py_None;
- Py_INCREF(val);
- }
- /* Make the raw exception data
- available to the handler,
- so a program can emulate the
- Python main loop. Don't do
- this for 'finally'. */
- if (b->b_type == SETUP_EXCEPT) {
- PyErr_NormalizeException(
- &exc, &val, &tb);
- set_exc_info(tstate,
- exc, val, tb);
- }
- if (tb == NULL) {
- Py_INCREF(Py_None);
- PUSH(Py_None);
- } else
- PUSH(tb);
- PUSH(val);
- PUSH(exc);
- }
- else {
- if (why & (WHY_RETURN | WHY_CONTINUE))
- PUSH(retval);
- v = PyInt_FromLong((long)why);
- PUSH(v);
- }
- why = WHY_NOT;
- JUMPTO(b->b_handler);
- break;
- }
- } /* unwind stack */
-
- /* End the loop if we still have an error (or return) */
-
- if (why != WHY_NOT)
- break;
- READ_TIMESTAMP(loop1);
-
- } /* main loop */
-
- assert(why != WHY_YIELD);
- /* Pop remaining stack entries. */
- while (!EMPTY()) {
- v = POP();
- Py_XDECREF(v);
- }
-
- if (why != WHY_RETURN)
- retval = NULL;
-
-fast_yield:
- if (tstate->use_tracing) {
- if (tstate->c_tracefunc) {
- if (why == WHY_RETURN || why == WHY_YIELD) {
- if (call_trace(tstate->c_tracefunc,
- tstate->c_traceobj, f,
- PyTrace_RETURN, retval)) {
- Py_XDECREF(retval);
- retval = NULL;
- why = WHY_EXCEPTION;
- }
- }
- else if (why == WHY_EXCEPTION) {
- call_trace_protected(tstate->c_tracefunc,
- tstate->c_traceobj, f,
- PyTrace_RETURN, NULL);
- }
- }
- if (tstate->c_profilefunc) {
- if (why == WHY_EXCEPTION)
- call_trace_protected(tstate->c_profilefunc,
- tstate->c_profileobj, f,
- PyTrace_RETURN, NULL);
- else if (call_trace(tstate->c_profilefunc,
- tstate->c_profileobj, f,
- PyTrace_RETURN, retval)) {
- Py_XDECREF(retval);
- retval = NULL;
- why = WHY_EXCEPTION;
- }
- }
- }
-
- if (tstate->frame->f_exc_type != NULL)
- reset_exc_info(tstate);
- else {
- assert(tstate->frame->f_exc_value == NULL);
- assert(tstate->frame->f_exc_traceback == NULL);
- }
-
- /* pop frame */
- exit_eval_frame:
- Py_LeaveRecursiveCall();
- tstate->frame = f->f_back;
-
- return retval;
-}
-
-/* This is gonna seem *real weird*, but if you put some other code between
- PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust
- the test in the if statements in Misc/gdbinit (pystack and pystackv). */
-
-PyObject *
-PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
- PyObject **args, int argcount, PyObject **kws, int kwcount,
- PyObject **defs, int defcount, PyObject *closure)
-{
- register PyFrameObject *f;
- register PyObject *retval = NULL;
- register PyObject **fastlocals, **freevars;
- PyThreadState *tstate = PyThreadState_GET();
- PyObject *x, *u;
-
- if (globals == NULL) {
- PyErr_SetString(PyExc_SystemError,
- "PyEval_EvalCodeEx: NULL globals");
- return NULL;
- }
-
- assert(tstate != NULL);
- assert(globals != NULL);
- f = PyFrame_New(tstate, co, globals, locals);
- if (f == NULL)
- return NULL;
-
- fastlocals = f->f_localsplus;
- freevars = f->f_localsplus + co->co_nlocals;
-
- if (co->co_argcount > 0 ||
- co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) {
- int i;
- int n = argcount;
- PyObject *kwdict = NULL;
- if (co->co_flags & CO_VARKEYWORDS) {
- kwdict = PyDict_New();
- if (kwdict == NULL)
- goto fail;
- i = co->co_argcount;
- if (co->co_flags & CO_VARARGS)
- i++;
- SETLOCAL(i, kwdict);
- }
- if (argcount > co->co_argcount) {
- if (!(co->co_flags & CO_VARARGS)) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() takes %s %d "
- "%sargument%s (%d given)",
- PyString_AsString(co->co_name),
- defcount ? "at most" : "exactly",
- co->co_argcount,
- kwcount ? "non-keyword " : "",
- co->co_argcount == 1 ? "" : "s",
- argcount);
- goto fail;
- }
- n = co->co_argcount;
- }
- for (i = 0; i < n; i++) {
- x = args[i];
- Py_INCREF(x);
- SETLOCAL(i, x);
- }
- if (co->co_flags & CO_VARARGS) {
- u = PyTuple_New(argcount - n);
- if (u == NULL)
- goto fail;
- SETLOCAL(co->co_argcount, u);
- for (i = n; i < argcount; i++) {
- x = args[i];
- Py_INCREF(x);
- PyTuple_SET_ITEM(u, i-n, x);
- }
- }
- for (i = 0; i < kwcount; i++) {
- PyObject *keyword = kws[2*i];
- PyObject *value = kws[2*i + 1];
- int j;
- if (keyword == NULL || !PyString_Check(keyword)) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() keywords must be strings",
- PyString_AsString(co->co_name));
- goto fail;
- }
- /* XXX slow -- speed up using dictionary? */
- for (j = 0; j < co->co_argcount; j++) {
- PyObject *nm = PyTuple_GET_ITEM(
- co->co_varnames, j);
- int cmp = PyObject_RichCompareBool(
- keyword, nm, Py_EQ);
- if (cmp > 0)
- break;
- else if (cmp < 0)
- goto fail;
- }
- /* Check errors from Compare */
- if (PyErr_Occurred())
- goto fail;
- if (j >= co->co_argcount) {
- if (kwdict == NULL) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() got an unexpected "
- "keyword argument '%.400s'",
- PyString_AsString(co->co_name),
- PyString_AsString(keyword));
- goto fail;
- }
- PyDict_SetItem(kwdict, keyword, value);
- }
- else {
- if (GETLOCAL(j) != NULL) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() got multiple "
- "values for keyword "
- "argument '%.400s'",
- PyString_AsString(co->co_name),
- PyString_AsString(keyword));
- goto fail;
- }
- Py_INCREF(value);
- SETLOCAL(j, value);
- }
- }
- if (argcount < co->co_argcount) {
- int m = co->co_argcount - defcount;
- for (i = argcount; i < m; i++) {
- if (GETLOCAL(i) == NULL) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() takes %s %d "
- "%sargument%s (%d given)",
- PyString_AsString(co->co_name),
- ((co->co_flags & CO_VARARGS) ||
- defcount) ? "at least"
- : "exactly",
- m, kwcount ? "non-keyword " : "",
- m == 1 ? "" : "s", i);
- goto fail;
- }
- }
- if (n > m)
- i = n - m;
- else
- i = 0;
- for (; i < defcount; i++) {
- if (GETLOCAL(m+i) == NULL) {
- PyObject *def = defs[i];
- Py_INCREF(def);
- SETLOCAL(m+i, def);
- }
- }
- }
- }
- else {
- if (argcount > 0 || kwcount > 0) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() takes no arguments (%d given)",
- PyString_AsString(co->co_name),
- argcount + kwcount);
- goto fail;
- }
- }
- /* Allocate and initialize storage for cell vars, and copy free
- vars into frame. This isn't too efficient right now. */
- if (PyTuple_GET_SIZE(co->co_cellvars)) {
- int i, j, nargs, found;
- char *cellname, *argname;
- PyObject *c;
-
- nargs = co->co_argcount;
- if (co->co_flags & CO_VARARGS)
- nargs++;
- if (co->co_flags & CO_VARKEYWORDS)
- nargs++;
-
- /* Initialize each cell var, taking into account
- cell vars that are initialized from arguments.
-
- Should arrange for the compiler to put cellvars
- that are arguments at the beginning of the cellvars
- list so that we can march over it more efficiently?
- */
- for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) {
- cellname = PyString_AS_STRING(
- PyTuple_GET_ITEM(co->co_cellvars, i));
- found = 0;
- for (j = 0; j < nargs; j++) {
- argname = PyString_AS_STRING(
- PyTuple_GET_ITEM(co->co_varnames, j));
- if (strcmp(cellname, argname) == 0) {
- c = PyCell_New(GETLOCAL(j));
- if (c == NULL)
- goto fail;
- GETLOCAL(co->co_nlocals + i) = c;
- found = 1;
- break;
- }
- }
- if (found == 0) {
- c = PyCell_New(NULL);
- if (c == NULL)
- goto fail;
- SETLOCAL(co->co_nlocals + i, c);
- }
- }
- }
- if (PyTuple_GET_SIZE(co->co_freevars)) {
- int i;
- for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
- PyObject *o = PyTuple_GET_ITEM(closure, i);
- Py_INCREF(o);
- freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;
- }
- }
-
- if (co->co_flags & CO_GENERATOR) {
- /* Don't need to keep the reference to f_back, it will be set
- * when the generator is resumed. */
- Py_XDECREF(f->f_back);
- f->f_back = NULL;
-
- PCALL(PCALL_GENERATOR);
-
- /* Create a new generator that owns the ready to run frame
- * and return that as the value. */
- return PyGen_New(f);
- }
-
- retval = PyEval_EvalFrameEx(f,0);
-
- fail: /* Jump here from prelude on failure */
-
- /* decref'ing the frame can cause __del__ methods to get invoked,
- which can call back into Python. While we're done with the
- current Python frame (f), the associated C stack is still in use,
- so recursion_depth must be boosted for the duration.
- */
- assert(tstate != NULL);
- ++tstate->recursion_depth;
- Py_DECREF(f);
- --tstate->recursion_depth;
- return retval;
-}
-
-
-/* Implementation notes for set_exc_info() and reset_exc_info():
-
-- Below, 'exc_ZZZ' stands for 'exc_type', 'exc_value' and
- 'exc_traceback'. These always travel together.
-
-- tstate->curexc_ZZZ is the "hot" exception that is set by
- PyErr_SetString(), cleared by PyErr_Clear(), and so on.
-
-- Once an exception is caught by an except clause, it is transferred
- from tstate->curexc_ZZZ to tstate->exc_ZZZ, from which sys.exc_info()
- can pick it up. This is the primary task of set_exc_info().
- XXX That can't be right: set_exc_info() doesn't look at tstate->curexc_ZZZ.
-
-- Now let me explain the complicated dance with frame->f_exc_ZZZ.
-
- Long ago, when none of this existed, there were just a few globals:
- one set corresponding to the "hot" exception, and one set
- corresponding to sys.exc_ZZZ. (Actually, the latter weren't C
- globals; they were simply stored as sys.exc_ZZZ. For backwards
- compatibility, they still are!) The problem was that in code like
- this:
-
- try:
- "something that may fail"
- except "some exception":
- "do something else first"
- "print the exception from sys.exc_ZZZ."
-
- if "do something else first" invoked something that raised and caught
- an exception, sys.exc_ZZZ were overwritten. That was a frequent
- cause of subtle bugs. I fixed this by changing the semantics as
- follows:
-
- - Within one frame, sys.exc_ZZZ will hold the last exception caught
- *in that frame*.
-
- - But initially, and as long as no exception is caught in a given
- frame, sys.exc_ZZZ will hold the last exception caught in the
- previous frame (or the frame before that, etc.).
-
- The first bullet fixed the bug in the above example. The second
- bullet was for backwards compatibility: it was (and is) common to
- have a function that is called when an exception is caught, and to
- have that function access the caught exception via sys.exc_ZZZ.
- (Example: traceback.print_exc()).
-
- At the same time I fixed the problem that sys.exc_ZZZ weren't
- thread-safe, by introducing sys.exc_info() which gets it from tstate;
- but that's really a separate improvement.
-
- The reset_exc_info() function in ceval.c restores the tstate->exc_ZZZ
- variables to what they were before the current frame was called. The
- set_exc_info() function saves them on the frame so that
- reset_exc_info() can restore them. The invariant is that
- frame->f_exc_ZZZ is NULL iff the current frame never caught an
- exception (where "catching" an exception applies only to successful
- except clauses); and if the current frame ever caught an exception,
- frame->f_exc_ZZZ is the exception that was stored in tstate->exc_ZZZ
- at the start of the current frame.
-
-*/
-
-static void
-set_exc_info(PyThreadState *tstate,
- PyObject *type, PyObject *value, PyObject *tb)
-{
- PyFrameObject *frame = tstate->frame;
- PyObject *tmp_type, *tmp_value, *tmp_tb;
-
- assert(type != NULL);
- assert(frame != NULL);
- if (frame->f_exc_type == NULL) {
- assert(frame->f_exc_value == NULL);
- assert(frame->f_exc_traceback == NULL);
- /* This frame didn't catch an exception before. */
- /* Save previous exception of this thread in this frame. */
- if (tstate->exc_type == NULL) {
- /* XXX Why is this set to Py_None? */
- Py_INCREF(Py_None);
- tstate->exc_type = Py_None;
- }
- Py_INCREF(tstate->exc_type);
- Py_XINCREF(tstate->exc_value);
- Py_XINCREF(tstate->exc_traceback);
- frame->f_exc_type = tstate->exc_type;
- frame->f_exc_value = tstate->exc_value;
- frame->f_exc_traceback = tstate->exc_traceback;
- }
- /* Set new exception for this thread. */
- tmp_type = tstate->exc_type;
- tmp_value = tstate->exc_value;
- tmp_tb = tstate->exc_traceback;
- Py_INCREF(type);
- Py_XINCREF(value);
- Py_XINCREF(tb);
- tstate->exc_type = type;
- tstate->exc_value = value;
- tstate->exc_traceback = tb;
- Py_XDECREF(tmp_type);
- Py_XDECREF(tmp_value);
- Py_XDECREF(tmp_tb);
- /* For b/w compatibility */
- PySys_SetObject("exc_type", type);
- PySys_SetObject("exc_value", value);
- PySys_SetObject("exc_traceback", tb);
-}
-
-static void
-reset_exc_info(PyThreadState *tstate)
-{
- PyFrameObject *frame;
- PyObject *tmp_type, *tmp_value, *tmp_tb;
-
- /* It's a precondition that the thread state's frame caught an
- * exception -- verify in a debug build.
- */
- assert(tstate != NULL);
- frame = tstate->frame;
- assert(frame != NULL);
- assert(frame->f_exc_type != NULL);
-
- /* Copy the frame's exception info back to the thread state. */
- tmp_type = tstate->exc_type;
- tmp_value = tstate->exc_value;
- tmp_tb = tstate->exc_traceback;
- Py_INCREF(frame->f_exc_type);
- Py_XINCREF(frame->f_exc_value);
- Py_XINCREF(frame->f_exc_traceback);
- tstate->exc_type = frame->f_exc_type;
- tstate->exc_value = frame->f_exc_value;
- tstate->exc_traceback = frame->f_exc_traceback;
- Py_XDECREF(tmp_type);
- Py_XDECREF(tmp_value);
- Py_XDECREF(tmp_tb);
-
- /* For b/w compatibility */
- PySys_SetObject("exc_type", frame->f_exc_type);
- PySys_SetObject("exc_value", frame->f_exc_value);
- PySys_SetObject("exc_traceback", frame->f_exc_traceback);
-
- /* Clear the frame's exception info. */
- tmp_type = frame->f_exc_type;
- tmp_value = frame->f_exc_value;
- tmp_tb = frame->f_exc_traceback;
- frame->f_exc_type = NULL;
- frame->f_exc_value = NULL;
- frame->f_exc_traceback = NULL;
- Py_DECREF(tmp_type);
- Py_XDECREF(tmp_value);
- Py_XDECREF(tmp_tb);
-}
-
-/* Logic for the raise statement (too complicated for inlining).
- This *consumes* a reference count to each of its arguments. */
-static enum why_code
-do_raise(PyObject *type, PyObject *value, PyObject *tb)
-{
- if (type == NULL) {
- /* Reraise */
- PyThreadState *tstate = PyThreadState_GET();
- type = tstate->exc_type == NULL ? Py_None : tstate->exc_type;
- value = tstate->exc_value;
- tb = tstate->exc_traceback;
- Py_XINCREF(type);
- Py_XINCREF(value);
- Py_XINCREF(tb);
- }
-
- /* We support the following forms of raise:
- raise <class>, <classinstance>
- raise <class>, <argument tuple>
- raise <class>, None
- raise <class>, <argument>
- raise <classinstance>, None
- raise <string>, <object>
- raise <string>, None
-
- An omitted second argument is the same as None.
-
- In addition, raise <tuple>, <anything> is the same as
- raising the tuple's first item (and it better have one!);
- this rule is applied recursively.
-
- Finally, an optional third argument can be supplied, which
- gives the traceback to be substituted (useful when
- re-raising an exception after examining it). */
-
- /* First, check the traceback argument, replacing None with
- NULL. */
- if (tb == Py_None) {
- Py_DECREF(tb);
- tb = NULL;
- }
- else if (tb != NULL && !PyTraceBack_Check(tb)) {
- PyErr_SetString(PyExc_TypeError,
- "raise: arg 3 must be a traceback or None");
- goto raise_error;
- }
-
- /* Next, replace a missing value with None */
- if (value == NULL) {
- value = Py_None;
- Py_INCREF(value);
- }
-
- /* Next, repeatedly, replace a tuple exception with its first item */
- while (PyTuple_Check(type) && PyTuple_Size(type) > 0) {
- PyObject *tmp = type;
- type = PyTuple_GET_ITEM(type, 0);
- Py_INCREF(type);
- Py_DECREF(tmp);
- }
-
- if (PyString_CheckExact(type)) {
- /* Raising builtin string is deprecated but still allowed --
- * do nothing. Raising an instance of a new-style str
- * subclass is right out. */
- if (PyErr_Warn(PyExc_DeprecationWarning,
- "raising a string exception is deprecated"))
- goto raise_error;
- }
- else if (PyExceptionClass_Check(type))
- PyErr_NormalizeException(&type, &value, &tb);
-
- else if (PyExceptionInstance_Check(type)) {
- /* Raising an instance. The value should be a dummy. */
- if (value != Py_None) {
- PyErr_SetString(PyExc_TypeError,
- "instance exception may not have a separate value");
- goto raise_error;
- }
- else {
- /* Normalize to raise <class>, <instance> */
- Py_DECREF(value);
- value = type;
- type = PyExceptionInstance_Class(type);
- Py_INCREF(type);
- }
- }
- else {
- /* Not something you can raise. You get an exception
- anyway, just not what you specified :-) */
- PyErr_Format(PyExc_TypeError,
- "exceptions must be classes, instances, or "
- "strings (deprecated), not %s",
- type->ob_type->tp_name);
- goto raise_error;
- }
- PyErr_Restore(type, value, tb);
- if (tb == NULL)
- return WHY_EXCEPTION;
- else
- return WHY_RERAISE;
- raise_error:
- Py_XDECREF(value);
- Py_XDECREF(type);
- Py_XDECREF(tb);
- return WHY_EXCEPTION;
-}
-
-/* Iterate v argcnt times and store the results on the stack (via decreasing
- sp). Return 1 for success, 0 if error. */
-
-static int
-unpack_iterable(PyObject *v, int argcnt, PyObject **sp)
-{
- int i = 0;
- PyObject *it; /* iter(v) */
- PyObject *w;
-
- assert(v != NULL);
-
- it = PyObject_GetIter(v);
- if (it == NULL)
- goto Error;
-
- for (; i < argcnt; i++) {
- w = PyIter_Next(it);
- if (w == NULL) {
- /* Iterator done, via error or exhaustion. */
- if (!PyErr_Occurred()) {
- PyErr_Format(PyExc_ValueError,
- "need more than %d value%s to unpack",
- i, i == 1 ? "" : "s");
- }
- goto Error;
- }
- *--sp = w;
- }
-
- /* We better have exhausted the iterator now. */
- w = PyIter_Next(it);
- if (w == NULL) {
- if (PyErr_Occurred())
- goto Error;
- Py_DECREF(it);
- return 1;
- }
- Py_DECREF(w);
- PyErr_SetString(PyExc_ValueError, "too many values to unpack");
- /* fall through */
-Error:
- for (; i > 0; i--, sp++)
- Py_DECREF(*sp);
- Py_XDECREF(it);
- return 0;
-}
-
-
-#ifdef LLTRACE
-static int
-prtrace(PyObject *v, char *str)
-{
- printf("%s ", str);
- if (PyObject_Print(v, stdout, 0) != 0)
- PyErr_Clear(); /* Don't know what else to do */
- printf("\n");
- return 1;
-}
-#endif
-
-static void
-call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f)
-{
- PyObject *type, *value, *traceback, *arg;
- int err;
- PyErr_Fetch(&type, &value, &traceback);
- if (value == NULL) {
- value = Py_None;
- Py_INCREF(value);
- }
- arg = PyTuple_Pack(3, type, value, traceback);
- if (arg == NULL) {
- PyErr_Restore(type, value, traceback);
- return;
- }
- err = call_trace(func, self, f, PyTrace_EXCEPTION, arg);
- Py_DECREF(arg);
- if (err == 0)
- PyErr_Restore(type, value, traceback);
- else {
- Py_XDECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(traceback);
- }
-}
-
-static void
-call_trace_protected(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
- int what, PyObject *arg)
-{
- PyObject *type, *value, *traceback;
- int err;
- PyErr_Fetch(&type, &value, &traceback);
- err = call_trace(func, obj, frame, what, arg);
- if (err == 0)
- PyErr_Restore(type, value, traceback);
- else {
- Py_XDECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(traceback);
- }
-}
-
-static int
-call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
- int what, PyObject *arg)
-{
- register PyThreadState *tstate = frame->f_tstate;
- int result;
- if (tstate->tracing)
- return 0;
- tstate->tracing++;
- tstate->use_tracing = 0;
- result = func(obj, frame, what, arg);
- tstate->use_tracing = ((tstate->c_tracefunc != NULL)
- || (tstate->c_profilefunc != NULL));
- tstate->tracing--;
- return result;
-}
-
-PyObject *
-_PyEval_CallTracing(PyObject *func, PyObject *args)
-{
- PyFrameObject *frame = PyEval_GetFrame();
- PyThreadState *tstate = frame->f_tstate;
- int save_tracing = tstate->tracing;
- int save_use_tracing = tstate->use_tracing;
- PyObject *result;
-
- tstate->tracing = 0;
- tstate->use_tracing = ((tstate->c_tracefunc != NULL)
- || (tstate->c_profilefunc != NULL));
- result = PyObject_Call(func, args, NULL);
- tstate->tracing = save_tracing;
- tstate->use_tracing = save_use_tracing;
- return result;
-}
-
-static int
-maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
- PyFrameObject *frame, int *instr_lb, int *instr_ub,
- int *instr_prev)
-{
- int result = 0;
-
- /* If the last instruction executed isn't in the current
- instruction window, reset the window. If the last
- instruction happens to fall at the start of a line or if it
- represents a jump backwards, call the trace function.
- */
- if ((frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub)) {
- int line;
- PyAddrPair bounds;
-
- line = PyCode_CheckLineNumber(frame->f_code, frame->f_lasti,
- &bounds);
- if (line >= 0) {
- frame->f_lineno = line;
- result = call_trace(func, obj, frame,
- PyTrace_LINE, Py_None);
- }
- *instr_lb = bounds.ap_lower;
- *instr_ub = bounds.ap_upper;
- }
- else if (frame->f_lasti <= *instr_prev) {
- result = call_trace(func, obj, frame, PyTrace_LINE, Py_None);
- }
- *instr_prev = frame->f_lasti;
- return result;
-}
-
-void
-PyEval_SetProfile(Py_tracefunc func, PyObject *arg)
-{
- PyThreadState *tstate = PyThreadState_GET();
- PyObject *temp = tstate->c_profileobj;
- Py_XINCREF(arg);
- tstate->c_profilefunc = NULL;
- tstate->c_profileobj = NULL;
- /* Must make sure that tracing is not ignored if 'temp' is freed */
- tstate->use_tracing = tstate->c_tracefunc != NULL;
- Py_XDECREF(temp);
- tstate->c_profilefunc = func;
- tstate->c_profileobj = arg;
- /* Flag that tracing or profiling is turned on */
- tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL);
-}
-
-void
-PyEval_SetTrace(Py_tracefunc func, PyObject *arg)
-{
- PyThreadState *tstate = PyThreadState_GET();
- PyObject *temp = tstate->c_traceobj;
- Py_XINCREF(arg);
- tstate->c_tracefunc = NULL;
- tstate->c_traceobj = NULL;
- /* Must make sure that profiling is not ignored if 'temp' is freed */
- tstate->use_tracing = tstate->c_profilefunc != NULL;
- Py_XDECREF(temp);
- tstate->c_tracefunc = func;
- tstate->c_traceobj = arg;
- /* Flag that tracing or profiling is turned on */
- tstate->use_tracing = ((func != NULL)
- || (tstate->c_profilefunc != NULL));
-}
-
-PyObject *
-PyEval_GetBuiltins(void)
-{
- PyFrameObject *current_frame = PyEval_GetFrame();
- if (current_frame == NULL)
- return PyThreadState_GET()->interp->builtins;
- else
- return current_frame->f_builtins;
-}
-
-PyObject *
-PyEval_GetLocals(void)
-{
- PyFrameObject *current_frame = PyEval_GetFrame();
- if (current_frame == NULL)
- return NULL;
- PyFrame_FastToLocals(current_frame);
- return current_frame->f_locals;
-}
-
-PyObject *
-PyEval_GetGlobals(void)
-{
- PyFrameObject *current_frame = PyEval_GetFrame();
- if (current_frame == NULL)
- return NULL;
- else
- return current_frame->f_globals;
-}
-
-PyFrameObject *
-PyEval_GetFrame(void)
-{
- PyThreadState *tstate = PyThreadState_GET();
- return _PyThreadState_GetFrame(tstate);
-}
-
-int
-PyEval_GetRestricted(void)
-{
- PyFrameObject *current_frame = PyEval_GetFrame();
- return current_frame == NULL ? 0 : PyFrame_IsRestricted(current_frame);
-}
-
-int
-PyEval_MergeCompilerFlags(PyCompilerFlags *cf)
-{
- PyFrameObject *current_frame = PyEval_GetFrame();
- int result = cf->cf_flags != 0;
-
- if (current_frame != NULL) {
- const int codeflags = current_frame->f_code->co_flags;
- const int compilerflags = codeflags & PyCF_MASK;
- if (compilerflags) {
- result = 1;
- cf->cf_flags |= compilerflags;
- }
-#if 0 /* future keyword */
- if (codeflags & CO_GENERATOR_ALLOWED) {
- result = 1;
- cf->cf_flags |= CO_GENERATOR_ALLOWED;
- }
-#endif
- }
- return result;
-}
-
-int
-Py_FlushLine(void)
-{
- PyObject *f = PySys_GetObject("stdout");
- if (f == NULL)
- return 0;
- if (!PyFile_SoftSpace(f, 0))
- return 0;
- return PyFile_WriteString("\n", f);
-}
-
-
-/* External interface to call any callable object.
- The arg must be a tuple or NULL. */
-
-#undef PyEval_CallObject
-/* for backward compatibility: export this interface */
-
-PyObject *
-PyEval_CallObject(PyObject *func, PyObject *arg)
-{
- return PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL);
-}
-#define PyEval_CallObject(func,arg) \
- PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL)
-
-PyObject *
-PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
-{
- PyObject *result;
-
- if (arg == NULL) {
- arg = PyTuple_New(0);
- if (arg == NULL)
- return NULL;
- }
- else if (!PyTuple_Check(arg)) {
- PyErr_SetString(PyExc_TypeError,
- "argument list must be a tuple");
- return NULL;
- }
- else
- Py_INCREF(arg);
-
- if (kw != NULL && !PyDict_Check(kw)) {
- PyErr_SetString(PyExc_TypeError,
- "keyword list must be a dictionary");
- Py_DECREF(arg);
- return NULL;
- }
-
- result = PyObject_Call(func, arg, kw);
- Py_DECREF(arg);
- return result;
-}
-
-const char *
-PyEval_GetFuncName(PyObject *func)
-{
- if (PyMethod_Check(func))
- return PyEval_GetFuncName(PyMethod_GET_FUNCTION(func));
- else if (PyFunction_Check(func))
- return PyString_AsString(((PyFunctionObject*)func)->func_name);
- else if (PyCFunction_Check(func))
- return ((PyCFunctionObject*)func)->m_ml->ml_name;
- else if (PyClass_Check(func))
- return PyString_AsString(((PyClassObject*)func)->cl_name);
- else if (PyInstance_Check(func)) {
- return PyString_AsString(
- ((PyInstanceObject*)func)->in_class->cl_name);
- } else {
- return func->ob_type->tp_name;
- }
-}
-
-const char *
-PyEval_GetFuncDesc(PyObject *func)
-{
- if (PyMethod_Check(func))
- return "()";
- else if (PyFunction_Check(func))
- return "()";
- else if (PyCFunction_Check(func))
- return "()";
- else if (PyClass_Check(func))
- return " constructor";
- else if (PyInstance_Check(func)) {
- return " instance";
- } else {
- return " object";
- }
-}
-
-static void
-err_args(PyObject *func, int flags, int nargs)
-{
- if (flags & METH_NOARGS)
- PyErr_Format(PyExc_TypeError,
- "%.200s() takes no arguments (%d given)",
- ((PyCFunctionObject *)func)->m_ml->ml_name,
- nargs);
- else
- PyErr_Format(PyExc_TypeError,
- "%.200s() takes exactly one argument (%d given)",
- ((PyCFunctionObject *)func)->m_ml->ml_name,
- nargs);
-}
-
-#define C_TRACE(x, call) \
-if (tstate->use_tracing && tstate->c_profilefunc) { \
- if (call_trace(tstate->c_profilefunc, \
- tstate->c_profileobj, \
- tstate->frame, PyTrace_C_CALL, \
- func)) { \
- x = NULL; \
- } \
- else { \
- x = call; \
- if (tstate->c_profilefunc != NULL) { \
- if (x == NULL) { \
- call_trace_protected(tstate->c_profilefunc, \
- tstate->c_profileobj, \
- tstate->frame, PyTrace_C_EXCEPTION, \
- func); \
- /* XXX should pass (type, value, tb) */ \
- } else { \
- if (call_trace(tstate->c_profilefunc, \
- tstate->c_profileobj, \
- tstate->frame, PyTrace_C_RETURN, \
- func)) { \
- Py_DECREF(x); \
- x = NULL; \
- } \
- } \
- } \
- } \
-} else { \
- x = call; \
- }
-
-static PyObject *
-call_function(PyObject ***pp_stack, int oparg
-#ifdef WITH_TSC
- , uint64* pintr0, uint64* pintr1
-#endif
- )
-{
- int na = oparg & 0xff;
- int nk = (oparg>>8) & 0xff;
- int n = na + 2 * nk;
- PyObject **pfunc = (*pp_stack) - n - 1;
- PyObject *func = *pfunc;
- PyObject *x, *w;
-
- /* Always dispatch PyCFunction first, because these are
- presumed to be the most frequent callable object.
- */
- if (PyCFunction_Check(func) && nk == 0) {
- int flags = PyCFunction_GET_FLAGS(func);
- PyThreadState *tstate = PyThreadState_GET();
-
- PCALL(PCALL_CFUNCTION);
- if (flags & (METH_NOARGS | METH_O)) {
- PyCFunction meth = PyCFunction_GET_FUNCTION(func);
- PyObject *self = PyCFunction_GET_SELF(func);
- if (flags & METH_NOARGS && na == 0) {
- C_TRACE(x, (*meth)(self,NULL));
- }
- else if (flags & METH_O && na == 1) {
- PyObject *arg = EXT_POP(*pp_stack);
- C_TRACE(x, (*meth)(self,arg));
- Py_DECREF(arg);
- }
- else {
- err_args(func, flags, na);
- x = NULL;
- }
- }
- else {
- PyObject *callargs;
- callargs = load_args(pp_stack, na);
- READ_TIMESTAMP(*pintr0);
- C_TRACE(x, PyCFunction_Call(func,callargs,NULL));
- READ_TIMESTAMP(*pintr1);
- Py_XDECREF(callargs);
- }
- } else {
- if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
- /* optimize access to bound methods */
- PyObject *self = PyMethod_GET_SELF(func);
- PCALL(PCALL_METHOD);
- PCALL(PCALL_BOUND_METHOD);
- Py_INCREF(self);
- func = PyMethod_GET_FUNCTION(func);
- Py_INCREF(func);
- Py_DECREF(*pfunc);
- *pfunc = self;
- na++;
- n++;
- } else
- Py_INCREF(func);
- READ_TIMESTAMP(*pintr0);
- if (PyFunction_Check(func))
- x = fast_function(func, pp_stack, n, na, nk);
- else
- x = do_call(func, pp_stack, na, nk);
- READ_TIMESTAMP(*pintr1);
- Py_DECREF(func);
- }
-
- /* Clear the stack of the function object. Also removes
- the arguments in case they weren't consumed already
- (fast_function() and err_args() leave them on the stack).
- */
- while ((*pp_stack) > pfunc) {
- w = EXT_POP(*pp_stack);
- Py_DECREF(w);
- PCALL(PCALL_POP);
- }
- return x;
-}
-
-/* The fast_function() function optimize calls for which no argument
- tuple is necessary; the objects are passed directly from the stack.
- For the simplest case -- a function that takes only positional
- arguments and is called with only positional arguments -- it
- inlines the most primitive frame setup code from
- PyEval_EvalCodeEx(), which vastly reduces the checks that must be
- done before evaluating the frame.
-*/
-
-static PyObject *
-fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)
-{
- PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
- PyObject *globals = PyFunction_GET_GLOBALS(func);
- PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
- PyObject **d = NULL;
- int nd = 0;
-
- PCALL(PCALL_FUNCTION);
- PCALL(PCALL_FAST_FUNCTION);
- if (argdefs == NULL && co->co_argcount == n && nk==0 &&
- co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) {
- PyFrameObject *f;
- PyObject *retval = NULL;
- PyThreadState *tstate = PyThreadState_GET();
- PyObject **fastlocals, **stack;
- int i;
-
- PCALL(PCALL_FASTER_FUNCTION);
- assert(globals != NULL);
- /* XXX Perhaps we should create a specialized
- PyFrame_New() that doesn't take locals, but does
- take builtins without sanity checking them.
- */
- assert(tstate != NULL);
- f = PyFrame_New(tstate, co, globals, NULL);
- if (f == NULL)
- return NULL;
-
- fastlocals = f->f_localsplus;
- stack = (*pp_stack) - n;
-
- for (i = 0; i < n; i++) {
- Py_INCREF(*stack);
- fastlocals[i] = *stack++;
- }
- retval = PyEval_EvalFrameEx(f,0);
- ++tstate->recursion_depth;
- Py_DECREF(f);
- --tstate->recursion_depth;
- return retval;
- }
- if (argdefs != NULL) {
- d = &PyTuple_GET_ITEM(argdefs, 0);
- nd = ((PyTupleObject *)argdefs)->ob_size;
- }
- return PyEval_EvalCodeEx(co, globals,
- (PyObject *)NULL, (*pp_stack)-n, na,
- (*pp_stack)-2*nk, nk, d, nd,
- PyFunction_GET_CLOSURE(func));
-}
-
-static PyObject *
-update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack,
- PyObject *func)
-{
- PyObject *kwdict = NULL;
- if (orig_kwdict == NULL)
- kwdict = PyDict_New();
- else {
- kwdict = PyDict_Copy(orig_kwdict);
- Py_DECREF(orig_kwdict);
- }
- if (kwdict == NULL)
- return NULL;
- while (--nk >= 0) {
- int err;
- PyObject *value = EXT_POP(*pp_stack);
- PyObject *key = EXT_POP(*pp_stack);
- if (PyDict_GetItem(kwdict, key) != NULL) {
- PyErr_Format(PyExc_TypeError,
- "%.200s%s got multiple values "
- "for keyword argument '%.200s'",
- PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func),
- PyString_AsString(key));
- Py_DECREF(key);
- Py_DECREF(value);
- Py_DECREF(kwdict);
- return NULL;
- }
- err = PyDict_SetItem(kwdict, key, value);
- Py_DECREF(key);
- Py_DECREF(value);
- if (err) {
- Py_DECREF(kwdict);
- return NULL;
- }
- }
- return kwdict;
-}
-
-static PyObject *
-update_star_args(int nstack, int nstar, PyObject *stararg,
- PyObject ***pp_stack)
-{
- PyObject *callargs, *w;
-
- callargs = PyTuple_New(nstack + nstar);
- if (callargs == NULL) {
- return NULL;
- }
- if (nstar) {
- int i;
- for (i = 0; i < nstar; i++) {
- PyObject *a = PyTuple_GET_ITEM(stararg, i);
- Py_INCREF(a);
- PyTuple_SET_ITEM(callargs, nstack + i, a);
- }
- }
- while (--nstack >= 0) {
- w = EXT_POP(*pp_stack);
- PyTuple_SET_ITEM(callargs, nstack, w);
- }
- return callargs;
-}
-
-static PyObject *
-load_args(PyObject ***pp_stack, int na)
-{
- PyObject *args = PyTuple_New(na);
- PyObject *w;
-
- if (args == NULL)
- return NULL;
- while (--na >= 0) {
- w = EXT_POP(*pp_stack);
- PyTuple_SET_ITEM(args, na, w);
- }
- return args;
-}
-
-static PyObject *
-do_call(PyObject *func, PyObject ***pp_stack, int na, int nk)
-{
- PyObject *callargs = NULL;
- PyObject *kwdict = NULL;
- PyObject *result = NULL;
-
- if (nk > 0) {
- kwdict = update_keyword_args(NULL, nk, pp_stack, func);
- if (kwdict == NULL)
- goto call_fail;
- }
- callargs = load_args(pp_stack, na);
- if (callargs == NULL)
- goto call_fail;
-#ifdef CALL_PROFILE
- /* At this point, we have to look at the type of func to
- update the call stats properly. Do it here so as to avoid
- exposing the call stats machinery outside ceval.c
- */
- if (PyFunction_Check(func))
- PCALL(PCALL_FUNCTION);
- else if (PyMethod_Check(func))
- PCALL(PCALL_METHOD);
- else if (PyType_Check(func))
- PCALL(PCALL_TYPE);
- else
- PCALL(PCALL_OTHER);
-#endif
- result = PyObject_Call(func, callargs, kwdict);
- call_fail:
- Py_XDECREF(callargs);
- Py_XDECREF(kwdict);
- return result;
-}
-
-static PyObject *
-ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
-{
- int nstar = 0;
- PyObject *callargs = NULL;
- PyObject *stararg = NULL;
- PyObject *kwdict = NULL;
- PyObject *result = NULL;
-
- if (flags & CALL_FLAG_KW) {
- kwdict = EXT_POP(*pp_stack);
- if (!(kwdict && PyDict_Check(kwdict))) {
- PyErr_Format(PyExc_TypeError,
- "%s%s argument after ** "
- "must be a dictionary",
- PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func));
- goto ext_call_fail;
- }
- }
- if (flags & CALL_FLAG_VAR) {
- stararg = EXT_POP(*pp_stack);
- if (!PyTuple_Check(stararg)) {
- PyObject *t = NULL;
- t = PySequence_Tuple(stararg);
- if (t == NULL) {
- if (PyErr_ExceptionMatches(PyExc_TypeError)) {
- PyErr_Format(PyExc_TypeError,
- "%s%s argument after * "
- "must be a sequence",
- PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func));
- }
- goto ext_call_fail;
- }
- Py_DECREF(stararg);
- stararg = t;
- }
- nstar = PyTuple_GET_SIZE(stararg);
- }
- if (nk > 0) {
- kwdict = update_keyword_args(kwdict, nk, pp_stack, func);
- if (kwdict == NULL)
- goto ext_call_fail;
- }
- callargs = update_star_args(na, nstar, stararg, pp_stack);
- if (callargs == NULL)
- goto ext_call_fail;
-#ifdef CALL_PROFILE
- /* At this point, we have to look at the type of func to
- update the call stats properly. Do it here so as to avoid
- exposing the call stats machinery outside ceval.c
- */
- if (PyFunction_Check(func))
- PCALL(PCALL_FUNCTION);
- else if (PyMethod_Check(func))
- PCALL(PCALL_METHOD);
- else if (PyType_Check(func))
- PCALL(PCALL_TYPE);
- else
- PCALL(PCALL_OTHER);
-#endif
- result = PyObject_Call(func, callargs, kwdict);
- ext_call_fail:
- Py_XDECREF(callargs);
- Py_XDECREF(kwdict);
- Py_XDECREF(stararg);
- return result;
-}
-
-/* Extract a slice index from a PyInt or PyLong or an object with the
- nb_index slot defined, and store in *pi.
- Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX,
- and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1.
- Return 0 on error, 1 on success.
-*/
-/* Note: If v is NULL, return success without storing into *pi. This
- is because_PyEval_SliceIndex() is called by apply_slice(), which can be
- called by the SLICE opcode with v and/or w equal to NULL.
-*/
-int
-_PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
-{
- if (v != NULL) {
- Py_ssize_t x;
- if (PyInt_Check(v)) {
- /* XXX(nnorwitz): I think PyInt_AS_LONG is correct,
- however, it looks like it should be AsSsize_t.
- There should be a comment here explaining why.
- */
- x = PyInt_AS_LONG(v);
- }
- else if (PyIndex_Check(v)) {
- x = PyNumber_AsSsize_t(v, NULL);
- if (x == -1 && PyErr_Occurred())
- return 0;
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "slice indices must be integers or "
- "None or have an __index__ method");
- return 0;
- }
- *pi = x;
- }
- return 1;
-}
-
-#undef ISINDEX
-#define ISINDEX(x) ((x) == NULL || \
- PyInt_Check(x) || PyLong_Check(x) || PyIndex_Check(x))
-
-static PyObject *
-apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
-{
- PyTypeObject *tp = u->ob_type;
- PySequenceMethods *sq = tp->tp_as_sequence;
-
- if (sq && sq->sq_slice && ISINDEX(v) && ISINDEX(w)) {
- Py_ssize_t ilow = 0, ihigh = PY_SSIZE_T_MAX;
- if (!_PyEval_SliceIndex(v, &ilow))
- return NULL;
- if (!_PyEval_SliceIndex(w, &ihigh))
- return NULL;
- return PySequence_GetSlice(u, ilow, ihigh);
- }
- else {
- PyObject *slice = PySlice_New(v, w, NULL);
- if (slice != NULL) {
- PyObject *res = PyObject_GetItem(u, slice);
- Py_DECREF(slice);
- return res;
- }
- else
- return NULL;
- }
-}
-
-static int
-assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
- /* u[v:w] = x */
-{
- PyTypeObject *tp = u->ob_type;
- PySequenceMethods *sq = tp->tp_as_sequence;
-
- if (sq && sq->sq_ass_slice && ISINDEX(v) && ISINDEX(w)) {
- Py_ssize_t ilow = 0, ihigh = PY_SSIZE_T_MAX;
- if (!_PyEval_SliceIndex(v, &ilow))
- return -1;
- if (!_PyEval_SliceIndex(w, &ihigh))
- return -1;
- if (x == NULL)
- return PySequence_DelSlice(u, ilow, ihigh);
- else
- return PySequence_SetSlice(u, ilow, ihigh, x);
- }
- else {
- PyObject *slice = PySlice_New(v, w, NULL);
- if (slice != NULL) {
- int res;
- if (x != NULL)
- res = PyObject_SetItem(u, slice, x);
- else
- res = PyObject_DelItem(u, slice);
- Py_DECREF(slice);
- return res;
- }
- else
- return -1;
- }
-}
-
-static PyObject *
-cmp_outcome(int op, register PyObject *v, register PyObject *w)
-{
- int res = 0;
- switch (op) {
- case PyCmp_IS:
- res = (v == w);
- break;
- case PyCmp_IS_NOT:
- res = (v != w);
- break;
- case PyCmp_IN:
- res = PySequence_Contains(w, v);
- if (res < 0)
- return NULL;
- break;
- case PyCmp_NOT_IN:
- res = PySequence_Contains(w, v);
- if (res < 0)
- return NULL;
- res = !res;
- break;
- case PyCmp_EXC_MATCH:
- res = PyErr_GivenExceptionMatches(v, w);
- break;
- default:
- return PyObject_RichCompare(v, w, op);
- }
- v = res ? Py_True : Py_False;
- Py_INCREF(v);
- return v;
-}
-
-static PyObject *
-import_from(PyObject *v, PyObject *name)
-{
- PyObject *x;
-
- x = PyObject_GetAttr(v, name);
- if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
- PyErr_Format(PyExc_ImportError,
- "cannot import name %.230s",
- PyString_AsString(name));
- }
- return x;
-}
-
-static int
-import_all_from(PyObject *locals, PyObject *v)
-{
- PyObject *all = PyObject_GetAttrString(v, "__all__");
- PyObject *dict, *name, *value;
- int skip_leading_underscores = 0;
- int pos, err;
-
- if (all == NULL) {
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))
- return -1; /* Unexpected error */
- PyErr_Clear();
- dict = PyObject_GetAttrString(v, "__dict__");
- if (dict == NULL) {
- if (!PyErr_ExceptionMatches(PyExc_AttributeError))
- return -1;
- PyErr_SetString(PyExc_ImportError,
- "from-import-* object has no __dict__ and no __all__");
- return -1;
- }
- all = PyMapping_Keys(dict);
- Py_DECREF(dict);
- if (all == NULL)
- return -1;
- skip_leading_underscores = 1;
- }
-
- for (pos = 0, err = 0; ; pos++) {
- name = PySequence_GetItem(all, pos);
- if (name == NULL) {
- if (!PyErr_ExceptionMatches(PyExc_IndexError))
- err = -1;
- else
- PyErr_Clear();
- break;
- }
- if (skip_leading_underscores &&
- PyString_Check(name) &&
- PyString_AS_STRING(name)[0] == '_')
- {
- Py_DECREF(name);
- continue;
- }
- value = PyObject_GetAttr(v, name);
- if (value == NULL)
- err = -1;
- else if (PyDict_CheckExact(locals))
- err = PyDict_SetItem(locals, name, value);
- else
- err = PyObject_SetItem(locals, name, value);
- Py_DECREF(name);
- Py_XDECREF(value);
- if (err != 0)
- break;
- }
- Py_DECREF(all);
- return err;
-}
-
-static PyObject *
-build_class(PyObject *methods, PyObject *bases, PyObject *name)
-{
- PyObject *metaclass = NULL, *result, *base;
-
- if (PyDict_Check(methods))
- metaclass = PyDict_GetItemString(methods, "__metaclass__");
- if (metaclass != NULL)
- Py_INCREF(metaclass);
- else if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
- base = PyTuple_GET_ITEM(bases, 0);
- metaclass = PyObject_GetAttrString(base, "__class__");
- if (metaclass == NULL) {
- PyErr_Clear();
- metaclass = (PyObject *)base->ob_type;
- Py_INCREF(metaclass);
- }
- }
- else {
- PyObject *g = PyEval_GetGlobals();
- if (g != NULL && PyDict_Check(g))
- metaclass = PyDict_GetItemString(g, "__metaclass__");
- if (metaclass == NULL)
- metaclass = (PyObject *) &PyClass_Type;
- Py_INCREF(metaclass);
- }
- result = PyObject_CallFunctionObjArgs(metaclass, name, bases, methods, NULL);
- Py_DECREF(metaclass);
- if (result == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
- /* A type error here likely means that the user passed
- in a base that was not a class (such the random module
- instead of the random.random type). Help them out with
- by augmenting the error message with more information.*/
-
- PyObject *ptype, *pvalue, *ptraceback;
-
- PyErr_Fetch(&ptype, &pvalue, &ptraceback);
- if (PyString_Check(pvalue)) {
- PyObject *newmsg;
- newmsg = PyString_FromFormat(
- "Error when calling the metaclass bases\n %s",
- PyString_AS_STRING(pvalue));
- if (newmsg != NULL) {
- Py_DECREF(pvalue);
- pvalue = newmsg;
- }
- }
- PyErr_Restore(ptype, pvalue, ptraceback);
- }
- return result;
-}
-
-static int
-exec_statement(PyFrameObject *f, PyObject *prog, PyObject *globals,
- PyObject *locals)
-{
- int n;
- PyObject *v;
- int plain = 0;
-
- if (PyTuple_Check(prog) && globals == Py_None && locals == Py_None &&
- ((n = PyTuple_Size(prog)) == 2 || n == 3)) {
- /* Backward compatibility hack */
- globals = PyTuple_GetItem(prog, 1);
- if (n == 3)
- locals = PyTuple_GetItem(prog, 2);
- prog = PyTuple_GetItem(prog, 0);
- }
- if (globals == Py_None) {
- globals = PyEval_GetGlobals();
- if (locals == Py_None) {
- locals = PyEval_GetLocals();
- plain = 1;
- }
- if (!globals || !locals) {
- PyErr_SetString(PyExc_SystemError,
- "globals and locals cannot be NULL");
- return -1;
- }
- }
- else if (locals == Py_None)
- locals = globals;
- if (!PyString_Check(prog) &&
- !PyUnicode_Check(prog) &&
- !PyCode_Check(prog) &&
- !PyFile_Check(prog)) {
- PyErr_SetString(PyExc_TypeError,
- "exec: arg 1 must be a string, file, or code object");
- return -1;
- }
- if (!PyDict_Check(globals)) {
- PyErr_SetString(PyExc_TypeError,
- "exec: arg 2 must be a dictionary or None");
- return -1;
- }
- if (!PyMapping_Check(locals)) {
- PyErr_SetString(PyExc_TypeError,
- "exec: arg 3 must be a mapping or None");
- return -1;
- }
- if (PyDict_GetItemString(globals, "__builtins__") == NULL)
- PyDict_SetItemString(globals, "__builtins__", f->f_builtins);
- if (PyCode_Check(prog)) {
- if (PyCode_GetNumFree((PyCodeObject *)prog) > 0) {
- PyErr_SetString(PyExc_TypeError,
- "code object passed to exec may not contain free variables");
- return -1;
- }
- v = PyEval_EvalCode((PyCodeObject *) prog, globals, locals);
- }
- else if (PyFile_Check(prog)) {
- FILE *fp = PyFile_AsFile(prog);
- char *name = PyString_AsString(PyFile_Name(prog));
- PyCompilerFlags cf;
- if (name == NULL)
- return -1;
- cf.cf_flags = 0;
- if (PyEval_MergeCompilerFlags(&cf))
- v = PyRun_FileFlags(fp, name, Py_file_input, globals,
- locals, &cf);
- else
- v = PyRun_File(fp, name, Py_file_input, globals,
- locals);
- }
- else {
- PyObject *tmp = NULL;
- char *str;
- PyCompilerFlags cf;
- cf.cf_flags = 0;
-#ifdef Py_USING_UNICODE
- if (PyUnicode_Check(prog)) {
- tmp = PyUnicode_AsUTF8String(prog);
- if (tmp == NULL)
- return -1;
- prog = tmp;
- cf.cf_flags |= PyCF_SOURCE_IS_UTF8;
- }
-#endif
- if (PyString_AsStringAndSize(prog, &str, NULL))
- return -1;
- if (PyEval_MergeCompilerFlags(&cf))
- v = PyRun_StringFlags(str, Py_file_input, globals,
- locals, &cf);
- else
- v = PyRun_String(str, Py_file_input, globals, locals);
- Py_XDECREF(tmp);
- }
- if (plain)
- PyFrame_LocalsToFast(f, 0);
- if (v == NULL)
- return -1;
- Py_DECREF(v);
- return 0;
-}
-
-static void
-format_exc_check_arg(PyObject *exc, char *format_str, PyObject *obj)
-{
- char *obj_str;
-
- if (!obj)
- return;
-
- obj_str = PyString_AsString(obj);
- if (!obj_str)
- return;
-
- PyErr_Format(exc, format_str, obj_str);
-}
-
-static PyObject *
-string_concatenate(PyObject *v, PyObject *w,
- PyFrameObject *f, unsigned char *next_instr)
-{
- /* This function implements 'variable += expr' when both arguments
- are strings. */
- Py_ssize_t v_len = PyString_GET_SIZE(v);
- Py_ssize_t w_len = PyString_GET_SIZE(w);
- Py_ssize_t new_len = v_len + w_len;
- if (new_len < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "strings are too large to concat");
- return NULL;
- }
-
- if (v->ob_refcnt == 2) {
- /* In the common case, there are 2 references to the value
- * stored in 'variable' when the += is performed: one on the
- * value stack (in 'v') and one still stored in the 'variable'.
- * We try to delete the variable now to reduce the refcnt to 1.
- */
- switch (*next_instr) {
- case STORE_FAST:
- {
- int oparg = PEEKARG();
- PyObject **fastlocals = f->f_localsplus;
- if (GETLOCAL(oparg) == v)
- SETLOCAL(oparg, NULL);
- break;
- }
- case STORE_DEREF:
- {
- PyObject **freevars = f->f_localsplus + f->f_code->co_nlocals;
- PyObject *c = freevars[PEEKARG()];
- if (PyCell_GET(c) == v)
- PyCell_Set(c, NULL);
- break;
- }
- case STORE_NAME:
- {
- PyObject *names = f->f_code->co_names;
- PyObject *name = GETITEM(names, PEEKARG());
- PyObject *locals = f->f_locals;
- if (PyDict_CheckExact(locals) &&
- PyDict_GetItem(locals, name) == v) {
- if (PyDict_DelItem(locals, name) != 0) {
- PyErr_Clear();
- }
- }
- break;
- }
- }
- }
-
- if (v->ob_refcnt == 1 && !PyString_CHECK_INTERNED(v)) {
- /* Now we own the last reference to 'v', so we can resize it
- * in-place.
- */
- if (_PyString_Resize(&v, new_len) != 0) {
- /* XXX if _PyString_Resize() fails, 'v' has been
- * deallocated so it cannot be put back into 'variable'.
- * The MemoryError is raised when there is no value in
- * 'variable', which might (very remotely) be a cause
- * of incompatibilities.
- */
- return NULL;
- }
- /* copy 'w' into the newly allocated area of 'v' */
- memcpy(PyString_AS_STRING(v) + v_len,
- PyString_AS_STRING(w), w_len);
- return v;
- }
- else {
- /* When in-place resizing is not an option. */
- PyString_Concat(&v, w);
- return v;
- }
-}
-
-#ifdef DYNAMIC_EXECUTION_PROFILE
-
-static PyObject *
-getarray(long a[256])
-{
- int i;
- PyObject *l = PyList_New(256);
- if (l == NULL) return NULL;
- for (i = 0; i < 256; i++) {
- PyObject *x = PyInt_FromLong(a[i]);
- if (x == NULL) {
- Py_DECREF(l);
- return NULL;
- }
- PyList_SetItem(l, i, x);
- }
- for (i = 0; i < 256; i++)
- a[i] = 0;
- return l;
-}
-
-PyObject *
-_Py_GetDXProfile(PyObject *self, PyObject *args)
-{
-#ifndef DXPAIRS
- return getarray(dxp);
-#else
- int i;
- PyObject *l = PyList_New(257);
- if (l == NULL) return NULL;
- for (i = 0; i < 257; i++) {
- PyObject *x = getarray(dxpairs[i]);
- if (x == NULL) {
- Py_DECREF(l);
- return NULL;
- }
- PyList_SetItem(l, i, x);
- }
- return l;
-#endif
-}
-
-#endif
diff --git a/sys/src/cmd/python/Python/codecs.c b/sys/src/cmd/python/Python/codecs.c
deleted file mode 100644
index 4b0f4cb0d..000000000
--- a/sys/src/cmd/python/Python/codecs.c
+++ /dev/null
@@ -1,860 +0,0 @@
-/* ------------------------------------------------------------------------
-
- Python Codec Registry and support functions
-
-Written by Marc-Andre Lemburg (mal@lemburg.com).
-
-Copyright (c) Corporation for National Research Initiatives.
-
- ------------------------------------------------------------------------ */
-
-#include "Python.h"
-#include <ctype.h>
-
-/* --- Codec Registry ----------------------------------------------------- */
-
-/* Import the standard encodings package which will register the first
- codec search function.
-
- This is done in a lazy way so that the Unicode implementation does
- not downgrade startup time of scripts not needing it.
-
- ImportErrors are silently ignored by this function. Only one try is
- made.
-
-*/
-
-static int _PyCodecRegistry_Init(void); /* Forward */
-
-int PyCodec_Register(PyObject *search_function)
-{
- PyInterpreterState *interp = PyThreadState_GET()->interp;
- if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
- goto onError;
- if (search_function == NULL) {
- PyErr_BadArgument();
- goto onError;
- }
- if (!PyCallable_Check(search_function)) {
- PyErr_SetString(PyExc_TypeError, "argument must be callable");
- goto onError;
- }
- return PyList_Append(interp->codec_search_path, search_function);
-
- onError:
- return -1;
-}
-
-/* Convert a string to a normalized Python string: all characters are
- converted to lower case, spaces are replaced with underscores. */
-
-static
-PyObject *normalizestring(const char *string)
-{
- register size_t i;
- size_t len = strlen(string);
- char *p;
- PyObject *v;
-
- if (len > PY_SSIZE_T_MAX) {
- PyErr_SetString(PyExc_OverflowError, "string is too large");
- return NULL;
- }
-
- v = PyString_FromStringAndSize(NULL, len);
- if (v == NULL)
- return NULL;
- p = PyString_AS_STRING(v);
- for (i = 0; i < len; i++) {
- register char ch = string[i];
- if (ch == ' ')
- ch = '-';
- else
- ch = tolower(Py_CHARMASK(ch));
- p[i] = ch;
- }
- return v;
-}
-
-/* Lookup the given encoding and return a tuple providing the codec
- facilities.
-
- The encoding string is looked up converted to all lower-case
- characters. This makes encodings looked up through this mechanism
- effectively case-insensitive.
-
- If no codec is found, a LookupError is set and NULL returned.
-
- As side effect, this tries to load the encodings package, if not
- yet done. This is part of the lazy load strategy for the encodings
- package.
-
-*/
-
-PyObject *_PyCodec_Lookup(const char *encoding)
-{
- PyInterpreterState *interp;
- PyObject *result, *args = NULL, *v;
- Py_ssize_t i, len;
-
- if (encoding == NULL) {
- PyErr_BadArgument();
- goto onError;
- }
-
- interp = PyThreadState_GET()->interp;
- if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
- goto onError;
-
- /* Convert the encoding to a normalized Python string: all
- characters are converted to lower case, spaces and hyphens are
- replaced with underscores. */
- v = normalizestring(encoding);
- if (v == NULL)
- goto onError;
- PyString_InternInPlace(&v);
-
- /* First, try to lookup the name in the registry dictionary */
- result = PyDict_GetItem(interp->codec_search_cache, v);
- if (result != NULL) {
- Py_INCREF(result);
- Py_DECREF(v);
- return result;
- }
-
- /* Next, scan the search functions in order of registration */
- args = PyTuple_New(1);
- if (args == NULL)
- goto onError;
- PyTuple_SET_ITEM(args,0,v);
-
- len = PyList_Size(interp->codec_search_path);
- if (len < 0)
- goto onError;
- if (len == 0) {
- PyErr_SetString(PyExc_LookupError,
- "no codec search functions registered: "
- "can't find encoding");
- goto onError;
- }
-
- for (i = 0; i < len; i++) {
- PyObject *func;
-
- func = PyList_GetItem(interp->codec_search_path, i);
- if (func == NULL)
- goto onError;
- result = PyEval_CallObject(func, args);
- if (result == NULL)
- goto onError;
- if (result == Py_None) {
- Py_DECREF(result);
- continue;
- }
- if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 4) {
- PyErr_SetString(PyExc_TypeError,
- "codec search functions must return 4-tuples");
- Py_DECREF(result);
- goto onError;
- }
- break;
- }
- if (i == len) {
- /* XXX Perhaps we should cache misses too ? */
- PyErr_Format(PyExc_LookupError,
- "unknown encoding: %s", encoding);
- goto onError;
- }
-
- /* Cache and return the result */
- PyDict_SetItem(interp->codec_search_cache, v, result);
- Py_DECREF(args);
- return result;
-
- onError:
- Py_XDECREF(args);
- return NULL;
-}
-
-static
-PyObject *args_tuple(PyObject *object,
- const char *errors)
-{
- PyObject *args;
-
- args = PyTuple_New(1 + (errors != NULL));
- if (args == NULL)
- return NULL;
- Py_INCREF(object);
- PyTuple_SET_ITEM(args,0,object);
- if (errors) {
- PyObject *v;
-
- v = PyString_FromString(errors);
- if (v == NULL) {
- Py_DECREF(args);
- return NULL;
- }
- PyTuple_SET_ITEM(args, 1, v);
- }
- return args;
-}
-
-/* Helper function to get a codec item */
-
-static
-PyObject *codec_getitem(const char *encoding, int index)
-{
- PyObject *codecs;
- PyObject *v;
-
- codecs = _PyCodec_Lookup(encoding);
- if (codecs == NULL)
- return NULL;
- v = PyTuple_GET_ITEM(codecs, index);
- Py_DECREF(codecs);
- Py_INCREF(v);
- return v;
-}
-
-/* Helper function to create an incremental codec. */
-
-static
-PyObject *codec_getincrementalcodec(const char *encoding,
- const char *errors,
- const char *attrname)
-{
- PyObject *codecs, *ret, *inccodec;
-
- codecs = _PyCodec_Lookup(encoding);
- if (codecs == NULL)
- return NULL;
- inccodec = PyObject_GetAttrString(codecs, attrname);
- Py_DECREF(codecs);
- if (inccodec == NULL)
- return NULL;
- if (errors)
- ret = PyObject_CallFunction(inccodec, "s", errors);
- else
- ret = PyObject_CallFunction(inccodec, NULL);
- Py_DECREF(inccodec);
- return ret;
-}
-
-/* Helper function to create a stream codec. */
-
-static
-PyObject *codec_getstreamcodec(const char *encoding,
- PyObject *stream,
- const char *errors,
- const int index)
-{
- PyObject *codecs, *streamcodec, *codeccls;
-
- codecs = _PyCodec_Lookup(encoding);
- if (codecs == NULL)
- return NULL;
-
- codeccls = PyTuple_GET_ITEM(codecs, index);
- if (errors != NULL)
- streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors);
- else
- streamcodec = PyObject_CallFunction(codeccls, "O", stream);
- Py_DECREF(codecs);
- return streamcodec;
-}
-
-/* Convenience APIs to query the Codec registry.
-
- All APIs return a codec object with incremented refcount.
-
- */
-
-PyObject *PyCodec_Encoder(const char *encoding)
-{
- return codec_getitem(encoding, 0);
-}
-
-PyObject *PyCodec_Decoder(const char *encoding)
-{
- return codec_getitem(encoding, 1);
-}
-
-PyObject *PyCodec_IncrementalEncoder(const char *encoding,
- const char *errors)
-{
- return codec_getincrementalcodec(encoding, errors, "incrementalencoder");
-}
-
-PyObject *PyCodec_IncrementalDecoder(const char *encoding,
- const char *errors)
-{
- return codec_getincrementalcodec(encoding, errors, "incrementaldecoder");
-}
-
-PyObject *PyCodec_StreamReader(const char *encoding,
- PyObject *stream,
- const char *errors)
-{
- return codec_getstreamcodec(encoding, stream, errors, 2);
-}
-
-PyObject *PyCodec_StreamWriter(const char *encoding,
- PyObject *stream,
- const char *errors)
-{
- return codec_getstreamcodec(encoding, stream, errors, 3);
-}
-
-/* Encode an object (e.g. an Unicode object) using the given encoding
- and return the resulting encoded object (usually a Python string).
-
- errors is passed to the encoder factory as argument if non-NULL. */
-
-PyObject *PyCodec_Encode(PyObject *object,
- const char *encoding,
- const char *errors)
-{
- PyObject *encoder = NULL;
- PyObject *args = NULL, *result = NULL;
- PyObject *v;
-
- encoder = PyCodec_Encoder(encoding);
- if (encoder == NULL)
- goto onError;
-
- args = args_tuple(object, errors);
- if (args == NULL)
- goto onError;
-
- result = PyEval_CallObject(encoder,args);
- if (result == NULL)
- goto onError;
-
- if (!PyTuple_Check(result) ||
- PyTuple_GET_SIZE(result) != 2) {
- PyErr_SetString(PyExc_TypeError,
- "encoder must return a tuple (object,integer)");
- goto onError;
- }
- v = PyTuple_GET_ITEM(result,0);
- Py_INCREF(v);
- /* We don't check or use the second (integer) entry. */
-
- Py_DECREF(args);
- Py_DECREF(encoder);
- Py_DECREF(result);
- return v;
-
- onError:
- Py_XDECREF(result);
- Py_XDECREF(args);
- Py_XDECREF(encoder);
- return NULL;
-}
-
-/* Decode an object (usually a Python string) using the given encoding
- and return an equivalent object (e.g. an Unicode object).
-
- errors is passed to the decoder factory as argument if non-NULL. */
-
-PyObject *PyCodec_Decode(PyObject *object,
- const char *encoding,
- const char *errors)
-{
- PyObject *decoder = NULL;
- PyObject *args = NULL, *result = NULL;
- PyObject *v;
-
- decoder = PyCodec_Decoder(encoding);
- if (decoder == NULL)
- goto onError;
-
- args = args_tuple(object, errors);
- if (args == NULL)
- goto onError;
-
- result = PyEval_CallObject(decoder,args);
- if (result == NULL)
- goto onError;
- if (!PyTuple_Check(result) ||
- PyTuple_GET_SIZE(result) != 2) {
- PyErr_SetString(PyExc_TypeError,
- "decoder must return a tuple (object,integer)");
- goto onError;
- }
- v = PyTuple_GET_ITEM(result,0);
- Py_INCREF(v);
- /* We don't check or use the second (integer) entry. */
-
- Py_DECREF(args);
- Py_DECREF(decoder);
- Py_DECREF(result);
- return v;
-
- onError:
- Py_XDECREF(args);
- Py_XDECREF(decoder);
- Py_XDECREF(result);
- return NULL;
-}
-
-/* Register the error handling callback function error under the name
- name. This function will be called by the codec when it encounters
- an unencodable characters/undecodable bytes and doesn't know the
- callback name, when name is specified as the error parameter
- in the call to the encode/decode function.
- Return 0 on success, -1 on error */
-int PyCodec_RegisterError(const char *name, PyObject *error)
-{
- PyInterpreterState *interp = PyThreadState_GET()->interp;
- if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
- return -1;
- if (!PyCallable_Check(error)) {
- PyErr_SetString(PyExc_TypeError, "handler must be callable");
- return -1;
- }
- return PyDict_SetItemString(interp->codec_error_registry,
- (char *)name, error);
-}
-
-/* Lookup the error handling callback function registered under the
- name error. As a special case NULL can be passed, in which case
- the error handling callback for strict encoding will be returned. */
-PyObject *PyCodec_LookupError(const char *name)
-{
- PyObject *handler = NULL;
-
- PyInterpreterState *interp = PyThreadState_GET()->interp;
- if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
- return NULL;
-
- if (name==NULL)
- name = "strict";
- handler = PyDict_GetItemString(interp->codec_error_registry, (char *)name);
- if (!handler)
- PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name);
- else
- Py_INCREF(handler);
- return handler;
-}
-
-static void wrong_exception_type(PyObject *exc)
-{
- PyObject *type = PyObject_GetAttrString(exc, "__class__");
- if (type != NULL) {
- PyObject *name = PyObject_GetAttrString(type, "__name__");
- Py_DECREF(type);
- if (name != NULL) {
- PyObject *string = PyObject_Str(name);
- Py_DECREF(name);
- if (string != NULL) {
- PyErr_Format(PyExc_TypeError,
- "don't know how to handle %.400s in error callback",
- PyString_AS_STRING(string));
- Py_DECREF(string);
- }
- }
- }
-}
-
-PyObject *PyCodec_StrictErrors(PyObject *exc)
-{
- if (PyExceptionInstance_Check(exc))
- PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
- else
- PyErr_SetString(PyExc_TypeError, "codec must pass exception instance");
- return NULL;
-}
-
-
-#ifdef Py_USING_UNICODE
-PyObject *PyCodec_IgnoreErrors(PyObject *exc)
-{
- Py_ssize_t end;
- if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
- if (PyUnicodeEncodeError_GetEnd(exc, &end))
- return NULL;
- }
- else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) {
- if (PyUnicodeDecodeError_GetEnd(exc, &end))
- return NULL;
- }
- else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) {
- if (PyUnicodeTranslateError_GetEnd(exc, &end))
- return NULL;
- }
- else {
- wrong_exception_type(exc);
- return NULL;
- }
- /* ouch: passing NULL, 0, pos gives None instead of u'' */
- return Py_BuildValue("(u#n)", &end, 0, end);
-}
-
-
-PyObject *PyCodec_ReplaceErrors(PyObject *exc)
-{
- PyObject *restuple;
- Py_ssize_t start;
- Py_ssize_t end;
- Py_ssize_t i;
-
- if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
- PyObject *res;
- Py_UNICODE *p;
- if (PyUnicodeEncodeError_GetStart(exc, &start))
- return NULL;
- if (PyUnicodeEncodeError_GetEnd(exc, &end))
- return NULL;
- res = PyUnicode_FromUnicode(NULL, end-start);
- if (res == NULL)
- return NULL;
- for (p = PyUnicode_AS_UNICODE(res), i = start;
- i<end; ++p, ++i)
- *p = '?';
- restuple = Py_BuildValue("(On)", res, end);
- Py_DECREF(res);
- return restuple;
- }
- else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) {
- Py_UNICODE res = Py_UNICODE_REPLACEMENT_CHARACTER;
- if (PyUnicodeDecodeError_GetEnd(exc, &end))
- return NULL;
- return Py_BuildValue("(u#n)", &res, 1, end);
- }
- else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) {
- PyObject *res;
- Py_UNICODE *p;
- if (PyUnicodeTranslateError_GetStart(exc, &start))
- return NULL;
- if (PyUnicodeTranslateError_GetEnd(exc, &end))
- return NULL;
- res = PyUnicode_FromUnicode(NULL, end-start);
- if (res == NULL)
- return NULL;
- for (p = PyUnicode_AS_UNICODE(res), i = start;
- i<end; ++p, ++i)
- *p = Py_UNICODE_REPLACEMENT_CHARACTER;
- restuple = Py_BuildValue("(On)", res, end);
- Py_DECREF(res);
- return restuple;
- }
- else {
- wrong_exception_type(exc);
- return NULL;
- }
-}
-
-PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc)
-{
- if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
- PyObject *restuple;
- PyObject *object;
- Py_ssize_t start;
- Py_ssize_t end;
- PyObject *res;
- Py_UNICODE *p;
- Py_UNICODE *startp;
- Py_UNICODE *outp;
- int ressize;
- if (PyUnicodeEncodeError_GetStart(exc, &start))
- return NULL;
- if (PyUnicodeEncodeError_GetEnd(exc, &end))
- return NULL;
- if (!(object = PyUnicodeEncodeError_GetObject(exc)))
- return NULL;
- startp = PyUnicode_AS_UNICODE(object);
- for (p = startp+start, ressize = 0; p < startp+end; ++p) {
- if (*p<10)
- ressize += 2+1+1;
- else if (*p<100)
- ressize += 2+2+1;
- else if (*p<1000)
- ressize += 2+3+1;
- else if (*p<10000)
- ressize += 2+4+1;
-#ifndef Py_UNICODE_WIDE
- else
- ressize += 2+5+1;
-#else
- else if (*p<100000)
- ressize += 2+5+1;
- else if (*p<1000000)
- ressize += 2+6+1;
- else
- ressize += 2+7+1;
-#endif
- }
- /* allocate replacement */
- res = PyUnicode_FromUnicode(NULL, ressize);
- if (res == NULL) {
- Py_DECREF(object);
- return NULL;
- }
- /* generate replacement */
- for (p = startp+start, outp = PyUnicode_AS_UNICODE(res);
- p < startp+end; ++p) {
- Py_UNICODE c = *p;
- int digits;
- int base;
- *outp++ = '&';
- *outp++ = '#';
- if (*p<10) {
- digits = 1;
- base = 1;
- }
- else if (*p<100) {
- digits = 2;
- base = 10;
- }
- else if (*p<1000) {
- digits = 3;
- base = 100;
- }
- else if (*p<10000) {
- digits = 4;
- base = 1000;
- }
-#ifndef Py_UNICODE_WIDE
- else {
- digits = 5;
- base = 10000;
- }
-#else
- else if (*p<100000) {
- digits = 5;
- base = 10000;
- }
- else if (*p<1000000) {
- digits = 6;
- base = 100000;
- }
- else {
- digits = 7;
- base = 1000000;
- }
-#endif
- while (digits-->0) {
- *outp++ = '0' + c/base;
- c %= base;
- base /= 10;
- }
- *outp++ = ';';
- }
- restuple = Py_BuildValue("(On)", res, end);
- Py_DECREF(res);
- Py_DECREF(object);
- return restuple;
- }
- else {
- wrong_exception_type(exc);
- return NULL;
- }
-}
-
-static Py_UNICODE hexdigits[] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
-};
-
-PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc)
-{
- if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
- PyObject *restuple;
- PyObject *object;
- Py_ssize_t start;
- Py_ssize_t end;
- PyObject *res;
- Py_UNICODE *p;
- Py_UNICODE *startp;
- Py_UNICODE *outp;
- int ressize;
- if (PyUnicodeEncodeError_GetStart(exc, &start))
- return NULL;
- if (PyUnicodeEncodeError_GetEnd(exc, &end))
- return NULL;
- if (!(object = PyUnicodeEncodeError_GetObject(exc)))
- return NULL;
- startp = PyUnicode_AS_UNICODE(object);
- for (p = startp+start, ressize = 0; p < startp+end; ++p) {
-#ifdef Py_UNICODE_WIDE
- if (*p >= 0x00010000)
- ressize += 1+1+8;
- else
-#endif
- if (*p >= 0x100) {
- ressize += 1+1+4;
- }
- else
- ressize += 1+1+2;
- }
- res = PyUnicode_FromUnicode(NULL, ressize);
- if (res==NULL)
- return NULL;
- for (p = startp+start, outp = PyUnicode_AS_UNICODE(res);
- p < startp+end; ++p) {
- Py_UNICODE c = *p;
- *outp++ = '\\';
-#ifdef Py_UNICODE_WIDE
- if (c >= 0x00010000) {
- *outp++ = 'U';
- *outp++ = hexdigits[(c>>28)&0xf];
- *outp++ = hexdigits[(c>>24)&0xf];
- *outp++ = hexdigits[(c>>20)&0xf];
- *outp++ = hexdigits[(c>>16)&0xf];
- *outp++ = hexdigits[(c>>12)&0xf];
- *outp++ = hexdigits[(c>>8)&0xf];
- }
- else
-#endif
- if (c >= 0x100) {
- *outp++ = 'u';
- *outp++ = hexdigits[(c>>12)&0xf];
- *outp++ = hexdigits[(c>>8)&0xf];
- }
- else
- *outp++ = 'x';
- *outp++ = hexdigits[(c>>4)&0xf];
- *outp++ = hexdigits[c&0xf];
- }
-
- restuple = Py_BuildValue("(On)", res, end);
- Py_DECREF(res);
- Py_DECREF(object);
- return restuple;
- }
- else {
- wrong_exception_type(exc);
- return NULL;
- }
-}
-#endif
-
-static PyObject *strict_errors(PyObject *self, PyObject *exc)
-{
- return PyCodec_StrictErrors(exc);
-}
-
-
-#ifdef Py_USING_UNICODE
-static PyObject *ignore_errors(PyObject *self, PyObject *exc)
-{
- return PyCodec_IgnoreErrors(exc);
-}
-
-
-static PyObject *replace_errors(PyObject *self, PyObject *exc)
-{
- return PyCodec_ReplaceErrors(exc);
-}
-
-
-static PyObject *xmlcharrefreplace_errors(PyObject *self, PyObject *exc)
-{
- return PyCodec_XMLCharRefReplaceErrors(exc);
-}
-
-
-static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc)
-{
- return PyCodec_BackslashReplaceErrors(exc);
-}
-#endif
-
-static int _PyCodecRegistry_Init(void)
-{
- static struct {
- char *name;
- PyMethodDef def;
- } methods[] =
- {
- {
- "strict",
- {
- "strict_errors",
- strict_errors,
- METH_O
- }
- },
-#ifdef Py_USING_UNICODE
- {
- "ignore",
- {
- "ignore_errors",
- ignore_errors,
- METH_O
- }
- },
- {
- "replace",
- {
- "replace_errors",
- replace_errors,
- METH_O
- }
- },
- {
- "xmlcharrefreplace",
- {
- "xmlcharrefreplace_errors",
- xmlcharrefreplace_errors,
- METH_O
- }
- },
- {
- "backslashreplace",
- {
- "backslashreplace_errors",
- backslashreplace_errors,
- METH_O
- }
- }
-#endif
- };
-
- PyInterpreterState *interp = PyThreadState_GET()->interp;
- PyObject *mod;
- unsigned i;
-
- if (interp->codec_search_path != NULL)
- return 0;
-
- interp->codec_search_path = PyList_New(0);
- interp->codec_search_cache = PyDict_New();
- interp->codec_error_registry = PyDict_New();
-
- if (interp->codec_error_registry) {
- for (i = 0; i < sizeof(methods)/sizeof(methods[0]); ++i) {
- PyObject *func = PyCFunction_New(&methods[i].def, NULL);
- int res;
- if (!func)
- Py_FatalError("can't initialize codec error registry");
- res = PyCodec_RegisterError(methods[i].name, func);
- Py_DECREF(func);
- if (res)
- Py_FatalError("can't initialize codec error registry");
- }
- }
-
- if (interp->codec_search_path == NULL ||
- interp->codec_search_cache == NULL ||
- interp->codec_error_registry == NULL)
- Py_FatalError("can't initialize codec registry");
-
- mod = PyImport_ImportModuleLevel("encodings", NULL, NULL, NULL, 0);
- if (mod == NULL) {
- if (PyErr_ExceptionMatches(PyExc_ImportError)) {
- /* Ignore ImportErrors... this is done so that
- distributions can disable the encodings package. Note
- that other errors are not masked, e.g. SystemErrors
- raised to inform the user of an error in the Python
- configuration are still reported back to the user. */
- PyErr_Clear();
- return 0;
- }
- return -1;
- }
- Py_DECREF(mod);
- return 0;
-}
diff --git a/sys/src/cmd/python/Python/compile.c b/sys/src/cmd/python/Python/compile.c
deleted file mode 100644
index e493beb6c..000000000
--- a/sys/src/cmd/python/Python/compile.c
+++ /dev/null
@@ -1,4570 +0,0 @@
-/*
- * This file compiles an abstract syntax tree (AST) into Python bytecode.
- *
- * The primary entry point is PyAST_Compile(), which returns a
- * PyCodeObject. The compiler makes several passes to build the code
- * object:
- * 1. Checks for future statements. See future.c
- * 2. Builds a symbol table. See symtable.c.
- * 3. Generate code for basic blocks. See compiler_mod() in this file.
- * 4. Assemble the basic blocks into final code. See assemble() in
- * this file.
- *
- * Note that compiler_mod() suggests module, but the module ast type
- * (mod_ty) has cases for expressions and interactive statements.
- *
- * CAUTION: The VISIT_* macros abort the current function when they
- * encounter a problem. So don't invoke them when there is memory
- * which needs to be released. Code blocks are OK, as the compiler
- * structure takes care of releasing those.
- */
-
-#include "Python.h"
-
-#include "Python-ast.h"
-#include "node.h"
-#include "pyarena.h"
-#include "ast.h"
-#include "code.h"
-#include "compile.h"
-#include "symtable.h"
-#include "opcode.h"
-
-int Py_OptimizeFlag = 0;
-
-/*
- ISSUES:
-
- opcode_stack_effect() function should be reviewed since stack depth bugs
- could be really hard to find later.
-
- Dead code is being generated (i.e. after unconditional jumps).
- XXX(nnorwitz): not sure this is still true
-*/
-
-#define DEFAULT_BLOCK_SIZE 16
-#define DEFAULT_BLOCKS 8
-#define DEFAULT_CODE_SIZE 128
-#define DEFAULT_LNOTAB_SIZE 16
-
-struct instr {
- unsigned i_jabs : 1;
- unsigned i_jrel : 1;
- unsigned i_hasarg : 1;
- unsigned char i_opcode;
- int i_oparg;
- struct basicblock_ *i_target; /* target block (if jump instruction) */
- int i_lineno;
-};
-
-typedef struct basicblock_ {
- /* Each basicblock in a compilation unit is linked via b_list in the
- reverse order that the block are allocated. b_list points to the next
- block, not to be confused with b_next, which is next by control flow. */
- struct basicblock_ *b_list;
- /* number of instructions used */
- int b_iused;
- /* length of instruction array (b_instr) */
- int b_ialloc;
- /* pointer to an array of instructions, initially NULL */
- struct instr *b_instr;
- /* If b_next is non-NULL, it is a pointer to the next
- block reached by normal control flow. */
- struct basicblock_ *b_next;
- /* b_seen is used to perform a DFS of basicblocks. */
- unsigned b_seen : 1;
- /* b_return is true if a RETURN_VALUE opcode is inserted. */
- unsigned b_return : 1;
- /* depth of stack upon entry of block, computed by stackdepth() */
- int b_startdepth;
- /* instruction offset for block, computed by assemble_jump_offsets() */
- int b_offset;
-} basicblock;
-
-/* fblockinfo tracks the current frame block.
-
-A frame block is used to handle loops, try/except, and try/finally.
-It's called a frame block to distinguish it from a basic block in the
-compiler IR.
-*/
-
-enum fblocktype { LOOP, EXCEPT, FINALLY_TRY, FINALLY_END };
-
-struct fblockinfo {
- enum fblocktype fb_type;
- basicblock *fb_block;
-};
-
-/* The following items change on entry and exit of code blocks.
- They must be saved and restored when returning to a block.
-*/
-struct compiler_unit {
- PySTEntryObject *u_ste;
-
- PyObject *u_name;
- /* The following fields are dicts that map objects to
- the index of them in co_XXX. The index is used as
- the argument for opcodes that refer to those collections.
- */
- PyObject *u_consts; /* all constants */
- PyObject *u_names; /* all names */
- PyObject *u_varnames; /* local variables */
- PyObject *u_cellvars; /* cell variables */
- PyObject *u_freevars; /* free variables */
-
- PyObject *u_private; /* for private name mangling */
-
- int u_argcount; /* number of arguments for block */
- /* Pointer to the most recently allocated block. By following b_list
- members, you can reach all early allocated blocks. */
- basicblock *u_blocks;
- basicblock *u_curblock; /* pointer to current block */
- int u_tmpname; /* temporary variables for list comps */
-
- int u_nfblocks;
- struct fblockinfo u_fblock[CO_MAXBLOCKS];
-
- int u_firstlineno; /* the first lineno of the block */
- int u_lineno; /* the lineno for the current stmt */
- bool u_lineno_set; /* boolean to indicate whether instr
- has been generated with current lineno */
-};
-
-/* This struct captures the global state of a compilation.
-
-The u pointer points to the current compilation unit, while units
-for enclosing blocks are stored in c_stack. The u and c_stack are
-managed by compiler_enter_scope() and compiler_exit_scope().
-*/
-
-struct compiler {
- const char *c_filename;
- struct symtable *c_st;
- PyFutureFeatures *c_future; /* pointer to module's __future__ */
- PyCompilerFlags *c_flags;
-
- int c_interactive; /* true if in interactive mode */
- int c_nestlevel;
-
- struct compiler_unit *u; /* compiler state for current block */
- PyObject *c_stack; /* Python list holding compiler_unit ptrs */
- char *c_encoding; /* source encoding (a borrowed reference) */
- PyArena *c_arena; /* pointer to memory allocation arena */
-};
-
-struct assembler {
- PyObject *a_bytecode; /* string containing bytecode */
- int a_offset; /* offset into bytecode */
- int a_nblocks; /* number of reachable blocks */
- basicblock **a_postorder; /* list of blocks in dfs postorder */
- PyObject *a_lnotab; /* string containing lnotab */
- int a_lnotab_off; /* offset into lnotab */
- int a_lineno; /* last lineno of emitted instruction */
- int a_lineno_off; /* bytecode offset of last lineno */
-};
-
-static int compiler_enter_scope(struct compiler *, identifier, void *, int);
-static void compiler_free(struct compiler *);
-static basicblock *compiler_new_block(struct compiler *);
-static int compiler_next_instr(struct compiler *, basicblock *);
-static int compiler_addop(struct compiler *, int);
-static int compiler_addop_o(struct compiler *, int, PyObject *, PyObject *);
-static int compiler_addop_i(struct compiler *, int, int);
-static int compiler_addop_j(struct compiler *, int, basicblock *, int);
-static basicblock *compiler_use_new_block(struct compiler *);
-static int compiler_error(struct compiler *, const char *);
-static int compiler_nameop(struct compiler *, identifier, expr_context_ty);
-
-static PyCodeObject *compiler_mod(struct compiler *, mod_ty);
-static int compiler_visit_stmt(struct compiler *, stmt_ty);
-static int compiler_visit_keyword(struct compiler *, keyword_ty);
-static int compiler_visit_expr(struct compiler *, expr_ty);
-static int compiler_augassign(struct compiler *, stmt_ty);
-static int compiler_visit_slice(struct compiler *, slice_ty,
- expr_context_ty);
-
-static int compiler_push_fblock(struct compiler *, enum fblocktype,
- basicblock *);
-static void compiler_pop_fblock(struct compiler *, enum fblocktype,
- basicblock *);
-/* Returns true if there is a loop on the fblock stack. */
-static int compiler_in_loop(struct compiler *);
-
-static int inplace_binop(struct compiler *, operator_ty);
-static int expr_constant(expr_ty e);
-
-static int compiler_with(struct compiler *, stmt_ty);
-
-static PyCodeObject *assemble(struct compiler *, int addNone);
-static PyObject *__doc__;
-
-PyObject *
-_Py_Mangle(PyObject *privateobj, PyObject *ident)
-{
- /* Name mangling: __private becomes _classname__private.
- This is independent from how the name is used. */
- const char *p, *name = PyString_AsString(ident);
- char *buffer;
- size_t nlen, plen;
- if (privateobj == NULL || !PyString_Check(privateobj) ||
- name == NULL || name[0] != '_' || name[1] != '_') {
- Py_INCREF(ident);
- return ident;
- }
- p = PyString_AsString(privateobj);
- nlen = strlen(name);
- if (name[nlen-1] == '_' && name[nlen-2] == '_') {
- Py_INCREF(ident);
- return ident; /* Don't mangle __whatever__ */
- }
- /* Strip leading underscores from class name */
- while (*p == '_')
- p++;
- if (*p == '\0') {
- Py_INCREF(ident);
- return ident; /* Don't mangle if class is just underscores */
- }
- plen = strlen(p);
- ident = PyString_FromStringAndSize(NULL, 1 + nlen + plen);
- if (!ident)
- return 0;
- /* ident = "_" + p[:plen] + name # i.e. 1+plen+nlen bytes */
- buffer = PyString_AS_STRING(ident);
- buffer[0] = '_';
- strncpy(buffer+1, p, plen);
- strcpy(buffer+1+plen, name);
- return ident;
-}
-
-static int
-compiler_init(struct compiler *c)
-{
- memset(c, 0, sizeof(struct compiler));
-
- c->c_stack = PyList_New(0);
- if (!c->c_stack)
- return 0;
-
- return 1;
-}
-
-PyCodeObject *
-PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
- PyArena *arena)
-{
- struct compiler c;
- PyCodeObject *co = NULL;
- PyCompilerFlags local_flags;
- int merged;
-
- if (!__doc__) {
- __doc__ = PyString_InternFromString("__doc__");
- if (!__doc__)
- return NULL;
- }
-
- if (!compiler_init(&c))
- return NULL;
- c.c_filename = filename;
- c.c_arena = arena;
- c.c_future = PyFuture_FromAST(mod, filename);
- if (c.c_future == NULL)
- goto finally;
- if (!flags) {
- local_flags.cf_flags = 0;
- flags = &local_flags;
- }
- merged = c.c_future->ff_features | flags->cf_flags;
- c.c_future->ff_features = merged;
- flags->cf_flags = merged;
- c.c_flags = flags;
- c.c_nestlevel = 0;
-
- c.c_st = PySymtable_Build(mod, filename, c.c_future);
- if (c.c_st == NULL) {
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_SystemError, "no symtable");
- goto finally;
- }
-
- /* XXX initialize to NULL for now, need to handle */
- c.c_encoding = NULL;
-
- co = compiler_mod(&c, mod);
-
- finally:
- compiler_free(&c);
- assert(co || PyErr_Occurred());
- return co;
-}
-
-PyCodeObject *
-PyNode_Compile(struct _node *n, const char *filename)
-{
- PyCodeObject *co = NULL;
- mod_ty mod;
- PyArena *arena = PyArena_New();
- if (!arena)
- return NULL;
- mod = PyAST_FromNode(n, NULL, filename, arena);
- if (mod)
- co = PyAST_Compile(mod, filename, NULL, arena);
- PyArena_Free(arena);
- return co;
-}
-
-static void
-compiler_free(struct compiler *c)
-{
- if (c->c_st)
- PySymtable_Free(c->c_st);
- if (c->c_future)
- PyObject_Free(c->c_future);
- Py_DECREF(c->c_stack);
-}
-
-static PyObject *
-list2dict(PyObject *list)
-{
- Py_ssize_t i, n;
- PyObject *v, *k;
- PyObject *dict = PyDict_New();
- if (!dict) return NULL;
-
- n = PyList_Size(list);
- for (i = 0; i < n; i++) {
- v = PyInt_FromLong(i);
- if (!v) {
- Py_DECREF(dict);
- return NULL;
- }
- k = PyList_GET_ITEM(list, i);
- k = PyTuple_Pack(2, k, k->ob_type);
- if (k == NULL || PyDict_SetItem(dict, k, v) < 0) {
- Py_XDECREF(k);
- Py_DECREF(v);
- Py_DECREF(dict);
- return NULL;
- }
- Py_DECREF(k);
- Py_DECREF(v);
- }
- return dict;
-}
-
-/* Return new dict containing names from src that match scope(s).
-
-src is a symbol table dictionary. If the scope of a name matches
-either scope_type or flag is set, insert it into the new dict. The
-values are integers, starting at offset and increasing by one for
-each key.
-*/
-
-static PyObject *
-dictbytype(PyObject *src, int scope_type, int flag, int offset)
-{
- Py_ssize_t pos = 0, i = offset, scope;
- PyObject *k, *v, *dest = PyDict_New();
-
- assert(offset >= 0);
- if (dest == NULL)
- return NULL;
-
- while (PyDict_Next(src, &pos, &k, &v)) {
- /* XXX this should probably be a macro in symtable.h */
- assert(PyInt_Check(v));
- scope = (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK;
-
- if (scope == scope_type || PyInt_AS_LONG(v) & flag) {
- PyObject *tuple, *item = PyInt_FromLong(i);
- if (item == NULL) {
- Py_DECREF(dest);
- return NULL;
- }
- i++;
- tuple = PyTuple_Pack(2, k, k->ob_type);
- if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) {
- Py_DECREF(item);
- Py_DECREF(dest);
- Py_XDECREF(tuple);
- return NULL;
- }
- Py_DECREF(item);
- Py_DECREF(tuple);
- }
- }
- return dest;
-}
-
-/* Begin: Peephole optimizations ----------------------------------------- */
-
-#define GETARG(arr, i) ((int)((arr[i+2]<<8) + arr[i+1]))
-#define UNCONDITIONAL_JUMP(op) (op==JUMP_ABSOLUTE || op==JUMP_FORWARD)
-#define ABSOLUTE_JUMP(op) (op==JUMP_ABSOLUTE || op==CONTINUE_LOOP)
-#define GETJUMPTGT(arr, i) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3))
-#define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255
-#define CODESIZE(op) (HAS_ARG(op) ? 3 : 1)
-#define ISBASICBLOCK(blocks, start, bytes) \
- (blocks[start]==blocks[start+bytes-1])
-
-/* Replace LOAD_CONST c1. LOAD_CONST c2 ... LOAD_CONST cn BUILD_TUPLE n
- with LOAD_CONST (c1, c2, ... cn).
- The consts table must still be in list form so that the
- new constant (c1, c2, ... cn) can be appended.
- Called with codestr pointing to the first LOAD_CONST.
- Bails out with no change if one or more of the LOAD_CONSTs is missing.
- Also works for BUILD_LIST when followed by an "in" or "not in" test.
-*/
-static int
-tuple_of_constants(unsigned char *codestr, int n, PyObject *consts)
-{
- PyObject *newconst, *constant;
- Py_ssize_t i, arg, len_consts;
-
- /* Pre-conditions */
- assert(PyList_CheckExact(consts));
- assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST);
- assert(GETARG(codestr, (n*3)) == n);
- for (i=0 ; i<n ; i++)
- assert(codestr[i*3] == LOAD_CONST);
-
- /* Buildup new tuple of constants */
- newconst = PyTuple_New(n);
- if (newconst == NULL)
- return 0;
- len_consts = PyList_GET_SIZE(consts);
- for (i=0 ; i<n ; i++) {
- arg = GETARG(codestr, (i*3));
- assert(arg < len_consts);
- constant = PyList_GET_ITEM(consts, arg);
- Py_INCREF(constant);
- PyTuple_SET_ITEM(newconst, i, constant);
- }
-
- /* Append folded constant onto consts */
- if (PyList_Append(consts, newconst)) {
- Py_DECREF(newconst);
- return 0;
- }
- Py_DECREF(newconst);
-
- /* Write NOPs over old LOAD_CONSTS and
- add a new LOAD_CONST newconst on top of the BUILD_TUPLE n */
- memset(codestr, NOP, n*3);
- codestr[n*3] = LOAD_CONST;
- SETARG(codestr, (n*3), len_consts);
- return 1;
-}
-
-/* Replace LOAD_CONST c1. LOAD_CONST c2 BINOP
- with LOAD_CONST binop(c1,c2)
- The consts table must still be in list form so that the
- new constant can be appended.
- Called with codestr pointing to the first LOAD_CONST.
- Abandons the transformation if the folding fails (i.e. 1+'a').
- If the new constant is a sequence, only folds when the size
- is below a threshold value. That keeps pyc files from
- becoming large in the presence of code like: (None,)*1000.
-*/
-static int
-fold_binops_on_constants(unsigned char *codestr, PyObject *consts)
-{
- PyObject *newconst, *v, *w;
- Py_ssize_t len_consts, size;
- int opcode;
-
- /* Pre-conditions */
- assert(PyList_CheckExact(consts));
- assert(codestr[0] == LOAD_CONST);
- assert(codestr[3] == LOAD_CONST);
-
- /* Create new constant */
- v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
- w = PyList_GET_ITEM(consts, GETARG(codestr, 3));
- opcode = codestr[6];
- switch (opcode) {
- case BINARY_POWER:
- newconst = PyNumber_Power(v, w, Py_None);
- break;
- case BINARY_MULTIPLY:
- newconst = PyNumber_Multiply(v, w);
- break;
- case BINARY_DIVIDE:
- /* Cannot fold this operation statically since
- the result can depend on the run-time presence
- of the -Qnew flag */
- return 0;
- case BINARY_TRUE_DIVIDE:
- newconst = PyNumber_TrueDivide(v, w);
- break;
- case BINARY_FLOOR_DIVIDE:
- newconst = PyNumber_FloorDivide(v, w);
- break;
- case BINARY_MODULO:
- newconst = PyNumber_Remainder(v, w);
- break;
- case BINARY_ADD:
- newconst = PyNumber_Add(v, w);
- break;
- case BINARY_SUBTRACT:
- newconst = PyNumber_Subtract(v, w);
- break;
- case BINARY_SUBSCR:
- newconst = PyObject_GetItem(v, w);
- break;
- case BINARY_LSHIFT:
- newconst = PyNumber_Lshift(v, w);
- break;
- case BINARY_RSHIFT:
- newconst = PyNumber_Rshift(v, w);
- break;
- case BINARY_AND:
- newconst = PyNumber_And(v, w);
- break;
- case BINARY_XOR:
- newconst = PyNumber_Xor(v, w);
- break;
- case BINARY_OR:
- newconst = PyNumber_Or(v, w);
- break;
- default:
- /* Called with an unknown opcode */
- PyErr_Format(PyExc_SystemError,
- "unexpected binary operation %d on a constant",
- opcode);
- return 0;
- }
- if (newconst == NULL) {
- PyErr_Clear();
- return 0;
- }
- size = PyObject_Size(newconst);
- if (size == -1)
- PyErr_Clear();
- else if (size > 20) {
- Py_DECREF(newconst);
- return 0;
- }
-
- /* Append folded constant into consts table */
- len_consts = PyList_GET_SIZE(consts);
- if (PyList_Append(consts, newconst)) {
- Py_DECREF(newconst);
- return 0;
- }
- Py_DECREF(newconst);
-
- /* Write NOP NOP NOP NOP LOAD_CONST newconst */
- memset(codestr, NOP, 4);
- codestr[4] = LOAD_CONST;
- SETARG(codestr, 4, len_consts);
- return 1;
-}
-
-static int
-fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)
-{
- PyObject *newconst=NULL, *v;
- Py_ssize_t len_consts;
- int opcode;
-
- /* Pre-conditions */
- assert(PyList_CheckExact(consts));
- assert(codestr[0] == LOAD_CONST);
-
- /* Create new constant */
- v = PyList_GET_ITEM(consts, GETARG(codestr, 0));
- opcode = codestr[3];
- switch (opcode) {
- case UNARY_NEGATIVE:
- /* Preserve the sign of -0.0 */
- if (PyObject_IsTrue(v) == 1)
- newconst = PyNumber_Negative(v);
- break;
- case UNARY_CONVERT:
- newconst = PyObject_Repr(v);
- break;
- case UNARY_INVERT:
- newconst = PyNumber_Invert(v);
- break;
- default:
- /* Called with an unknown opcode */
- PyErr_Format(PyExc_SystemError,
- "unexpected unary operation %d on a constant",
- opcode);
- return 0;
- }
- if (newconst == NULL) {
- PyErr_Clear();
- return 0;
- }
-
- /* Append folded constant into consts table */
- len_consts = PyList_GET_SIZE(consts);
- if (PyList_Append(consts, newconst)) {
- Py_DECREF(newconst);
- return 0;
- }
- Py_DECREF(newconst);
-
- /* Write NOP LOAD_CONST newconst */
- codestr[0] = NOP;
- codestr[1] = LOAD_CONST;
- SETARG(codestr, 1, len_consts);
- return 1;
-}
-
-static unsigned int *
-markblocks(unsigned char *code, int len)
-{
- unsigned int *blocks = (unsigned int *)PyMem_Malloc(len*sizeof(int));
- int i,j, opcode, blockcnt = 0;
-
- if (blocks == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
- memset(blocks, 0, len*sizeof(int));
-
- /* Mark labels in the first pass */
- for (i=0 ; i<len ; i+=CODESIZE(opcode)) {
- opcode = code[i];
- switch (opcode) {
- case FOR_ITER:
- case JUMP_FORWARD:
- case JUMP_IF_FALSE:
- case JUMP_IF_TRUE:
- case JUMP_ABSOLUTE:
- case CONTINUE_LOOP:
- case SETUP_LOOP:
- case SETUP_EXCEPT:
- case SETUP_FINALLY:
- j = GETJUMPTGT(code, i);
- blocks[j] = 1;
- break;
- }
- }
- /* Build block numbers in the second pass */
- for (i=0 ; i<len ; i++) {
- blockcnt += blocks[i]; /* increment blockcnt over labels */
- blocks[i] = blockcnt;
- }
- return blocks;
-}
-
-/* Perform basic peephole optimizations to components of a code object.
- The consts object should still be in list form to allow new constants
- to be appended.
-
- To keep the optimizer simple, it bails out (does nothing) for code
- containing extended arguments or that has a length over 32,700. That
- allows us to avoid overflow and sign issues. Likewise, it bails when
- the lineno table has complex encoding for gaps >= 255.
-
- Optimizations are restricted to simple transformations occuring within a
- single basic block. All transformations keep the code size the same or
- smaller. For those that reduce size, the gaps are initially filled with
- NOPs. Later those NOPs are removed and the jump addresses retargeted in
- a single pass. Line numbering is adjusted accordingly. */
-
-static PyObject *
-optimize_code(PyObject *code, PyObject* consts, PyObject *names,
- PyObject *lineno_obj)
-{
- Py_ssize_t i, j, codelen;
- int nops, h, adj;
- int tgt, tgttgt, opcode;
- unsigned char *codestr = NULL;
- unsigned char *lineno;
- int *addrmap = NULL;
- int new_line, cum_orig_line, last_line, tabsiz;
- int cumlc=0, lastlc=0; /* Count runs of consecutive LOAD_CONSTs */
- unsigned int *blocks = NULL;
- char *name;
-
- /* Bail out if an exception is set */
- if (PyErr_Occurred())
- goto exitUnchanged;
-
- /* Bypass optimization when the lineno table is too complex */
- assert(PyString_Check(lineno_obj));
- lineno = (unsigned char*)PyString_AS_STRING(lineno_obj);
- tabsiz = PyString_GET_SIZE(lineno_obj);
- if (memchr(lineno, 255, tabsiz) != NULL)
- goto exitUnchanged;
-
- /* Avoid situations where jump retargeting could overflow */
- assert(PyString_Check(code));
- codelen = PyString_Size(code);
- if (codelen > 32700)
- goto exitUnchanged;
-
- /* Make a modifiable copy of the code string */
- codestr = (unsigned char *)PyMem_Malloc(codelen);
- if (codestr == NULL)
- goto exitUnchanged;
- codestr = (unsigned char *)memcpy(codestr,
- PyString_AS_STRING(code), codelen);
-
- /* Verify that RETURN_VALUE terminates the codestring. This allows
- the various transformation patterns to look ahead several
- instructions without additional checks to make sure they are not
- looking beyond the end of the code string.
- */
- if (codestr[codelen-1] != RETURN_VALUE)
- goto exitUnchanged;
-
- /* Mapping to new jump targets after NOPs are removed */
- addrmap = (int *)PyMem_Malloc(codelen * sizeof(int));
- if (addrmap == NULL)
- goto exitUnchanged;
-
- blocks = markblocks(codestr, codelen);
- if (blocks == NULL)
- goto exitUnchanged;
- assert(PyList_Check(consts));
-
- for (i=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
- opcode = codestr[i];
-
- lastlc = cumlc;
- cumlc = 0;
-
- switch (opcode) {
-
- /* Replace UNARY_NOT JUMP_IF_FALSE POP_TOP with
- with JUMP_IF_TRUE POP_TOP */
- case UNARY_NOT:
- if (codestr[i+1] != JUMP_IF_FALSE ||
- codestr[i+4] != POP_TOP ||
- !ISBASICBLOCK(blocks,i,5))
- continue;
- tgt = GETJUMPTGT(codestr, (i+1));
- if (codestr[tgt] != POP_TOP)
- continue;
- j = GETARG(codestr, i+1) + 1;
- codestr[i] = JUMP_IF_TRUE;
- SETARG(codestr, i, j);
- codestr[i+3] = POP_TOP;
- codestr[i+4] = NOP;
- break;
-
- /* not a is b --> a is not b
- not a in b --> a not in b
- not a is not b --> a is b
- not a not in b --> a in b
- */
- case COMPARE_OP:
- j = GETARG(codestr, i);
- if (j < 6 || j > 9 ||
- codestr[i+3] != UNARY_NOT ||
- !ISBASICBLOCK(blocks,i,4))
- continue;
- SETARG(codestr, i, (j^1));
- codestr[i+3] = NOP;
- break;
-
- /* Replace LOAD_GLOBAL/LOAD_NAME None
- with LOAD_CONST None */
- case LOAD_NAME:
- case LOAD_GLOBAL:
- j = GETARG(codestr, i);
- name = PyString_AsString(PyTuple_GET_ITEM(names, j));
- if (name == NULL || strcmp(name, "None") != 0)
- continue;
- for (j=0 ; j < PyList_GET_SIZE(consts) ; j++) {
- if (PyList_GET_ITEM(consts, j) == Py_None)
- break;
- }
- if (j == PyList_GET_SIZE(consts)) {
- if (PyList_Append(consts, Py_None) == -1)
- goto exitUnchanged;
- }
- assert(PyList_GET_ITEM(consts, j) == Py_None);
- codestr[i] = LOAD_CONST;
- SETARG(codestr, i, j);
- cumlc = lastlc + 1;
- break;
-
- /* Skip over LOAD_CONST trueconst
- JUMP_IF_FALSE xx POP_TOP */
- case LOAD_CONST:
- cumlc = lastlc + 1;
- j = GETARG(codestr, i);
- if (codestr[i+3] != JUMP_IF_FALSE ||
- codestr[i+6] != POP_TOP ||
- !ISBASICBLOCK(blocks,i,7) ||
- !PyObject_IsTrue(PyList_GET_ITEM(consts, j)))
- continue;
- memset(codestr+i, NOP, 7);
- cumlc = 0;
- break;
-
- /* Try to fold tuples of constants (includes a case for lists
- which are only used for "in" and "not in" tests).
- Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
- Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
- Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
- case BUILD_TUPLE:
- case BUILD_LIST:
- j = GETARG(codestr, i);
- h = i - 3 * j;
- if (h >= 0 &&
- j <= lastlc &&
- ((opcode == BUILD_TUPLE &&
- ISBASICBLOCK(blocks, h, 3*(j+1))) ||
- (opcode == BUILD_LIST &&
- codestr[i+3]==COMPARE_OP &&
- ISBASICBLOCK(blocks, h, 3*(j+2)) &&
- (GETARG(codestr,i+3)==6 ||
- GETARG(codestr,i+3)==7))) &&
- tuple_of_constants(&codestr[h], j, consts)) {
- assert(codestr[i] == LOAD_CONST);
- cumlc = 1;
- break;
- }
- if (codestr[i+3] != UNPACK_SEQUENCE ||
- !ISBASICBLOCK(blocks,i,6) ||
- j != GETARG(codestr, i+3))
- continue;
- if (j == 1) {
- memset(codestr+i, NOP, 6);
- } else if (j == 2) {
- codestr[i] = ROT_TWO;
- memset(codestr+i+1, NOP, 5);
- } else if (j == 3) {
- codestr[i] = ROT_THREE;
- codestr[i+1] = ROT_TWO;
- memset(codestr+i+2, NOP, 4);
- }
- break;
-
- /* Fold binary ops on constants.
- LOAD_CONST c1 LOAD_CONST c2 BINOP --> LOAD_CONST binop(c1,c2) */
- case BINARY_POWER:
- case BINARY_MULTIPLY:
- case BINARY_TRUE_DIVIDE:
- case BINARY_FLOOR_DIVIDE:
- case BINARY_MODULO:
- case BINARY_ADD:
- case BINARY_SUBTRACT:
- case BINARY_SUBSCR:
- case BINARY_LSHIFT:
- case BINARY_RSHIFT:
- case BINARY_AND:
- case BINARY_XOR:
- case BINARY_OR:
- if (lastlc >= 2 &&
- ISBASICBLOCK(blocks, i-6, 7) &&
- fold_binops_on_constants(&codestr[i-6], consts)) {
- i -= 2;
- assert(codestr[i] == LOAD_CONST);
- cumlc = 1;
- }
- break;
-
- /* Fold unary ops on constants.
- LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */
- case UNARY_NEGATIVE:
- case UNARY_CONVERT:
- case UNARY_INVERT:
- if (lastlc >= 1 &&
- ISBASICBLOCK(blocks, i-3, 4) &&
- fold_unaryops_on_constants(&codestr[i-3], consts)) {
- i -= 2;
- assert(codestr[i] == LOAD_CONST);
- cumlc = 1;
- }
- break;
-
- /* Simplify conditional jump to conditional jump where the
- result of the first test implies the success of a similar
- test or the failure of the opposite test.
- Arises in code like:
- "if a and b:"
- "if a or b:"
- "a and b or c"
- "(a and b) and c"
- x:JUMP_IF_FALSE y y:JUMP_IF_FALSE z --> x:JUMP_IF_FALSE z
- x:JUMP_IF_FALSE y y:JUMP_IF_TRUE z --> x:JUMP_IF_FALSE y+3
- where y+3 is the instruction following the second test.
- */
- case JUMP_IF_FALSE:
- case JUMP_IF_TRUE:
- tgt = GETJUMPTGT(codestr, i);
- j = codestr[tgt];
- if (j == JUMP_IF_FALSE || j == JUMP_IF_TRUE) {
- if (j == opcode) {
- tgttgt = GETJUMPTGT(codestr, tgt) - i - 3;
- SETARG(codestr, i, tgttgt);
- } else {
- tgt -= i;
- SETARG(codestr, i, tgt);
- }
- break;
- }
- /* Intentional fallthrough */
-
- /* Replace jumps to unconditional jumps */
- case FOR_ITER:
- case JUMP_FORWARD:
- case JUMP_ABSOLUTE:
- case CONTINUE_LOOP:
- case SETUP_LOOP:
- case SETUP_EXCEPT:
- case SETUP_FINALLY:
- tgt = GETJUMPTGT(codestr, i);
- if (!UNCONDITIONAL_JUMP(codestr[tgt]))
- continue;
- tgttgt = GETJUMPTGT(codestr, tgt);
- if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */
- opcode = JUMP_ABSOLUTE;
- if (!ABSOLUTE_JUMP(opcode))
- tgttgt -= i + 3; /* Calc relative jump addr */
- if (tgttgt < 0) /* No backward relative jumps */
- continue;
- codestr[i] = opcode;
- SETARG(codestr, i, tgttgt);
- break;
-
- case EXTENDED_ARG:
- goto exitUnchanged;
-
- /* Replace RETURN LOAD_CONST None RETURN with just RETURN */
- case RETURN_VALUE:
- if (i+4 >= codelen ||
- codestr[i+4] != RETURN_VALUE ||
- !ISBASICBLOCK(blocks,i,5))
- continue;
- memset(codestr+i+1, NOP, 4);
- break;
- }
- }
-
- /* Fixup linenotab */
- for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
- addrmap[i] = i - nops;
- if (codestr[i] == NOP)
- nops++;
- }
- cum_orig_line = 0;
- last_line = 0;
- for (i=0 ; i < tabsiz ; i+=2) {
- cum_orig_line += lineno[i];
- new_line = addrmap[cum_orig_line];
- assert (new_line - last_line < 255);
- lineno[i] =((unsigned char)(new_line - last_line));
- last_line = new_line;
- }
-
- /* Remove NOPs and fixup jump targets */
- for (i=0, h=0 ; i<codelen ; ) {
- opcode = codestr[i];
- switch (opcode) {
- case NOP:
- i++;
- continue;
-
- case JUMP_ABSOLUTE:
- case CONTINUE_LOOP:
- j = addrmap[GETARG(codestr, i)];
- SETARG(codestr, i, j);
- break;
-
- case FOR_ITER:
- case JUMP_FORWARD:
- case JUMP_IF_FALSE:
- case JUMP_IF_TRUE:
- case SETUP_LOOP:
- case SETUP_EXCEPT:
- case SETUP_FINALLY:
- j = addrmap[GETARG(codestr, i) + i + 3] - addrmap[i] - 3;
- SETARG(codestr, i, j);
- break;
- }
- adj = CODESIZE(opcode);
- while (adj--)
- codestr[h++] = codestr[i++];
- }
- assert(h + nops == codelen);
-
- code = PyString_FromStringAndSize((char *)codestr, h);
- PyMem_Free(addrmap);
- PyMem_Free(codestr);
- PyMem_Free(blocks);
- return code;
-
- exitUnchanged:
- if (blocks != NULL)
- PyMem_Free(blocks);
- if (addrmap != NULL)
- PyMem_Free(addrmap);
- if (codestr != NULL)
- PyMem_Free(codestr);
- Py_INCREF(code);
- return code;
-}
-
-/* End: Peephole optimizations ----------------------------------------- */
-
-/*
-
-Leave this debugging code for just a little longer.
-
-static void
-compiler_display_symbols(PyObject *name, PyObject *symbols)
-{
-PyObject *key, *value;
-int flags;
-Py_ssize_t pos = 0;
-
-fprintf(stderr, "block %s\n", PyString_AS_STRING(name));
-while (PyDict_Next(symbols, &pos, &key, &value)) {
-flags = PyInt_AsLong(value);
-fprintf(stderr, "var %s:", PyString_AS_STRING(key));
-if (flags & DEF_GLOBAL)
-fprintf(stderr, " declared_global");
-if (flags & DEF_LOCAL)
-fprintf(stderr, " local");
-if (flags & DEF_PARAM)
-fprintf(stderr, " param");
-if (flags & DEF_STAR)
-fprintf(stderr, " stararg");
-if (flags & DEF_DOUBLESTAR)
-fprintf(stderr, " starstar");
-if (flags & DEF_INTUPLE)
-fprintf(stderr, " tuple");
-if (flags & DEF_FREE)
-fprintf(stderr, " free");
-if (flags & DEF_FREE_GLOBAL)
-fprintf(stderr, " global");
-if (flags & DEF_FREE_CLASS)
-fprintf(stderr, " free/class");
-if (flags & DEF_IMPORT)
-fprintf(stderr, " import");
-fprintf(stderr, "\n");
-}
- fprintf(stderr, "\n");
-}
-*/
-
-static void
-compiler_unit_check(struct compiler_unit *u)
-{
- basicblock *block;
- for (block = u->u_blocks; block != NULL; block = block->b_list) {
- assert(block != (void *)0xcbcbcbcb);
- assert(block != (void *)0xfbfbfbfb);
- assert(block != (void *)0xdbdbdbdb);
- if (block->b_instr != NULL) {
- assert(block->b_ialloc > 0);
- assert(block->b_iused > 0);
- assert(block->b_ialloc >= block->b_iused);
- }
- else {
- assert (block->b_iused == 0);
- assert (block->b_ialloc == 0);
- }
- }
-}
-
-static void
-compiler_unit_free(struct compiler_unit *u)
-{
- basicblock *b, *next;
-
- compiler_unit_check(u);
- b = u->u_blocks;
- while (b != NULL) {
- if (b->b_instr)
- PyObject_Free((void *)b->b_instr);
- next = b->b_list;
- PyObject_Free((void *)b);
- b = next;
- }
- Py_CLEAR(u->u_ste);
- Py_CLEAR(u->u_name);
- Py_CLEAR(u->u_consts);
- Py_CLEAR(u->u_names);
- Py_CLEAR(u->u_varnames);
- Py_CLEAR(u->u_freevars);
- Py_CLEAR(u->u_cellvars);
- Py_CLEAR(u->u_private);
- PyObject_Free(u);
-}
-
-static int
-compiler_enter_scope(struct compiler *c, identifier name, void *key,
- int lineno)
-{
- struct compiler_unit *u;
-
- u = (struct compiler_unit *)PyObject_Malloc(sizeof(
- struct compiler_unit));
- if (!u) {
- PyErr_NoMemory();
- return 0;
- }
- memset(u, 0, sizeof(struct compiler_unit));
- u->u_argcount = 0;
- u->u_ste = PySymtable_Lookup(c->c_st, key);
- if (!u->u_ste) {
- compiler_unit_free(u);
- return 0;
- }
- Py_INCREF(name);
- u->u_name = name;
- u->u_varnames = list2dict(u->u_ste->ste_varnames);
- u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0);
- if (!u->u_varnames || !u->u_cellvars) {
- compiler_unit_free(u);
- return 0;
- }
-
- u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS,
- PyDict_Size(u->u_cellvars));
- if (!u->u_freevars) {
- compiler_unit_free(u);
- return 0;
- }
-
- u->u_blocks = NULL;
- u->u_tmpname = 0;
- u->u_nfblocks = 0;
- u->u_firstlineno = lineno;
- u->u_lineno = 0;
- u->u_lineno_set = false;
- u->u_consts = PyDict_New();
- if (!u->u_consts) {
- compiler_unit_free(u);
- return 0;
- }
- u->u_names = PyDict_New();
- if (!u->u_names) {
- compiler_unit_free(u);
- return 0;
- }
-
- u->u_private = NULL;
-
- /* Push the old compiler_unit on the stack. */
- if (c->u) {
- PyObject *wrapper = PyCObject_FromVoidPtr(c->u, NULL);
- if (!wrapper || PyList_Append(c->c_stack, wrapper) < 0) {
- Py_XDECREF(wrapper);
- compiler_unit_free(u);
- return 0;
- }
- Py_DECREF(wrapper);
- u->u_private = c->u->u_private;
- Py_XINCREF(u->u_private);
- }
- c->u = u;
-
- c->c_nestlevel++;
- if (compiler_use_new_block(c) == NULL)
- return 0;
-
- return 1;
-}
-
-static void
-compiler_exit_scope(struct compiler *c)
-{
- int n;
- PyObject *wrapper;
-
- c->c_nestlevel--;
- compiler_unit_free(c->u);
- /* Restore c->u to the parent unit. */
- n = PyList_GET_SIZE(c->c_stack) - 1;
- if (n >= 0) {
- wrapper = PyList_GET_ITEM(c->c_stack, n);
- c->u = (struct compiler_unit *)PyCObject_AsVoidPtr(wrapper);
- /* we are deleting from a list so this really shouldn't fail */
- if (PySequence_DelItem(c->c_stack, n) < 0)
- Py_FatalError("compiler_exit_scope()");
- compiler_unit_check(c->u);
- }
- else
- c->u = NULL;
-
-}
-
-/* Allocate a new "anonymous" local variable.
- Used by list comprehensions and with statements.
-*/
-
-static PyObject *
-compiler_new_tmpname(struct compiler *c)
-{
- char tmpname[256];
- PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", ++c->u->u_tmpname);
- return PyString_FromString(tmpname);
-}
-
-/* Allocate a new block and return a pointer to it.
- Returns NULL on error.
-*/
-
-static basicblock *
-compiler_new_block(struct compiler *c)
-{
- basicblock *b;
- struct compiler_unit *u;
-
- u = c->u;
- b = (basicblock *)PyObject_Malloc(sizeof(basicblock));
- if (b == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
- memset((void *)b, 0, sizeof(basicblock));
- /* Extend the singly linked list of blocks with new block. */
- b->b_list = u->u_blocks;
- u->u_blocks = b;
- return b;
-}
-
-static basicblock *
-compiler_use_new_block(struct compiler *c)
-{
- basicblock *block = compiler_new_block(c);
- if (block == NULL)
- return NULL;
- c->u->u_curblock = block;
- return block;
-}
-
-static basicblock *
-compiler_next_block(struct compiler *c)
-{
- basicblock *block = compiler_new_block(c);
- if (block == NULL)
- return NULL;
- c->u->u_curblock->b_next = block;
- c->u->u_curblock = block;
- return block;
-}
-
-static basicblock *
-compiler_use_next_block(struct compiler *c, basicblock *block)
-{
- assert(block != NULL);
- c->u->u_curblock->b_next = block;
- c->u->u_curblock = block;
- return block;
-}
-
-/* Returns the offset of the next instruction in the current block's
- b_instr array. Resizes the b_instr as necessary.
- Returns -1 on failure.
- */
-
-static int
-compiler_next_instr(struct compiler *c, basicblock *b)
-{
- assert(b != NULL);
- if (b->b_instr == NULL) {
- b->b_instr = (struct instr *)PyObject_Malloc(
- sizeof(struct instr) * DEFAULT_BLOCK_SIZE);
- if (b->b_instr == NULL) {
- PyErr_NoMemory();
- return -1;
- }
- b->b_ialloc = DEFAULT_BLOCK_SIZE;
- memset((char *)b->b_instr, 0,
- sizeof(struct instr) * DEFAULT_BLOCK_SIZE);
- }
- else if (b->b_iused == b->b_ialloc) {
- struct instr *tmp;
- size_t oldsize, newsize;
- oldsize = b->b_ialloc * sizeof(struct instr);
- newsize = oldsize << 1;
- if (newsize == 0) {
- PyErr_NoMemory();
- return -1;
- }
- b->b_ialloc <<= 1;
- tmp = (struct instr *)PyObject_Realloc(
- (void *)b->b_instr, newsize);
- if (tmp == NULL) {
- PyErr_NoMemory();
- return -1;
- }
- b->b_instr = tmp;
- memset((char *)b->b_instr + oldsize, 0, newsize - oldsize);
- }
- return b->b_iused++;
-}
-
-/* Set the i_lineno member of the instruction at offse off if the
- line number for the current expression/statement (?) has not
- already been set. If it has been set, the call has no effect.
-
- Every time a new node is b
- */
-
-static void
-compiler_set_lineno(struct compiler *c, int off)
-{
- basicblock *b;
- if (c->u->u_lineno_set)
- return;
- c->u->u_lineno_set = true;
- b = c->u->u_curblock;
- b->b_instr[off].i_lineno = c->u->u_lineno;
-}
-
-static int
-opcode_stack_effect(int opcode, int oparg)
-{
- switch (opcode) {
- case POP_TOP:
- return -1;
- case ROT_TWO:
- case ROT_THREE:
- return 0;
- case DUP_TOP:
- return 1;
- case ROT_FOUR:
- return 0;
-
- case UNARY_POSITIVE:
- case UNARY_NEGATIVE:
- case UNARY_NOT:
- case UNARY_CONVERT:
- case UNARY_INVERT:
- return 0;
-
- case LIST_APPEND:
- return -2;
-
- case BINARY_POWER:
- case BINARY_MULTIPLY:
- case BINARY_DIVIDE:
- case BINARY_MODULO:
- case BINARY_ADD:
- case BINARY_SUBTRACT:
- case BINARY_SUBSCR:
- case BINARY_FLOOR_DIVIDE:
- case BINARY_TRUE_DIVIDE:
- return -1;
- case INPLACE_FLOOR_DIVIDE:
- case INPLACE_TRUE_DIVIDE:
- return -1;
-
- case SLICE+0:
- return 1;
- case SLICE+1:
- return 0;
- case SLICE+2:
- return 0;
- case SLICE+3:
- return -1;
-
- case STORE_SLICE+0:
- return -2;
- case STORE_SLICE+1:
- return -3;
- case STORE_SLICE+2:
- return -3;
- case STORE_SLICE+3:
- return -4;
-
- case DELETE_SLICE+0:
- return -1;
- case DELETE_SLICE+1:
- return -2;
- case DELETE_SLICE+2:
- return -2;
- case DELETE_SLICE+3:
- return -3;
-
- case INPLACE_ADD:
- case INPLACE_SUBTRACT:
- case INPLACE_MULTIPLY:
- case INPLACE_DIVIDE:
- case INPLACE_MODULO:
- return -1;
- case STORE_SUBSCR:
- return -3;
- case DELETE_SUBSCR:
- return -2;
-
- case BINARY_LSHIFT:
- case BINARY_RSHIFT:
- case BINARY_AND:
- case BINARY_XOR:
- case BINARY_OR:
- return -1;
- case INPLACE_POWER:
- return -1;
- case GET_ITER:
- return 0;
-
- case PRINT_EXPR:
- return -1;
- case PRINT_ITEM:
- return -1;
- case PRINT_NEWLINE:
- return 0;
- case PRINT_ITEM_TO:
- return -2;
- case PRINT_NEWLINE_TO:
- return -1;
- case INPLACE_LSHIFT:
- case INPLACE_RSHIFT:
- case INPLACE_AND:
- case INPLACE_XOR:
- case INPLACE_OR:
- return -1;
- case BREAK_LOOP:
- return 0;
- case WITH_CLEANUP:
- return -1; /* XXX Sometimes more */
- case LOAD_LOCALS:
- return 1;
- case RETURN_VALUE:
- return -1;
- case IMPORT_STAR:
- return -1;
- case EXEC_STMT:
- return -3;
- case YIELD_VALUE:
- return 0;
-
- case POP_BLOCK:
- return 0;
- case END_FINALLY:
- return -1; /* or -2 or -3 if exception occurred */
- case BUILD_CLASS:
- return -2;
-
- case STORE_NAME:
- return -1;
- case DELETE_NAME:
- return 0;
- case UNPACK_SEQUENCE:
- return oparg-1;
- case FOR_ITER:
- return 1;
-
- case STORE_ATTR:
- return -2;
- case DELETE_ATTR:
- return -1;
- case STORE_GLOBAL:
- return -1;
- case DELETE_GLOBAL:
- return 0;
- case DUP_TOPX:
- return oparg;
- case LOAD_CONST:
- return 1;
- case LOAD_NAME:
- return 1;
- case BUILD_TUPLE:
- case BUILD_LIST:
- return 1-oparg;
- case BUILD_MAP:
- return 1;
- case LOAD_ATTR:
- return 0;
- case COMPARE_OP:
- return -1;
- case IMPORT_NAME:
- return 0;
- case IMPORT_FROM:
- return 1;
-
- case JUMP_FORWARD:
- case JUMP_IF_FALSE:
- case JUMP_IF_TRUE:
- case JUMP_ABSOLUTE:
- return 0;
-
- case LOAD_GLOBAL:
- return 1;
-
- case CONTINUE_LOOP:
- return 0;
- case SETUP_LOOP:
- return 0;
- case SETUP_EXCEPT:
- case SETUP_FINALLY:
- return 3; /* actually pushed by an exception */
-
- case LOAD_FAST:
- return 1;
- case STORE_FAST:
- return -1;
- case DELETE_FAST:
- return 0;
-
- case RAISE_VARARGS:
- return -oparg;
-#define NARGS(o) (((o) % 256) + 2*((o) / 256))
- case CALL_FUNCTION:
- return -NARGS(oparg);
- case CALL_FUNCTION_VAR:
- case CALL_FUNCTION_KW:
- return -NARGS(oparg)-1;
- case CALL_FUNCTION_VAR_KW:
- return -NARGS(oparg)-2;
-#undef NARGS
- case MAKE_FUNCTION:
- return -oparg;
- case BUILD_SLICE:
- if (oparg == 3)
- return -2;
- else
- return -1;
-
- case MAKE_CLOSURE:
- return -oparg;
- case LOAD_CLOSURE:
- return 1;
- case LOAD_DEREF:
- return 1;
- case STORE_DEREF:
- return -1;
- default:
- fprintf(stderr, "opcode = %d\n", opcode);
- Py_FatalError("opcode_stack_effect()");
-
- }
- return 0; /* not reachable */
-}
-
-/* Add an opcode with no argument.
- Returns 0 on failure, 1 on success.
-*/
-
-static int
-compiler_addop(struct compiler *c, int opcode)
-{
- basicblock *b;
- struct instr *i;
- int off;
- off = compiler_next_instr(c, c->u->u_curblock);
- if (off < 0)
- return 0;
- b = c->u->u_curblock;
- i = &b->b_instr[off];
- i->i_opcode = opcode;
- i->i_hasarg = 0;
- if (opcode == RETURN_VALUE)
- b->b_return = 1;
- compiler_set_lineno(c, off);
- return 1;
-}
-
-static int
-compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
-{
- PyObject *t, *v;
- Py_ssize_t arg;
-
- /* necessary to make sure types aren't coerced (e.g., int and long) */
- t = PyTuple_Pack(2, o, o->ob_type);
- if (t == NULL)
- return -1;
-
- v = PyDict_GetItem(dict, t);
- if (!v) {
- arg = PyDict_Size(dict);
- v = PyInt_FromLong(arg);
- if (!v) {
- Py_DECREF(t);
- return -1;
- }
- if (PyDict_SetItem(dict, t, v) < 0) {
- Py_DECREF(t);
- Py_DECREF(v);
- return -1;
- }
- Py_DECREF(v);
- }
- else
- arg = PyInt_AsLong(v);
- Py_DECREF(t);
- return arg;
-}
-
-static int
-compiler_addop_o(struct compiler *c, int opcode, PyObject *dict,
- PyObject *o)
-{
- int arg = compiler_add_o(c, dict, o);
- if (arg < 0)
- return 0;
- return compiler_addop_i(c, opcode, arg);
-}
-
-static int
-compiler_addop_name(struct compiler *c, int opcode, PyObject *dict,
- PyObject *o)
-{
- int arg;
- PyObject *mangled = _Py_Mangle(c->u->u_private, o);
- if (!mangled)
- return 0;
- arg = compiler_add_o(c, dict, mangled);
- Py_DECREF(mangled);
- if (arg < 0)
- return 0;
- return compiler_addop_i(c, opcode, arg);
-}
-
-/* Add an opcode with an integer argument.
- Returns 0 on failure, 1 on success.
-*/
-
-static int
-compiler_addop_i(struct compiler *c, int opcode, int oparg)
-{
- struct instr *i;
- int off;
- off = compiler_next_instr(c, c->u->u_curblock);
- if (off < 0)
- return 0;
- i = &c->u->u_curblock->b_instr[off];
- i->i_opcode = opcode;
- i->i_oparg = oparg;
- i->i_hasarg = 1;
- compiler_set_lineno(c, off);
- return 1;
-}
-
-static int
-compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
-{
- struct instr *i;
- int off;
-
- assert(b != NULL);
- off = compiler_next_instr(c, c->u->u_curblock);
- if (off < 0)
- return 0;
- i = &c->u->u_curblock->b_instr[off];
- i->i_opcode = opcode;
- i->i_target = b;
- i->i_hasarg = 1;
- if (absolute)
- i->i_jabs = 1;
- else
- i->i_jrel = 1;
- compiler_set_lineno(c, off);
- return 1;
-}
-
-/* The distinction between NEW_BLOCK and NEXT_BLOCK is subtle. (I'd
- like to find better names.) NEW_BLOCK() creates a new block and sets
- it as the current block. NEXT_BLOCK() also creates an implicit jump
- from the current block to the new block.
-*/
-
-/* XXX The returns inside these macros make it impossible to decref
- objects created in the local function.
-*/
-
-
-#define NEW_BLOCK(C) { \
- if (compiler_use_new_block((C)) == NULL) \
- return 0; \
-}
-
-#define NEXT_BLOCK(C) { \
- if (compiler_next_block((C)) == NULL) \
- return 0; \
-}
-
-#define ADDOP(C, OP) { \
- if (!compiler_addop((C), (OP))) \
- return 0; \
-}
-
-#define ADDOP_IN_SCOPE(C, OP) { \
- if (!compiler_addop((C), (OP))) { \
- compiler_exit_scope(c); \
- return 0; \
- } \
-}
-
-#define ADDOP_O(C, OP, O, TYPE) { \
- if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \
- return 0; \
-}
-
-#define ADDOP_NAME(C, OP, O, TYPE) { \
- if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \
- return 0; \
-}
-
-#define ADDOP_I(C, OP, O) { \
- if (!compiler_addop_i((C), (OP), (O))) \
- return 0; \
-}
-
-#define ADDOP_JABS(C, OP, O) { \
- if (!compiler_addop_j((C), (OP), (O), 1)) \
- return 0; \
-}
-
-#define ADDOP_JREL(C, OP, O) { \
- if (!compiler_addop_j((C), (OP), (O), 0)) \
- return 0; \
-}
-
-/* VISIT and VISIT_SEQ takes an ASDL type as their second argument. They use
- the ASDL name to synthesize the name of the C type and the visit function.
-*/
-
-#define VISIT(C, TYPE, V) {\
- if (!compiler_visit_ ## TYPE((C), (V))) \
- return 0; \
-}
-
-#define VISIT_IN_SCOPE(C, TYPE, V) {\
- if (!compiler_visit_ ## TYPE((C), (V))) { \
- compiler_exit_scope(c); \
- return 0; \
- } \
-}
-
-#define VISIT_SLICE(C, V, CTX) {\
- if (!compiler_visit_slice((C), (V), (CTX))) \
- return 0; \
-}
-
-#define VISIT_SEQ(C, TYPE, SEQ) { \
- int _i; \
- asdl_seq *seq = (SEQ); /* avoid variable capture */ \
- for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
- TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
- if (!compiler_visit_ ## TYPE((C), elt)) \
- return 0; \
- } \
-}
-
-#define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \
- int _i; \
- asdl_seq *seq = (SEQ); /* avoid variable capture */ \
- for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
- TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
- if (!compiler_visit_ ## TYPE((C), elt)) { \
- compiler_exit_scope(c); \
- return 0; \
- } \
- } \
-}
-
-static int
-compiler_isdocstring(stmt_ty s)
-{
- if (s->kind != Expr_kind)
- return 0;
- return s->v.Expr.value->kind == Str_kind;
-}
-
-/* Compile a sequence of statements, checking for a docstring. */
-
-static int
-compiler_body(struct compiler *c, asdl_seq *stmts)
-{
- int i = 0;
- stmt_ty st;
-
- if (!asdl_seq_LEN(stmts))
- return 1;
- st = (stmt_ty)asdl_seq_GET(stmts, 0);
- if (compiler_isdocstring(st)) {
- i = 1;
- VISIT(c, expr, st->v.Expr.value);
- if (!compiler_nameop(c, __doc__, Store))
- return 0;
- }
- for (; i < asdl_seq_LEN(stmts); i++)
- VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
- return 1;
-}
-
-static PyCodeObject *
-compiler_mod(struct compiler *c, mod_ty mod)
-{
- PyCodeObject *co;
- int addNone = 1;
- static PyObject *module;
- if (!module) {
- module = PyString_FromString("<module>");
- if (!module)
- return NULL;
- }
- /* Use 0 for firstlineno initially, will fixup in assemble(). */
- if (!compiler_enter_scope(c, module, mod, 0))
- return NULL;
- switch (mod->kind) {
- case Module_kind:
- if (!compiler_body(c, mod->v.Module.body)) {
- compiler_exit_scope(c);
- return 0;
- }
- break;
- case Interactive_kind:
- c->c_interactive = 1;
- VISIT_SEQ_IN_SCOPE(c, stmt,
- mod->v.Interactive.body);
- break;
- case Expression_kind:
- VISIT_IN_SCOPE(c, expr, mod->v.Expression.body);
- addNone = 0;
- break;
- case Suite_kind:
- PyErr_SetString(PyExc_SystemError,
- "suite should not be possible");
- return 0;
- default:
- PyErr_Format(PyExc_SystemError,
- "module kind %d should not be possible",
- mod->kind);
- return 0;
- }
- co = assemble(c, addNone);
- compiler_exit_scope(c);
- return co;
-}
-
-/* The test for LOCAL must come before the test for FREE in order to
- handle classes where name is both local and free. The local var is
- a method and the free var is a free var referenced within a method.
-*/
-
-static int
-get_ref_type(struct compiler *c, PyObject *name)
-{
- int scope = PyST_GetScope(c->u->u_ste, name);
- if (scope == 0) {
- char buf[350];
- PyOS_snprintf(buf, sizeof(buf),
- "unknown scope for %.100s in %.100s(%s) in %s\n"
- "symbols: %s\nlocals: %s\nglobals: %s\n",
- PyString_AS_STRING(name),
- PyString_AS_STRING(c->u->u_name),
- PyObject_REPR(c->u->u_ste->ste_id),
- c->c_filename,
- PyObject_REPR(c->u->u_ste->ste_symbols),
- PyObject_REPR(c->u->u_varnames),
- PyObject_REPR(c->u->u_names)
- );
- Py_FatalError(buf);
- }
-
- return scope;
-}
-
-static int
-compiler_lookup_arg(PyObject *dict, PyObject *name)
-{
- PyObject *k, *v;
- k = PyTuple_Pack(2, name, name->ob_type);
- if (k == NULL)
- return -1;
- v = PyDict_GetItem(dict, k);
- Py_DECREF(k);
- if (v == NULL)
- return -1;
- return PyInt_AS_LONG(v);
-}
-
-static int
-compiler_make_closure(struct compiler *c, PyCodeObject *co, int args)
-{
- int i, free = PyCode_GetNumFree(co);
- if (free == 0) {
- ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts);
- ADDOP_I(c, MAKE_FUNCTION, args);
- return 1;
- }
- for (i = 0; i < free; ++i) {
- /* Bypass com_addop_varname because it will generate
- LOAD_DEREF but LOAD_CLOSURE is needed.
- */
- PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i);
- int arg, reftype;
-
- /* Special case: If a class contains a method with a
- free variable that has the same name as a method,
- the name will be considered free *and* local in the
- class. It should be handled by the closure, as
- well as by the normal name loookup logic.
- */
- reftype = get_ref_type(c, name);
- if (reftype == CELL)
- arg = compiler_lookup_arg(c->u->u_cellvars, name);
- else /* (reftype == FREE) */
- arg = compiler_lookup_arg(c->u->u_freevars, name);
- if (arg == -1) {
- printf("lookup %s in %s %d %d\n"
- "freevars of %s: %s\n",
- PyObject_REPR(name),
- PyString_AS_STRING(c->u->u_name),
- reftype, arg,
- PyString_AS_STRING(co->co_name),
- PyObject_REPR(co->co_freevars));
- Py_FatalError("compiler_make_closure()");
- }
- ADDOP_I(c, LOAD_CLOSURE, arg);
- }
- ADDOP_I(c, BUILD_TUPLE, free);
- ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts);
- ADDOP_I(c, MAKE_CLOSURE, args);
- return 1;
-}
-
-static int
-compiler_decorators(struct compiler *c, asdl_seq* decos)
-{
- int i;
-
- if (!decos)
- return 1;
-
- for (i = 0; i < asdl_seq_LEN(decos); i++) {
- VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i));
- }
- return 1;
-}
-
-static int
-compiler_arguments(struct compiler *c, arguments_ty args)
-{
- int i;
- int n = asdl_seq_LEN(args->args);
- /* Correctly handle nested argument lists */
- for (i = 0; i < n; i++) {
- expr_ty arg = (expr_ty)asdl_seq_GET(args->args, i);
- if (arg->kind == Tuple_kind) {
- PyObject *id = PyString_FromFormat(".%d", i);
- if (id == NULL) {
- return 0;
- }
- if (!compiler_nameop(c, id, Load)) {
- Py_DECREF(id);
- return 0;
- }
- Py_DECREF(id);
- VISIT(c, expr, arg);
- }
- }
- return 1;
-}
-
-static int
-compiler_function(struct compiler *c, stmt_ty s)
-{
- PyCodeObject *co;
- PyObject *first_const = Py_None;
- arguments_ty args = s->v.FunctionDef.args;
- asdl_seq* decos = s->v.FunctionDef.decorators;
- stmt_ty st;
- int i, n, docstring;
-
- assert(s->kind == FunctionDef_kind);
-
- if (!compiler_decorators(c, decos))
- return 0;
- if (args->defaults)
- VISIT_SEQ(c, expr, args->defaults);
- if (!compiler_enter_scope(c, s->v.FunctionDef.name, (void *)s,
- s->lineno))
- return 0;
-
- st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, 0);
- docstring = compiler_isdocstring(st);
- if (docstring)
- first_const = st->v.Expr.value->v.Str.s;
- if (compiler_add_o(c, c->u->u_consts, first_const) < 0) {
- compiler_exit_scope(c);
- return 0;
- }
-
- /* unpack nested arguments */
- compiler_arguments(c, args);
-
- c->u->u_argcount = asdl_seq_LEN(args->args);
- n = asdl_seq_LEN(s->v.FunctionDef.body);
- /* if there was a docstring, we need to skip the first statement */
- for (i = docstring; i < n; i++) {
- st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, i);
- VISIT_IN_SCOPE(c, stmt, st);
- }
- co = assemble(c, 1);
- compiler_exit_scope(c);
- if (co == NULL)
- return 0;
-
- compiler_make_closure(c, co, asdl_seq_LEN(args->defaults));
- Py_DECREF(co);
-
- for (i = 0; i < asdl_seq_LEN(decos); i++) {
- ADDOP_I(c, CALL_FUNCTION, 1);
- }
-
- return compiler_nameop(c, s->v.FunctionDef.name, Store);
-}
-
-static int
-compiler_class(struct compiler *c, stmt_ty s)
-{
- int n;
- PyCodeObject *co;
- PyObject *str;
- /* push class name on stack, needed by BUILD_CLASS */
- ADDOP_O(c, LOAD_CONST, s->v.ClassDef.name, consts);
- /* push the tuple of base classes on the stack */
- n = asdl_seq_LEN(s->v.ClassDef.bases);
- if (n > 0)
- VISIT_SEQ(c, expr, s->v.ClassDef.bases);
- ADDOP_I(c, BUILD_TUPLE, n);
- if (!compiler_enter_scope(c, s->v.ClassDef.name, (void *)s,
- s->lineno))
- return 0;
- c->u->u_private = s->v.ClassDef.name;
- Py_INCREF(c->u->u_private);
- str = PyString_InternFromString("__name__");
- if (!str || !compiler_nameop(c, str, Load)) {
- Py_XDECREF(str);
- compiler_exit_scope(c);
- return 0;
- }
-
- Py_DECREF(str);
- str = PyString_InternFromString("__module__");
- if (!str || !compiler_nameop(c, str, Store)) {
- Py_XDECREF(str);
- compiler_exit_scope(c);
- return 0;
- }
- Py_DECREF(str);
-
- if (!compiler_body(c, s->v.ClassDef.body)) {
- compiler_exit_scope(c);
- return 0;
- }
-
- ADDOP_IN_SCOPE(c, LOAD_LOCALS);
- ADDOP_IN_SCOPE(c, RETURN_VALUE);
- co = assemble(c, 1);
- compiler_exit_scope(c);
- if (co == NULL)
- return 0;
-
- compiler_make_closure(c, co, 0);
- Py_DECREF(co);
-
- ADDOP_I(c, CALL_FUNCTION, 0);
- ADDOP(c, BUILD_CLASS);
- if (!compiler_nameop(c, s->v.ClassDef.name, Store))
- return 0;
- return 1;
-}
-
-static int
-compiler_ifexp(struct compiler *c, expr_ty e)
-{
- basicblock *end, *next;
-
- assert(e->kind == IfExp_kind);
- end = compiler_new_block(c);
- if (end == NULL)
- return 0;
- next = compiler_new_block(c);
- if (next == NULL)
- return 0;
- VISIT(c, expr, e->v.IfExp.test);
- ADDOP_JREL(c, JUMP_IF_FALSE, next);
- ADDOP(c, POP_TOP);
- VISIT(c, expr, e->v.IfExp.body);
- ADDOP_JREL(c, JUMP_FORWARD, end);
- compiler_use_next_block(c, next);
- ADDOP(c, POP_TOP);
- VISIT(c, expr, e->v.IfExp.orelse);
- compiler_use_next_block(c, end);
- return 1;
-}
-
-static int
-compiler_lambda(struct compiler *c, expr_ty e)
-{
- PyCodeObject *co;
- static identifier name;
- arguments_ty args = e->v.Lambda.args;
- assert(e->kind == Lambda_kind);
-
- if (!name) {
- name = PyString_InternFromString("<lambda>");
- if (!name)
- return 0;
- }
-
- if (args->defaults)
- VISIT_SEQ(c, expr, args->defaults);
- if (!compiler_enter_scope(c, name, (void *)e, e->lineno))
- return 0;
-
- /* unpack nested arguments */
- compiler_arguments(c, args);
-
- c->u->u_argcount = asdl_seq_LEN(args->args);
- VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
- ADDOP_IN_SCOPE(c, RETURN_VALUE);
- co = assemble(c, 1);
- compiler_exit_scope(c);
- if (co == NULL)
- return 0;
-
- compiler_make_closure(c, co, asdl_seq_LEN(args->defaults));
- Py_DECREF(co);
-
- return 1;
-}
-
-static int
-compiler_print(struct compiler *c, stmt_ty s)
-{
- int i, n;
- bool dest;
-
- assert(s->kind == Print_kind);
- n = asdl_seq_LEN(s->v.Print.values);
- dest = false;
- if (s->v.Print.dest) {
- VISIT(c, expr, s->v.Print.dest);
- dest = true;
- }
- for (i = 0; i < n; i++) {
- expr_ty e = (expr_ty)asdl_seq_GET(s->v.Print.values, i);
- if (dest) {
- ADDOP(c, DUP_TOP);
- VISIT(c, expr, e);
- ADDOP(c, ROT_TWO);
- ADDOP(c, PRINT_ITEM_TO);
- }
- else {
- VISIT(c, expr, e);
- ADDOP(c, PRINT_ITEM);
- }
- }
- if (s->v.Print.nl) {
- if (dest)
- ADDOP(c, PRINT_NEWLINE_TO)
- else
- ADDOP(c, PRINT_NEWLINE)
- }
- else if (dest)
- ADDOP(c, POP_TOP);
- return 1;
-}
-
-static int
-compiler_if(struct compiler *c, stmt_ty s)
-{
- basicblock *end, *next;
- int constant;
- assert(s->kind == If_kind);
- end = compiler_new_block(c);
- if (end == NULL)
- return 0;
- next = compiler_new_block(c);
- if (next == NULL)
- return 0;
-
- constant = expr_constant(s->v.If.test);
- /* constant = 0: "if 0"
- * constant = 1: "if 1", "if 2", ...
- * constant = -1: rest */
- if (constant == 0) {
- if (s->v.If.orelse)
- VISIT_SEQ(c, stmt, s->v.If.orelse);
- } else if (constant == 1) {
- VISIT_SEQ(c, stmt, s->v.If.body);
- } else {
- VISIT(c, expr, s->v.If.test);
- ADDOP_JREL(c, JUMP_IF_FALSE, next);
- ADDOP(c, POP_TOP);
- VISIT_SEQ(c, stmt, s->v.If.body);
- ADDOP_JREL(c, JUMP_FORWARD, end);
- compiler_use_next_block(c, next);
- ADDOP(c, POP_TOP);
- if (s->v.If.orelse)
- VISIT_SEQ(c, stmt, s->v.If.orelse);
- }
- compiler_use_next_block(c, end);
- return 1;
-}
-
-static int
-compiler_for(struct compiler *c, stmt_ty s)
-{
- basicblock *start, *cleanup, *end;
-
- start = compiler_new_block(c);
- cleanup = compiler_new_block(c);
- end = compiler_new_block(c);
- if (start == NULL || end == NULL || cleanup == NULL)
- return 0;
- ADDOP_JREL(c, SETUP_LOOP, end);
- if (!compiler_push_fblock(c, LOOP, start))
- return 0;
- VISIT(c, expr, s->v.For.iter);
- ADDOP(c, GET_ITER);
- compiler_use_next_block(c, start);
- /* XXX(nnorwitz): is there a better way to handle this?
- for loops are special, we want to be able to trace them
- each time around, so we need to set an extra line number. */
- c->u->u_lineno_set = false;
- ADDOP_JREL(c, FOR_ITER, cleanup);
- VISIT(c, expr, s->v.For.target);
- VISIT_SEQ(c, stmt, s->v.For.body);
- ADDOP_JABS(c, JUMP_ABSOLUTE, start);
- compiler_use_next_block(c, cleanup);
- ADDOP(c, POP_BLOCK);
- compiler_pop_fblock(c, LOOP, start);
- VISIT_SEQ(c, stmt, s->v.For.orelse);
- compiler_use_next_block(c, end);
- return 1;
-}
-
-static int
-compiler_while(struct compiler *c, stmt_ty s)
-{
- basicblock *loop, *orelse, *end, *anchor = NULL;
- int constant = expr_constant(s->v.While.test);
-
- if (constant == 0)
- return 1;
- loop = compiler_new_block(c);
- end = compiler_new_block(c);
- if (constant == -1) {
- anchor = compiler_new_block(c);
- if (anchor == NULL)
- return 0;
- }
- if (loop == NULL || end == NULL)
- return 0;
- if (s->v.While.orelse) {
- orelse = compiler_new_block(c);
- if (orelse == NULL)
- return 0;
- }
- else
- orelse = NULL;
-
- ADDOP_JREL(c, SETUP_LOOP, end);
- compiler_use_next_block(c, loop);
- if (!compiler_push_fblock(c, LOOP, loop))
- return 0;
- if (constant == -1) {
- VISIT(c, expr, s->v.While.test);
- ADDOP_JREL(c, JUMP_IF_FALSE, anchor);
- ADDOP(c, POP_TOP);
- }
- VISIT_SEQ(c, stmt, s->v.While.body);
- ADDOP_JABS(c, JUMP_ABSOLUTE, loop);
-
- /* XXX should the two POP instructions be in a separate block
- if there is no else clause ?
- */
-
- if (constant == -1) {
- compiler_use_next_block(c, anchor);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_BLOCK);
- }
- compiler_pop_fblock(c, LOOP, loop);
- if (orelse != NULL) /* what if orelse is just pass? */
- VISIT_SEQ(c, stmt, s->v.While.orelse);
- compiler_use_next_block(c, end);
-
- return 1;
-}
-
-static int
-compiler_continue(struct compiler *c)
-{
- static const char LOOP_ERROR_MSG[] = "'continue' not properly in loop";
- static const char IN_FINALLY_ERROR_MSG[] =
- "'continue' not supported inside 'finally' clause";
- int i;
-
- if (!c->u->u_nfblocks)
- return compiler_error(c, LOOP_ERROR_MSG);
- i = c->u->u_nfblocks - 1;
- switch (c->u->u_fblock[i].fb_type) {
- case LOOP:
- ADDOP_JABS(c, JUMP_ABSOLUTE, c->u->u_fblock[i].fb_block);
- break;
- case EXCEPT:
- case FINALLY_TRY:
- while (--i >= 0 && c->u->u_fblock[i].fb_type != LOOP) {
- /* Prevent try: ... finally:
- try: continue ... or
- try: ... except: continue */
- if (c->u->u_fblock[i].fb_type == FINALLY_END)
- return compiler_error(c, IN_FINALLY_ERROR_MSG);
- }
- if (i == -1)
- return compiler_error(c, LOOP_ERROR_MSG);
- ADDOP_JABS(c, CONTINUE_LOOP, c->u->u_fblock[i].fb_block);
- break;
- case FINALLY_END:
- return compiler_error(c, IN_FINALLY_ERROR_MSG);
- }
-
- return 1;
-}
-
-/* Code generated for "try: <body> finally: <finalbody>" is as follows:
-
- SETUP_FINALLY L
- <code for body>
- POP_BLOCK
- LOAD_CONST <None>
- L: <code for finalbody>
- END_FINALLY
-
- The special instructions use the block stack. Each block
- stack entry contains the instruction that created it (here
- SETUP_FINALLY), the level of the value stack at the time the
- block stack entry was created, and a label (here L).
-
- SETUP_FINALLY:
- Pushes the current value stack level and the label
- onto the block stack.
- POP_BLOCK:
- Pops en entry from the block stack, and pops the value
- stack until its level is the same as indicated on the
- block stack. (The label is ignored.)
- END_FINALLY:
- Pops a variable number of entries from the *value* stack
- and re-raises the exception they specify. The number of
- entries popped depends on the (pseudo) exception type.
-
- The block stack is unwound when an exception is raised:
- when a SETUP_FINALLY entry is found, the exception is pushed
- onto the value stack (and the exception condition is cleared),
- and the interpreter jumps to the label gotten from the block
- stack.
-*/
-
-static int
-compiler_try_finally(struct compiler *c, stmt_ty s)
-{
- basicblock *body, *end;
- body = compiler_new_block(c);
- end = compiler_new_block(c);
- if (body == NULL || end == NULL)
- return 0;
-
- ADDOP_JREL(c, SETUP_FINALLY, end);
- compiler_use_next_block(c, body);
- if (!compiler_push_fblock(c, FINALLY_TRY, body))
- return 0;
- VISIT_SEQ(c, stmt, s->v.TryFinally.body);
- ADDOP(c, POP_BLOCK);
- compiler_pop_fblock(c, FINALLY_TRY, body);
-
- ADDOP_O(c, LOAD_CONST, Py_None, consts);
- compiler_use_next_block(c, end);
- if (!compiler_push_fblock(c, FINALLY_END, end))
- return 0;
- VISIT_SEQ(c, stmt, s->v.TryFinally.finalbody);
- ADDOP(c, END_FINALLY);
- compiler_pop_fblock(c, FINALLY_END, end);
-
- return 1;
-}
-
-/*
- Code generated for "try: S except E1, V1: S1 except E2, V2: S2 ...":
- (The contents of the value stack is shown in [], with the top
- at the right; 'tb' is trace-back info, 'val' the exception's
- associated value, and 'exc' the exception.)
-
- Value stack Label Instruction Argument
- [] SETUP_EXCEPT L1
- [] <code for S>
- [] POP_BLOCK
- [] JUMP_FORWARD L0
-
- [tb, val, exc] L1: DUP )
- [tb, val, exc, exc] <evaluate E1> )
- [tb, val, exc, exc, E1] COMPARE_OP EXC_MATCH ) only if E1
- [tb, val, exc, 1-or-0] JUMP_IF_FALSE L2 )
- [tb, val, exc, 1] POP )
- [tb, val, exc] POP
- [tb, val] <assign to V1> (or POP if no V1)
- [tb] POP
- [] <code for S1>
- JUMP_FORWARD L0
-
- [tb, val, exc, 0] L2: POP
- [tb, val, exc] DUP
- .............................etc.......................
-
- [tb, val, exc, 0] Ln+1: POP
- [tb, val, exc] END_FINALLY # re-raise exception
-
- [] L0: <next statement>
-
- Of course, parts are not generated if Vi or Ei is not present.
-*/
-static int
-compiler_try_except(struct compiler *c, stmt_ty s)
-{
- basicblock *body, *orelse, *except, *end;
- int i, n;
-
- body = compiler_new_block(c);
- except = compiler_new_block(c);
- orelse = compiler_new_block(c);
- end = compiler_new_block(c);
- if (body == NULL || except == NULL || orelse == NULL || end == NULL)
- return 0;
- ADDOP_JREL(c, SETUP_EXCEPT, except);
- compiler_use_next_block(c, body);
- if (!compiler_push_fblock(c, EXCEPT, body))
- return 0;
- VISIT_SEQ(c, stmt, s->v.TryExcept.body);
- ADDOP(c, POP_BLOCK);
- compiler_pop_fblock(c, EXCEPT, body);
- ADDOP_JREL(c, JUMP_FORWARD, orelse);
- n = asdl_seq_LEN(s->v.TryExcept.handlers);
- compiler_use_next_block(c, except);
- for (i = 0; i < n; i++) {
- excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
- s->v.TryExcept.handlers, i);
- if (!handler->type && i < n-1)
- return compiler_error(c, "default 'except:' must be last");
- c->u->u_lineno_set = false;
- c->u->u_lineno = handler->lineno;
- except = compiler_new_block(c);
- if (except == NULL)
- return 0;
- if (handler->type) {
- ADDOP(c, DUP_TOP);
- VISIT(c, expr, handler->type);
- ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH);
- ADDOP_JREL(c, JUMP_IF_FALSE, except);
- ADDOP(c, POP_TOP);
- }
- ADDOP(c, POP_TOP);
- if (handler->name) {
- VISIT(c, expr, handler->name);
- }
- else {
- ADDOP(c, POP_TOP);
- }
- ADDOP(c, POP_TOP);
- VISIT_SEQ(c, stmt, handler->body);
- ADDOP_JREL(c, JUMP_FORWARD, end);
- compiler_use_next_block(c, except);
- if (handler->type)
- ADDOP(c, POP_TOP);
- }
- ADDOP(c, END_FINALLY);
- compiler_use_next_block(c, orelse);
- VISIT_SEQ(c, stmt, s->v.TryExcept.orelse);
- compiler_use_next_block(c, end);
- return 1;
-}
-
-static int
-compiler_import_as(struct compiler *c, identifier name, identifier asname)
-{
- /* The IMPORT_NAME opcode was already generated. This function
- merely needs to bind the result to a name.
-
- If there is a dot in name, we need to split it and emit a
- LOAD_ATTR for each name.
- */
- const char *src = PyString_AS_STRING(name);
- const char *dot = strchr(src, '.');
- if (dot) {
- /* Consume the base module name to get the first attribute */
- src = dot + 1;
- while (dot) {
- /* NB src is only defined when dot != NULL */
- PyObject *attr;
- dot = strchr(src, '.');
- attr = PyString_FromStringAndSize(src,
- dot ? dot - src : strlen(src));
- if (!attr)
- return -1;
- ADDOP_O(c, LOAD_ATTR, attr, names);
- Py_DECREF(attr);
- src = dot + 1;
- }
- }
- return compiler_nameop(c, asname, Store);
-}
-
-static int
-compiler_import(struct compiler *c, stmt_ty s)
-{
- /* The Import node stores a module name like a.b.c as a single
- string. This is convenient for all cases except
- import a.b.c as d
- where we need to parse that string to extract the individual
- module names.
- XXX Perhaps change the representation to make this case simpler?
- */
- int i, n = asdl_seq_LEN(s->v.Import.names);
-
- for (i = 0; i < n; i++) {
- alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
- int r;
- PyObject *level;
-
- if (c->c_flags && (c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT))
- level = PyInt_FromLong(0);
- else
- level = PyInt_FromLong(-1);
-
- if (level == NULL)
- return 0;
-
- ADDOP_O(c, LOAD_CONST, level, consts);
- Py_DECREF(level);
- ADDOP_O(c, LOAD_CONST, Py_None, consts);
- ADDOP_NAME(c, IMPORT_NAME, alias->name, names);
-
- if (alias->asname) {
- r = compiler_import_as(c, alias->name, alias->asname);
- if (!r)
- return r;
- }
- else {
- identifier tmp = alias->name;
- const char *base = PyString_AS_STRING(alias->name);
- char *dot = strchr(base, '.');
- if (dot)
- tmp = PyString_FromStringAndSize(base,
- dot - base);
- r = compiler_nameop(c, tmp, Store);
- if (dot) {
- Py_DECREF(tmp);
- }
- if (!r)
- return r;
- }
- }
- return 1;
-}
-
-static int
-compiler_from_import(struct compiler *c, stmt_ty s)
-{
- int i, n = asdl_seq_LEN(s->v.ImportFrom.names);
-
- PyObject *names = PyTuple_New(n);
- PyObject *level;
-
- if (!names)
- return 0;
-
- if (s->v.ImportFrom.level == 0 && c->c_flags &&
- !(c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT))
- level = PyInt_FromLong(-1);
- else
- level = PyInt_FromLong(s->v.ImportFrom.level);
-
- if (!level) {
- Py_DECREF(names);
- return 0;
- }
-
- /* build up the names */
- for (i = 0; i < n; i++) {
- alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
- Py_INCREF(alias->name);
- PyTuple_SET_ITEM(names, i, alias->name);
- }
-
- if (s->lineno > c->c_future->ff_lineno) {
- if (!strcmp(PyString_AS_STRING(s->v.ImportFrom.module),
- "__future__")) {
- Py_DECREF(level);
- Py_DECREF(names);
- return compiler_error(c,
- "from __future__ imports must occur "
- "at the beginning of the file");
-
- }
- }
-
- ADDOP_O(c, LOAD_CONST, level, consts);
- Py_DECREF(level);
- ADDOP_O(c, LOAD_CONST, names, consts);
- Py_DECREF(names);
- ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names);
- for (i = 0; i < n; i++) {
- alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
- identifier store_name;
-
- if (i == 0 && *PyString_AS_STRING(alias->name) == '*') {
- assert(n == 1);
- ADDOP(c, IMPORT_STAR);
- return 1;
- }
-
- ADDOP_NAME(c, IMPORT_FROM, alias->name, names);
- store_name = alias->name;
- if (alias->asname)
- store_name = alias->asname;
-
- if (!compiler_nameop(c, store_name, Store)) {
- Py_DECREF(names);
- return 0;
- }
- }
- /* remove imported module */
- ADDOP(c, POP_TOP);
- return 1;
-}
-
-static int
-compiler_assert(struct compiler *c, stmt_ty s)
-{
- static PyObject *assertion_error = NULL;
- basicblock *end;
-
- if (Py_OptimizeFlag)
- return 1;
- if (assertion_error == NULL) {
- assertion_error = PyString_FromString("AssertionError");
- if (assertion_error == NULL)
- return 0;
- }
- VISIT(c, expr, s->v.Assert.test);
- end = compiler_new_block(c);
- if (end == NULL)
- return 0;
- ADDOP_JREL(c, JUMP_IF_TRUE, end);
- ADDOP(c, POP_TOP);
- ADDOP_O(c, LOAD_GLOBAL, assertion_error, names);
- if (s->v.Assert.msg) {
- VISIT(c, expr, s->v.Assert.msg);
- ADDOP_I(c, RAISE_VARARGS, 2);
- }
- else {
- ADDOP_I(c, RAISE_VARARGS, 1);
- }
- compiler_use_next_block(c, end);
- ADDOP(c, POP_TOP);
- return 1;
-}
-
-static int
-compiler_visit_stmt(struct compiler *c, stmt_ty s)
-{
- int i, n;
-
- /* Always assign a lineno to the next instruction for a stmt. */
- c->u->u_lineno = s->lineno;
- c->u->u_lineno_set = false;
-
- switch (s->kind) {
- case FunctionDef_kind:
- return compiler_function(c, s);
- case ClassDef_kind:
- return compiler_class(c, s);
- case Return_kind:
- if (c->u->u_ste->ste_type != FunctionBlock)
- return compiler_error(c, "'return' outside function");
- if (s->v.Return.value) {
- VISIT(c, expr, s->v.Return.value);
- }
- else
- ADDOP_O(c, LOAD_CONST, Py_None, consts);
- ADDOP(c, RETURN_VALUE);
- break;
- case Delete_kind:
- VISIT_SEQ(c, expr, s->v.Delete.targets)
- break;
- case Assign_kind:
- n = asdl_seq_LEN(s->v.Assign.targets);
- VISIT(c, expr, s->v.Assign.value);
- for (i = 0; i < n; i++) {
- if (i < n - 1)
- ADDOP(c, DUP_TOP);
- VISIT(c, expr,
- (expr_ty)asdl_seq_GET(s->v.Assign.targets, i));
- }
- break;
- case AugAssign_kind:
- return compiler_augassign(c, s);
- case Print_kind:
- return compiler_print(c, s);
- case For_kind:
- return compiler_for(c, s);
- case While_kind:
- return compiler_while(c, s);
- case If_kind:
- return compiler_if(c, s);
- case Raise_kind:
- n = 0;
- if (s->v.Raise.type) {
- VISIT(c, expr, s->v.Raise.type);
- n++;
- if (s->v.Raise.inst) {
- VISIT(c, expr, s->v.Raise.inst);
- n++;
- if (s->v.Raise.tback) {
- VISIT(c, expr, s->v.Raise.tback);
- n++;
- }
- }
- }
- ADDOP_I(c, RAISE_VARARGS, n);
- break;
- case TryExcept_kind:
- return compiler_try_except(c, s);
- case TryFinally_kind:
- return compiler_try_finally(c, s);
- case Assert_kind:
- return compiler_assert(c, s);
- case Import_kind:
- return compiler_import(c, s);
- case ImportFrom_kind:
- return compiler_from_import(c, s);
- case Exec_kind:
- VISIT(c, expr, s->v.Exec.body);
- if (s->v.Exec.globals) {
- VISIT(c, expr, s->v.Exec.globals);
- if (s->v.Exec.locals) {
- VISIT(c, expr, s->v.Exec.locals);
- } else {
- ADDOP(c, DUP_TOP);
- }
- } else {
- ADDOP_O(c, LOAD_CONST, Py_None, consts);
- ADDOP(c, DUP_TOP);
- }
- ADDOP(c, EXEC_STMT);
- break;
- case Global_kind:
- break;
- case Expr_kind:
- if (c->c_interactive && c->c_nestlevel <= 1) {
- VISIT(c, expr, s->v.Expr.value);
- ADDOP(c, PRINT_EXPR);
- }
- else if (s->v.Expr.value->kind != Str_kind &&
- s->v.Expr.value->kind != Num_kind) {
- VISIT(c, expr, s->v.Expr.value);
- ADDOP(c, POP_TOP);
- }
- break;
- case Pass_kind:
- break;
- case Break_kind:
- if (!compiler_in_loop(c))
- return compiler_error(c, "'break' outside loop");
- ADDOP(c, BREAK_LOOP);
- break;
- case Continue_kind:
- return compiler_continue(c);
- case With_kind:
- return compiler_with(c, s);
- }
- return 1;
-}
-
-static int
-unaryop(unaryop_ty op)
-{
- switch (op) {
- case Invert:
- return UNARY_INVERT;
- case Not:
- return UNARY_NOT;
- case UAdd:
- return UNARY_POSITIVE;
- case USub:
- return UNARY_NEGATIVE;
- }
- return 0;
-}
-
-static int
-binop(struct compiler *c, operator_ty op)
-{
- switch (op) {
- case Add:
- return BINARY_ADD;
- case Sub:
- return BINARY_SUBTRACT;
- case Mult:
- return BINARY_MULTIPLY;
- case Div:
- if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION)
- return BINARY_TRUE_DIVIDE;
- else
- return BINARY_DIVIDE;
- case Mod:
- return BINARY_MODULO;
- case Pow:
- return BINARY_POWER;
- case LShift:
- return BINARY_LSHIFT;
- case RShift:
- return BINARY_RSHIFT;
- case BitOr:
- return BINARY_OR;
- case BitXor:
- return BINARY_XOR;
- case BitAnd:
- return BINARY_AND;
- case FloorDiv:
- return BINARY_FLOOR_DIVIDE;
- }
- return 0;
-}
-
-static int
-cmpop(cmpop_ty op)
-{
- switch (op) {
- case Eq:
- return PyCmp_EQ;
- case NotEq:
- return PyCmp_NE;
- case Lt:
- return PyCmp_LT;
- case LtE:
- return PyCmp_LE;
- case Gt:
- return PyCmp_GT;
- case GtE:
- return PyCmp_GE;
- case Is:
- return PyCmp_IS;
- case IsNot:
- return PyCmp_IS_NOT;
- case In:
- return PyCmp_IN;
- case NotIn:
- return PyCmp_NOT_IN;
- }
- return PyCmp_BAD;
-}
-
-static int
-inplace_binop(struct compiler *c, operator_ty op)
-{
- switch (op) {
- case Add:
- return INPLACE_ADD;
- case Sub:
- return INPLACE_SUBTRACT;
- case Mult:
- return INPLACE_MULTIPLY;
- case Div:
- if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION)
- return INPLACE_TRUE_DIVIDE;
- else
- return INPLACE_DIVIDE;
- case Mod:
- return INPLACE_MODULO;
- case Pow:
- return INPLACE_POWER;
- case LShift:
- return INPLACE_LSHIFT;
- case RShift:
- return INPLACE_RSHIFT;
- case BitOr:
- return INPLACE_OR;
- case BitXor:
- return INPLACE_XOR;
- case BitAnd:
- return INPLACE_AND;
- case FloorDiv:
- return INPLACE_FLOOR_DIVIDE;
- }
- PyErr_Format(PyExc_SystemError,
- "inplace binary op %d should not be possible", op);
- return 0;
-}
-
-static int
-compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
-{
- int op, scope, arg;
- enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype;
-
- PyObject *dict = c->u->u_names;
- PyObject *mangled;
- /* XXX AugStore isn't used anywhere! */
-
- /* First check for assignment to __debug__. Param? */
- if ((ctx == Store || ctx == AugStore || ctx == Del)
- && !strcmp(PyString_AS_STRING(name), "__debug__")) {
- return compiler_error(c, "can not assign to __debug__");
- }
-
- mangled = _Py_Mangle(c->u->u_private, name);
- if (!mangled)
- return 0;
-
- op = 0;
- optype = OP_NAME;
- scope = PyST_GetScope(c->u->u_ste, mangled);
- switch (scope) {
- case FREE:
- dict = c->u->u_freevars;
- optype = OP_DEREF;
- break;
- case CELL:
- dict = c->u->u_cellvars;
- optype = OP_DEREF;
- break;
- case LOCAL:
- if (c->u->u_ste->ste_type == FunctionBlock)
- optype = OP_FAST;
- break;
- case GLOBAL_IMPLICIT:
- if (c->u->u_ste->ste_type == FunctionBlock &&
- !c->u->u_ste->ste_unoptimized)
- optype = OP_GLOBAL;
- break;
- case GLOBAL_EXPLICIT:
- optype = OP_GLOBAL;
- break;
- default:
- /* scope can be 0 */
- break;
- }
-
- /* XXX Leave assert here, but handle __doc__ and the like better */
- assert(scope || PyString_AS_STRING(name)[0] == '_');
-
- switch (optype) {
- case OP_DEREF:
- switch (ctx) {
- case Load: op = LOAD_DEREF; break;
- case Store: op = STORE_DEREF; break;
- case AugLoad:
- case AugStore:
- break;
- case Del:
- PyErr_Format(PyExc_SyntaxError,
- "can not delete variable '%s' referenced "
- "in nested scope",
- PyString_AS_STRING(name));
- Py_DECREF(mangled);
- return 0;
- case Param:
- default:
- PyErr_SetString(PyExc_SystemError,
- "param invalid for deref variable");
- return 0;
- }
- break;
- case OP_FAST:
- switch (ctx) {
- case Load: op = LOAD_FAST; break;
- case Store: op = STORE_FAST; break;
- case Del: op = DELETE_FAST; break;
- case AugLoad:
- case AugStore:
- break;
- case Param:
- default:
- PyErr_SetString(PyExc_SystemError,
- "param invalid for local variable");
- return 0;
- }
- ADDOP_O(c, op, mangled, varnames);
- Py_DECREF(mangled);
- return 1;
- case OP_GLOBAL:
- switch (ctx) {
- case Load: op = LOAD_GLOBAL; break;
- case Store: op = STORE_GLOBAL; break;
- case Del: op = DELETE_GLOBAL; break;
- case AugLoad:
- case AugStore:
- break;
- case Param:
- default:
- PyErr_SetString(PyExc_SystemError,
- "param invalid for global variable");
- return 0;
- }
- break;
- case OP_NAME:
- switch (ctx) {
- case Load: op = LOAD_NAME; break;
- case Store: op = STORE_NAME; break;
- case Del: op = DELETE_NAME; break;
- case AugLoad:
- case AugStore:
- break;
- case Param:
- default:
- PyErr_SetString(PyExc_SystemError,
- "param invalid for name variable");
- return 0;
- }
- break;
- }
-
- assert(op);
- arg = compiler_add_o(c, dict, mangled);
- Py_DECREF(mangled);
- if (arg < 0)
- return 0;
- return compiler_addop_i(c, op, arg);
-}
-
-static int
-compiler_boolop(struct compiler *c, expr_ty e)
-{
- basicblock *end;
- int jumpi, i, n;
- asdl_seq *s;
-
- assert(e->kind == BoolOp_kind);
- if (e->v.BoolOp.op == And)
- jumpi = JUMP_IF_FALSE;
- else
- jumpi = JUMP_IF_TRUE;
- end = compiler_new_block(c);
- if (end == NULL)
- return 0;
- s = e->v.BoolOp.values;
- n = asdl_seq_LEN(s) - 1;
- assert(n >= 0);
- for (i = 0; i < n; ++i) {
- VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
- ADDOP_JREL(c, jumpi, end);
- ADDOP(c, POP_TOP)
- }
- VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n));
- compiler_use_next_block(c, end);
- return 1;
-}
-
-static int
-compiler_list(struct compiler *c, expr_ty e)
-{
- int n = asdl_seq_LEN(e->v.List.elts);
- if (e->v.List.ctx == Store) {
- ADDOP_I(c, UNPACK_SEQUENCE, n);
- }
- VISIT_SEQ(c, expr, e->v.List.elts);
- if (e->v.List.ctx == Load) {
- ADDOP_I(c, BUILD_LIST, n);
- }
- return 1;
-}
-
-static int
-compiler_tuple(struct compiler *c, expr_ty e)
-{
- int n = asdl_seq_LEN(e->v.Tuple.elts);
- if (e->v.Tuple.ctx == Store) {
- ADDOP_I(c, UNPACK_SEQUENCE, n);
- }
- VISIT_SEQ(c, expr, e->v.Tuple.elts);
- if (e->v.Tuple.ctx == Load) {
- ADDOP_I(c, BUILD_TUPLE, n);
- }
- return 1;
-}
-
-static int
-compiler_compare(struct compiler *c, expr_ty e)
-{
- int i, n;
- basicblock *cleanup = NULL;
-
- /* XXX the logic can be cleaned up for 1 or multiple comparisons */
- VISIT(c, expr, e->v.Compare.left);
- n = asdl_seq_LEN(e->v.Compare.ops);
- assert(n > 0);
- if (n > 1) {
- cleanup = compiler_new_block(c);
- if (cleanup == NULL)
- return 0;
- VISIT(c, expr,
- (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0));
- }
- for (i = 1; i < n; i++) {
- ADDOP(c, DUP_TOP);
- ADDOP(c, ROT_THREE);
- ADDOP_I(c, COMPARE_OP,
- cmpop((cmpop_ty)(asdl_seq_GET(
- e->v.Compare.ops, i - 1))));
- ADDOP_JREL(c, JUMP_IF_FALSE, cleanup);
- NEXT_BLOCK(c);
- ADDOP(c, POP_TOP);
- if (i < (n - 1))
- VISIT(c, expr,
- (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
- }
- VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n - 1));
- ADDOP_I(c, COMPARE_OP,
- cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, n - 1))));
- if (n > 1) {
- basicblock *end = compiler_new_block(c);
- if (end == NULL)
- return 0;
- ADDOP_JREL(c, JUMP_FORWARD, end);
- compiler_use_next_block(c, cleanup);
- ADDOP(c, ROT_TWO);
- ADDOP(c, POP_TOP);
- compiler_use_next_block(c, end);
- }
- return 1;
-}
-#undef CMPCAST
-
-static int
-compiler_call(struct compiler *c, expr_ty e)
-{
- int n, code = 0;
-
- VISIT(c, expr, e->v.Call.func);
- n = asdl_seq_LEN(e->v.Call.args);
- VISIT_SEQ(c, expr, e->v.Call.args);
- if (e->v.Call.keywords) {
- VISIT_SEQ(c, keyword, e->v.Call.keywords);
- n |= asdl_seq_LEN(e->v.Call.keywords) << 8;
- }
- if (e->v.Call.starargs) {
- VISIT(c, expr, e->v.Call.starargs);
- code |= 1;
- }
- if (e->v.Call.kwargs) {
- VISIT(c, expr, e->v.Call.kwargs);
- code |= 2;
- }
- switch (code) {
- case 0:
- ADDOP_I(c, CALL_FUNCTION, n);
- break;
- case 1:
- ADDOP_I(c, CALL_FUNCTION_VAR, n);
- break;
- case 2:
- ADDOP_I(c, CALL_FUNCTION_KW, n);
- break;
- case 3:
- ADDOP_I(c, CALL_FUNCTION_VAR_KW, n);
- break;
- }
- return 1;
-}
-
-static int
-compiler_listcomp_generator(struct compiler *c, PyObject *tmpname,
- asdl_seq *generators, int gen_index,
- expr_ty elt)
-{
- /* generate code for the iterator, then each of the ifs,
- and then write to the element */
-
- comprehension_ty l;
- basicblock *start, *anchor, *skip, *if_cleanup;
- int i, n;
-
- start = compiler_new_block(c);
- skip = compiler_new_block(c);
- if_cleanup = compiler_new_block(c);
- anchor = compiler_new_block(c);
-
- if (start == NULL || skip == NULL || if_cleanup == NULL ||
- anchor == NULL)
- return 0;
-
- l = (comprehension_ty)asdl_seq_GET(generators, gen_index);
- VISIT(c, expr, l->iter);
- ADDOP(c, GET_ITER);
- compiler_use_next_block(c, start);
- ADDOP_JREL(c, FOR_ITER, anchor);
- NEXT_BLOCK(c);
- VISIT(c, expr, l->target);
-
- /* XXX this needs to be cleaned up...a lot! */
- n = asdl_seq_LEN(l->ifs);
- for (i = 0; i < n; i++) {
- expr_ty e = (expr_ty)asdl_seq_GET(l->ifs, i);
- VISIT(c, expr, e);
- ADDOP_JREL(c, JUMP_IF_FALSE, if_cleanup);
- NEXT_BLOCK(c);
- ADDOP(c, POP_TOP);
- }
-
- if (++gen_index < asdl_seq_LEN(generators))
- if (!compiler_listcomp_generator(c, tmpname,
- generators, gen_index, elt))
- return 0;
-
- /* only append after the last for generator */
- if (gen_index >= asdl_seq_LEN(generators)) {
- if (!compiler_nameop(c, tmpname, Load))
- return 0;
- VISIT(c, expr, elt);
- ADDOP(c, LIST_APPEND);
-
- compiler_use_next_block(c, skip);
- }
- for (i = 0; i < n; i++) {
- ADDOP_I(c, JUMP_FORWARD, 1);
- if (i == 0)
- compiler_use_next_block(c, if_cleanup);
- ADDOP(c, POP_TOP);
- }
- ADDOP_JABS(c, JUMP_ABSOLUTE, start);
- compiler_use_next_block(c, anchor);
- /* delete the append method added to locals */
- if (gen_index == 1)
- if (!compiler_nameop(c, tmpname, Del))
- return 0;
-
- return 1;
-}
-
-static int
-compiler_listcomp(struct compiler *c, expr_ty e)
-{
- identifier tmp;
- int rc = 0;
- static identifier append;
- asdl_seq *generators = e->v.ListComp.generators;
-
- assert(e->kind == ListComp_kind);
- if (!append) {
- append = PyString_InternFromString("append");
- if (!append)
- return 0;
- }
- tmp = compiler_new_tmpname(c);
- if (!tmp)
- return 0;
- ADDOP_I(c, BUILD_LIST, 0);
- ADDOP(c, DUP_TOP);
- if (compiler_nameop(c, tmp, Store))
- rc = compiler_listcomp_generator(c, tmp, generators, 0,
- e->v.ListComp.elt);
- Py_DECREF(tmp);
- return rc;
-}
-
-static int
-compiler_genexp_generator(struct compiler *c,
- asdl_seq *generators, int gen_index,
- expr_ty elt)
-{
- /* generate code for the iterator, then each of the ifs,
- and then write to the element */
-
- comprehension_ty ge;
- basicblock *start, *anchor, *skip, *if_cleanup, *end;
- int i, n;
-
- start = compiler_new_block(c);
- skip = compiler_new_block(c);
- if_cleanup = compiler_new_block(c);
- anchor = compiler_new_block(c);
- end = compiler_new_block(c);
-
- if (start == NULL || skip == NULL || if_cleanup == NULL ||
- anchor == NULL || end == NULL)
- return 0;
-
- ge = (comprehension_ty)asdl_seq_GET(generators, gen_index);
- ADDOP_JREL(c, SETUP_LOOP, end);
- if (!compiler_push_fblock(c, LOOP, start))
- return 0;
-
- if (gen_index == 0) {
- /* Receive outermost iter as an implicit argument */
- c->u->u_argcount = 1;
- ADDOP_I(c, LOAD_FAST, 0);
- }
- else {
- /* Sub-iter - calculate on the fly */
- VISIT(c, expr, ge->iter);
- ADDOP(c, GET_ITER);
- }
- compiler_use_next_block(c, start);
- ADDOP_JREL(c, FOR_ITER, anchor);
- NEXT_BLOCK(c);
- VISIT(c, expr, ge->target);
-
- /* XXX this needs to be cleaned up...a lot! */
- n = asdl_seq_LEN(ge->ifs);
- for (i = 0; i < n; i++) {
- expr_ty e = (expr_ty)asdl_seq_GET(ge->ifs, i);
- VISIT(c, expr, e);
- ADDOP_JREL(c, JUMP_IF_FALSE, if_cleanup);
- NEXT_BLOCK(c);
- ADDOP(c, POP_TOP);
- }
-
- if (++gen_index < asdl_seq_LEN(generators))
- if (!compiler_genexp_generator(c, generators, gen_index, elt))
- return 0;
-
- /* only append after the last 'for' generator */
- if (gen_index >= asdl_seq_LEN(generators)) {
- VISIT(c, expr, elt);
- ADDOP(c, YIELD_VALUE);
- ADDOP(c, POP_TOP);
-
- compiler_use_next_block(c, skip);
- }
- for (i = 0; i < n; i++) {
- ADDOP_I(c, JUMP_FORWARD, 1);
- if (i == 0)
- compiler_use_next_block(c, if_cleanup);
-
- ADDOP(c, POP_TOP);
- }
- ADDOP_JABS(c, JUMP_ABSOLUTE, start);
- compiler_use_next_block(c, anchor);
- ADDOP(c, POP_BLOCK);
- compiler_pop_fblock(c, LOOP, start);
- compiler_use_next_block(c, end);
-
- return 1;
-}
-
-static int
-compiler_genexp(struct compiler *c, expr_ty e)
-{
- static identifier name;
- PyCodeObject *co;
- expr_ty outermost_iter = ((comprehension_ty)
- (asdl_seq_GET(e->v.GeneratorExp.generators,
- 0)))->iter;
-
- if (!name) {
- name = PyString_FromString("<genexpr>");
- if (!name)
- return 0;
- }
-
- if (!compiler_enter_scope(c, name, (void *)e, e->lineno))
- return 0;
- compiler_genexp_generator(c, e->v.GeneratorExp.generators, 0,
- e->v.GeneratorExp.elt);
- co = assemble(c, 1);
- compiler_exit_scope(c);
- if (co == NULL)
- return 0;
-
- compiler_make_closure(c, co, 0);
- Py_DECREF(co);
-
- VISIT(c, expr, outermost_iter);
- ADDOP(c, GET_ITER);
- ADDOP_I(c, CALL_FUNCTION, 1);
-
- return 1;
-}
-
-static int
-compiler_visit_keyword(struct compiler *c, keyword_ty k)
-{
- ADDOP_O(c, LOAD_CONST, k->arg, consts);
- VISIT(c, expr, k->value);
- return 1;
-}
-
-/* Test whether expression is constant. For constants, report
- whether they are true or false.
-
- Return values: 1 for true, 0 for false, -1 for non-constant.
- */
-
-static int
-expr_constant(expr_ty e)
-{
- switch (e->kind) {
- case Num_kind:
- return PyObject_IsTrue(e->v.Num.n);
- case Str_kind:
- return PyObject_IsTrue(e->v.Str.s);
- case Name_kind:
- /* __debug__ is not assignable, so we can optimize
- * it away in if and while statements */
- if (strcmp(PyString_AS_STRING(e->v.Name.id),
- "__debug__") == 0)
- return ! Py_OptimizeFlag;
- /* fall through */
- default:
- return -1;
- }
-}
-
-/*
- Implements the with statement from PEP 343.
-
- The semantics outlined in that PEP are as follows:
-
- with EXPR as VAR:
- BLOCK
-
- It is implemented roughly as:
-
- context = EXPR
- exit = context.__exit__ # not calling it
- value = context.__enter__()
- try:
- VAR = value # if VAR present in the syntax
- BLOCK
- finally:
- if an exception was raised:
- exc = copy of (exception, instance, traceback)
- else:
- exc = (None, None, None)
- exit(*exc)
- */
-static int
-compiler_with(struct compiler *c, stmt_ty s)
-{
- static identifier enter_attr, exit_attr;
- basicblock *block, *finally;
- identifier tmpexit, tmpvalue = NULL;
-
- assert(s->kind == With_kind);
-
- if (!enter_attr) {
- enter_attr = PyString_InternFromString("__enter__");
- if (!enter_attr)
- return 0;
- }
- if (!exit_attr) {
- exit_attr = PyString_InternFromString("__exit__");
- if (!exit_attr)
- return 0;
- }
-
- block = compiler_new_block(c);
- finally = compiler_new_block(c);
- if (!block || !finally)
- return 0;
-
- /* Create a temporary variable to hold context.__exit__ */
- tmpexit = compiler_new_tmpname(c);
- if (tmpexit == NULL)
- return 0;
- PyArena_AddPyObject(c->c_arena, tmpexit);
-
- if (s->v.With.optional_vars) {
- /* Create a temporary variable to hold context.__enter__().
- We need to do this rather than preserving it on the stack
- because SETUP_FINALLY remembers the stack level.
- We need to do the assignment *inside* the try/finally
- so that context.__exit__() is called when the assignment
- fails. But we need to call context.__enter__() *before*
- the try/finally so that if it fails we won't call
- context.__exit__().
- */
- tmpvalue = compiler_new_tmpname(c);
- if (tmpvalue == NULL)
- return 0;
- PyArena_AddPyObject(c->c_arena, tmpvalue);
- }
-
- /* Evaluate EXPR */
- VISIT(c, expr, s->v.With.context_expr);
-
- /* Squirrel away context.__exit__ */
- ADDOP(c, DUP_TOP);
- ADDOP_O(c, LOAD_ATTR, exit_attr, names);
- if (!compiler_nameop(c, tmpexit, Store))
- return 0;
-
- /* Call context.__enter__() */
- ADDOP_O(c, LOAD_ATTR, enter_attr, names);
- ADDOP_I(c, CALL_FUNCTION, 0);
-
- if (s->v.With.optional_vars) {
- /* Store it in tmpvalue */
- if (!compiler_nameop(c, tmpvalue, Store))
- return 0;
- }
- else {
- /* Discard result from context.__enter__() */
- ADDOP(c, POP_TOP);
- }
-
- /* Start the try block */
- ADDOP_JREL(c, SETUP_FINALLY, finally);
-
- compiler_use_next_block(c, block);
- if (!compiler_push_fblock(c, FINALLY_TRY, block)) {
- return 0;
- }
-
- if (s->v.With.optional_vars) {
- /* Bind saved result of context.__enter__() to VAR */
- if (!compiler_nameop(c, tmpvalue, Load) ||
- !compiler_nameop(c, tmpvalue, Del))
- return 0;
- VISIT(c, expr, s->v.With.optional_vars);
- }
-
- /* BLOCK code */
- VISIT_SEQ(c, stmt, s->v.With.body);
-
- /* End of try block; start the finally block */
- ADDOP(c, POP_BLOCK);
- compiler_pop_fblock(c, FINALLY_TRY, block);
-
- ADDOP_O(c, LOAD_CONST, Py_None, consts);
- compiler_use_next_block(c, finally);
- if (!compiler_push_fblock(c, FINALLY_END, finally))
- return 0;
-
- /* Finally block starts; push tmpexit and issue our magic opcode. */
- if (!compiler_nameop(c, tmpexit, Load) ||
- !compiler_nameop(c, tmpexit, Del))
- return 0;
- ADDOP(c, WITH_CLEANUP);
-
- /* Finally block ends. */
- ADDOP(c, END_FINALLY);
- compiler_pop_fblock(c, FINALLY_END, finally);
- return 1;
-}
-
-static int
-compiler_visit_expr(struct compiler *c, expr_ty e)
-{
- int i, n;
-
- /* If expr e has a different line number than the last expr/stmt,
- set a new line number for the next instruction.
- */
- if (e->lineno > c->u->u_lineno) {
- c->u->u_lineno = e->lineno;
- c->u->u_lineno_set = false;
- }
- switch (e->kind) {
- case BoolOp_kind:
- return compiler_boolop(c, e);
- case BinOp_kind:
- VISIT(c, expr, e->v.BinOp.left);
- VISIT(c, expr, e->v.BinOp.right);
- ADDOP(c, binop(c, e->v.BinOp.op));
- break;
- case UnaryOp_kind:
- VISIT(c, expr, e->v.UnaryOp.operand);
- ADDOP(c, unaryop(e->v.UnaryOp.op));
- break;
- case Lambda_kind:
- return compiler_lambda(c, e);
- case IfExp_kind:
- return compiler_ifexp(c, e);
- case Dict_kind:
- /* XXX get rid of arg? */
- ADDOP_I(c, BUILD_MAP, 0);
- n = asdl_seq_LEN(e->v.Dict.values);
- /* We must arrange things just right for STORE_SUBSCR.
- It wants the stack to look like (value) (dict) (key) */
- for (i = 0; i < n; i++) {
- ADDOP(c, DUP_TOP);
- VISIT(c, expr,
- (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
- ADDOP(c, ROT_TWO);
- VISIT(c, expr,
- (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
- ADDOP(c, STORE_SUBSCR);
- }
- break;
- case ListComp_kind:
- return compiler_listcomp(c, e);
- case GeneratorExp_kind:
- return compiler_genexp(c, e);
- case Yield_kind:
- if (c->u->u_ste->ste_type != FunctionBlock)
- return compiler_error(c, "'yield' outside function");
- /*
- for (i = 0; i < c->u->u_nfblocks; i++) {
- if (c->u->u_fblock[i].fb_type == FINALLY_TRY)
- return compiler_error(
- c, "'yield' not allowed in a 'try' "
- "block with a 'finally' clause");
- }
- */
- if (e->v.Yield.value) {
- VISIT(c, expr, e->v.Yield.value);
- }
- else {
- ADDOP_O(c, LOAD_CONST, Py_None, consts);
- }
- ADDOP(c, YIELD_VALUE);
- break;
- case Compare_kind:
- return compiler_compare(c, e);
- case Call_kind:
- return compiler_call(c, e);
- case Repr_kind:
- VISIT(c, expr, e->v.Repr.value);
- ADDOP(c, UNARY_CONVERT);
- break;
- case Num_kind:
- ADDOP_O(c, LOAD_CONST, e->v.Num.n, consts);
- break;
- case Str_kind:
- ADDOP_O(c, LOAD_CONST, e->v.Str.s, consts);
- break;
- /* The following exprs can be assignment targets. */
- case Attribute_kind:
- if (e->v.Attribute.ctx != AugStore)
- VISIT(c, expr, e->v.Attribute.value);
- switch (e->v.Attribute.ctx) {
- case AugLoad:
- ADDOP(c, DUP_TOP);
- /* Fall through to load */
- case Load:
- ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);
- break;
- case AugStore:
- ADDOP(c, ROT_TWO);
- /* Fall through to save */
- case Store:
- ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
- break;
- case Del:
- ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names);
- break;
- case Param:
- default:
- PyErr_SetString(PyExc_SystemError,
- "param invalid in attribute expression");
- return 0;
- }
- break;
- case Subscript_kind:
- switch (e->v.Subscript.ctx) {
- case AugLoad:
- VISIT(c, expr, e->v.Subscript.value);
- VISIT_SLICE(c, e->v.Subscript.slice, AugLoad);
- break;
- case Load:
- VISIT(c, expr, e->v.Subscript.value);
- VISIT_SLICE(c, e->v.Subscript.slice, Load);
- break;
- case AugStore:
- VISIT_SLICE(c, e->v.Subscript.slice, AugStore);
- break;
- case Store:
- VISIT(c, expr, e->v.Subscript.value);
- VISIT_SLICE(c, e->v.Subscript.slice, Store);
- break;
- case Del:
- VISIT(c, expr, e->v.Subscript.value);
- VISIT_SLICE(c, e->v.Subscript.slice, Del);
- break;
- case Param:
- default:
- PyErr_SetString(PyExc_SystemError,
- "param invalid in subscript expression");
- return 0;
- }
- break;
- case Name_kind:
- return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx);
- /* child nodes of List and Tuple will have expr_context set */
- case List_kind:
- return compiler_list(c, e);
- case Tuple_kind:
- return compiler_tuple(c, e);
- }
- return 1;
-}
-
-static int
-compiler_augassign(struct compiler *c, stmt_ty s)
-{
- expr_ty e = s->v.AugAssign.target;
- expr_ty auge;
-
- assert(s->kind == AugAssign_kind);
-
- switch (e->kind) {
- case Attribute_kind:
- auge = Attribute(e->v.Attribute.value, e->v.Attribute.attr,
- AugLoad, e->lineno, e->col_offset, c->c_arena);
- if (auge == NULL)
- return 0;
- VISIT(c, expr, auge);
- VISIT(c, expr, s->v.AugAssign.value);
- ADDOP(c, inplace_binop(c, s->v.AugAssign.op));
- auge->v.Attribute.ctx = AugStore;
- VISIT(c, expr, auge);
- break;
- case Subscript_kind:
- auge = Subscript(e->v.Subscript.value, e->v.Subscript.slice,
- AugLoad, e->lineno, e->col_offset, c->c_arena);
- if (auge == NULL)
- return 0;
- VISIT(c, expr, auge);
- VISIT(c, expr, s->v.AugAssign.value);
- ADDOP(c, inplace_binop(c, s->v.AugAssign.op));
- auge->v.Subscript.ctx = AugStore;
- VISIT(c, expr, auge);
- break;
- case Name_kind:
- if (!compiler_nameop(c, e->v.Name.id, Load))
- return 0;
- VISIT(c, expr, s->v.AugAssign.value);
- ADDOP(c, inplace_binop(c, s->v.AugAssign.op));
- return compiler_nameop(c, e->v.Name.id, Store);
- default:
- PyErr_Format(PyExc_SystemError,
- "invalid node type (%d) for augmented assignment",
- e->kind);
- return 0;
- }
- return 1;
-}
-
-static int
-compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b)
-{
- struct fblockinfo *f;
- if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
- PyErr_SetString(PyExc_SystemError,
- "too many statically nested blocks");
- return 0;
- }
- f = &c->u->u_fblock[c->u->u_nfblocks++];
- f->fb_type = t;
- f->fb_block = b;
- return 1;
-}
-
-static void
-compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b)
-{
- struct compiler_unit *u = c->u;
- assert(u->u_nfblocks > 0);
- u->u_nfblocks--;
- assert(u->u_fblock[u->u_nfblocks].fb_type == t);
- assert(u->u_fblock[u->u_nfblocks].fb_block == b);
-}
-
-static int
-compiler_in_loop(struct compiler *c) {
- int i;
- struct compiler_unit *u = c->u;
- for (i = 0; i < u->u_nfblocks; ++i) {
- if (u->u_fblock[i].fb_type == LOOP)
- return 1;
- }
- return 0;
-}
-/* Raises a SyntaxError and returns 0.
- If something goes wrong, a different exception may be raised.
-*/
-
-static int
-compiler_error(struct compiler *c, const char *errstr)
-{
- PyObject *loc;
- PyObject *u = NULL, *v = NULL;
-
- loc = PyErr_ProgramText(c->c_filename, c->u->u_lineno);
- if (!loc) {
- Py_INCREF(Py_None);
- loc = Py_None;
- }
- u = Py_BuildValue("(ziOO)", c->c_filename, c->u->u_lineno,
- Py_None, loc);
- if (!u)
- goto exit;
- v = Py_BuildValue("(zO)", errstr, u);
- if (!v)
- goto exit;
- PyErr_SetObject(PyExc_SyntaxError, v);
- exit:
- Py_DECREF(loc);
- Py_XDECREF(u);
- Py_XDECREF(v);
- return 0;
-}
-
-static int
-compiler_handle_subscr(struct compiler *c, const char *kind,
- expr_context_ty ctx)
-{
- int op = 0;
-
- /* XXX this code is duplicated */
- switch (ctx) {
- case AugLoad: /* fall through to Load */
- case Load: op = BINARY_SUBSCR; break;
- case AugStore:/* fall through to Store */
- case Store: op = STORE_SUBSCR; break;
- case Del: op = DELETE_SUBSCR; break;
- case Param:
- PyErr_Format(PyExc_SystemError,
- "invalid %s kind %d in subscript\n",
- kind, ctx);
- return 0;
- }
- if (ctx == AugLoad) {
- ADDOP_I(c, DUP_TOPX, 2);
- }
- else if (ctx == AugStore) {
- ADDOP(c, ROT_THREE);
- }
- ADDOP(c, op);
- return 1;
-}
-
-static int
-compiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
-{
- int n = 2;
- assert(s->kind == Slice_kind);
-
- /* only handles the cases where BUILD_SLICE is emitted */
- if (s->v.Slice.lower) {
- VISIT(c, expr, s->v.Slice.lower);
- }
- else {
- ADDOP_O(c, LOAD_CONST, Py_None, consts);
- }
-
- if (s->v.Slice.upper) {
- VISIT(c, expr, s->v.Slice.upper);
- }
- else {
- ADDOP_O(c, LOAD_CONST, Py_None, consts);
- }
-
- if (s->v.Slice.step) {
- n++;
- VISIT(c, expr, s->v.Slice.step);
- }
- ADDOP_I(c, BUILD_SLICE, n);
- return 1;
-}
-
-static int
-compiler_simple_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
-{
- int op = 0, slice_offset = 0, stack_count = 0;
-
- assert(s->v.Slice.step == NULL);
- if (s->v.Slice.lower) {
- slice_offset++;
- stack_count++;
- if (ctx != AugStore)
- VISIT(c, expr, s->v.Slice.lower);
- }
- if (s->v.Slice.upper) {
- slice_offset += 2;
- stack_count++;
- if (ctx != AugStore)
- VISIT(c, expr, s->v.Slice.upper);
- }
-
- if (ctx == AugLoad) {
- switch (stack_count) {
- case 0: ADDOP(c, DUP_TOP); break;
- case 1: ADDOP_I(c, DUP_TOPX, 2); break;
- case 2: ADDOP_I(c, DUP_TOPX, 3); break;
- }
- }
- else if (ctx == AugStore) {
- switch (stack_count) {
- case 0: ADDOP(c, ROT_TWO); break;
- case 1: ADDOP(c, ROT_THREE); break;
- case 2: ADDOP(c, ROT_FOUR); break;
- }
- }
-
- switch (ctx) {
- case AugLoad: /* fall through to Load */
- case Load: op = SLICE; break;
- case AugStore:/* fall through to Store */
- case Store: op = STORE_SLICE; break;
- case Del: op = DELETE_SLICE; break;
- case Param:
- default:
- PyErr_SetString(PyExc_SystemError,
- "param invalid in simple slice");
- return 0;
- }
-
- ADDOP(c, op + slice_offset);
- return 1;
-}
-
-static int
-compiler_visit_nested_slice(struct compiler *c, slice_ty s,
- expr_context_ty ctx)
-{
- switch (s->kind) {
- case Ellipsis_kind:
- ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);
- break;
- case Slice_kind:
- return compiler_slice(c, s, ctx);
- case Index_kind:
- VISIT(c, expr, s->v.Index.value);
- break;
- case ExtSlice_kind:
- default:
- PyErr_SetString(PyExc_SystemError,
- "extended slice invalid in nested slice");
- return 0;
- }
- return 1;
-}
-
-
-static int
-compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
-{
- char * kindname = NULL;
- switch (s->kind) {
- case Index_kind:
- kindname = "index";
- if (ctx != AugStore) {
- VISIT(c, expr, s->v.Index.value);
- }
- break;
- case Ellipsis_kind:
- kindname = "ellipsis";
- if (ctx != AugStore) {
- ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);
- }
- break;
- case Slice_kind:
- kindname = "slice";
- if (!s->v.Slice.step)
- return compiler_simple_slice(c, s, ctx);
- if (ctx != AugStore) {
- if (!compiler_slice(c, s, ctx))
- return 0;
- }
- break;
- case ExtSlice_kind:
- kindname = "extended slice";
- if (ctx != AugStore) {
- int i, n = asdl_seq_LEN(s->v.ExtSlice.dims);
- for (i = 0; i < n; i++) {
- slice_ty sub = (slice_ty)asdl_seq_GET(
- s->v.ExtSlice.dims, i);
- if (!compiler_visit_nested_slice(c, sub, ctx))
- return 0;
- }
- ADDOP_I(c, BUILD_TUPLE, n);
- }
- break;
- default:
- PyErr_Format(PyExc_SystemError,
- "invalid subscript kind %d", s->kind);
- return 0;
- }
- return compiler_handle_subscr(c, kindname, ctx);
-}
-
-/* do depth-first search of basic block graph, starting with block.
- post records the block indices in post-order.
-
- XXX must handle implicit jumps from one block to next
-*/
-
-static void
-dfs(struct compiler *c, basicblock *b, struct assembler *a)
-{
- int i;
- struct instr *instr = NULL;
-
- if (b->b_seen)
- return;
- b->b_seen = 1;
- if (b->b_next != NULL)
- dfs(c, b->b_next, a);
- for (i = 0; i < b->b_iused; i++) {
- instr = &b->b_instr[i];
- if (instr->i_jrel || instr->i_jabs)
- dfs(c, instr->i_target, a);
- }
- a->a_postorder[a->a_nblocks++] = b;
-}
-
-static int
-stackdepth_walk(struct compiler *c, basicblock *b, int depth, int maxdepth)
-{
- int i;
- struct instr *instr;
- if (b->b_seen || b->b_startdepth >= depth)
- return maxdepth;
- b->b_seen = 1;
- b->b_startdepth = depth;
- for (i = 0; i < b->b_iused; i++) {
- instr = &b->b_instr[i];
- depth += opcode_stack_effect(instr->i_opcode, instr->i_oparg);
- if (depth > maxdepth)
- maxdepth = depth;
- assert(depth >= 0); /* invalid code or bug in stackdepth() */
- if (instr->i_jrel || instr->i_jabs) {
- maxdepth = stackdepth_walk(c, instr->i_target,
- depth, maxdepth);
- if (instr->i_opcode == JUMP_ABSOLUTE ||
- instr->i_opcode == JUMP_FORWARD) {
- goto out; /* remaining code is dead */
- }
- }
- }
- if (b->b_next)
- maxdepth = stackdepth_walk(c, b->b_next, depth, maxdepth);
-out:
- b->b_seen = 0;
- return maxdepth;
-}
-
-/* Find the flow path that needs the largest stack. We assume that
- * cycles in the flow graph have no net effect on the stack depth.
- */
-static int
-stackdepth(struct compiler *c)
-{
- basicblock *b, *entryblock;
- entryblock = NULL;
- for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
- b->b_seen = 0;
- b->b_startdepth = INT_MIN;
- entryblock = b;
- }
- if (!entryblock)
- return 0;
- return stackdepth_walk(c, entryblock, 0, 0);
-}
-
-static int
-assemble_init(struct assembler *a, int nblocks, int firstlineno)
-{
- memset(a, 0, sizeof(struct assembler));
- a->a_lineno = firstlineno;
- a->a_bytecode = PyString_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
- if (!a->a_bytecode)
- return 0;
- a->a_lnotab = PyString_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
- if (!a->a_lnotab)
- return 0;
- a->a_postorder = (basicblock **)PyObject_Malloc(
- sizeof(basicblock *) * nblocks);
- if (!a->a_postorder) {
- PyErr_NoMemory();
- return 0;
- }
- return 1;
-}
-
-static void
-assemble_free(struct assembler *a)
-{
- Py_XDECREF(a->a_bytecode);
- Py_XDECREF(a->a_lnotab);
- if (a->a_postorder)
- PyObject_Free(a->a_postorder);
-}
-
-/* Return the size of a basic block in bytes. */
-
-static int
-instrsize(struct instr *instr)
-{
- if (!instr->i_hasarg)
- return 1;
- if (instr->i_oparg > 0xffff)
- return 6;
- return 3;
-}
-
-static int
-blocksize(basicblock *b)
-{
- int i;
- int size = 0;
-
- for (i = 0; i < b->b_iused; i++)
- size += instrsize(&b->b_instr[i]);
- return size;
-}
-
-/* All about a_lnotab.
-
-c_lnotab is an array of unsigned bytes disguised as a Python string.
-It is used to map bytecode offsets to source code line #s (when needed
-for tracebacks).
-
-The array is conceptually a list of
- (bytecode offset increment, line number increment)
-pairs. The details are important and delicate, best illustrated by example:
-
- byte code offset source code line number
- 0 1
- 6 2
- 50 7
- 350 307
- 361 308
-
-The first trick is that these numbers aren't stored, only the increments
-from one row to the next (this doesn't really work, but it's a start):
-
- 0, 1, 6, 1, 44, 5, 300, 300, 11, 1
-
-The second trick is that an unsigned byte can't hold negative values, or
-values larger than 255, so (a) there's a deep assumption that byte code
-offsets and their corresponding line #s both increase monotonically, and (b)
-if at least one column jumps by more than 255 from one row to the next, more
-than one pair is written to the table. In case #b, there's no way to know
-from looking at the table later how many were written. That's the delicate
-part. A user of c_lnotab desiring to find the source line number
-corresponding to a bytecode address A should do something like this
-
- lineno = addr = 0
- for addr_incr, line_incr in c_lnotab:
- addr += addr_incr
- if addr > A:
- return lineno
- lineno += line_incr
-
-In order for this to work, when the addr field increments by more than 255,
-the line # increment in each pair generated must be 0 until the remaining addr
-increment is < 256. So, in the example above, assemble_lnotab (it used
-to be called com_set_lineno) should not (as was actually done until 2.2)
-expand 300, 300 to 255, 255, 45, 45,
- but to 255, 0, 45, 255, 0, 45.
-*/
-
-static int
-assemble_lnotab(struct assembler *a, struct instr *i)
-{
- int d_bytecode, d_lineno;
- int len;
- unsigned char *lnotab;
-
- d_bytecode = a->a_offset - a->a_lineno_off;
- d_lineno = i->i_lineno - a->a_lineno;
-
- assert(d_bytecode >= 0);
- assert(d_lineno >= 0);
-
- /* XXX(nnorwitz): is there a better way to handle this?
- for loops are special, we want to be able to trace them
- each time around, so we need to set an extra line number. */
- if (d_lineno == 0 && i->i_opcode != FOR_ITER)
- return 1;
-
- if (d_bytecode > 255) {
- int j, nbytes, ncodes = d_bytecode / 255;
- nbytes = a->a_lnotab_off + 2 * ncodes;
- len = PyString_GET_SIZE(a->a_lnotab);
- if (nbytes >= len) {
- if (len * 2 < nbytes)
- len = nbytes;
- else
- len *= 2;
- if (_PyString_Resize(&a->a_lnotab, len) < 0)
- return 0;
- }
- lnotab = (unsigned char *)
- PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
- for (j = 0; j < ncodes; j++) {
- *lnotab++ = 255;
- *lnotab++ = 0;
- }
- d_bytecode -= ncodes * 255;
- a->a_lnotab_off += ncodes * 2;
- }
- assert(d_bytecode <= 255);
- if (d_lineno > 255) {
- int j, nbytes, ncodes = d_lineno / 255;
- nbytes = a->a_lnotab_off + 2 * ncodes;
- len = PyString_GET_SIZE(a->a_lnotab);
- if (nbytes >= len) {
- if (len * 2 < nbytes)
- len = nbytes;
- else
- len *= 2;
- if (_PyString_Resize(&a->a_lnotab, len) < 0)
- return 0;
- }
- lnotab = (unsigned char *)
- PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
- *lnotab++ = d_bytecode;
- *lnotab++ = 255;
- d_bytecode = 0;
- for (j = 1; j < ncodes; j++) {
- *lnotab++ = 0;
- *lnotab++ = 255;
- }
- d_lineno -= ncodes * 255;
- a->a_lnotab_off += ncodes * 2;
- }
-
- len = PyString_GET_SIZE(a->a_lnotab);
- if (a->a_lnotab_off + 2 >= len) {
- if (_PyString_Resize(&a->a_lnotab, len * 2) < 0)
- return 0;
- }
- lnotab = (unsigned char *)
- PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
-
- a->a_lnotab_off += 2;
- if (d_bytecode) {
- *lnotab++ = d_bytecode;
- *lnotab++ = d_lineno;
- }
- else { /* First line of a block; def stmt, etc. */
- *lnotab++ = 0;
- *lnotab++ = d_lineno;
- }
- a->a_lineno = i->i_lineno;
- a->a_lineno_off = a->a_offset;
- return 1;
-}
-
-/* assemble_emit()
- Extend the bytecode with a new instruction.
- Update lnotab if necessary.
-*/
-
-static int
-assemble_emit(struct assembler *a, struct instr *i)
-{
- int size, arg = 0, ext = 0;
- Py_ssize_t len = PyString_GET_SIZE(a->a_bytecode);
- char *code;
-
- size = instrsize(i);
- if (i->i_hasarg) {
- arg = i->i_oparg;
- ext = arg >> 16;
- }
- if (i->i_lineno && !assemble_lnotab(a, i))
- return 0;
- if (a->a_offset + size >= len) {
- if (_PyString_Resize(&a->a_bytecode, len * 2) < 0)
- return 0;
- }
- code = PyString_AS_STRING(a->a_bytecode) + a->a_offset;
- a->a_offset += size;
- if (size == 6) {
- assert(i->i_hasarg);
- *code++ = (char)EXTENDED_ARG;
- *code++ = ext & 0xff;
- *code++ = ext >> 8;
- arg &= 0xffff;
- }
- *code++ = i->i_opcode;
- if (i->i_hasarg) {
- assert(size == 3 || size == 6);
- *code++ = arg & 0xff;
- *code++ = arg >> 8;
- }
- return 1;
-}
-
-static void
-assemble_jump_offsets(struct assembler *a, struct compiler *c)
-{
- basicblock *b;
- int bsize, totsize, extended_arg_count, last_extended_arg_count = 0;
- int i;
-
- /* Compute the size of each block and fixup jump args.
- Replace block pointer with position in bytecode. */
-start:
- totsize = 0;
- for (i = a->a_nblocks - 1; i >= 0; i--) {
- b = a->a_postorder[i];
- bsize = blocksize(b);
- b->b_offset = totsize;
- totsize += bsize;
- }
- extended_arg_count = 0;
- for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
- bsize = b->b_offset;
- for (i = 0; i < b->b_iused; i++) {
- struct instr *instr = &b->b_instr[i];
- /* Relative jumps are computed relative to
- the instruction pointer after fetching
- the jump instruction.
- */
- bsize += instrsize(instr);
- if (instr->i_jabs)
- instr->i_oparg = instr->i_target->b_offset;
- else if (instr->i_jrel) {
- int delta = instr->i_target->b_offset - bsize;
- instr->i_oparg = delta;
- }
- else
- continue;
- if (instr->i_oparg > 0xffff)
- extended_arg_count++;
- }
- }
-
- /* XXX: This is an awful hack that could hurt performance, but
- on the bright side it should work until we come up
- with a better solution.
-
- In the meantime, should the goto be dropped in favor
- of a loop?
-
- The issue is that in the first loop blocksize() is called
- which calls instrsize() which requires i_oparg be set
- appropriately. There is a bootstrap problem because
- i_oparg is calculated in the second loop above.
-
- So we loop until we stop seeing new EXTENDED_ARGs.
- The only EXTENDED_ARGs that could be popping up are
- ones in jump instructions. So this should converge
- fairly quickly.
- */
- if (last_extended_arg_count != extended_arg_count) {
- last_extended_arg_count = extended_arg_count;
- goto start;
- }
-}
-
-static PyObject *
-dict_keys_inorder(PyObject *dict, int offset)
-{
- PyObject *tuple, *k, *v;
- Py_ssize_t i, pos = 0, size = PyDict_Size(dict);
-
- tuple = PyTuple_New(size);
- if (tuple == NULL)
- return NULL;
- while (PyDict_Next(dict, &pos, &k, &v)) {
- i = PyInt_AS_LONG(v);
- k = PyTuple_GET_ITEM(k, 0);
- Py_INCREF(k);
- assert((i - offset) < size);
- assert((i - offset) >= 0);
- PyTuple_SET_ITEM(tuple, i - offset, k);
- }
- return tuple;
-}
-
-static int
-compute_code_flags(struct compiler *c)
-{
- PySTEntryObject *ste = c->u->u_ste;
- int flags = 0, n;
- if (ste->ste_type != ModuleBlock)
- flags |= CO_NEWLOCALS;
- if (ste->ste_type == FunctionBlock) {
- if (!ste->ste_unoptimized)
- flags |= CO_OPTIMIZED;
- if (ste->ste_nested)
- flags |= CO_NESTED;
- if (ste->ste_generator)
- flags |= CO_GENERATOR;
- }
- if (ste->ste_varargs)
- flags |= CO_VARARGS;
- if (ste->ste_varkeywords)
- flags |= CO_VARKEYWORDS;
- if (ste->ste_generator)
- flags |= CO_GENERATOR;
-
- /* (Only) inherit compilerflags in PyCF_MASK */
- flags |= (c->c_flags->cf_flags & PyCF_MASK);
-
- n = PyDict_Size(c->u->u_freevars);
- if (n < 0)
- return -1;
- if (n == 0) {
- n = PyDict_Size(c->u->u_cellvars);
- if (n < 0)
- return -1;
- if (n == 0) {
- flags |= CO_NOFREE;
- }
- }
-
- return flags;
-}
-
-static PyCodeObject *
-makecode(struct compiler *c, struct assembler *a)
-{
- PyObject *tmp;
- PyCodeObject *co = NULL;
- PyObject *consts = NULL;
- PyObject *names = NULL;
- PyObject *varnames = NULL;
- PyObject *filename = NULL;
- PyObject *name = NULL;
- PyObject *freevars = NULL;
- PyObject *cellvars = NULL;
- PyObject *bytecode = NULL;
- int nlocals, flags;
-
- tmp = dict_keys_inorder(c->u->u_consts, 0);
- if (!tmp)
- goto error;
- consts = PySequence_List(tmp); /* optimize_code requires a list */
- Py_DECREF(tmp);
-
- names = dict_keys_inorder(c->u->u_names, 0);
- varnames = dict_keys_inorder(c->u->u_varnames, 0);
- if (!consts || !names || !varnames)
- goto error;
-
- cellvars = dict_keys_inorder(c->u->u_cellvars, 0);
- if (!cellvars)
- goto error;
- freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars));
- if (!freevars)
- goto error;
- filename = PyString_FromString(c->c_filename);
- if (!filename)
- goto error;
-
- nlocals = PyDict_Size(c->u->u_varnames);
- flags = compute_code_flags(c);
- if (flags < 0)
- goto error;
-
- bytecode = optimize_code(a->a_bytecode, consts, names, a->a_lnotab);
- if (!bytecode)
- goto error;
-
- tmp = PyList_AsTuple(consts); /* PyCode_New requires a tuple */
- if (!tmp)
- goto error;
- Py_DECREF(consts);
- consts = tmp;
-
- co = PyCode_New(c->u->u_argcount, nlocals, stackdepth(c), flags,
- bytecode, consts, names, varnames,
- freevars, cellvars,
- filename, c->u->u_name,
- c->u->u_firstlineno,
- a->a_lnotab);
- error:
- Py_XDECREF(consts);
- Py_XDECREF(names);
- Py_XDECREF(varnames);
- Py_XDECREF(filename);
- Py_XDECREF(name);
- Py_XDECREF(freevars);
- Py_XDECREF(cellvars);
- Py_XDECREF(bytecode);
- return co;
-}
-
-
-/* For debugging purposes only */
-#if 0
-static void
-dump_instr(const struct instr *i)
-{
- const char *jrel = i->i_jrel ? "jrel " : "";
- const char *jabs = i->i_jabs ? "jabs " : "";
- char arg[128];
-
- *arg = '\0';
- if (i->i_hasarg)
- sprintf(arg, "arg: %d ", i->i_oparg);
-
- fprintf(stderr, "line: %d, opcode: %d %s%s%s\n",
- i->i_lineno, i->i_opcode, arg, jabs, jrel);
-}
-
-static void
-dump_basicblock(const basicblock *b)
-{
- const char *seen = b->b_seen ? "seen " : "";
- const char *b_return = b->b_return ? "return " : "";
- fprintf(stderr, "used: %d, depth: %d, offset: %d %s%s\n",
- b->b_iused, b->b_startdepth, b->b_offset, seen, b_return);
- if (b->b_instr) {
- int i;
- for (i = 0; i < b->b_iused; i++) {
- fprintf(stderr, " [%02d] ", i);
- dump_instr(b->b_instr + i);
- }
- }
-}
-#endif
-
-static PyCodeObject *
-assemble(struct compiler *c, int addNone)
-{
- basicblock *b, *entryblock;
- struct assembler a;
- int i, j, nblocks;
- PyCodeObject *co = NULL;
-
- /* Make sure every block that falls off the end returns None.
- XXX NEXT_BLOCK() isn't quite right, because if the last
- block ends with a jump or return b_next shouldn't set.
- */
- if (!c->u->u_curblock->b_return) {
- NEXT_BLOCK(c);
- if (addNone)
- ADDOP_O(c, LOAD_CONST, Py_None, consts);
- ADDOP(c, RETURN_VALUE);
- }
-
- nblocks = 0;
- entryblock = NULL;
- for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
- nblocks++;
- entryblock = b;
- }
-
- /* Set firstlineno if it wasn't explicitly set. */
- if (!c->u->u_firstlineno) {
- if (entryblock && entryblock->b_instr)
- c->u->u_firstlineno = entryblock->b_instr->i_lineno;
- else
- c->u->u_firstlineno = 1;
- }
- if (!assemble_init(&a, nblocks, c->u->u_firstlineno))
- goto error;
- dfs(c, entryblock, &a);
-
- /* Can't modify the bytecode after computing jump offsets. */
- assemble_jump_offsets(&a, c);
-
- /* Emit code in reverse postorder from dfs. */
- for (i = a.a_nblocks - 1; i >= 0; i--) {
- b = a.a_postorder[i];
- for (j = 0; j < b->b_iused; j++)
- if (!assemble_emit(&a, &b->b_instr[j]))
- goto error;
- }
-
- if (_PyString_Resize(&a.a_lnotab, a.a_lnotab_off) < 0)
- goto error;
- if (_PyString_Resize(&a.a_bytecode, a.a_offset) < 0)
- goto error;
-
- co = makecode(c, &a);
- error:
- assemble_free(&a);
- return co;
-}
diff --git a/sys/src/cmd/python/Python/dup2.c b/sys/src/cmd/python/Python/dup2.c
deleted file mode 100644
index ba7413a0c..000000000
--- a/sys/src/cmd/python/Python/dup2.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Public domain dup2() lookalike
- * by Curtis Jackson @ AT&T Technologies, Burlington, NC
- * electronic address: burl!rcj
- *
- * dup2 performs the following functions:
- *
- * Check to make sure that fd1 is a valid open file descriptor.
- * Check to see if fd2 is already open; if so, close it.
- * Duplicate fd1 onto fd2; checking to make sure fd2 is a valid fd.
- * Return fd2 if all went well; return BADEXIT otherwise.
- */
-
-#include <fcntl.h>
-
-#define BADEXIT -1
-
-int
-dup2(int fd1, int fd2)
-{
- if (fd1 != fd2) {
- if (fcntl(fd1, F_GETFL) < 0)
- return BADEXIT;
- if (fcntl(fd2, F_GETFL) >= 0)
- close(fd2);
- if (fcntl(fd1, F_DUPFD, fd2) < 0)
- return BADEXIT;
- }
- return fd2;
-}
diff --git a/sys/src/cmd/python/Python/dynload_aix.c b/sys/src/cmd/python/Python/dynload_aix.c
deleted file mode 100644
index 7a604f223..000000000
--- a/sys/src/cmd/python/Python/dynload_aix.c
+++ /dev/null
@@ -1,183 +0,0 @@
-
-/* Support for dynamic loading of extension modules */
-
-#include "Python.h"
-#include "importdl.h"
-
-#include <ctype.h> /* for isdigit() */
-#include <errno.h> /* for global errno */
-#include <string.h> /* for strerror() */
-#include <stdlib.h> /* for malloc(), free() */
-#include <sys/ldr.h>
-
-
-#ifdef AIX_GENUINE_CPLUSPLUS
-#include "/usr/lpp/xlC/include/load.h"
-#define aix_load loadAndInit
-#else
-#define aix_load load
-#endif
-
-
-extern char *Py_GetProgramName(void);
-
-typedef struct Module {
- struct Module *next;
- void *entry;
-} Module, *ModulePtr;
-
-const struct filedescr _PyImport_DynLoadFiletab[] = {
- {".so", "rb", C_EXTENSION},
- {"module.so", "rb", C_EXTENSION},
- {0, 0}
-};
-
-static int
-aix_getoldmodules(void **modlistptr)
-{
- register ModulePtr modptr, prevmodptr;
- register struct ld_info *ldiptr;
- register char *ldibuf;
- register int errflag, bufsize = 1024;
- register unsigned int offset;
- char *progname = Py_GetProgramName();
-
- /*
- -- Get the list of loaded modules into ld_info structures.
- */
- if ((ldibuf = malloc(bufsize)) == NULL) {
- PyErr_SetString(PyExc_ImportError, strerror(errno));
- return -1;
- }
- while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
- && errno == ENOMEM) {
- free(ldibuf);
- bufsize += 1024;
- if ((ldibuf = malloc(bufsize)) == NULL) {
- PyErr_SetString(PyExc_ImportError, strerror(errno));
- return -1;
- }
- }
- if (errflag == -1) {
- PyErr_SetString(PyExc_ImportError, strerror(errno));
- return -1;
- }
- /*
- -- Make the modules list from the ld_info structures.
- */
- ldiptr = (struct ld_info *)ldibuf;
- prevmodptr = NULL;
- do {
- if (strstr(progname, ldiptr->ldinfo_filename) == NULL &&
- strstr(ldiptr->ldinfo_filename, "python") == NULL) {
- /*
- -- Extract only the modules belonging to the main
- -- executable + those containing "python" as a
- -- substring (like the "python[version]" binary or
- -- "libpython[version].a" in case it's a shared lib).
- */
- offset = (unsigned int)ldiptr->ldinfo_next;
- ldiptr = (struct ld_info *)((char*)ldiptr + offset);
- continue;
- }
- if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
- PyErr_SetString(PyExc_ImportError, strerror(errno));
- while (*modlistptr) {
- modptr = (ModulePtr)*modlistptr;
- *modlistptr = (void *)modptr->next;
- free(modptr);
- }
- return -1;
- }
- modptr->entry = ldiptr->ldinfo_dataorg;
- modptr->next = NULL;
- if (prevmodptr == NULL)
- *modlistptr = (void *)modptr;
- else
- prevmodptr->next = modptr;
- prevmodptr = modptr;
- offset = (unsigned int)ldiptr->ldinfo_next;
- ldiptr = (struct ld_info *)((char*)ldiptr + offset);
- } while (offset);
- free(ldibuf);
- return 0;
-}
-
-
-static void
-aix_loaderror(const char *pathname)
-{
-
- char *message[1024], errbuf[1024];
- register int i,j;
-
- struct errtab {
- int errNo;
- char *errstr;
- } load_errtab[] = {
- {L_ERROR_TOOMANY, "too many errors, rest skipped."},
- {L_ERROR_NOLIB, "can't load library:"},
- {L_ERROR_UNDEF, "can't find symbol in library:"},
- {L_ERROR_RLDBAD,
- "RLD index out of range or bad relocation type:"},
- {L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
- {L_ERROR_MEMBER,
- "file not an archive or does not contain requested member:"},
- {L_ERROR_TYPE, "symbol table mismatch:"},
- {L_ERROR_ALIGN, "text alignment in file is wrong."},
- {L_ERROR_SYSTEM, "System error:"},
- {L_ERROR_ERRNO, NULL}
- };
-
-#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
-#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
-
- PyOS_snprintf(errbuf, sizeof(errbuf), "from module %.200s ", pathname);
-
- if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
- ERRBUF_APPEND(strerror(errno));
- ERRBUF_APPEND("\n");
- }
- for(i = 0; message[i] && *message[i]; i++) {
- int nerr = atoi(message[i]);
- for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
- if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
- ERRBUF_APPEND(load_errtab[j].errstr);
- }
- while (isdigit(Py_CHARMASK(*message[i]))) message[i]++ ;
- ERRBUF_APPEND(message[i]);
- ERRBUF_APPEND("\n");
- }
- errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
- PyErr_SetString(PyExc_ImportError, errbuf);
- return;
-}
-
-
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
-{
- dl_funcptr p;
-
- /*
- -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
- -- of the shared module unresolved. Thus we have to resolve them
- -- explicitly with loadbind. The new module is loaded, then we
- -- resolve its symbols using the list of already loaded modules
- -- (only those that belong to the python executable). Get these
- -- with loadquery(L_GETINFO).
- */
-
- static void *staticmodlistptr = NULL;
-
- if (!staticmodlistptr)
- if (aix_getoldmodules(&staticmodlistptr) == -1)
- return NULL;
- p = (dl_funcptr) aix_load((char *)pathname, L_NOAUTODEFER, 0);
- if (p == NULL) {
- aix_loaderror(pathname);
- return NULL;
- }
-
- return p;
-}
diff --git a/sys/src/cmd/python/Python/dynload_atheos.c b/sys/src/cmd/python/Python/dynload_atheos.c
deleted file mode 100644
index 6f4df73c3..000000000
--- a/sys/src/cmd/python/Python/dynload_atheos.c
+++ /dev/null
@@ -1,47 +0,0 @@
-
-/* Support for dynamic loading of extension modules */
-
-#include <atheos/image.h>
-#include <errno.h>
-
-#include "Python.h"
-#include "importdl.h"
-
-
-const struct filedescr _PyImport_DynLoadFiletab[] = {
- {".so", "rb", C_EXTENSION},
- {"module.so", "rb", C_EXTENSION},
- {0, 0}
-};
-
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
-{
- void *p;
- int lib;
- char funcname[258];
-
- if (Py_VerboseFlag)
- printf("load_library %s\n", pathname);
-
- lib = load_library(pathname, 0);
- if (lib < 0) {
- char buf[512];
- if (Py_VerboseFlag)
- perror(pathname);
- PyOS_snprintf(buf, sizeof(buf), "Failed to load %.200s: %.200s",
- pathname, strerror(errno));
- PyErr_SetString(PyExc_ImportError, buf);
- return NULL;
- }
- PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
- if (Py_VerboseFlag)
- printf("get_symbol_address %s\n", funcname);
- if (get_symbol_address(lib, funcname, -1, &p) < 0) {
- p = NULL;
- if (Py_VerboseFlag)
- perror(funcname);
- }
-
- return (dl_funcptr) p;
-}
diff --git a/sys/src/cmd/python/Python/dynload_beos.c b/sys/src/cmd/python/Python/dynload_beos.c
deleted file mode 100644
index 5b05d6b73..000000000
--- a/sys/src/cmd/python/Python/dynload_beos.c
+++ /dev/null
@@ -1,254 +0,0 @@
-
-/* Support for dynamic loading of extension modules */
-
-#include <kernel/image.h>
-#include <kernel/OS.h>
-#include <stdlib.h>
-
-#include "Python.h"
-#include "importdl.h"
-
-const struct filedescr _PyImport_DynLoadFiletab[] = {
- {".so", "rb", C_EXTENSION},
- {"module.so", "rb", C_EXTENSION},
- {0, 0}
-};
-
-#if defined(MAXPATHLEN) && !defined(_SYS_PARAM_H)
-#undef MAXPATHLEN
-#endif
-
-#ifdef WITH_THREAD
-#include "pythread.h"
-static PyThread_type_lock beos_dyn_lock;
-#endif
-
-static PyObject *beos_dyn_images = NULL;
-
-/* ----------------------------------------------------------------------
- * BeOS dynamic loading support
- *
- * This uses shared libraries, but BeOS has its own way of doing things
- * (much easier than dlfnc.h, from the look of things). We'll use a
- * Python Dictionary object to store the images_ids so we can be very
- * nice and unload them when we exit.
- *
- * Note that this is thread-safe. Probably irrelevent, because of losing
- * systems... Python probably disables threads while loading modules.
- * Note the use of "probably"! Better to be safe than sorry. [chrish]
- *
- * As of 1.5.1 this should also work properly when you've configured
- * Python without thread support; the 1.5 version required it, which wasn't
- * very friendly. Note that I haven't tested it without threading... why
- * would you want to avoid threads on BeOS? [chrish]
- *
- * As of 1.5.2, the PyImport_BeImageID() function has been removed; Donn
- * tells me it's not necessary anymore because of PyCObject_Import().
- * [chrish]
- */
-
-/* Whack an item; the item is an image_id in disguise, so we'll call
- * unload_add_on() for it.
- */
-static void beos_nuke_dyn( PyObject *item )
-{
- status_t retval;
-
- if( item ) {
- image_id id = (image_id)PyInt_AsLong( item );
-
- retval = unload_add_on( id );
- }
-}
-
-/* atexit() handler that'll call unload_add_on() for every item in the
- * dictionary.
- */
-static void beos_cleanup_dyn( void )
-{
- if( beos_dyn_images ) {
- int idx;
- int list_size;
- PyObject *id_list;
-
-#ifdef WITH_THREAD
- PyThread_acquire_lock( beos_dyn_lock, 1 );
-#endif
-
- id_list = PyDict_Values( beos_dyn_images );
-
- list_size = PyList_Size( id_list );
- for( idx = 0; idx < list_size; idx++ ) {
- PyObject *the_item;
-
- the_item = PyList_GetItem( id_list, idx );
- beos_nuke_dyn( the_item );
- }
-
- PyDict_Clear( beos_dyn_images );
-
-#ifdef WITH_THREAD
- PyThread_free_lock( beos_dyn_lock );
-#endif
- }
-}
-
-/*
- * Initialize our dictionary, and the dictionary mutex.
- */
-static void beos_init_dyn( void )
-{
- /* We're protected from a race condition here by the atomic init_count
- * variable.
- */
- static int32 init_count = 0;
- int32 val;
-
- val = atomic_add( &init_count, 1 );
- if( beos_dyn_images == NULL && val == 0 ) {
- beos_dyn_images = PyDict_New();
-#ifdef WITH_THREAD
- beos_dyn_lock = PyThread_allocate_lock();
-#endif
- atexit( beos_cleanup_dyn );
- }
-}
-
-/*
- * Add an image_id to the dictionary; the module name of the loaded image
- * is the key. Note that if the key is already in the dict, we unload
- * that image; this should allow reload() to work on dynamically loaded
- * modules (super-keen!).
- */
-static void beos_add_dyn( char *name, image_id id )
-{
- int retval;
- PyObject *py_id;
-
- if( beos_dyn_images == NULL ) {
- beos_init_dyn();
- }
-
-#ifdef WITH_THREAD
- retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
-#endif
-
- /* If there's already an object with this key in the dictionary,
- * we're doing a reload(), so let's nuke it.
- */
- py_id = PyDict_GetItemString( beos_dyn_images, name );
- if( py_id ) {
- beos_nuke_dyn( py_id );
- retval = PyDict_DelItemString( beos_dyn_images, name );
- }
-
- py_id = PyInt_FromLong( (long)id );
- if( py_id ) {
- retval = PyDict_SetItemString( beos_dyn_images, name, py_id );
- }
-
-#ifdef WITH_THREAD
- PyThread_release_lock( beos_dyn_lock );
-#endif
-}
-
-
-
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
-{
- dl_funcptr p;
- image_id the_id;
- status_t retval;
- char fullpath[PATH_MAX];
- char funcname[258];
-
- if( Py_VerboseFlag ) {
- printf( "load_add_on( %s )\n", pathname );
- }
-
- /* Hmm, this old bug appears to have regenerated itself; if the
- * path isn't absolute, load_add_on() will fail. Reported to Be
- * April 21, 1998.
- */
- if( pathname[0] != '/' ) {
- (void)getcwd( fullpath, PATH_MAX );
- (void)strncat( fullpath, "/", PATH_MAX );
- (void)strncat( fullpath, pathname, PATH_MAX );
-
- if( Py_VerboseFlag ) {
- printf( "load_add_on( %s )\n", fullpath );
- }
- } else {
- (void)strcpy( fullpath, pathname );
- }
-
- the_id = load_add_on( fullpath );
- if( the_id < B_NO_ERROR ) {
- /* It's too bad load_add_on() doesn't set errno or something...
- */
- char buff[256]; /* hate hard-coded string sizes... */
-
- if( Py_VerboseFlag ) {
- printf( "load_add_on( %s ) failed", fullpath );
- }
-
- if( the_id == B_ERROR )
- PyOS_snprintf( buff, sizeof(buff),
- "BeOS: Failed to load %.200s",
- fullpath );
- else
- PyOS_snprintf( buff, sizeof(buff),
- "Unknown error loading %.200s",
- fullpath );
-
- PyErr_SetString( PyExc_ImportError, buff );
- return NULL;
- }
-
- PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
- if( Py_VerboseFlag ) {
- printf( "get_image_symbol( %s )\n", funcname );
- }
-
- retval = get_image_symbol( the_id, funcname, B_SYMBOL_TYPE_TEXT, &p );
- if( retval != B_NO_ERROR || p == NULL ) {
- /* That's bad, we can't find that symbol in the module...
- */
- char buff[256]; /* hate hard-coded string sizes... */
-
- if( Py_VerboseFlag ) {
- printf( "get_image_symbol( %s ) failed", funcname );
- }
-
- switch( retval ) {
- case B_BAD_IMAGE_ID:
- PyOS_snprintf( buff, sizeof(buff),
- "can't load init function for dynamic module: "
- "Invalid image ID for %.180s", fullpath );
- break;
- case B_BAD_INDEX:
- PyOS_snprintf( buff, sizeof(buff),
- "can't load init function for dynamic module: "
- "Bad index for %.180s", funcname );
- break;
- default:
- PyOS_snprintf( buff, sizeof(buff),
- "can't load init function for dynamic module: "
- "Unknown error looking up %.180s", funcname );
- break;
- }
-
- retval = unload_add_on( the_id );
-
- PyErr_SetString( PyExc_ImportError, buff );
- return NULL;
- }
-
- /* Save the module name and image ID for later so we can clean up
- * gracefully.
- */
- beos_add_dyn( fqname, the_id );
-
- return p;
-}
diff --git a/sys/src/cmd/python/Python/dynload_dl.c b/sys/src/cmd/python/Python/dynload_dl.c
deleted file mode 100644
index 4675a6722..000000000
--- a/sys/src/cmd/python/Python/dynload_dl.c
+++ /dev/null
@@ -1,26 +0,0 @@
-
-/* Support for dynamic loading of extension modules */
-
-#include "dl.h"
-
-#include "Python.h"
-#include "importdl.h"
-
-
-extern char *Py_GetProgramName(void);
-
-const struct filedescr _PyImport_DynLoadFiletab[] = {
- {".o", "rb", C_EXTENSION},
- {"module.o", "rb", C_EXTENSION},
- {0, 0}
-};
-
-
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
-{
- char funcname[258];
-
- PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
- return dl_loadmod(Py_GetProgramName(), pathname, funcname);
-}
diff --git a/sys/src/cmd/python/Python/dynload_hpux.c b/sys/src/cmd/python/Python/dynload_hpux.c
deleted file mode 100644
index fec0826ca..000000000
--- a/sys/src/cmd/python/Python/dynload_hpux.c
+++ /dev/null
@@ -1,58 +0,0 @@
-
-/* Support for dynamic loading of extension modules */
-
-#include "dl.h"
-#include <errno.h>
-
-#include "Python.h"
-#include "importdl.h"
-
-#if defined(__hp9000s300)
-#define FUNCNAME_PATTERN "_init%.200s"
-#else
-#define FUNCNAME_PATTERN "init%.200s"
-#endif
-
-const struct filedescr _PyImport_DynLoadFiletab[] = {
- {SHLIB_EXT, "rb", C_EXTENSION},
- {"module"SHLIB_EXT, "rb", C_EXTENSION},
- {0, 0}
-};
-
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
-{
- dl_funcptr p;
- shl_t lib;
- int flags;
- char funcname[258];
-
- flags = BIND_FIRST | BIND_DEFERRED;
- if (Py_VerboseFlag) {
- flags = BIND_FIRST | BIND_IMMEDIATE |
- BIND_NONFATAL | BIND_VERBOSE;
- printf("shl_load %s\n",pathname);
- }
- lib = shl_load(pathname, flags, 0);
- /* XXX Chuck Blake once wrote that 0 should be BIND_NOSTART? */
- if (lib == NULL) {
- char buf[256];
- if (Py_VerboseFlag)
- perror(pathname);
- PyOS_snprintf(buf, sizeof(buf), "Failed to load %.200s",
- pathname);
- PyErr_SetString(PyExc_ImportError, buf);
- return NULL;
- }
- PyOS_snprintf(funcname, sizeof(funcname), FUNCNAME_PATTERN, shortname);
- if (Py_VerboseFlag)
- printf("shl_findsym %s\n", funcname);
- if (shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p) == -1) {
- shl_unload(lib);
- p = NULL;
- }
- if (p == NULL && Py_VerboseFlag)
- perror(funcname);
-
- return p;
-}
diff --git a/sys/src/cmd/python/Python/dynload_next.c b/sys/src/cmd/python/Python/dynload_next.c
deleted file mode 100644
index 27df35696..000000000
--- a/sys/src/cmd/python/Python/dynload_next.c
+++ /dev/null
@@ -1,114 +0,0 @@
-
-/* Support for dynamic loading of extension modules on Mac OS X
-** All references to "NeXT" are for historical reasons.
-*/
-
-#include "Python.h"
-#include "importdl.h"
-
-#include <mach-o/dyld.h>
-
-const struct filedescr _PyImport_DynLoadFiletab[] = {
- {".so", "rb", C_EXTENSION},
- {"module.so", "rb", C_EXTENSION},
- {0, 0}
-};
-
-/*
-** Python modules are Mach-O MH_BUNDLE files. The best way to load these
-** is each in a private namespace, so you can load, say, a module bar and a
-** module foo.bar. If we load everything in the global namespace the two
-** initbar() symbols will conflict.
-** However, it seems some extension packages depend upon being able to access
-** each others' global symbols. There seems to be no way to eat our cake and
-** have it, so the USE_DYLD_GLOBAL_NAMESPACE define determines which behaviour
-** you get.
-*/
-
-#ifdef USE_DYLD_GLOBAL_NAMESPACE
-#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR
-#else
-#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \
- NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
-#endif
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
-{
- dl_funcptr p = NULL;
- char funcname[258];
- NSObjectFileImageReturnCode rc;
- NSObjectFileImage image;
- NSModule newModule;
- NSSymbol theSym;
- const char *errString;
- char errBuf[512];
-
- PyOS_snprintf(funcname, sizeof(funcname), "_init%.200s", shortname);
-
-#ifdef USE_DYLD_GLOBAL_NAMESPACE
- if (NSIsSymbolNameDefined(funcname)) {
- theSym = NSLookupAndBindSymbol(funcname);
- p = (dl_funcptr)NSAddressOfSymbol(theSym);
- return p;
- }
-#endif
- rc = NSCreateObjectFileImageFromFile(pathname, &image);
- switch(rc) {
- default:
- case NSObjectFileImageFailure:
- case NSObjectFileImageFormat:
- /* for these a message is printed on stderr by dyld */
- errString = "Can't create object file image";
- break;
- case NSObjectFileImageSuccess:
- errString = NULL;
- break;
- case NSObjectFileImageInappropriateFile:
- errString = "Inappropriate file type for dynamic loading";
- break;
- case NSObjectFileImageArch:
- errString = "Wrong CPU type in object file";
- break;
- case NSObjectFileImageAccess:
- errString = "Can't read object file (no access)";
- break;
- }
- if (errString == NULL) {
- newModule = NSLinkModule(image, pathname, LINKOPTIONS);
- if (newModule == NULL) {
- int errNo;
- const char *fileName, *moreErrorStr;
- NSLinkEditErrors c;
- NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr );
- PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s",
- fileName, moreErrorStr);
- errString = errBuf;
- }
- }
- if (errString != NULL) {
- PyErr_SetString(PyExc_ImportError, errString);
- return NULL;
- }
-#ifdef USE_DYLD_GLOBAL_NAMESPACE
- if (!NSIsSymbolNameDefined(funcname)) {
- /* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
- /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
- PyErr_Format(PyExc_ImportError,
- "Loaded module does not contain symbol %.200s",
- funcname);
- return NULL;
- }
- theSym = NSLookupAndBindSymbol(funcname);
-#else
- theSym = NSLookupSymbolInModule(newModule, funcname);
- if ( theSym == NULL ) {
- /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
- PyErr_Format(PyExc_ImportError,
- "Loaded module does not contain symbol %.200s",
- funcname);
- return NULL;
- }
-#endif
- p = (dl_funcptr)NSAddressOfSymbol(theSym);
- return p;
-}
diff --git a/sys/src/cmd/python/Python/dynload_os2.c b/sys/src/cmd/python/Python/dynload_os2.c
deleted file mode 100644
index d660e2750..000000000
--- a/sys/src/cmd/python/Python/dynload_os2.c
+++ /dev/null
@@ -1,46 +0,0 @@
-
-/* Support for dynamic loading of extension modules */
-
-#define INCL_DOSERRORS
-#define INCL_DOSMODULEMGR
-#include <os2.h>
-
-#include "Python.h"
-#include "importdl.h"
-
-
-const struct filedescr _PyImport_DynLoadFiletab[] = {
- {".pyd", "rb", C_EXTENSION},
- {".dll", "rb", C_EXTENSION},
- {0, 0}
-};
-
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
-{
- dl_funcptr p;
- APIRET rc;
- HMODULE hDLL;
- char failreason[256];
- char funcname[258];
-
- rc = DosLoadModule(failreason,
- sizeof(failreason),
- pathname,
- &hDLL);
-
- if (rc != NO_ERROR) {
- char errBuf[256];
- PyOS_snprintf(errBuf, sizeof(errBuf),
- "DLL load failed, rc = %d: %.200s",
- rc, failreason);
- PyErr_SetString(PyExc_ImportError, errBuf);
- return NULL;
- }
-
- PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
- rc = DosQueryProcAddr(hDLL, 0L, funcname, &p);
- if (rc != NO_ERROR)
- p = NULL; /* Signify Failure to Acquire Entrypoint */
- return p;
-}
diff --git a/sys/src/cmd/python/Python/dynload_shlib.c b/sys/src/cmd/python/Python/dynload_shlib.c
deleted file mode 100644
index f12a93cb5..000000000
--- a/sys/src/cmd/python/Python/dynload_shlib.c
+++ /dev/null
@@ -1,143 +0,0 @@
-
-/* Support for dynamic loading of extension modules */
-
-#include "Python.h"
-#include "importdl.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#if defined(__NetBSD__)
-#include <sys/param.h>
-#if (NetBSD < 199712)
-#include <nlist.h>
-#include <link.h>
-#define dlerror() "error in dynamic linking"
-#endif
-#endif /* NetBSD */
-
-#ifdef HAVE_DLFCN_H
-#include <dlfcn.h>
-#else
-#if defined(PYOS_OS2) && defined(PYCC_GCC)
-#include "dlfcn.h"
-#endif
-#endif
-
-#if (defined(__OpenBSD__) || defined(__NetBSD__)) && !defined(__ELF__)
-#define LEAD_UNDERSCORE "_"
-#else
-#define LEAD_UNDERSCORE ""
-#endif
-
-
-const struct filedescr _PyImport_DynLoadFiletab[] = {
-#ifdef __CYGWIN__
- {".dll", "rb", C_EXTENSION},
- {"module.dll", "rb", C_EXTENSION},
-#else
-#if defined(PYOS_OS2) && defined(PYCC_GCC)
- {".pyd", "rb", C_EXTENSION},
- {".dll", "rb", C_EXTENSION},
-#else
-#ifdef __VMS
- {".exe", "rb", C_EXTENSION},
- {".EXE", "rb", C_EXTENSION},
- {"module.exe", "rb", C_EXTENSION},
- {"MODULE.EXE", "rb", C_EXTENSION},
-#else
- {".so", "rb", C_EXTENSION},
- {"module.so", "rb", C_EXTENSION},
-#endif
-#endif
-#endif
- {0, 0}
-};
-
-static struct {
- dev_t dev;
-#ifdef __VMS
- ino_t ino[3];
-#else
- ino_t ino;
-#endif
- void *handle;
-} handles[128];
-static int nhandles = 0;
-
-
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
-{
- dl_funcptr p;
- void *handle;
- char funcname[258];
- char pathbuf[260];
- int dlopenflags=0;
-
- if (strchr(pathname, '/') == NULL) {
- /* Prefix bare filename with "./" */
- PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
- pathname = pathbuf;
- }
-
- PyOS_snprintf(funcname, sizeof(funcname),
- LEAD_UNDERSCORE "init%.200s", shortname);
-
- if (fp != NULL) {
- int i;
- struct stat statb;
- fstat(fileno(fp), &statb);
- for (i = 0; i < nhandles; i++) {
- if (statb.st_dev == handles[i].dev &&
- statb.st_ino == handles[i].ino) {
- p = (dl_funcptr) dlsym(handles[i].handle,
- funcname);
- return p;
- }
- }
- if (nhandles < 128) {
- handles[nhandles].dev = statb.st_dev;
-#ifdef __VMS
- handles[nhandles].ino[0] = statb.st_ino[0];
- handles[nhandles].ino[1] = statb.st_ino[1];
- handles[nhandles].ino[2] = statb.st_ino[2];
-#else
- handles[nhandles].ino = statb.st_ino;
-#endif
- }
- }
-
-#if !(defined(PYOS_OS2) && defined(PYCC_GCC))
- dlopenflags = PyThreadState_GET()->interp->dlopenflags;
-#endif
-
- if (Py_VerboseFlag)
- PySys_WriteStderr("dlopen(\"%s\", %x);\n", pathname,
- dlopenflags);
-
-#ifdef __VMS
- /* VMS currently don't allow a pathname, use a logical name instead */
- /* Concatenate 'python_module_' and shortname */
- /* so "import vms.bar" will use the logical python_module_bar */
- /* As C module use only one name space this is probably not a */
- /* important limitation */
- PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s",
- shortname);
- pathname = pathbuf;
-#endif
-
- handle = dlopen(pathname, dlopenflags);
-
- if (handle == NULL) {
- const char *error = dlerror();
- if (error == NULL)
- error = "unknown dlopen() error";
- PyErr_SetString(PyExc_ImportError, error);
- return NULL;
- }
- if (fp != NULL && nhandles < 128)
- handles[nhandles++].handle = handle;
- p = (dl_funcptr) dlsym(handle, funcname);
- return p;
-}
diff --git a/sys/src/cmd/python/Python/dynload_stub.c b/sys/src/cmd/python/Python/dynload_stub.c
deleted file mode 100644
index 69f8b450b..000000000
--- a/sys/src/cmd/python/Python/dynload_stub.c
+++ /dev/null
@@ -1,11 +0,0 @@
-
-/* This module provides the necessary stubs for when dynamic loading is
- not present. */
-
-#include "Python.h"
-#include "importdl.h"
-
-
-const struct filedescr _PyImport_DynLoadFiletab[] = {
- {0, 0}
-};
diff --git a/sys/src/cmd/python/Python/dynload_win.c b/sys/src/cmd/python/Python/dynload_win.c
deleted file mode 100644
index 37d6d2ee3..000000000
--- a/sys/src/cmd/python/Python/dynload_win.c
+++ /dev/null
@@ -1,263 +0,0 @@
-
-/* Support for dynamic loading of extension modules */
-
-#include <windows.h>
-#ifdef HAVE_DIRECT_H
-#include <direct.h>
-#endif
-#include <ctype.h>
-
-#include "Python.h"
-#include "importdl.h"
-
-const struct filedescr _PyImport_DynLoadFiletab[] = {
-#ifdef _DEBUG
- {"_d.pyd", "rb", C_EXTENSION},
- /* Temporarily disable .dll, to avoid conflicts between sqlite3.dll
- and the sqlite3 package. If this needs to be reverted for 2.5,
- some other solution for the naming conflict must be found.
- {"_d.dll", "rb", C_EXTENSION},
- */
-#else
- {".pyd", "rb", C_EXTENSION},
- /* Likewise
- {".dll", "rb", C_EXTENSION},
- */
-#endif
- {0, 0}
-};
-
-
-/* Case insensitive string compare, to avoid any dependencies on particular
- C RTL implementations */
-
-static int strcasecmp (char *string1, char *string2)
-{
- int first, second;
-
- do {
- first = tolower(*string1);
- second = tolower(*string2);
- string1++;
- string2++;
- } while (first && first == second);
-
- return (first - second);
-}
-
-
-/* Function to return the name of the "python" DLL that the supplied module
- directly imports. Looks through the list of imported modules and
- returns the first entry that starts with "python" (case sensitive) and
- is followed by nothing but numbers until the separator (period).
-
- Returns a pointer to the import name, or NULL if no matching name was
- located.
-
- This function parses through the PE header for the module as loaded in
- memory by the system loader. The PE header is accessed as documented by
- Microsoft in the MSDN PE and COFF specification (2/99), and handles
- both PE32 and PE32+. It only worries about the direct import table and
- not the delay load import table since it's unlikely an extension is
- going to be delay loading Python (after all, it's already loaded).
-
- If any magic values are not found (e.g., the PE header or optional
- header magic), then this function simply returns NULL. */
-
-#define DWORD_AT(mem) (*(DWORD *)(mem))
-#define WORD_AT(mem) (*(WORD *)(mem))
-
-static char *GetPythonImport (HINSTANCE hModule)
-{
- unsigned char *dllbase, *import_data, *import_name;
- DWORD pe_offset, opt_offset;
- WORD opt_magic;
- int num_dict_off, import_off;
-
- /* Safety check input */
- if (hModule == NULL) {
- return NULL;
- }
-
- /* Module instance is also the base load address. First portion of
- memory is the MS-DOS loader, which holds the offset to the PE
- header (from the load base) at 0x3C */
- dllbase = (unsigned char *)hModule;
- pe_offset = DWORD_AT(dllbase + 0x3C);
-
- /* The PE signature must be "PE\0\0" */
- if (memcmp(dllbase+pe_offset,"PE\0\0",4)) {
- return NULL;
- }
-
- /* Following the PE signature is the standard COFF header (20
- bytes) and then the optional header. The optional header starts
- with a magic value of 0x10B for PE32 or 0x20B for PE32+ (PE32+
- uses 64-bits for some fields). It might also be 0x107 for a ROM
- image, but we don't process that here.
-
- The optional header ends with a data dictionary that directly
- points to certain types of data, among them the import entries
- (in the second table entry). Based on the header type, we
- determine offsets for the data dictionary count and the entry
- within the dictionary pointing to the imports. */
-
- opt_offset = pe_offset + 4 + 20;
- opt_magic = WORD_AT(dllbase+opt_offset);
- if (opt_magic == 0x10B) {
- /* PE32 */
- num_dict_off = 92;
- import_off = 104;
- } else if (opt_magic == 0x20B) {
- /* PE32+ */
- num_dict_off = 108;
- import_off = 120;
- } else {
- /* Unsupported */
- return NULL;
- }
-
- /* Now if an import table exists, offset to it and walk the list of
- imports. The import table is an array (ending when an entry has
- empty values) of structures (20 bytes each), which contains (at
- offset 12) a relative address (to the module base) at which a
- string constant holding the import name is located. */
-
- if (DWORD_AT(dllbase + opt_offset + num_dict_off) >= 2) {
- /* We have at least 2 tables - the import table is the second
- one. But still it may be that the table size is zero */
- if (0 == DWORD_AT(dllbase + opt_offset + import_off + sizeof(DWORD)))
- return NULL;
- import_data = dllbase + DWORD_AT(dllbase +
- opt_offset +
- import_off);
- while (DWORD_AT(import_data)) {
- import_name = dllbase + DWORD_AT(import_data+12);
- if (strlen(import_name) >= 6 &&
- !strncmp(import_name,"python",6)) {
- char *pch;
-
- /* Ensure python prefix is followed only
- by numbers to the end of the basename */
- pch = import_name + 6;
-#ifdef _DEBUG
- while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') {
-#else
- while (*pch && *pch != '.') {
-#endif
- if (*pch >= '0' && *pch <= '9') {
- pch++;
- } else {
- pch = NULL;
- break;
- }
- }
-
- if (pch) {
- /* Found it - return the name */
- return import_name;
- }
- }
- import_data += 20;
- }
- }
-
- return NULL;
-}
-
-
-dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
-{
- dl_funcptr p;
- char funcname[258], *import_python;
-
- PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
-
- {
- HINSTANCE hDLL = NULL;
- char pathbuf[260];
- LPTSTR dummy;
- /* We use LoadLibraryEx so Windows looks for dependent DLLs
- in directory of pathname first. However, Windows95
- can sometimes not work correctly unless the absolute
- path is used. If GetFullPathName() fails, the LoadLibrary
- will certainly fail too, so use its error code */
- if (GetFullPathName(pathname,
- sizeof(pathbuf),
- pathbuf,
- &dummy))
- /* XXX This call doesn't exist in Windows CE */
- hDLL = LoadLibraryEx(pathname, NULL,
- LOAD_WITH_ALTERED_SEARCH_PATH);
- if (hDLL==NULL){
- char errBuf[256];
- unsigned int errorCode;
-
- /* Get an error string from Win32 error code */
- char theInfo[256]; /* Pointer to error text
- from system */
- int theLength; /* Length of error text */
-
- errorCode = GetLastError();
-
- theLength = FormatMessage(
- FORMAT_MESSAGE_FROM_SYSTEM, /* flags */
- NULL, /* message source */
- errorCode, /* the message (error) ID */
- 0, /* default language environment */
- (LPTSTR) theInfo, /* the buffer */
- sizeof(theInfo), /* the buffer size */
- NULL); /* no additional format args. */
-
- /* Problem: could not get the error message.
- This should not happen if called correctly. */
- if (theLength == 0) {
- PyOS_snprintf(errBuf, sizeof(errBuf),
- "DLL load failed with error code %d",
- errorCode);
- } else {
- size_t len;
- /* For some reason a \r\n
- is appended to the text */
- if (theLength >= 2 &&
- theInfo[theLength-2] == '\r' &&
- theInfo[theLength-1] == '\n') {
- theLength -= 2;
- theInfo[theLength] = '\0';
- }
- strcpy(errBuf, "DLL load failed: ");
- len = strlen(errBuf);
- strncpy(errBuf+len, theInfo,
- sizeof(errBuf)-len);
- errBuf[sizeof(errBuf)-1] = '\0';
- }
- PyErr_SetString(PyExc_ImportError, errBuf);
- return NULL;
- } else {
- char buffer[256];
-
-#ifdef _DEBUG
- PyOS_snprintf(buffer, sizeof(buffer), "python%d%d_d.dll",
-#else
- PyOS_snprintf(buffer, sizeof(buffer), "python%d%d.dll",
-#endif
- PY_MAJOR_VERSION,PY_MINOR_VERSION);
- import_python = GetPythonImport(hDLL);
-
- if (import_python &&
- strcasecmp(buffer,import_python)) {
- PyOS_snprintf(buffer, sizeof(buffer),
- "Module use of %.150s conflicts "
- "with this version of Python.",
- import_python);
- PyErr_SetString(PyExc_ImportError,buffer);
- FreeLibrary(hDLL);
- return NULL;
- }
- }
- p = GetProcAddress(hDLL, funcname);
- }
-
- return p;
-}
diff --git a/sys/src/cmd/python/Python/errors.c b/sys/src/cmd/python/Python/errors.c
deleted file mode 100644
index bc77c3c1b..000000000
--- a/sys/src/cmd/python/Python/errors.c
+++ /dev/null
@@ -1,822 +0,0 @@
-
-/* Error handling */
-
-#include "Python.h"
-
-#ifndef __STDC__
-#ifndef MS_WINDOWS
-extern char *strerror(int);
-#endif
-#endif
-
-#ifdef MS_WINDOWS
-#include "windows.h"
-#include "winbase.h"
-#endif
-
-#include <ctype.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-void
-PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
-{
- PyThreadState *tstate = PyThreadState_GET();
- PyObject *oldtype, *oldvalue, *oldtraceback;
-
- if (traceback != NULL && !PyTraceBack_Check(traceback)) {
- /* XXX Should never happen -- fatal error instead? */
- /* Well, it could be None. */
- Py_DECREF(traceback);
- traceback = NULL;
- }
-
- /* Save these in locals to safeguard against recursive
- invocation through Py_XDECREF */
- oldtype = tstate->curexc_type;
- oldvalue = tstate->curexc_value;
- oldtraceback = tstate->curexc_traceback;
-
- tstate->curexc_type = type;
- tstate->curexc_value = value;
- tstate->curexc_traceback = traceback;
-
- Py_XDECREF(oldtype);
- Py_XDECREF(oldvalue);
- Py_XDECREF(oldtraceback);
-}
-
-void
-PyErr_SetObject(PyObject *exception, PyObject *value)
-{
- Py_XINCREF(exception);
- Py_XINCREF(value);
- PyErr_Restore(exception, value, (PyObject *)NULL);
-}
-
-void
-PyErr_SetNone(PyObject *exception)
-{
- PyErr_SetObject(exception, (PyObject *)NULL);
-}
-
-void
-PyErr_SetString(PyObject *exception, const char *string)
-{
- PyObject *value = PyString_FromString(string);
- PyErr_SetObject(exception, value);
- Py_XDECREF(value);
-}
-
-
-PyObject *
-PyErr_Occurred(void)
-{
- PyThreadState *tstate = PyThreadState_GET();
-
- return tstate->curexc_type;
-}
-
-
-int
-PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
-{
- if (err == NULL || exc == NULL) {
- /* maybe caused by "import exceptions" that failed early on */
- return 0;
- }
- if (PyTuple_Check(exc)) {
- Py_ssize_t i, n;
- n = PyTuple_Size(exc);
- for (i = 0; i < n; i++) {
- /* Test recursively */
- if (PyErr_GivenExceptionMatches(
- err, PyTuple_GET_ITEM(exc, i)))
- {
- return 1;
- }
- }
- return 0;
- }
- /* err might be an instance, so check its class. */
- if (PyExceptionInstance_Check(err))
- err = PyExceptionInstance_Class(err);
-
- if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
- /* problems here!? not sure PyObject_IsSubclass expects to
- be called with an exception pending... */
- return PyObject_IsSubclass(err, exc);
- }
-
- return err == exc;
-}
-
-
-int
-PyErr_ExceptionMatches(PyObject *exc)
-{
- return PyErr_GivenExceptionMatches(PyErr_Occurred(), exc);
-}
-
-
-/* Used in many places to normalize a raised exception, including in
- eval_code2(), do_raise(), and PyErr_Print()
-*/
-void
-PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
-{
- PyObject *type = *exc;
- PyObject *value = *val;
- PyObject *inclass = NULL;
- PyObject *initial_tb = NULL;
-
- if (type == NULL) {
- /* There was no exception, so nothing to do. */
- return;
- }
-
- /* If PyErr_SetNone() was used, the value will have been actually
- set to NULL.
- */
- if (!value) {
- value = Py_None;
- Py_INCREF(value);
- }
-
- if (PyExceptionInstance_Check(value))
- inclass = PyExceptionInstance_Class(value);
-
- /* Normalize the exception so that if the type is a class, the
- value will be an instance.
- */
- if (PyExceptionClass_Check(type)) {
- /* if the value was not an instance, or is not an instance
- whose class is (or is derived from) type, then use the
- value as an argument to instantiation of the type
- class.
- */
- if (!inclass || !PyObject_IsSubclass(inclass, type)) {
- PyObject *args, *res;
-
- if (value == Py_None)
- args = PyTuple_New(0);
- else if (PyTuple_Check(value)) {
- Py_INCREF(value);
- args = value;
- }
- else
- args = PyTuple_Pack(1, value);
-
- if (args == NULL)
- goto finally;
- res = PyEval_CallObject(type, args);
- Py_DECREF(args);
- if (res == NULL)
- goto finally;
- Py_DECREF(value);
- value = res;
- }
- /* if the class of the instance doesn't exactly match the
- class of the type, believe the instance
- */
- else if (inclass != type) {
- Py_DECREF(type);
- type = inclass;
- Py_INCREF(type);
- }
- }
- *exc = type;
- *val = value;
- return;
-finally:
- Py_DECREF(type);
- Py_DECREF(value);
- /* If the new exception doesn't set a traceback and the old
- exception had a traceback, use the old traceback for the
- new exception. It's better than nothing.
- */
- initial_tb = *tb;
- PyErr_Fetch(exc, val, tb);
- if (initial_tb != NULL) {
- if (*tb == NULL)
- *tb = initial_tb;
- else
- Py_DECREF(initial_tb);
- }
- /* normalize recursively */
- PyErr_NormalizeException(exc, val, tb);
-}
-
-
-void
-PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
-{
- PyThreadState *tstate = PyThreadState_GET();
-
- *p_type = tstate->curexc_type;
- *p_value = tstate->curexc_value;
- *p_traceback = tstate->curexc_traceback;
-
- tstate->curexc_type = NULL;
- tstate->curexc_value = NULL;
- tstate->curexc_traceback = NULL;
-}
-
-void
-PyErr_Clear(void)
-{
- PyErr_Restore(NULL, NULL, NULL);
-}
-
-/* Convenience functions to set a type error exception and return 0 */
-
-int
-PyErr_BadArgument(void)
-{
- PyErr_SetString(PyExc_TypeError,
- "bad argument type for built-in operation");
- return 0;
-}
-
-PyObject *
-PyErr_NoMemory(void)
-{
- if (PyErr_ExceptionMatches(PyExc_MemoryError))
- /* already current */
- return NULL;
-
- /* raise the pre-allocated instance if it still exists */
- if (PyExc_MemoryErrorInst)
- PyErr_SetObject(PyExc_MemoryError, PyExc_MemoryErrorInst);
- else
- /* this will probably fail since there's no memory and hee,
- hee, we have to instantiate this class
- */
- PyErr_SetNone(PyExc_MemoryError);
-
- return NULL;
-}
-
-PyObject *
-PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
-{
- PyObject *v;
- char *s;
- int i = errno;
-#ifdef PLAN9
- char errbuf[ERRMAX];
-#endif
-#ifdef MS_WINDOWS
- char *s_buf = NULL;
- char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */
-#endif
-#ifdef EINTR
- if (i == EINTR && PyErr_CheckSignals())
- return NULL;
-#endif
-#ifdef PLAN9
- rerrstr(errbuf, sizeof errbuf);
- s = errbuf;
-#else
- if (i == 0)
- s = "Error"; /* Sometimes errno didn't get set */
- else
-#ifndef MS_WINDOWS
- s = strerror(i);
-#else
- {
- /* Note that the Win32 errors do not lineup with the
- errno error. So if the error is in the MSVC error
- table, we use it, otherwise we assume it really _is_
- a Win32 error code
- */
- if (i > 0 && i < _sys_nerr) {
- s = _sys_errlist[i];
- }
- else {
- int len = FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, /* no message source */
- i,
- MAKELANGID(LANG_NEUTRAL,
- SUBLANG_DEFAULT),
- /* Default language */
- (LPTSTR) &s_buf,
- 0, /* size not used */
- NULL); /* no args */
- if (len==0) {
- /* Only ever seen this in out-of-mem
- situations */
- sprintf(s_small_buf, "Windows Error 0x%X", i);
- s = s_small_buf;
- s_buf = NULL;
- } else {
- s = s_buf;
- /* remove trailing cr/lf and dots */
- while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
- s[--len] = '\0';
- }
- }
- }
-#endif /* Unix/Windows */
-#endif /* PLAN 9*/
- if (filenameObject != NULL)
- v = Py_BuildValue("(isO)", i, s, filenameObject);
- else
- v = Py_BuildValue("(is)", i, s);
- if (v != NULL) {
- PyErr_SetObject(exc, v);
- Py_DECREF(v);
- }
-#ifdef MS_WINDOWS
- LocalFree(s_buf);
-#endif
- return NULL;
-}
-
-
-PyObject *
-PyErr_SetFromErrnoWithFilename(PyObject *exc, char *filename)
-{
- PyObject *name = filename ? PyString_FromString(filename) : NULL;
- PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
- Py_XDECREF(name);
- return result;
-}
-
-#ifdef Py_WIN_WIDE_FILENAMES
-PyObject *
-PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, Py_UNICODE *filename)
-{
- PyObject *name = filename ?
- PyUnicode_FromUnicode(filename, wcslen(filename)) :
- NULL;
- PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);
- Py_XDECREF(name);
- return result;
-}
-#endif /* Py_WIN_WIDE_FILENAMES */
-
-PyObject *
-PyErr_SetFromErrno(PyObject *exc)
-{
- return PyErr_SetFromErrnoWithFilenameObject(exc, NULL);
-}
-
-#ifdef MS_WINDOWS
-/* Windows specific error code handling */
-PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
- PyObject *exc,
- int ierr,
- PyObject *filenameObject)
-{
- int len;
- char *s;
- char *s_buf = NULL; /* Free via LocalFree */
- char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */
- PyObject *v;
- DWORD err = (DWORD)ierr;
- if (err==0) err = GetLastError();
- len = FormatMessage(
- /* Error API error */
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, /* no message source */
- err,
- MAKELANGID(LANG_NEUTRAL,
- SUBLANG_DEFAULT), /* Default language */
- (LPTSTR) &s_buf,
- 0, /* size not used */
- NULL); /* no args */
- if (len==0) {
- /* Only seen this in out of mem situations */
- sprintf(s_small_buf, "Windows Error 0x%X", err);
- s = s_small_buf;
- s_buf = NULL;
- } else {
- s = s_buf;
- /* remove trailing cr/lf and dots */
- while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
- s[--len] = '\0';
- }
- if (filenameObject != NULL)
- v = Py_BuildValue("(isO)", err, s, filenameObject);
- else
- v = Py_BuildValue("(is)", err, s);
- if (v != NULL) {
- PyErr_SetObject(exc, v);
- Py_DECREF(v);
- }
- LocalFree(s_buf);
- return NULL;
-}
-
-PyObject *PyErr_SetExcFromWindowsErrWithFilename(
- PyObject *exc,
- int ierr,
- const char *filename)
-{
- PyObject *name = filename ? PyString_FromString(filename) : NULL;
- PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
- ierr,
- name);
- Py_XDECREF(name);
- return ret;
-}
-
-#ifdef Py_WIN_WIDE_FILENAMES
-PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(
- PyObject *exc,
- int ierr,
- const Py_UNICODE *filename)
-{
- PyObject *name = filename ?
- PyUnicode_FromUnicode(filename, wcslen(filename)) :
- NULL;
- PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,
- ierr,
- name);
- Py_XDECREF(name);
- return ret;
-}
-#endif /* Py_WIN_WIDE_FILENAMES */
-
-PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
-{
- return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
-}
-
-PyObject *PyErr_SetFromWindowsErr(int ierr)
-{
- return PyErr_SetExcFromWindowsErrWithFilename(PyExc_WindowsError,
- ierr, NULL);
-}
-PyObject *PyErr_SetFromWindowsErrWithFilename(
- int ierr,
- const char *filename)
-{
- PyObject *name = filename ? PyString_FromString(filename) : NULL;
- PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
- PyExc_WindowsError,
- ierr, name);
- Py_XDECREF(name);
- return result;
-}
-
-#ifdef Py_WIN_WIDE_FILENAMES
-PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(
- int ierr,
- const Py_UNICODE *filename)
-{
- PyObject *name = filename ?
- PyUnicode_FromUnicode(filename, wcslen(filename)) :
- NULL;
- PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(
- PyExc_WindowsError,
- ierr, name);
- Py_XDECREF(name);
- return result;
-}
-#endif /* Py_WIN_WIDE_FILENAMES */
-#endif /* MS_WINDOWS */
-
-void
-_PyErr_BadInternalCall(char *filename, int lineno)
-{
- PyErr_Format(PyExc_SystemError,
- "%s:%d: bad argument to internal function",
- filename, lineno);
-}
-
-/* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can
- export the entry point for existing object code: */
-#undef PyErr_BadInternalCall
-void
-PyErr_BadInternalCall(void)
-{
- PyErr_Format(PyExc_SystemError,
- "bad argument to internal function");
-}
-#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
-
-
-
-PyObject *
-PyErr_Format(PyObject *exception, const char *format, ...)
-{
- va_list vargs;
- PyObject* string;
-
-#ifdef HAVE_STDARG_PROTOTYPES
- va_start(vargs, format);
-#else
- va_start(vargs);
-#endif
-
- string = PyString_FromFormatV(format, vargs);
- PyErr_SetObject(exception, string);
- Py_XDECREF(string);
- va_end(vargs);
- return NULL;
-}
-
-
-
-PyObject *
-PyErr_NewException(char *name, PyObject *base, PyObject *dict)
-{
- char *dot;
- PyObject *modulename = NULL;
- PyObject *classname = NULL;
- PyObject *mydict = NULL;
- PyObject *bases = NULL;
- PyObject *result = NULL;
- dot = strrchr(name, '.');
- if (dot == NULL) {
- PyErr_SetString(PyExc_SystemError,
- "PyErr_NewException: name must be module.class");
- return NULL;
- }
- if (base == NULL)
- base = PyExc_Exception;
- if (dict == NULL) {
- dict = mydict = PyDict_New();
- if (dict == NULL)
- goto failure;
- }
- if (PyDict_GetItemString(dict, "__module__") == NULL) {
- modulename = PyString_FromStringAndSize(name,
- (Py_ssize_t)(dot-name));
- if (modulename == NULL)
- goto failure;
- if (PyDict_SetItemString(dict, "__module__", modulename) != 0)
- goto failure;
- }
- if (PyTuple_Check(base)) {
- bases = base;
- /* INCREF as we create a new ref in the else branch */
- Py_INCREF(bases);
- } else {
- bases = PyTuple_Pack(1, base);
- if (bases == NULL)
- goto failure;
- }
- /* Create a real new-style class. */
- result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
- dot+1, bases, dict);
- failure:
- Py_XDECREF(bases);
- Py_XDECREF(mydict);
- Py_XDECREF(classname);
- Py_XDECREF(modulename);
- return result;
-}
-
-/* Call when an exception has occurred but there is no way for Python
- to handle it. Examples: exception in __del__ or during GC. */
-void
-PyErr_WriteUnraisable(PyObject *obj)
-{
- PyObject *f, *t, *v, *tb;
- PyErr_Fetch(&t, &v, &tb);
- f = PySys_GetObject("stderr");
- if (f != NULL) {
- PyFile_WriteString("Exception ", f);
- if (t) {
- PyObject* moduleName;
- char* className = NULL;
- if (PyExceptionClass_Check(t))
- className = PyExceptionClass_Name(t);
- else if (PyString_Check(t))
- className = PyString_AS_STRING(t);
-
- if (className != NULL) {
- char *dot = strrchr(className, '.');
- if (dot != NULL)
- className = dot+1;
- }
-
- moduleName = PyObject_GetAttrString(t, "__module__");
- if (moduleName == NULL)
- PyFile_WriteString("<unknown>", f);
- else {
- char* modstr = PyString_AsString(moduleName);
- if (modstr)
- {
- PyFile_WriteString(modstr, f);
- PyFile_WriteString(".", f);
- }
- }
- if (className == NULL)
- PyFile_WriteString("<unknown>", f);
- else
- PyFile_WriteString(className, f);
- if (v && v != Py_None) {
- PyFile_WriteString(": ", f);
- PyFile_WriteObject(v, f, 0);
- }
- Py_XDECREF(moduleName);
- }
- PyFile_WriteString(" in ", f);
- PyFile_WriteObject(obj, f, 0);
- PyFile_WriteString(" ignored\n", f);
- PyErr_Clear(); /* Just in case */
- }
- Py_XDECREF(t);
- Py_XDECREF(v);
- Py_XDECREF(tb);
-}
-
-extern PyObject *PyModule_GetWarningsModule(void);
-
-/* Function to issue a warning message; may raise an exception. */
-int
-PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level)
-{
- PyObject *dict, *func = NULL;
- PyObject *warnings_module = PyModule_GetWarningsModule();
-
- if (warnings_module != NULL) {
- dict = PyModule_GetDict(warnings_module);
- if (dict != NULL)
- func = PyDict_GetItemString(dict, "warn");
- }
- if (func == NULL) {
- PySys_WriteStderr("warning: %s\n", message);
- return 0;
- }
- else {
- PyObject *res;
-
- if (category == NULL)
- category = PyExc_RuntimeWarning;
- res = PyObject_CallFunction(func, "sOn",
- message, category, stack_level);
- if (res == NULL)
- return -1;
- Py_DECREF(res);
- return 0;
- }
-}
-
-/* PyErr_Warn is only for backwards compatability and will be removed.
- Use PyErr_WarnEx instead. */
-
-#undef PyErr_Warn
-
-PyAPI_FUNC(int)
-PyErr_Warn(PyObject *category, char *message)
-{
- return PyErr_WarnEx(category, message, 1);
-}
-
-/* Warning with explicit origin */
-int
-PyErr_WarnExplicit(PyObject *category, const char *message,
- const char *filename, int lineno,
- const char *module, PyObject *registry)
-{
- PyObject *mod, *dict, *func = NULL;
-
- mod = PyImport_ImportModule("warnings");
- if (mod != NULL) {
- dict = PyModule_GetDict(mod);
- func = PyDict_GetItemString(dict, "warn_explicit");
- Py_DECREF(mod);
- }
- if (func == NULL) {
- PySys_WriteStderr("warning: %s\n", message);
- return 0;
- }
- else {
- PyObject *res;
-
- if (category == NULL)
- category = PyExc_RuntimeWarning;
- if (registry == NULL)
- registry = Py_None;
- res = PyObject_CallFunction(func, "sOsizO", message, category,
- filename, lineno, module, registry);
- if (res == NULL)
- return -1;
- Py_DECREF(res);
- return 0;
- }
-}
-
-
-/* Set file and line information for the current exception.
- If the exception is not a SyntaxError, also sets additional attributes
- to make printing of exceptions believe it is a syntax error. */
-
-void
-PyErr_SyntaxLocation(const char *filename, int lineno)
-{
- PyObject *exc, *v, *tb, *tmp;
-
- /* add attributes for the line number and filename for the error */
- PyErr_Fetch(&exc, &v, &tb);
- PyErr_NormalizeException(&exc, &v, &tb);
- /* XXX check that it is, indeed, a syntax error. It might not
- * be, though. */
- tmp = PyInt_FromLong(lineno);
- if (tmp == NULL)
- PyErr_Clear();
- else {
- if (PyObject_SetAttrString(v, "lineno", tmp))
- PyErr_Clear();
- Py_DECREF(tmp);
- }
- if (filename != NULL) {
- tmp = PyString_FromString(filename);
- if (tmp == NULL)
- PyErr_Clear();
- else {
- if (PyObject_SetAttrString(v, "filename", tmp))
- PyErr_Clear();
- Py_DECREF(tmp);
- }
-
- tmp = PyErr_ProgramText(filename, lineno);
- if (tmp) {
- if (PyObject_SetAttrString(v, "text", tmp))
- PyErr_Clear();
- Py_DECREF(tmp);
- }
- }
- if (PyObject_SetAttrString(v, "offset", Py_None)) {
- PyErr_Clear();
- }
- if (exc != PyExc_SyntaxError) {
- if (!PyObject_HasAttrString(v, "msg")) {
- tmp = PyObject_Str(v);
- if (tmp) {
- if (PyObject_SetAttrString(v, "msg", tmp))
- PyErr_Clear();
- Py_DECREF(tmp);
- } else {
- PyErr_Clear();
- }
- }
- if (!PyObject_HasAttrString(v, "print_file_and_line")) {
- if (PyObject_SetAttrString(v, "print_file_and_line",
- Py_None))
- PyErr_Clear();
- }
- }
- PyErr_Restore(exc, v, tb);
-}
-
-/* com_fetch_program_text will attempt to load the line of text that
- the exception refers to. If it fails, it will return NULL but will
- not set an exception.
-
- XXX The functionality of this function is quite similar to the
- functionality in tb_displayline() in traceback.c.
-*/
-
-PyObject *
-PyErr_ProgramText(const char *filename, int lineno)
-{
- FILE *fp;
- int i;
- char linebuf[1000];
-
- if (filename == NULL || *filename == '\0' || lineno <= 0)
- return NULL;
- fp = fopen(filename, "r" PY_STDIOTEXTMODE);
- if (fp == NULL)
- return NULL;
- for (i = 0; i < lineno; i++) {
- char *pLastChar = &linebuf[sizeof(linebuf) - 2];
- do {
- *pLastChar = '\0';
- if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, fp, NULL) == NULL)
- break;
- /* fgets read *something*; if it didn't get as
- far as pLastChar, it must have found a newline
- or hit the end of the file; if pLastChar is \n,
- it obviously found a newline; else we haven't
- yet seen a newline, so must continue */
- } while (*pLastChar != '\0' && *pLastChar != '\n');
- }
- fclose(fp);
- if (i == lineno) {
- char *p = linebuf;
- while (*p == ' ' || *p == '\t' || *p == '\014')
- p++;
- return PyString_FromString(p);
- }
- return NULL;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/sys/src/cmd/python/Python/fmod.c b/sys/src/cmd/python/Python/fmod.c
deleted file mode 100644
index 919c6cc74..000000000
--- a/sys/src/cmd/python/Python/fmod.c
+++ /dev/null
@@ -1,27 +0,0 @@
-
-/* Portable fmod(x, y) implementation for systems that don't have it */
-
-#include "pyconfig.h"
-
-#include "pyport.h"
-#include <errno.h>
-
-double
-fmod(double x, double y)
-{
- double i, f;
-
- if (y == 0.0) {
- errno = EDOM;
- return 0.0;
- }
-
- /* return f such that x = i*y + f for some integer i
- such that |f| < |y| and f has the same sign as x */
-
- i = floor(x/y);
- f = x - i*y;
- if ((x < 0.0) != (y < 0.0))
- f = f-y;
- return f;
-}
diff --git a/sys/src/cmd/python/Python/frozen.c b/sys/src/cmd/python/Python/frozen.c
deleted file mode 100644
index 946d626bd..000000000
--- a/sys/src/cmd/python/Python/frozen.c
+++ /dev/null
@@ -1,38 +0,0 @@
-
-/* Dummy frozen modules initializer */
-
-#include "Python.h"
-
-/* In order to test the support for frozen modules, by default we
- define a single frozen module, __hello__. Loading it will print
- some famous words... */
-
-/* To regenerate this data after the bytecode or marshal format has changed,
- go to ../Tools/freeze/ and freeze the hello.py file; then copy and paste
- the appropriate bytes from M___main__.c. */
-
-static unsigned char M___hello__[] = {
- 99,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
- 0,115,9,0,0,0,100,0,0,71,72,100,1,0,83,40,
- 2,0,0,0,115,14,0,0,0,72,101,108,108,111,32,119,
- 111,114,108,100,46,46,46,78,40,0,0,0,0,40,0,0,
- 0,0,40,0,0,0,0,40,0,0,0,0,115,8,0,0,
- 0,104,101,108,108,111,46,112,121,115,1,0,0,0,63,1,
- 0,0,0,115,0,0,0,0,
-};
-
-#define SIZE (int)sizeof(M___hello__)
-
-static struct _frozen _PyImport_FrozenModules[] = {
- /* Test module */
- {"__hello__", M___hello__, SIZE},
- /* Test package (negative size indicates package-ness) */
- {"__phello__", M___hello__, -SIZE},
- {"__phello__.spam", M___hello__, SIZE},
- {0, 0, 0} /* sentinel */
-};
-
-/* Embedding apps may change this pointer to point to their favorite
- collection of frozen modules: */
-
-struct _frozen *PyImport_FrozenModules = _PyImport_FrozenModules;
diff --git a/sys/src/cmd/python/Python/frozenmain.c b/sys/src/cmd/python/Python/frozenmain.c
deleted file mode 100644
index 397f0465c..000000000
--- a/sys/src/cmd/python/Python/frozenmain.c
+++ /dev/null
@@ -1,68 +0,0 @@
-
-/* Python interpreter main program for frozen scripts */
-
-#include "Python.h"
-
-#ifdef MS_WINDOWS
-extern void PyWinFreeze_ExeInit(void);
-extern void PyWinFreeze_ExeTerm(void);
-extern int PyInitFrozenExtensions(void);
-#endif
-
-/* Main program */
-
-int
-Py_FrozenMain(int argc, char **argv)
-{
- char *p;
- int n, sts;
- int inspect = 0;
- int unbuffered = 0;
-
- Py_FrozenFlag = 1; /* Suppress errors from getpath.c */
-
- if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
- inspect = 1;
- if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
- unbuffered = 1;
-
- if (unbuffered) {
- setbuf(stdin, (char *)NULL);
- setbuf(stdout, (char *)NULL);
- setbuf(stderr, (char *)NULL);
- }
-
-#ifdef MS_WINDOWS
- PyInitFrozenExtensions();
-#endif /* MS_WINDOWS */
- Py_SetProgramName(argv[0]);
- Py_Initialize();
-#ifdef MS_WINDOWS
- PyWinFreeze_ExeInit();
-#endif
-
- if (Py_VerboseFlag)
- fprintf(stderr, "Python %s\n%s\n",
- Py_GetVersion(), Py_GetCopyright());
-
- PySys_SetArgv(argc, argv);
-
- n = PyImport_ImportFrozenModule("__main__");
- if (n == 0)
- Py_FatalError("__main__ not frozen");
- if (n < 0) {
- PyErr_Print();
- sts = 1;
- }
- else
- sts = 0;
-
- if (inspect && isatty((int)fileno(stdin)))
- sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
-
-#ifdef MS_WINDOWS
- PyWinFreeze_ExeTerm();
-#endif
- Py_Finalize();
- return sts;
-}
diff --git a/sys/src/cmd/python/Python/future.c b/sys/src/cmd/python/Python/future.c
deleted file mode 100644
index 3b3ca1d7b..000000000
--- a/sys/src/cmd/python/Python/future.c
+++ /dev/null
@@ -1,136 +0,0 @@
-#include "Python.h"
-#include "Python-ast.h"
-#include "node.h"
-#include "token.h"
-#include "graminit.h"
-#include "code.h"
-#include "compile.h"
-#include "symtable.h"
-
-#define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
-
-static int
-future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename)
-{
- int i;
- asdl_seq *names;
-
- assert(s->kind == ImportFrom_kind);
-
- names = s->v.ImportFrom.names;
- for (i = 0; i < asdl_seq_LEN(names); i++) {
- alias_ty name = (alias_ty)asdl_seq_GET(names, i);
- const char *feature = PyString_AsString(name->name);
- if (!feature)
- return 0;
- if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
- continue;
- } else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
- continue;
- } else if (strcmp(feature, FUTURE_DIVISION) == 0) {
- ff->ff_features |= CO_FUTURE_DIVISION;
- } else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) {
- ff->ff_features |= CO_FUTURE_ABSOLUTE_IMPORT;
- } else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) {
- ff->ff_features |= CO_FUTURE_WITH_STATEMENT;
- } else if (strcmp(feature, "braces") == 0) {
- PyErr_SetString(PyExc_SyntaxError,
- "not a chance");
- PyErr_SyntaxLocation(filename, s->lineno);
- return 0;
- } else {
- PyErr_Format(PyExc_SyntaxError,
- UNDEFINED_FUTURE_FEATURE, feature);
- PyErr_SyntaxLocation(filename, s->lineno);
- return 0;
- }
- }
- return 1;
-}
-
-static int
-future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
-{
- int i, found_docstring = 0, done = 0, prev_line = 0;
-
- static PyObject *future;
- if (!future) {
- future = PyString_InternFromString("__future__");
- if (!future)
- return 0;
- }
-
- if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
- return 1;
-
- /* A subsequent pass will detect future imports that don't
- appear at the beginning of the file. There's one case,
- however, that is easier to handl here: A series of imports
- joined by semi-colons, where the first import is a future
- statement but some subsequent import has the future form
- but is preceded by a regular import.
- */
-
-
- for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
- stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
-
- if (done && s->lineno > prev_line)
- return 1;
- prev_line = s->lineno;
-
- /* The tests below will return from this function unless it is
- still possible to find a future statement. The only things
- that can precede a future statement are another future
- statement and a doc string.
- */
-
- if (s->kind == ImportFrom_kind) {
- if (s->v.ImportFrom.module == future) {
- if (done) {
- PyErr_SetString(PyExc_SyntaxError,
- ERR_LATE_FUTURE);
- PyErr_SyntaxLocation(filename,
- s->lineno);
- return 0;
- }
- if (!future_check_features(ff, s, filename))
- return 0;
- ff->ff_lineno = s->lineno;
- }
- else
- done = 1;
- }
- else if (s->kind == Expr_kind && !found_docstring) {
- expr_ty e = s->v.Expr.value;
- if (e->kind != Str_kind)
- done = 1;
- else
- found_docstring = 1;
- }
- else
- done = 1;
- }
- return 1;
-}
-
-
-PyFutureFeatures *
-PyFuture_FromAST(mod_ty mod, const char *filename)
-{
- PyFutureFeatures *ff;
-
- ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures));
- if (ff == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
- ff->ff_features = 0;
- ff->ff_lineno = -1;
-
- if (!future_parse(ff, mod, filename)) {
- PyObject_Free(ff);
- return NULL;
- }
- return ff;
-}
diff --git a/sys/src/cmd/python/Python/getargs.c b/sys/src/cmd/python/Python/getargs.c
deleted file mode 100644
index d62559863..000000000
--- a/sys/src/cmd/python/Python/getargs.c
+++ /dev/null
@@ -1,1771 +0,0 @@
-
-/* New getargs implementation */
-
-#include "Python.h"
-
-#include <ctype.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-int PyArg_Parse(PyObject *, const char *, ...);
-int PyArg_ParseTuple(PyObject *, const char *, ...);
-int PyArg_VaParse(PyObject *, const char *, va_list);
-
-int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
- const char *, char **, ...);
-int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
- const char *, char **, va_list);
-
-#ifdef HAVE_DECLSPEC_DLL
-/* Export functions */
-PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, char *, ...);
-PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, char *, ...);
-PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
- const char *, char **, ...);
-PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
-PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, char *, va_list);
-PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
- const char *, char **, va_list);
-#endif
-
-#define FLAG_COMPAT 1
-#define FLAG_SIZE_T 2
-
-
-/* Forward */
-static int vgetargs1(PyObject *, const char *, va_list *, int);
-static void seterror(int, const char *, int *, const char *, const char *);
-static char *convertitem(PyObject *, const char **, va_list *, int, int *,
- char *, size_t, PyObject **);
-static char *converttuple(PyObject *, const char **, va_list *, int,
- int *, char *, size_t, int, PyObject **);
-static char *convertsimple(PyObject *, const char **, va_list *, int, char *,
- size_t, PyObject **);
-static Py_ssize_t convertbuffer(PyObject *, void **p, char **);
-
-static int vgetargskeywords(PyObject *, PyObject *,
- const char *, char **, va_list *, int);
-static char *skipitem(const char **, va_list *, int);
-
-int
-PyArg_Parse(PyObject *args, const char *format, ...)
-{
- int retval;
- va_list va;
-
- va_start(va, format);
- retval = vgetargs1(args, format, &va, FLAG_COMPAT);
- va_end(va);
- return retval;
-}
-
-int
-_PyArg_Parse_SizeT(PyObject *args, char *format, ...)
-{
- int retval;
- va_list va;
-
- va_start(va, format);
- retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
- va_end(va);
- return retval;
-}
-
-
-int
-PyArg_ParseTuple(PyObject *args, const char *format, ...)
-{
- int retval;
- va_list va;
-
- va_start(va, format);
- retval = vgetargs1(args, format, &va, 0);
- va_end(va);
- return retval;
-}
-
-int
-_PyArg_ParseTuple_SizeT(PyObject *args, char *format, ...)
-{
- int retval;
- va_list va;
-
- va_start(va, format);
- retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
- va_end(va);
- return retval;
-}
-
-
-int
-PyArg_VaParse(PyObject *args, const char *format, va_list va)
-{
- va_list lva;
-
-#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(lva, va);
-#else
- lva = va;
-#endif
-#endif
-
- return vgetargs1(args, format, &lva, 0);
-}
-
-int
-_PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)
-{
- va_list lva;
-
-#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(lva, va);
-#else
- lva = va;
-#endif
-#endif
-
- return vgetargs1(args, format, &lva, FLAG_SIZE_T);
-}
-
-
-/* Handle cleanup of allocated memory in case of exception */
-
-static int
-addcleanup(void *ptr, PyObject **freelist)
-{
- PyObject *cobj;
- if (!*freelist) {
- *freelist = PyList_New(0);
- if (!*freelist) {
- PyMem_FREE(ptr);
- return -1;
- }
- }
- cobj = PyCObject_FromVoidPtr(ptr, NULL);
- if (!cobj) {
- PyMem_FREE(ptr);
- return -1;
- }
- if(PyList_Append(*freelist, cobj)) {
- PyMem_FREE(ptr);
- Py_DECREF(cobj);
- return -1;
- }
- Py_DECREF(cobj);
- return 0;
-}
-
-static int
-cleanreturn(int retval, PyObject *freelist)
-{
- if(freelist) {
- if((retval) == 0) {
- Py_ssize_t len = PyList_GET_SIZE(freelist), i;
- for (i = 0; i < len; i++)
- PyMem_FREE(PyCObject_AsVoidPtr(
- PyList_GET_ITEM(freelist, i)));
- }
- Py_DECREF(freelist);
- }
- return retval;
-}
-
-
-static int
-vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
-{
- char msgbuf[256];
- int levels[32];
- const char *fname = NULL;
- const char *message = NULL;
- int min = -1;
- int max = 0;
- int level = 0;
- int endfmt = 0;
- const char *formatsave = format;
- Py_ssize_t i, len;
- char *msg;
- PyObject *freelist = NULL;
- int compat = flags & FLAG_COMPAT;
-
- assert(compat || (args != (PyObject*)NULL));
- flags = flags & ~FLAG_COMPAT;
-
- while (endfmt == 0) {
- int c = *format++;
- switch (c) {
- case '(':
- if (level == 0)
- max++;
- level++;
- if (level >= 30)
- Py_FatalError("too many tuple nesting levels "
- "in argument format string");
- break;
- case ')':
- if (level == 0)
- Py_FatalError("excess ')' in getargs format");
- else
- level--;
- break;
- case '\0':
- endfmt = 1;
- break;
- case ':':
- fname = format;
- endfmt = 1;
- break;
- case ';':
- message = format;
- endfmt = 1;
- break;
- default:
- if (level == 0) {
- if (c == 'O')
- max++;
- else if (isalpha(Py_CHARMASK(c))) {
- if (c != 'e') /* skip encoded */
- max++;
- } else if (c == '|')
- min = max;
- }
- break;
- }
- }
-
- if (level != 0)
- Py_FatalError(/* '(' */ "missing ')' in getargs format");
-
- if (min < 0)
- min = max;
-
- format = formatsave;
-
- if (compat) {
- if (max == 0) {
- if (args == NULL)
- return 1;
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.200s%s takes no arguments",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()");
- PyErr_SetString(PyExc_TypeError, msgbuf);
- return 0;
- }
- else if (min == 1 && max == 1) {
- if (args == NULL) {
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.200s%s takes at least one argument",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()");
- PyErr_SetString(PyExc_TypeError, msgbuf);
- return 0;
- }
- msg = convertitem(args, &format, p_va, flags, levels,
- msgbuf, sizeof(msgbuf), &freelist);
- if (msg == NULL)
- return cleanreturn(1, freelist);
- seterror(levels[0], msg, levels+1, fname, message);
- return cleanreturn(0, freelist);
- }
- else {
- PyErr_SetString(PyExc_SystemError,
- "old style getargs format uses new features");
- return 0;
- }
- }
-
- if (!PyTuple_Check(args)) {
- PyErr_SetString(PyExc_SystemError,
- "new style getargs format but argument is not a tuple");
- return 0;
- }
-
- len = PyTuple_GET_SIZE(args);
-
- if (len < min || max < len) {
- if (message == NULL) {
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.150s%s takes %s %d argument%s "
- "(%ld given)",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()",
- min==max ? "exactly"
- : len < min ? "at least" : "at most",
- len < min ? min : max,
- (len < min ? min : max) == 1 ? "" : "s",
- Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
- message = msgbuf;
- }
- PyErr_SetString(PyExc_TypeError, message);
- return 0;
- }
-
- for (i = 0; i < len; i++) {
- if (*format == '|')
- format++;
- msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
- flags, levels, msgbuf,
- sizeof(msgbuf), &freelist);
- if (msg) {
- seterror(i+1, msg, levels, fname, message);
- return cleanreturn(0, freelist);
- }
- }
-
- if (*format != '\0' && !isalpha(Py_CHARMASK(*format)) &&
- *format != '(' &&
- *format != '|' && *format != ':' && *format != ';') {
- PyErr_Format(PyExc_SystemError,
- "bad format string: %.200s", formatsave);
- return cleanreturn(0, freelist);
- }
-
- return cleanreturn(1, freelist);
-}
-
-
-
-static void
-seterror(int iarg, const char *msg, int *levels, const char *fname,
- const char *message)
-{
- char buf[512];
- int i;
- char *p = buf;
-
- if (PyErr_Occurred())
- return;
- else if (message == NULL) {
- if (fname != NULL) {
- PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
- p += strlen(p);
- }
- if (iarg != 0) {
- PyOS_snprintf(p, sizeof(buf) - (p - buf),
- "argument %d", iarg);
- i = 0;
- p += strlen(p);
- while (levels[i] > 0 && i < 32 && (int)(p-buf) < 220) {
- PyOS_snprintf(p, sizeof(buf) - (p - buf),
- ", item %d", levels[i]-1);
- p += strlen(p);
- i++;
- }
- }
- else {
- PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
- p += strlen(p);
- }
- PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
- message = buf;
- }
- PyErr_SetString(PyExc_TypeError, message);
-}
-
-
-/* Convert a tuple argument.
- On entry, *p_format points to the character _after_ the opening '('.
- On successful exit, *p_format points to the closing ')'.
- If successful:
- *p_format and *p_va are updated,
- *levels and *msgbuf are untouched,
- and NULL is returned.
- If the argument is invalid:
- *p_format is unchanged,
- *p_va is undefined,
- *levels is a 0-terminated list of item numbers,
- *msgbuf contains an error message, whose format is:
- "must be <typename1>, not <typename2>", where:
- <typename1> is the name of the expected type, and
- <typename2> is the name of the actual type,
- and msgbuf is returned.
-*/
-
-static char *
-converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
- int *levels, char *msgbuf, size_t bufsize, int toplevel,
- PyObject **freelist)
-{
- int level = 0;
- int n = 0;
- const char *format = *p_format;
- int i;
-
- for (;;) {
- int c = *format++;
- if (c == '(') {
- if (level == 0)
- n++;
- level++;
- }
- else if (c == ')') {
- if (level == 0)
- break;
- level--;
- }
- else if (c == ':' || c == ';' || c == '\0')
- break;
- else if (level == 0 && isalpha(Py_CHARMASK(c)))
- n++;
- }
-
- if (!PySequence_Check(arg) || PyString_Check(arg)) {
- levels[0] = 0;
- PyOS_snprintf(msgbuf, bufsize,
- toplevel ? "expected %d arguments, not %.50s" :
- "must be %d-item sequence, not %.50s",
- n,
- arg == Py_None ? "None" : arg->ob_type->tp_name);
- return msgbuf;
- }
-
- if ((i = PySequence_Size(arg)) != n) {
- levels[0] = 0;
- PyOS_snprintf(msgbuf, bufsize,
- toplevel ? "expected %d arguments, not %d" :
- "must be sequence of length %d, not %d",
- n, i);
- return msgbuf;
- }
-
- format = *p_format;
- for (i = 0; i < n; i++) {
- char *msg;
- PyObject *item;
- item = PySequence_GetItem(arg, i);
- if (item == NULL) {
- PyErr_Clear();
- levels[0] = i+1;
- levels[1] = 0;
- strncpy(msgbuf, "is not retrievable", bufsize);
- return msgbuf;
- }
- msg = convertitem(item, &format, p_va, flags, levels+1,
- msgbuf, bufsize, freelist);
- /* PySequence_GetItem calls tp->sq_item, which INCREFs */
- Py_XDECREF(item);
- if (msg != NULL) {
- levels[0] = i+1;
- return msg;
- }
- }
-
- *p_format = format;
- return NULL;
-}
-
-
-/* Convert a single item. */
-
-static char *
-convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
- int *levels, char *msgbuf, size_t bufsize, PyObject **freelist)
-{
- char *msg;
- const char *format = *p_format;
-
- if (*format == '(' /* ')' */) {
- format++;
- msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
- bufsize, 0, freelist);
- if (msg == NULL)
- format++;
- }
- else {
- msg = convertsimple(arg, &format, p_va, flags,
- msgbuf, bufsize, freelist);
- if (msg != NULL)
- levels[0] = 0;
- }
- if (msg == NULL)
- *p_format = format;
- return msg;
-}
-
-
-
-#define UNICODE_DEFAULT_ENCODING(arg) \
- _PyUnicode_AsDefaultEncodedString(arg, NULL)
-
-/* Format an error message generated by convertsimple(). */
-
-static char *
-converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
-{
- assert(expected != NULL);
- assert(arg != NULL);
- PyOS_snprintf(msgbuf, bufsize,
- "must be %.50s, not %.50s", expected,
- arg == Py_None ? "None" : arg->ob_type->tp_name);
- return msgbuf;
-}
-
-#define CONV_UNICODE "(unicode conversion error)"
-
-/* explicitly check for float arguments when integers are expected. For now
- * signal a warning. Returns true if an exception was raised. */
-static int
-float_argument_error(PyObject *arg)
-{
- if (PyFloat_Check(arg) &&
- PyErr_Warn(PyExc_DeprecationWarning,
- "integer argument expected, got float" ))
- return 1;
- else
- return 0;
-}
-
-/* Convert a non-tuple argument. Return NULL if conversion went OK,
- or a string with a message describing the failure. The message is
- formatted as "must be <desired type>, not <actual type>".
- When failing, an exception may or may not have been raised.
- Don't call if a tuple is expected.
-
- When you add new format codes, please don't forget poor skipitem() below.
-*/
-
-static char *
-convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
- char *msgbuf, size_t bufsize, PyObject **freelist)
-{
- /* For # codes */
-#define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\
- if (flags & FLAG_SIZE_T) q2=va_arg(*p_va, Py_ssize_t*); \
- else q=va_arg(*p_va, int*);
-#define STORE_SIZE(s) if (flags & FLAG_SIZE_T) *q2=s; else *q=s;
-#define BUFFER_LEN ((flags & FLAG_SIZE_T) ? *q2:*q)
-
- const char *format = *p_format;
- char c = *format++;
-#ifdef Py_USING_UNICODE
- PyObject *uarg;
-#endif
-
- switch (c) {
-
- case 'b': { /* unsigned byte -- very short int */
- char *p = va_arg(*p_va, char *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<b>", arg, msgbuf, bufsize);
- ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<b>", arg, msgbuf, bufsize);
- else if (ival < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned byte integer is less than minimum");
- return converterr("integer<b>", arg, msgbuf, bufsize);
- }
- else if (ival > UCHAR_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned byte integer is greater than maximum");
- return converterr("integer<b>", arg, msgbuf, bufsize);
- }
- else
- *p = (unsigned char) ival;
- break;
- }
-
- case 'B': {/* byte sized bitfield - both signed and unsigned
- values allowed */
- char *p = va_arg(*p_va, char *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<B>", arg, msgbuf, bufsize);
- ival = PyInt_AsUnsignedLongMask(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<B>", arg, msgbuf, bufsize);
- else
- *p = (unsigned char) ival;
- break;
- }
-
- case 'h': {/* signed short int */
- short *p = va_arg(*p_va, short *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<h>", arg, msgbuf, bufsize);
- ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<h>", arg, msgbuf, bufsize);
- else if (ival < SHRT_MIN) {
- PyErr_SetString(PyExc_OverflowError,
- "signed short integer is less than minimum");
- return converterr("integer<h>", arg, msgbuf, bufsize);
- }
- else if (ival > SHRT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "signed short integer is greater than maximum");
- return converterr("integer<h>", arg, msgbuf, bufsize);
- }
- else
- *p = (short) ival;
- break;
- }
-
- case 'H': { /* short int sized bitfield, both signed and
- unsigned allowed */
- unsigned short *p = va_arg(*p_va, unsigned short *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<H>", arg, msgbuf, bufsize);
- ival = PyInt_AsUnsignedLongMask(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<H>", arg, msgbuf, bufsize);
- else
- *p = (unsigned short) ival;
- break;
- }
-
- case 'i': {/* signed int */
- int *p = va_arg(*p_va, int *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<i>", arg, msgbuf, bufsize);
- ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<i>", arg, msgbuf, bufsize);
- else if (ival > INT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "signed integer is greater than maximum");
- return converterr("integer<i>", arg, msgbuf, bufsize);
- }
- else if (ival < INT_MIN) {
- PyErr_SetString(PyExc_OverflowError,
- "signed integer is less than minimum");
- return converterr("integer<i>", arg, msgbuf, bufsize);
- }
- else
- *p = ival;
- break;
- }
-
- case 'I': { /* int sized bitfield, both signed and
- unsigned allowed */
- unsigned int *p = va_arg(*p_va, unsigned int *);
- unsigned int ival;
- if (float_argument_error(arg))
- return converterr("integer<I>", arg, msgbuf, bufsize);
- ival = (unsigned int)PyInt_AsUnsignedLongMask(arg);
- if (ival == (unsigned int)-1 && PyErr_Occurred())
- return converterr("integer<I>", arg, msgbuf, bufsize);
- else
- *p = ival;
- break;
- }
-
- case 'n': /* Py_ssize_t */
-#if SIZEOF_SIZE_T != SIZEOF_LONG
- {
- Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
- Py_ssize_t ival;
- if (float_argument_error(arg))
- return converterr("integer<n>", arg, msgbuf, bufsize);
- ival = PyInt_AsSsize_t(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<n>", arg, msgbuf, bufsize);
- *p = ival;
- break;
- }
-#endif
- /* Fall through from 'n' to 'l' if Py_ssize_t is int */
- case 'l': {/* long int */
- long *p = va_arg(*p_va, long *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<l>", arg, msgbuf, bufsize);
- ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<l>", arg, msgbuf, bufsize);
- else
- *p = ival;
- break;
- }
-
- case 'k': { /* long sized bitfield */
- unsigned long *p = va_arg(*p_va, unsigned long *);
- unsigned long ival;
- if (PyInt_Check(arg))
- ival = PyInt_AsUnsignedLongMask(arg);
- else if (PyLong_Check(arg))
- ival = PyLong_AsUnsignedLongMask(arg);
- else
- return converterr("integer<k>", arg, msgbuf, bufsize);
- *p = ival;
- break;
- }
-
-#ifdef HAVE_LONG_LONG
- case 'L': {/* PY_LONG_LONG */
- PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );
- PY_LONG_LONG ival = PyLong_AsLongLong( arg );
- if( ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) {
- return converterr("long<L>", arg, msgbuf, bufsize);
- } else {
- *p = ival;
- }
- break;
- }
-
- case 'K': { /* long long sized bitfield */
- unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *);
- unsigned PY_LONG_LONG ival;
- if (PyInt_Check(arg))
- ival = PyInt_AsUnsignedLongMask(arg);
- else if (PyLong_Check(arg))
- ival = PyLong_AsUnsignedLongLongMask(arg);
- else
- return converterr("integer<K>", arg, msgbuf, bufsize);
- *p = ival;
- break;
- }
-#endif
-
- case 'f': {/* float */
- float *p = va_arg(*p_va, float *);
- double dval = PyFloat_AsDouble(arg);
- if (PyErr_Occurred())
- return converterr("float<f>", arg, msgbuf, bufsize);
- else
- *p = (float) dval;
- break;
- }
-
- case 'd': {/* double */
- double *p = va_arg(*p_va, double *);
- double dval = PyFloat_AsDouble(arg);
- if (PyErr_Occurred())
- return converterr("float<d>", arg, msgbuf, bufsize);
- else
- *p = dval;
- break;
- }
-
-#ifndef WITHOUT_COMPLEX
- case 'D': {/* complex double */
- Py_complex *p = va_arg(*p_va, Py_complex *);
- Py_complex cval;
- cval = PyComplex_AsCComplex(arg);
- if (PyErr_Occurred())
- return converterr("complex<D>", arg, msgbuf, bufsize);
- else
- *p = cval;
- break;
- }
-#endif /* WITHOUT_COMPLEX */
-
- case 'c': {/* char */
- char *p = va_arg(*p_va, char *);
- if (PyString_Check(arg) && PyString_Size(arg) == 1)
- *p = PyString_AS_STRING(arg)[0];
- else
- return converterr("char", arg, msgbuf, bufsize);
- break;
- }
-
- case 's': {/* string */
- if (*format == '#') {
- void **p = (void **)va_arg(*p_va, char **);
- FETCH_SIZE;
-
- if (PyString_Check(arg)) {
- *p = PyString_AS_STRING(arg);
- STORE_SIZE(PyString_GET_SIZE(arg));
- }
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyString_AS_STRING(uarg);
- STORE_SIZE(PyString_GET_SIZE(uarg));
- }
-#endif
- else { /* any buffer-like object */
- char *buf;
- Py_ssize_t count = convertbuffer(arg, p, &buf);
- if (count < 0)
- return converterr(buf, arg, msgbuf, bufsize);
- STORE_SIZE(count);
- }
- format++;
- } else {
- char **p = va_arg(*p_va, char **);
-
- if (PyString_Check(arg))
- *p = PyString_AS_STRING(arg);
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyString_AS_STRING(uarg);
- }
-#endif
- else
- return converterr("string", arg, msgbuf, bufsize);
- if ((Py_ssize_t)strlen(*p) != PyString_Size(arg))
- return converterr("string without null bytes",
- arg, msgbuf, bufsize);
- }
- break;
- }
-
- case 'z': {/* string, may be NULL (None) */
- if (*format == '#') { /* any buffer-like object */
- void **p = (void **)va_arg(*p_va, char **);
- FETCH_SIZE;
-
- if (arg == Py_None) {
- *p = 0;
- STORE_SIZE(0);
- }
- else if (PyString_Check(arg)) {
- *p = PyString_AS_STRING(arg);
- STORE_SIZE(PyString_GET_SIZE(arg));
- }
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyString_AS_STRING(uarg);
- STORE_SIZE(PyString_GET_SIZE(uarg));
- }
-#endif
- else { /* any buffer-like object */
- char *buf;
- Py_ssize_t count = convertbuffer(arg, p, &buf);
- if (count < 0)
- return converterr(buf, arg, msgbuf, bufsize);
- STORE_SIZE(count);
- }
- format++;
- } else {
- char **p = va_arg(*p_va, char **);
-
- if (arg == Py_None)
- *p = 0;
- else if (PyString_Check(arg))
- *p = PyString_AS_STRING(arg);
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyString_AS_STRING(uarg);
- }
-#endif
- else
- return converterr("string or None",
- arg, msgbuf, bufsize);
- if (*format == '#') {
- FETCH_SIZE;
- assert(0); /* XXX redundant with if-case */
- if (arg == Py_None)
- *q = 0;
- else
- *q = PyString_Size(arg);
- format++;
- }
- else if (*p != NULL &&
- (Py_ssize_t)strlen(*p) != PyString_Size(arg))
- return converterr(
- "string without null bytes or None",
- arg, msgbuf, bufsize);
- }
- break;
- }
-
- case 'e': {/* encoded string */
- char **buffer;
- const char *encoding;
- PyObject *s;
- int size, recode_strings;
-
- /* Get 'e' parameter: the encoding name */
- encoding = (const char *)va_arg(*p_va, const char *);
-#ifdef Py_USING_UNICODE
- if (encoding == NULL)
- encoding = PyUnicode_GetDefaultEncoding();
-#endif
-
- /* Get output buffer parameter:
- 's' (recode all objects via Unicode) or
- 't' (only recode non-string objects)
- */
- if (*format == 's')
- recode_strings = 1;
- else if (*format == 't')
- recode_strings = 0;
- else
- return converterr(
- "(unknown parser marker combination)",
- arg, msgbuf, bufsize);
- buffer = (char **)va_arg(*p_va, char **);
- format++;
- if (buffer == NULL)
- return converterr("(buffer is NULL)",
- arg, msgbuf, bufsize);
-
- /* Encode object */
- if (!recode_strings && PyString_Check(arg)) {
- s = arg;
- Py_INCREF(s);
- }
- else {
-#ifdef Py_USING_UNICODE
- PyObject *u;
-
- /* Convert object to Unicode */
- u = PyUnicode_FromObject(arg);
- if (u == NULL)
- return converterr(
- "string or unicode or text buffer",
- arg, msgbuf, bufsize);
-
- /* Encode object; use default error handling */
- s = PyUnicode_AsEncodedString(u,
- encoding,
- NULL);
- Py_DECREF(u);
- if (s == NULL)
- return converterr("(encoding failed)",
- arg, msgbuf, bufsize);
- if (!PyString_Check(s)) {
- Py_DECREF(s);
- return converterr(
- "(encoder failed to return a string)",
- arg, msgbuf, bufsize);
- }
-#else
- return converterr("string<e>", arg, msgbuf, bufsize);
-#endif
- }
- size = PyString_GET_SIZE(s);
-
- /* Write output; output is guaranteed to be 0-terminated */
- if (*format == '#') {
- /* Using buffer length parameter '#':
-
- - if *buffer is NULL, a new buffer of the
- needed size is allocated and the data
- copied into it; *buffer is updated to point
- to the new buffer; the caller is
- responsible for PyMem_Free()ing it after
- usage
-
- - if *buffer is not NULL, the data is
- copied to *buffer; *buffer_len has to be
- set to the size of the buffer on input;
- buffer overflow is signalled with an error;
- buffer has to provide enough room for the
- encoded string plus the trailing 0-byte
-
- - in both cases, *buffer_len is updated to
- the size of the buffer /excluding/ the
- trailing 0-byte
-
- */
- FETCH_SIZE;
-
- format++;
- if (q == NULL && q2 == NULL) {
- Py_DECREF(s);
- return converterr(
- "(buffer_len is NULL)",
- arg, msgbuf, bufsize);
- }
- if (*buffer == NULL) {
- *buffer = PyMem_NEW(char, size + 1);
- if (*buffer == NULL) {
- Py_DECREF(s);
- return converterr(
- "(memory error)",
- arg, msgbuf, bufsize);
- }
- if(addcleanup(*buffer, freelist)) {
- Py_DECREF(s);
- return converterr(
- "(cleanup problem)",
- arg, msgbuf, bufsize);
- }
- } else {
- if (size + 1 > BUFFER_LEN) {
- Py_DECREF(s);
- return converterr(
- "(buffer overflow)",
- arg, msgbuf, bufsize);
- }
- }
- memcpy(*buffer,
- PyString_AS_STRING(s),
- size + 1);
- STORE_SIZE(size);
- } else {
- /* Using a 0-terminated buffer:
-
- - the encoded string has to be 0-terminated
- for this variant to work; if it is not, an
- error raised
-
- - a new buffer of the needed size is
- allocated and the data copied into it;
- *buffer is updated to point to the new
- buffer; the caller is responsible for
- PyMem_Free()ing it after usage
-
- */
- if ((Py_ssize_t)strlen(PyString_AS_STRING(s))
- != size) {
- Py_DECREF(s);
- return converterr(
- "(encoded string without NULL bytes)",
- arg, msgbuf, bufsize);
- }
- *buffer = PyMem_NEW(char, size + 1);
- if (*buffer == NULL) {
- Py_DECREF(s);
- return converterr("(memory error)",
- arg, msgbuf, bufsize);
- }
- if(addcleanup(*buffer, freelist)) {
- Py_DECREF(s);
- return converterr("(cleanup problem)",
- arg, msgbuf, bufsize);
- }
- memcpy(*buffer,
- PyString_AS_STRING(s),
- size + 1);
- }
- Py_DECREF(s);
- break;
- }
-
-#ifdef Py_USING_UNICODE
- case 'u': {/* raw unicode buffer (Py_UNICODE *) */
- if (*format == '#') { /* any buffer-like object */
- void **p = (void **)va_arg(*p_va, char **);
- FETCH_SIZE;
- if (PyUnicode_Check(arg)) {
- *p = PyUnicode_AS_UNICODE(arg);
- STORE_SIZE(PyUnicode_GET_SIZE(arg));
- }
- else {
- return converterr("cannot convert raw buffers",
- arg, msgbuf, bufsize);
- }
- format++;
- } else {
- Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
- if (PyUnicode_Check(arg))
- *p = PyUnicode_AS_UNICODE(arg);
- else
- return converterr("unicode", arg, msgbuf, bufsize);
- }
- break;
- }
-#endif
-
- case 'S': { /* string object */
- PyObject **p = va_arg(*p_va, PyObject **);
- if (PyString_Check(arg))
- *p = arg;
- else
- return converterr("string", arg, msgbuf, bufsize);
- break;
- }
-
-#ifdef Py_USING_UNICODE
- case 'U': { /* Unicode object */
- PyObject **p = va_arg(*p_va, PyObject **);
- if (PyUnicode_Check(arg))
- *p = arg;
- else
- return converterr("unicode", arg, msgbuf, bufsize);
- break;
- }
-#endif
-
- case 'O': { /* object */
- PyTypeObject *type;
- PyObject **p;
- if (*format == '!') {
- type = va_arg(*p_va, PyTypeObject*);
- p = va_arg(*p_va, PyObject **);
- format++;
- if (PyType_IsSubtype(arg->ob_type, type))
- *p = arg;
- else
- return converterr(type->tp_name, arg, msgbuf, bufsize);
-
- }
- else if (*format == '?') {
- inquiry pred = va_arg(*p_va, inquiry);
- p = va_arg(*p_va, PyObject **);
- format++;
- if ((*pred)(arg))
- *p = arg;
- else
- return converterr("(unspecified)",
- arg, msgbuf, bufsize);
-
- }
- else if (*format == '&') {
- typedef int (*converter)(PyObject *, void *);
- converter convert = va_arg(*p_va, converter);
- void *addr = va_arg(*p_va, void *);
- format++;
- if (! (*convert)(arg, addr))
- return converterr("(unspecified)",
- arg, msgbuf, bufsize);
- }
- else {
- p = va_arg(*p_va, PyObject **);
- *p = arg;
- }
- break;
- }
-
-
- case 'w': { /* memory buffer, read-write access */
- void **p = va_arg(*p_va, void **);
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- int count;
-
- if (pb == NULL ||
- pb->bf_getwritebuffer == NULL ||
- pb->bf_getsegcount == NULL)
- return converterr("read-write buffer", arg, msgbuf, bufsize);
- if ((*pb->bf_getsegcount)(arg, NULL) != 1)
- return converterr("single-segment read-write buffer",
- arg, msgbuf, bufsize);
- if ((count = pb->bf_getwritebuffer(arg, 0, p)) < 0)
- return converterr("(unspecified)", arg, msgbuf, bufsize);
- if (*format == '#') {
- FETCH_SIZE;
- STORE_SIZE(count);
- format++;
- }
- break;
- }
-
- case 't': { /* 8-bit character buffer, read-only access */
- char **p = va_arg(*p_va, char **);
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- int count;
-
- if (*format++ != '#')
- return converterr(
- "invalid use of 't' format character",
- arg, msgbuf, bufsize);
- if (!PyType_HasFeature(arg->ob_type,
- Py_TPFLAGS_HAVE_GETCHARBUFFER) ||
- pb == NULL || pb->bf_getcharbuffer == NULL ||
- pb->bf_getsegcount == NULL)
- return converterr(
- "string or read-only character buffer",
- arg, msgbuf, bufsize);
-
- if (pb->bf_getsegcount(arg, NULL) != 1)
- return converterr(
- "string or single-segment read-only buffer",
- arg, msgbuf, bufsize);
-
- count = pb->bf_getcharbuffer(arg, 0, p);
- if (count < 0)
- return converterr("(unspecified)", arg, msgbuf, bufsize);
- {
- FETCH_SIZE;
- STORE_SIZE(count);
- }
- break;
- }
-
- default:
- return converterr("impossible<bad format char>", arg, msgbuf, bufsize);
-
- }
-
- *p_format = format;
- return NULL;
-}
-
-static Py_ssize_t
-convertbuffer(PyObject *arg, void **p, char **errmsg)
-{
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- Py_ssize_t count;
- if (pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL) {
- *errmsg = "string or read-only buffer";
- return -1;
- }
- if ((*pb->bf_getsegcount)(arg, NULL) != 1) {
- *errmsg = "string or single-segment read-only buffer";
- return -1;
- }
- if ((count = (*pb->bf_getreadbuffer)(arg, 0, p)) < 0) {
- *errmsg = "(unspecified)";
- }
- return count;
-}
-
-/* Support for keyword arguments donated by
- Geoff Philbrick <philbric@delphi.hks.com> */
-
-/* Return false (0) for error, else true. */
-int
-PyArg_ParseTupleAndKeywords(PyObject *args,
- PyObject *keywords,
- const char *format,
- char **kwlist, ...)
-{
- int retval;
- va_list va;
-
- if ((args == NULL || !PyTuple_Check(args)) ||
- (keywords != NULL && !PyDict_Check(keywords)) ||
- format == NULL ||
- kwlist == NULL)
- {
- PyErr_BadInternalCall();
- return 0;
- }
-
- va_start(va, kwlist);
- retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
- va_end(va);
- return retval;
-}
-
-int
-_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
- PyObject *keywords,
- const char *format,
- char **kwlist, ...)
-{
- int retval;
- va_list va;
-
- if ((args == NULL || !PyTuple_Check(args)) ||
- (keywords != NULL && !PyDict_Check(keywords)) ||
- format == NULL ||
- kwlist == NULL)
- {
- PyErr_BadInternalCall();
- return 0;
- }
-
- va_start(va, kwlist);
- retval = vgetargskeywords(args, keywords, format,
- kwlist, &va, FLAG_SIZE_T);
- va_end(va);
- return retval;
-}
-
-
-int
-PyArg_VaParseTupleAndKeywords(PyObject *args,
- PyObject *keywords,
- const char *format,
- char **kwlist, va_list va)
-{
- int retval;
- va_list lva;
-
- if ((args == NULL || !PyTuple_Check(args)) ||
- (keywords != NULL && !PyDict_Check(keywords)) ||
- format == NULL ||
- kwlist == NULL)
- {
- PyErr_BadInternalCall();
- return 0;
- }
-
-#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(lva, va);
-#else
- lva = va;
-#endif
-#endif
-
- retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
- return retval;
-}
-
-int
-_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
- PyObject *keywords,
- const char *format,
- char **kwlist, va_list va)
-{
- int retval;
- va_list lva;
-
- if ((args == NULL || !PyTuple_Check(args)) ||
- (keywords != NULL && !PyDict_Check(keywords)) ||
- format == NULL ||
- kwlist == NULL)
- {
- PyErr_BadInternalCall();
- return 0;
- }
-
-#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(lva, va);
-#else
- lva = va;
-#endif
-#endif
-
- retval = vgetargskeywords(args, keywords, format,
- kwlist, &lva, FLAG_SIZE_T);
- return retval;
-}
-
-
-static int
-vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
- char **kwlist, va_list *p_va, int flags)
-{
- char msgbuf[512];
- int levels[32];
- const char *fname, *message;
- int min, max;
- const char *formatsave;
- int i, len, nargs, nkeywords;
- const char *msg;
- char **p;
- PyObject *freelist = NULL;
-
- assert(args != NULL && PyTuple_Check(args));
- assert(keywords == NULL || PyDict_Check(keywords));
- assert(format != NULL);
- assert(kwlist != NULL);
- assert(p_va != NULL);
-
- /* Search the format:
- message <- error msg, if any (else NULL).
- fname <- routine name, if any (else NULL).
- min <- # of required arguments, or -1 if all are required.
- max <- most arguments (required + optional).
- Check that kwlist has a non-NULL entry for each arg.
- Raise error if a tuple arg spec is found.
- */
- fname = message = NULL;
- formatsave = format;
- p = kwlist;
- min = -1;
- max = 0;
- while ((i = *format++) != '\0') {
- if (isalpha(Py_CHARMASK(i)) && i != 'e') {
- max++;
- if (*p == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "more argument specifiers than "
- "keyword list entries");
- return 0;
- }
- p++;
- }
- else if (i == '|')
- min = max;
- else if (i == ':') {
- fname = format;
- break;
- }
- else if (i == ';') {
- message = format;
- break;
- }
- else if (i == '(') {
- PyErr_SetString(PyExc_RuntimeError,
- "tuple found in format when using keyword "
- "arguments");
- return 0;
- }
- }
- format = formatsave;
- if (*p != NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "more keyword list entries than "
- "argument specifiers");
- return 0;
- }
- if (min < 0) {
- /* All arguments are required. */
- min = max;
- }
-
- nargs = PyTuple_GET_SIZE(args);
- nkeywords = keywords == NULL ? 0 : PyDict_Size(keywords);
-
- /* make sure there are no duplicate values for an argument;
- its not clear when to use the term "keyword argument vs.
- keyword parameter in messages */
- if (nkeywords > 0) {
- for (i = 0; i < nargs; i++) {
- const char *thiskw = kwlist[i];
- if (thiskw == NULL)
- break;
- if (PyDict_GetItemString(keywords, thiskw)) {
- PyErr_Format(PyExc_TypeError,
- "keyword parameter '%s' was given "
- "by position and by name",
- thiskw);
- return 0;
- }
- else if (PyErr_Occurred())
- return 0;
- }
- }
-
- /* required arguments missing from args can be supplied by keyword
- arguments; set len to the number of positional arguments, and,
- if that's less than the minimum required, add in the number of
- required arguments that are supplied by keywords */
- len = nargs;
- if (nkeywords > 0 && nargs < min) {
- for (i = nargs; i < min; i++) {
- if (PyDict_GetItemString(keywords, kwlist[i]))
- len++;
- else if (PyErr_Occurred())
- return 0;
- }
- }
-
- /* make sure we got an acceptable number of arguments; the message
- is a little confusing with keywords since keyword arguments
- which are supplied, but don't match the required arguments
- are not included in the "%d given" part of the message
- XXX and this isn't a bug!? */
- if (len < min || max < len) {
- if (message == NULL) {
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.200s%s takes %s %d argument%s "
- "(%d given)",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()",
- min==max ? "exactly"
- : len < min ? "at least" : "at most",
- len < min ? min : max,
- (len < min ? min : max) == 1 ? "" : "s",
- len);
- message = msgbuf;
- }
- PyErr_SetString(PyExc_TypeError, message);
- return 0;
- }
-
- /* convert the positional arguments */
- for (i = 0; i < nargs; i++) {
- if (*format == '|')
- format++;
- msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
- flags, levels, msgbuf, sizeof(msgbuf),
- &freelist);
- if (msg) {
- seterror(i+1, msg, levels, fname, message);
- return cleanreturn(0, freelist);
- }
- }
-
- /* handle no keyword parameters in call */
- if (nkeywords == 0)
- return cleanreturn(1, freelist);
-
- /* convert the keyword arguments; this uses the format
- string where it was left after processing args */
- for (i = nargs; i < max; i++) {
- PyObject *item;
- if (*format == '|')
- format++;
- item = PyDict_GetItemString(keywords, kwlist[i]);
- if (item != NULL) {
- Py_INCREF(item);
- msg = convertitem(item, &format, p_va, flags, levels,
- msgbuf, sizeof(msgbuf), &freelist);
- Py_DECREF(item);
- if (msg) {
- seterror(i+1, msg, levels, fname, message);
- return cleanreturn(0, freelist);
- }
- --nkeywords;
- if (nkeywords == 0)
- break;
- }
- else if (PyErr_Occurred())
- return cleanreturn(0, freelist);
- else {
- msg = skipitem(&format, p_va, flags);
- if (msg) {
- levels[0] = 0;
- seterror(i+1, msg, levels, fname, message);
- return cleanreturn(0, freelist);
- }
- }
- }
-
- /* make sure there are no extraneous keyword arguments */
- if (nkeywords > 0) {
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(keywords, &pos, &key, &value)) {
- int match = 0;
- char *ks;
- if (!PyString_Check(key)) {
- PyErr_SetString(PyExc_TypeError,
- "keywords must be strings");
- return cleanreturn(0, freelist);
- }
- ks = PyString_AsString(key);
- for (i = 0; i < max; i++) {
- if (!strcmp(ks, kwlist[i])) {
- match = 1;
- break;
- }
- }
- if (!match) {
- PyErr_Format(PyExc_TypeError,
- "'%s' is an invalid keyword "
- "argument for this function",
- ks);
- return cleanreturn(0, freelist);
- }
- }
- }
-
- return cleanreturn(1, freelist);
-}
-
-
-static char *
-skipitem(const char **p_format, va_list *p_va, int flags)
-{
- const char *format = *p_format;
- char c = *format++;
-
- switch (c) {
-
- /* simple codes
- * The individual types (second arg of va_arg) are irrelevant */
-
- case 'b': /* byte -- very short int */
- case 'B': /* byte as bitfield */
- case 'h': /* short int */
- case 'H': /* short int as bitfield */
- case 'i': /* int */
- case 'I': /* int sized bitfield */
- case 'l': /* long int */
- case 'k': /* long int sized bitfield */
-#ifdef HAVE_LONG_LONG
- case 'L': /* PY_LONG_LONG */
- case 'K': /* PY_LONG_LONG sized bitfield */
-#endif
- case 'f': /* float */
- case 'd': /* double */
-#ifndef WITHOUT_COMPLEX
- case 'D': /* complex double */
-#endif
- case 'c': /* char */
- {
- (void) va_arg(*p_va, void *);
- break;
- }
-
- case 'n': /* Py_ssize_t */
- {
- (void) va_arg(*p_va, Py_ssize_t *);
- break;
- }
-
- /* string codes */
-
- case 'e': /* string with encoding */
- {
- (void) va_arg(*p_va, const char *);
- if (!(*format == 's' || *format == 't'))
- /* after 'e', only 's' and 't' is allowed */
- goto err;
- format++;
- /* explicit fallthrough to string cases */
- }
-
- case 's': /* string */
- case 'z': /* string or None */
-#ifdef Py_USING_UNICODE
- case 'u': /* unicode string */
-#endif
- case 't': /* buffer, read-only */
- case 'w': /* buffer, read-write */
- {
- (void) va_arg(*p_va, char **);
- if (*format == '#') {
- if (flags & FLAG_SIZE_T)
- (void) va_arg(*p_va, Py_ssize_t *);
- else
- (void) va_arg(*p_va, int *);
- format++;
- }
- break;
- }
-
- /* object codes */
-
- case 'S': /* string object */
-#ifdef Py_USING_UNICODE
- case 'U': /* unicode string object */
-#endif
- {
- (void) va_arg(*p_va, PyObject **);
- break;
- }
-
- case 'O': /* object */
- {
- if (*format == '!') {
- format++;
- (void) va_arg(*p_va, PyTypeObject*);
- (void) va_arg(*p_va, PyObject **);
- }
-#if 0
-/* I don't know what this is for */
- else if (*format == '?') {
- inquiry pred = va_arg(*p_va, inquiry);
- format++;
- if ((*pred)(arg)) {
- (void) va_arg(*p_va, PyObject **);
- }
- }
-#endif
- else if (*format == '&') {
- typedef int (*converter)(PyObject *, void *);
- (void) va_arg(*p_va, converter);
- (void) va_arg(*p_va, void *);
- format++;
- }
- else {
- (void) va_arg(*p_va, PyObject **);
- }
- break;
- }
-
- default:
-err:
- return "impossible<bad format char>";
-
- }
-
- /* The "(...)" format code for tuples is not handled here because
- * it is not allowed with keyword args. */
-
- *p_format = format;
- return NULL;
-}
-
-
-int
-PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
-{
- Py_ssize_t i, l;
- PyObject **o;
- va_list vargs;
-
-#ifdef HAVE_STDARG_PROTOTYPES
- va_start(vargs, max);
-#else
- va_start(vargs);
-#endif
-
- assert(min >= 0);
- assert(min <= max);
- if (!PyTuple_Check(args)) {
- PyErr_SetString(PyExc_SystemError,
- "PyArg_UnpackTuple() argument list is not a tuple");
- return 0;
- }
- l = PyTuple_GET_SIZE(args);
- if (l < min) {
- if (name != NULL)
- PyErr_Format(
- PyExc_TypeError,
- "%s expected %s%zd arguments, got %zd",
- name, (min == max ? "" : "at least "), min, l);
- else
- PyErr_Format(
- PyExc_TypeError,
- "unpacked tuple should have %s%zd elements,"
- " but has %zd",
- (min == max ? "" : "at least "), min, l);
- va_end(vargs);
- return 0;
- }
- if (l > max) {
- if (name != NULL)
- PyErr_Format(
- PyExc_TypeError,
- "%s expected %s%zd arguments, got %zd",
- name, (min == max ? "" : "at most "), max, l);
- else
- PyErr_Format(
- PyExc_TypeError,
- "unpacked tuple should have %s%zd elements,"
- " but has %zd",
- (min == max ? "" : "at most "), max, l);
- va_end(vargs);
- return 0;
- }
- for (i = 0; i < l; i++) {
- o = va_arg(vargs, PyObject **);
- *o = PyTuple_GET_ITEM(args, i);
- }
- va_end(vargs);
- return 1;
-}
-
-
-/* For type constructors that don't take keyword args
- *
- * Sets a TypeError and returns 0 if the kwds dict is
- * not emtpy, returns 1 otherwise
- */
-int
-_PyArg_NoKeywords(const char *funcname, PyObject *kw)
-{
- if (kw == NULL)
- return 1;
- if (!PyDict_CheckExact(kw)) {
- PyErr_BadInternalCall();
- return 0;
- }
- if (PyDict_Size(kw) == 0)
- return 1;
-
- PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments",
- funcname);
- return 0;
-}
-#ifdef __cplusplus
-};
-#endif
diff --git a/sys/src/cmd/python/Python/getcompiler.c b/sys/src/cmd/python/Python/getcompiler.c
deleted file mode 100644
index 0f441deb8..000000000
--- a/sys/src/cmd/python/Python/getcompiler.c
+++ /dev/null
@@ -1,28 +0,0 @@
-
-/* Return the compiler identification, if possible. */
-
-#include "Python.h"
-
-#ifndef COMPILER
-
-#ifdef __GNUC__
-#define COMPILER "\n[GCC " __VERSION__ "]"
-#endif
-
-#endif /* !COMPILER */
-
-#ifndef COMPILER
-
-#ifdef __cplusplus
-#define COMPILER "[C++]"
-#else
-#define COMPILER "[C]"
-#endif
-
-#endif /* !COMPILER */
-
-const char *
-Py_GetCompiler(void)
-{
- return COMPILER;
-}
diff --git a/sys/src/cmd/python/Python/getcopyright.c b/sys/src/cmd/python/Python/getcopyright.c
deleted file mode 100644
index c10aea452..000000000
--- a/sys/src/cmd/python/Python/getcopyright.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Return the copyright string. This is updated manually. */
-
-#include "Python.h"
-
-static char cprt[] =
-"\
-Copyright (c) 2001-2007 Python Software Foundation.\n\
-All Rights Reserved.\n\
-\n\
-Copyright (c) 2000 BeOpen.com.\n\
-All Rights Reserved.\n\
-\n\
-Copyright (c) 1995-2001 Corporation for National Research Initiatives.\n\
-All Rights Reserved.\n\
-\n\
-Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.\n\
-All Rights Reserved.";
-
-const char *
-Py_GetCopyright(void)
-{
- return cprt;
-}
diff --git a/sys/src/cmd/python/Python/getcwd.c b/sys/src/cmd/python/Python/getcwd.c
deleted file mode 100644
index 967d484b3..000000000
--- a/sys/src/cmd/python/Python/getcwd.c
+++ /dev/null
@@ -1,83 +0,0 @@
-
-/* Two PD getcwd() implementations.
- Author: Guido van Rossum, CWI Amsterdam, Jan 1991, <guido@cwi.nl>. */
-
-#include <stdio.h>
-#include <errno.h>
-
-#ifdef HAVE_GETWD
-
-/* Version for BSD systems -- use getwd() */
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-#ifndef MAXPATHLEN
-#if defined(PATH_MAX) && PATH_MAX > 1024
-#define MAXPATHLEN PATH_MAX
-#else
-#define MAXPATHLEN 1024
-#endif
-#endif
-
-extern char *getwd(char *);
-
-char *
-getcwd(char *buf, int size)
-{
- char localbuf[MAXPATHLEN+1];
- char *ret;
-
- if (size <= 0) {
- errno = EINVAL;
- return NULL;
- }
- ret = getwd(localbuf);
- if (ret != NULL && strlen(localbuf) >= (size_t)size) {
- errno = ERANGE;
- return NULL;
- }
- if (ret == NULL) {
- errno = EACCES; /* Most likely error */
- return NULL;
- }
- strncpy(buf, localbuf, size);
- return buf;
-}
-
-#else /* !HAVE_GETWD */
-
-/* Version for really old UNIX systems -- use pipe from pwd */
-
-#ifndef PWD_CMD
-#define PWD_CMD "/bin/pwd"
-#endif
-
-char *
-getcwd(char *buf, int size)
-{
- FILE *fp;
- char *p;
- int sts;
- if (size <= 0) {
- errno = EINVAL;
- return NULL;
- }
- if ((fp = popen(PWD_CMD, "r")) == NULL)
- return NULL;
- if (fgets(buf, size, fp) == NULL || (sts = pclose(fp)) != 0) {
- errno = EACCES; /* Most likely error */
- return NULL;
- }
- for (p = buf; *p != '\n'; p++) {
- if (*p == '\0') {
- errno = ERANGE;
- return NULL;
- }
- }
- *p = '\0';
- return buf;
-}
-
-#endif /* !HAVE_GETWD */
diff --git a/sys/src/cmd/python/Python/getmtime.c b/sys/src/cmd/python/Python/getmtime.c
deleted file mode 100644
index 54edb531d..000000000
--- a/sys/src/cmd/python/Python/getmtime.c
+++ /dev/null
@@ -1,26 +0,0 @@
-
-/* Subroutine to get the last modification time of a file */
-
-/* (A separate file because this may be OS dependent) */
-
-#include "Python.h"
-#include "pyconfig.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-time_t
-PyOS_GetLastModificationTime(char *path, FILE *fp)
-{
- struct stat st;
- if (fstat(fileno(fp), &st) != 0)
- return -1;
- else
- return st.st_mtime;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/sys/src/cmd/python/Python/getopt.c b/sys/src/cmd/python/Python/getopt.c
deleted file mode 100644
index 659efcfff..000000000
--- a/sys/src/cmd/python/Python/getopt.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*---------------------------------------------------------------------------*
- * <RCS keywords>
- *
- * C++ Library
- *
- * Copyright 1992-1994, David Gottner
- *
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice, this permission notice and
- * the following disclaimer notice appear unmodified in all copies.
- *
- * I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL I
- * BE LIABLE FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
- * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Nevertheless, I would like to know about bugs in this library or
- * suggestions for improvment. Send bug reports and feedback to
- * davegottner@delphi.com.
- *---------------------------------------------------------------------------*/
-
-/* Modified to support --help and --version, as well as /? on Windows
- * by Georg Brandl. */
-
-#include <stdio.h>
-#include <string.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int _PyOS_opterr = 1; /* generate error messages */
-int _PyOS_optind = 1; /* index into argv array */
-char *_PyOS_optarg = NULL; /* optional argument */
-
-int _PyOS_GetOpt(int argc, char **argv, char *optstring)
-{
- static char *opt_ptr = "";
- char *ptr;
- int option;
-
- if (*opt_ptr == '\0') {
-
- if (_PyOS_optind >= argc)
- return -1;
-#ifdef MS_WINDOWS
- else if (strcmp(argv[_PyOS_optind], "/?") == 0) {
- ++_PyOS_optind;
- return 'h';
- }
-#endif
-
- else if (argv[_PyOS_optind][0] != '-' ||
- argv[_PyOS_optind][1] == '\0' /* lone dash */ )
- return -1;
-
- else if (strcmp(argv[_PyOS_optind], "--") == 0) {
- ++_PyOS_optind;
- return -1;
- }
-
- else if (strcmp(argv[_PyOS_optind], "--help") == 0) {
- ++_PyOS_optind;
- return 'h';
- }
-
- else if (strcmp(argv[_PyOS_optind], "--version") == 0) {
- ++_PyOS_optind;
- return 'V';
- }
-
-
- opt_ptr = &argv[_PyOS_optind++][1];
- }
-
- if ( (option = *opt_ptr++) == '\0')
- return -1;
-
- if ((ptr = strchr(optstring, option)) == NULL) {
- if (_PyOS_opterr)
- fprintf(stderr, "Unknown option: -%c\n", option);
-
- return '_';
- }
-
- if (*(ptr + 1) == ':') {
- if (*opt_ptr != '\0') {
- _PyOS_optarg = opt_ptr;
- opt_ptr = "";
- }
-
- else {
- if (_PyOS_optind >= argc) {
- if (_PyOS_opterr)
- fprintf(stderr,
- "Argument expected for the -%c option\n", option);
- return '_';
- }
-
- _PyOS_optarg = argv[_PyOS_optind++];
- }
- }
-
- return option;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/sys/src/cmd/python/Python/getplatform.c b/sys/src/cmd/python/Python/getplatform.c
deleted file mode 100644
index 7a3c8b534..000000000
--- a/sys/src/cmd/python/Python/getplatform.c
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#include "Python.h"
-
-#ifndef PLATFORM
-#define PLATFORM "plan9"
-#endif
-
-const char *
-Py_GetPlatform(void)
-{
- return PLATFORM;
-}
diff --git a/sys/src/cmd/python/Python/getversion.c b/sys/src/cmd/python/Python/getversion.c
deleted file mode 100644
index 7af16fc81..000000000
--- a/sys/src/cmd/python/Python/getversion.c
+++ /dev/null
@@ -1,15 +0,0 @@
-
-/* Return the full version string. */
-
-#include "Python.h"
-
-#include "patchlevel.h"
-
-const char *
-Py_GetVersion(void)
-{
- static char version[250];
- PyOS_snprintf(version, sizeof(version), "%.80s (%.80s) %.80s",
- PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler());
- return version;
-}
diff --git a/sys/src/cmd/python/Python/hypot.c b/sys/src/cmd/python/Python/hypot.c
deleted file mode 100644
index 755d0c31c..000000000
--- a/sys/src/cmd/python/Python/hypot.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* hypot() replacement */
-
-#include "pyconfig.h"
-#include "pyport.h"
-
-double hypot(double x, double y)
-{
- double yx;
-
- x = fabs(x);
- y = fabs(y);
- if (x < y) {
- double temp = x;
- x = y;
- y = temp;
- }
- if (x == 0.)
- return 0.;
- else {
- yx = y/x;
- return x*sqrt(1.+yx*yx);
- }
-}
diff --git a/sys/src/cmd/python/Python/import.c b/sys/src/cmd/python/Python/import.c
deleted file mode 100644
index 7a3719f66..000000000
--- a/sys/src/cmd/python/Python/import.c
+++ /dev/null
@@ -1,3033 +0,0 @@
-
-/* Module definition and import implementation */
-
-#include "Python.h"
-
-#include "Python-ast.h"
-#include "pyarena.h"
-#include "pythonrun.h"
-#include "errcode.h"
-#include "marshal.h"
-#include "code.h"
-#include "compile.h"
-#include "eval.h"
-#include "osdefs.h"
-#include "importdl.h"
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern time_t PyOS_GetLastModificationTime(char *, FILE *);
- /* In getmtime.c */
-
-/* Magic word to reject .pyc files generated by other Python versions.
- It should change for each incompatible change to the bytecode.
-
- The value of CR and LF is incorporated so if you ever read or write
- a .pyc file in text mode the magic number will be wrong; also, the
- Apple MPW compiler swaps their values, botching string constants.
-
- The magic numbers must be spaced apart atleast 2 values, as the
- -U interpeter flag will cause MAGIC+1 being used. They have been
- odd numbers for some time now.
-
- There were a variety of old schemes for setting the magic number.
- The current working scheme is to increment the previous value by
- 10.
-
- Known values:
- Python 1.5: 20121
- Python 1.5.1: 20121
- Python 1.5.2: 20121
- Python 1.6: 50428
- Python 2.0: 50823
- Python 2.0.1: 50823
- Python 2.1: 60202
- Python 2.1.1: 60202
- Python 2.1.2: 60202
- Python 2.2: 60717
- Python 2.3a0: 62011
- Python 2.3a0: 62021
- Python 2.3a0: 62011 (!)
- Python 2.4a0: 62041
- Python 2.4a3: 62051
- Python 2.4b1: 62061
- Python 2.5a0: 62071
- Python 2.5a0: 62081 (ast-branch)
- Python 2.5a0: 62091 (with)
- Python 2.5a0: 62092 (changed WITH_CLEANUP opcode)
- Python 2.5b3: 62101 (fix wrong code: for x, in ...)
- Python 2.5b3: 62111 (fix wrong code: x += yield)
- Python 2.5c1: 62121 (fix wrong lnotab with for loops and
- storing constants that should have been removed)
- Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp)
-.
-*/
-#define MAGIC (62131 | ((long)'\r'<<16) | ((long)'\n'<<24))
-
-/* Magic word as global; note that _PyImport_Init() can change the
- value of this global to accommodate for alterations of how the
- compiler works which are enabled by command line switches. */
-static long pyc_magic = MAGIC;
-
-/* See _PyImport_FixupExtension() below */
-static PyObject *extensions = NULL;
-
-/* This table is defined in config.c: */
-extern struct _inittab _PyImport_Inittab[];
-
-struct _inittab *PyImport_Inittab = _PyImport_Inittab;
-
-/* these tables define the module suffixes that Python recognizes */
-struct filedescr * _PyImport_Filetab = NULL;
-
-#ifdef RISCOS
-static const struct filedescr _PyImport_StandardFiletab[] = {
- {"/py", "U", PY_SOURCE},
- {0, 0}
-};
-#else
-static const struct filedescr _PyImport_StandardFiletab[] = {
- {".py", "U", PY_SOURCE},
- {0, 0}
-};
-#endif
-
-static PyTypeObject NullImporterType; /* Forward reference */
-
-/* Initialize things */
-
-void
-_PyImport_Init(void)
-{
- const struct filedescr *scan;
- struct filedescr *filetab;
- int countD = 0;
- int countS = 0;
-
- /* prepare _PyImport_Filetab: copy entries from
- _PyImport_DynLoadFiletab and _PyImport_StandardFiletab.
- */
- for (scan = _PyImport_DynLoadFiletab; scan->suffix != NULL; ++scan)
- ++countD;
- for (scan = _PyImport_StandardFiletab; scan->suffix != NULL; ++scan)
- ++countS;
- filetab = PyMem_NEW(struct filedescr, countD + countS + 1);
- if (filetab == NULL)
- Py_FatalError("Can't initialize import file table.");
- memcpy(filetab, _PyImport_DynLoadFiletab,
- countD * sizeof(struct filedescr));
- memcpy(filetab + countD, _PyImport_StandardFiletab,
- countS * sizeof(struct filedescr));
- filetab[countD + countS].suffix = NULL;
-
- _PyImport_Filetab = filetab;
-
- if (Py_OptimizeFlag) {
- /* Replace ".pyc" with ".pyo" in _PyImport_Filetab */
- for (; filetab->suffix != NULL; filetab++) {
-#ifndef RISCOS
- if (strcmp(filetab->suffix, ".pyc") == 0)
- filetab->suffix = ".pyo";
-#else
- if (strcmp(filetab->suffix, "/pyc") == 0)
- filetab->suffix = "/pyo";
-#endif
- }
- }
-
- if (Py_UnicodeFlag) {
- /* Fix the pyc_magic so that byte compiled code created
- using the all-Unicode method doesn't interfere with
- code created in normal operation mode. */
- pyc_magic = MAGIC + 1;
- }
-}
-
-void
-_PyImportHooks_Init(void)
-{
- PyObject *v, *path_hooks = NULL, *zimpimport;
- int err = 0;
-
- /* adding sys.path_hooks and sys.path_importer_cache, setting up
- zipimport */
- if (PyType_Ready(&NullImporterType) < 0)
- goto error;
-
- if (Py_VerboseFlag)
- PySys_WriteStderr("# installing zipimport hook\n");
-
- v = PyList_New(0);
- if (v == NULL)
- goto error;
- err = PySys_SetObject("meta_path", v);
- Py_DECREF(v);
- if (err)
- goto error;
- v = PyDict_New();
- if (v == NULL)
- goto error;
- err = PySys_SetObject("path_importer_cache", v);
- Py_DECREF(v);
- if (err)
- goto error;
- path_hooks = PyList_New(0);
- if (path_hooks == NULL)
- goto error;
- err = PySys_SetObject("path_hooks", path_hooks);
- if (err) {
- error:
- PyErr_Print();
- Py_FatalError("initializing sys.meta_path, sys.path_hooks, "
- "path_importer_cache, or NullImporter failed"
- );
- }
-
- zimpimport = PyImport_ImportModule("zipimport");
- if (zimpimport == NULL) {
- PyErr_Clear(); /* No zip import module -- okay */
- if (Py_VerboseFlag)
- PySys_WriteStderr("# can't import zipimport\n");
- }
- else {
- PyObject *zipimporter = PyObject_GetAttrString(zimpimport,
- "zipimporter");
- Py_DECREF(zimpimport);
- if (zipimporter == NULL) {
- PyErr_Clear(); /* No zipimporter object -- okay */
- if (Py_VerboseFlag)
- PySys_WriteStderr(
- "# can't import zipimport.zipimporter\n");
- }
- else {
- /* sys.path_hooks.append(zipimporter) */
- err = PyList_Append(path_hooks, zipimporter);
- Py_DECREF(zipimporter);
- if (err)
- goto error;
- if (Py_VerboseFlag)
- PySys_WriteStderr(
- "# installed zipimport hook\n");
- }
- }
- Py_DECREF(path_hooks);
-}
-
-void
-_PyImport_Fini(void)
-{
- Py_XDECREF(extensions);
- extensions = NULL;
- PyMem_DEL(_PyImport_Filetab);
- _PyImport_Filetab = NULL;
-}
-
-
-/* Locking primitives to prevent parallel imports of the same module
- in different threads to return with a partially loaded module.
- These calls are serialized by the global interpreter lock. */
-
-#ifdef WITH_THREAD
-
-#include "pythread.h"
-
-static PyThread_type_lock import_lock = 0;
-static long import_lock_thread = -1;
-static int import_lock_level = 0;
-
-static void
-lock_import(void)
-{
- long me = PyThread_get_thread_ident();
- if (me == -1)
- return; /* Too bad */
- if (import_lock == NULL) {
- import_lock = PyThread_allocate_lock();
- if (import_lock == NULL)
- return; /* Nothing much we can do. */
- }
- if (import_lock_thread == me) {
- import_lock_level++;
- return;
- }
- if (import_lock_thread != -1 || !PyThread_acquire_lock(import_lock, 0))
- {
- PyThreadState *tstate = PyEval_SaveThread();
- PyThread_acquire_lock(import_lock, 1);
- PyEval_RestoreThread(tstate);
- }
- import_lock_thread = me;
- import_lock_level = 1;
-}
-
-static int
-unlock_import(void)
-{
- long me = PyThread_get_thread_ident();
- if (me == -1 || import_lock == NULL)
- return 0; /* Too bad */
- if (import_lock_thread != me)
- return -1;
- import_lock_level--;
- if (import_lock_level == 0) {
- import_lock_thread = -1;
- PyThread_release_lock(import_lock);
- }
- return 1;
-}
-
-/* This function is called from PyOS_AfterFork to ensure that newly
- created child processes do not share locks with the parent. */
-
-void
-_PyImport_ReInitLock(void)
-{
-#ifdef _AIX
- if (import_lock != NULL)
- import_lock = PyThread_allocate_lock();
-#endif
-}
-
-#else
-
-#define lock_import()
-#define unlock_import() 0
-
-#endif
-
-static PyObject *
-imp_lock_held(PyObject *self, PyObject *noargs)
-{
-#ifdef WITH_THREAD
- return PyBool_FromLong(import_lock_thread != -1);
-#else
- return PyBool_FromLong(0);
-#endif
-}
-
-static PyObject *
-imp_acquire_lock(PyObject *self, PyObject *noargs)
-{
-#ifdef WITH_THREAD
- lock_import();
-#endif
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *
-imp_release_lock(PyObject *self, PyObject *noargs)
-{
-#ifdef WITH_THREAD
- if (unlock_import() < 0) {
- PyErr_SetString(PyExc_RuntimeError,
- "not holding the import lock");
- return NULL;
- }
-#endif
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static void
-imp_modules_reloading_clear (void)
-{
- PyInterpreterState *interp = PyThreadState_Get()->interp;
- if (interp->modules_reloading == NULL)
- return;
- PyDict_Clear(interp->modules_reloading);
- return;
-}
-
-/* Helper for sys */
-
-PyObject *
-PyImport_GetModuleDict(void)
-{
- PyInterpreterState *interp = PyThreadState_GET()->interp;
- if (interp->modules == NULL)
- Py_FatalError("PyImport_GetModuleDict: no module dictionary!");
- return interp->modules;
-}
-
-
-/* List of names to clear in sys */
-static char* sys_deletes[] = {
- "path", "argv", "ps1", "ps2", "exitfunc",
- "exc_type", "exc_value", "exc_traceback",
- "last_type", "last_value", "last_traceback",
- "path_hooks", "path_importer_cache", "meta_path",
- NULL
-};
-
-static char* sys_files[] = {
- "stdin", "__stdin__",
- "stdout", "__stdout__",
- "stderr", "__stderr__",
- NULL
-};
-
-
-/* Un-initialize things, as good as we can */
-
-void
-PyImport_Cleanup(void)
-{
- Py_ssize_t pos, ndone;
- char *name;
- PyObject *key, *value, *dict;
- PyInterpreterState *interp = PyThreadState_GET()->interp;
- PyObject *modules = interp->modules;
-
- if (modules == NULL)
- return; /* Already done */
-
- /* Delete some special variables first. These are common
- places where user values hide and people complain when their
- destructors fail. Since the modules containing them are
- deleted *last* of all, they would come too late in the normal
- destruction order. Sigh. */
-
- value = PyDict_GetItemString(modules, "__builtin__");
- if (value != NULL && PyModule_Check(value)) {
- dict = PyModule_GetDict(value);
- if (Py_VerboseFlag)
- PySys_WriteStderr("# clear __builtin__._\n");
- PyDict_SetItemString(dict, "_", Py_None);
- }
- value = PyDict_GetItemString(modules, "sys");
- if (value != NULL && PyModule_Check(value)) {
- char **p;
- PyObject *v;
- dict = PyModule_GetDict(value);
- for (p = sys_deletes; *p != NULL; p++) {
- if (Py_VerboseFlag)
- PySys_WriteStderr("# clear sys.%s\n", *p);
- PyDict_SetItemString(dict, *p, Py_None);
- }
- for (p = sys_files; *p != NULL; p+=2) {
- if (Py_VerboseFlag)
- PySys_WriteStderr("# restore sys.%s\n", *p);
- v = PyDict_GetItemString(dict, *(p+1));
- if (v == NULL)
- v = Py_None;
- PyDict_SetItemString(dict, *p, v);
- }
- }
-
- /* First, delete __main__ */
- value = PyDict_GetItemString(modules, "__main__");
- if (value != NULL && PyModule_Check(value)) {
- if (Py_VerboseFlag)
- PySys_WriteStderr("# cleanup __main__\n");
- _PyModule_Clear(value);
- PyDict_SetItemString(modules, "__main__", Py_None);
- }
-
- /* The special treatment of __builtin__ here is because even
- when it's not referenced as a module, its dictionary is
- referenced by almost every module's __builtins__. Since
- deleting a module clears its dictionary (even if there are
- references left to it), we need to delete the __builtin__
- module last. Likewise, we don't delete sys until the very
- end because it is implicitly referenced (e.g. by print).
-
- Also note that we 'delete' modules by replacing their entry
- in the modules dict with None, rather than really deleting
- them; this avoids a rehash of the modules dictionary and
- also marks them as "non existent" so they won't be
- re-imported. */
-
- /* Next, repeatedly delete modules with a reference count of
- one (skipping __builtin__ and sys) and delete them */
- do {
- ndone = 0;
- pos = 0;
- while (PyDict_Next(modules, &pos, &key, &value)) {
- if (value->ob_refcnt != 1)
- continue;
- if (PyString_Check(key) && PyModule_Check(value)) {
- name = PyString_AS_STRING(key);
- if (strcmp(name, "__builtin__") == 0)
- continue;
- if (strcmp(name, "sys") == 0)
- continue;
- if (Py_VerboseFlag)
- PySys_WriteStderr(
- "# cleanup[1] %s\n", name);
- _PyModule_Clear(value);
- PyDict_SetItem(modules, key, Py_None);
- ndone++;
- }
- }
- } while (ndone > 0);
-
- /* Next, delete all modules (still skipping __builtin__ and sys) */
- pos = 0;
- while (PyDict_Next(modules, &pos, &key, &value)) {
- if (PyString_Check(key) && PyModule_Check(value)) {
- name = PyString_AS_STRING(key);
- if (strcmp(name, "__builtin__") == 0)
- continue;
- if (strcmp(name, "sys") == 0)
- continue;
- if (Py_VerboseFlag)
- PySys_WriteStderr("# cleanup[2] %s\n", name);
- _PyModule_Clear(value);
- PyDict_SetItem(modules, key, Py_None);
- }
- }
-
- /* Next, delete sys and __builtin__ (in that order) */
- value = PyDict_GetItemString(modules, "sys");
- if (value != NULL && PyModule_Check(value)) {
- if (Py_VerboseFlag)
- PySys_WriteStderr("# cleanup sys\n");
- _PyModule_Clear(value);
- PyDict_SetItemString(modules, "sys", Py_None);
- }
- value = PyDict_GetItemString(modules, "__builtin__");
- if (value != NULL && PyModule_Check(value)) {
- if (Py_VerboseFlag)
- PySys_WriteStderr("# cleanup __builtin__\n");
- _PyModule_Clear(value);
- PyDict_SetItemString(modules, "__builtin__", Py_None);
- }
-
- /* Finally, clear and delete the modules directory */
- PyDict_Clear(modules);
- interp->modules = NULL;
- Py_DECREF(modules);
- Py_CLEAR(interp->modules_reloading);
-}
-
-
-/* Helper for pythonrun.c -- return magic number */
-
-long
-PyImport_GetMagicNumber(void)
-{
- return pyc_magic;
-}
-
-
-/* Magic for extension modules (built-in as well as dynamically
- loaded). To prevent initializing an extension module more than
- once, we keep a static dictionary 'extensions' keyed by module name
- (for built-in modules) or by filename (for dynamically loaded
- modules), containing these modules. A copy of the module's
- dictionary is stored by calling _PyImport_FixupExtension()
- immediately after the module initialization function succeeds. A
- copy can be retrieved from there by calling
- _PyImport_FindExtension(). */
-
-PyObject *
-_PyImport_FixupExtension(char *name, char *filename)
-{
- PyObject *modules, *mod, *dict, *copy;
- if (extensions == NULL) {
- extensions = PyDict_New();
- if (extensions == NULL)
- return NULL;
- }
- modules = PyImport_GetModuleDict();
- mod = PyDict_GetItemString(modules, name);
- if (mod == NULL || !PyModule_Check(mod)) {
- PyErr_Format(PyExc_SystemError,
- "_PyImport_FixupExtension: module %.200s not loaded", name);
- return NULL;
- }
- dict = PyModule_GetDict(mod);
- if (dict == NULL)
- return NULL;
- copy = PyDict_Copy(dict);
- if (copy == NULL)
- return NULL;
- PyDict_SetItemString(extensions, filename, copy);
- Py_DECREF(copy);
- return copy;
-}
-
-PyObject *
-_PyImport_FindExtension(char *name, char *filename)
-{
- PyObject *dict, *mod, *mdict;
- if (extensions == NULL)
- return NULL;
- dict = PyDict_GetItemString(extensions, filename);
- if (dict == NULL)
- return NULL;
- mod = PyImport_AddModule(name);
- if (mod == NULL)
- return NULL;
- mdict = PyModule_GetDict(mod);
- if (mdict == NULL)
- return NULL;
- if (PyDict_Update(mdict, dict))
- return NULL;
- if (Py_VerboseFlag)
- PySys_WriteStderr("import %s # previously loaded (%s)\n",
- name, filename);
- return mod;
-}
-
-
-/* Get the module object corresponding to a module name.
- First check the modules dictionary if there's one there,
- if not, create a new one and insert it in the modules dictionary.
- Because the former action is most common, THIS DOES NOT RETURN A
- 'NEW' REFERENCE! */
-
-PyObject *
-PyImport_AddModule(const char *name)
-{
- PyObject *modules = PyImport_GetModuleDict();
- PyObject *m;
-
- if ((m = PyDict_GetItemString(modules, name)) != NULL &&
- PyModule_Check(m))
- return m;
- m = PyModule_New(name);
- if (m == NULL)
- return NULL;
- if (PyDict_SetItemString(modules, name, m) != 0) {
- Py_DECREF(m);
- return NULL;
- }
- Py_DECREF(m); /* Yes, it still exists, in modules! */
-
- return m;
-}
-
-/* Remove name from sys.modules, if it's there. */
-static void
-_RemoveModule(const char *name)
-{
- PyObject *modules = PyImport_GetModuleDict();
- if (PyDict_GetItemString(modules, name) == NULL)
- return;
- if (PyDict_DelItemString(modules, name) < 0)
- Py_FatalError("import: deleting existing key in"
- "sys.modules failed");
-}
-
-/* Execute a code object in a module and return the module object
- * WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is
- * removed from sys.modules, to avoid leaving damaged module objects
- * in sys.modules. The caller may wish to restore the original
- * module object (if any) in this case; PyImport_ReloadModule is an
- * example.
- */
-PyObject *
-PyImport_ExecCodeModule(char *name, PyObject *co)
-{
- return PyImport_ExecCodeModuleEx(name, co, (char *)NULL);
-}
-
-PyObject *
-PyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname)
-{
- PyObject *modules = PyImport_GetModuleDict();
- PyObject *m, *d, *v;
-
- m = PyImport_AddModule(name);
- if (m == NULL)
- return NULL;
- /* If the module is being reloaded, we get the old module back
- and re-use its dict to exec the new code. */
- d = PyModule_GetDict(m);
- if (PyDict_GetItemString(d, "__builtins__") == NULL) {
- if (PyDict_SetItemString(d, "__builtins__",
- PyEval_GetBuiltins()) != 0)
- goto error;
- }
- /* Remember the filename as the __file__ attribute */
- v = NULL;
- if (pathname != NULL) {
- v = PyString_FromString(pathname);
- if (v == NULL)
- PyErr_Clear();
- }
- if (v == NULL) {
- v = ((PyCodeObject *)co)->co_filename;
- Py_INCREF(v);
- }
- if (PyDict_SetItemString(d, "__file__", v) != 0)
- PyErr_Clear(); /* Not important enough to report */
- Py_DECREF(v);
-
- v = PyEval_EvalCode((PyCodeObject *)co, d, d);
- if (v == NULL)
- goto error;
- Py_DECREF(v);
-
- if ((m = PyDict_GetItemString(modules, name)) == NULL) {
- PyErr_Format(PyExc_ImportError,
- "Loaded module %.200s not found in sys.modules",
- name);
- return NULL;
- }
-
- Py_INCREF(m);
-
- return m;
-
- error:
- _RemoveModule(name);
- return NULL;
-}
-
-
-/* Read a code object from a file and check it for validity */
-
-static PyCodeObject *
-read_compiled_module(char *cpathname, FILE *fp)
-{
- PyObject *co;
-
- co = PyMarshal_ReadLastObjectFromFile(fp);
- if (co == NULL)
- return NULL;
- if (!PyCode_Check(co)) {
- PyErr_Format(PyExc_ImportError,
- "Non-code object in %.200s", cpathname);
- Py_DECREF(co);
- return NULL;
- }
- return (PyCodeObject *)co;
-}
-
-
-/* Load a module from a compiled file, execute it, and return its
- module object WITH INCREMENTED REFERENCE COUNT */
-
-static PyObject *
-load_compiled_module(char *name, char *cpathname, FILE *fp)
-{
- long magic;
- PyCodeObject *co;
- PyObject *m;
-
- magic = PyMarshal_ReadLongFromFile(fp);
- if (magic != pyc_magic) {
- PyErr_Format(PyExc_ImportError,
- "Bad magic number in %.200s", cpathname);
- return NULL;
- }
- (void) PyMarshal_ReadLongFromFile(fp);
- co = read_compiled_module(cpathname, fp);
- if (co == NULL)
- return NULL;
- if (Py_VerboseFlag)
- PySys_WriteStderr("import %s # precompiled from %s\n",
- name, cpathname);
- m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, cpathname);
- Py_DECREF(co);
-
- return m;
-}
-
-/* Parse a source file and return the corresponding code object */
-
-static PyCodeObject *
-parse_source_module(const char *pathname, FILE *fp)
-{
- PyCodeObject *co = NULL;
- mod_ty mod;
- PyArena *arena = PyArena_New();
- if (arena == NULL)
- return NULL;
-
- mod = PyParser_ASTFromFile(fp, pathname, Py_file_input, 0, 0, 0,
- NULL, arena);
- if (mod) {
- co = PyAST_Compile(mod, pathname, NULL, arena);
- }
- PyArena_Free(arena);
- return co;
-}
-
-
-/* Helper to open a bytecode file for writing in exclusive mode */
-
-static FILE *
-open_exclusive(char *filename)
-{
-#if defined(O_EXCL)&&defined(O_CREAT)&&defined(O_WRONLY)&&defined(O_TRUNC)
- /* Use O_EXCL to avoid a race condition when another process tries to
- write the same file. When that happens, our open() call fails,
- which is just fine (since it's only a cache).
- XXX If the file exists and is writable but the directory is not
- writable, the file will never be written. Oh well.
- */
- int fd;
- (void) unlink(filename);
- fd = open(filename, O_EXCL|O_CREAT|O_WRONLY|O_TRUNC
-#ifdef O_BINARY
- |O_BINARY /* necessary for Windows */
-#endif
-#ifdef __VMS
- , 0666, "ctxt=bin", "shr=nil"
-#else
- , 0666
-#endif
- );
- if (fd < 0)
- return NULL;
- return fdopen(fd, "wb");
-#else
- /* Best we can do -- on Windows this can't happen anyway */
- return fopen(filename, "wb");
-#endif
-}
-
-/* Load a source module from a given file and return its module
- object WITH INCREMENTED REFERENCE COUNT. If there's a matching
- byte-compiled file, use that instead. */
-
-static PyObject *
-load_source_module(char *name, char *pathname, FILE *fp)
-{
- time_t mtime;
- FILE *fpc;
- char buf[MAXPATHLEN+1];
- PyCodeObject *co;
- PyObject *m;
-
- mtime = PyOS_GetLastModificationTime(pathname, fp);
- if (mtime == (time_t)(-1)) {
- PyErr_Format(PyExc_RuntimeError,
- "unable to get modification time from '%s'",
- pathname);
- return NULL;
- }
-#if SIZEOF_TIME_T > 4
- /* Python's .pyc timestamp handling presumes that the timestamp fits
- in 4 bytes. This will be fine until sometime in the year 2038,
- when a 4-byte signed time_t will overflow.
- */
- if (mtime >> 32) {
- PyErr_SetString(PyExc_OverflowError,
- "modification time overflows a 4 byte field");
- return NULL;
- }
-#endif
- co = parse_source_module(pathname, fp);
- if (co == NULL)
- return NULL;
- if (Py_VerboseFlag)
- PySys_WriteStderr("import %s # from %s\n",
- name, pathname);
- m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname);
- Py_DECREF(co);
-
- return m;
-}
-
-
-/* Forward */
-static PyObject *load_module(char *, FILE *, char *, int, PyObject *);
-static struct filedescr *find_module(char *, char *, PyObject *,
- char *, size_t, FILE **, PyObject **);
-static struct _frozen *find_frozen(char *name);
-
-/* Load a package and return its module object WITH INCREMENTED
- REFERENCE COUNT */
-
-static PyObject *
-load_package(char *name, char *pathname)
-{
- PyObject *m, *d;
- PyObject *file = NULL;
- PyObject *path = NULL;
- int err;
- char buf[MAXPATHLEN+1];
- FILE *fp = NULL;
- struct filedescr *fdp;
-
- m = PyImport_AddModule(name);
- if (m == NULL)
- return NULL;
- if (Py_VerboseFlag)
- PySys_WriteStderr("import %s # directory %s\n",
- name, pathname);
- d = PyModule_GetDict(m);
- file = PyString_FromString(pathname);
- if (file == NULL)
- goto error;
- path = Py_BuildValue("[O]", file);
- if (path == NULL)
- goto error;
- err = PyDict_SetItemString(d, "__file__", file);
- if (err == 0)
- err = PyDict_SetItemString(d, "__path__", path);
- if (err != 0)
- goto error;
- buf[0] = '\0';
- fdp = find_module(name, "__init__", path, buf, sizeof(buf), &fp, NULL);
- if (fdp == NULL) {
- if (PyErr_ExceptionMatches(PyExc_ImportError)) {
- PyErr_Clear();
- Py_INCREF(m);
- }
- else
- m = NULL;
- goto cleanup;
- }
- m = load_module(name, fp, buf, fdp->type, NULL);
- if (fp != NULL)
- fclose(fp);
- goto cleanup;
-
- error:
- m = NULL;
- cleanup:
- Py_XDECREF(path);
- Py_XDECREF(file);
- return m;
-}
-
-
-/* Helper to test for built-in module */
-
-static int
-is_builtin(char *name)
-{
- int i;
- for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
- if (strcmp(name, PyImport_Inittab[i].name) == 0) {
- if (PyImport_Inittab[i].initfunc == NULL)
- return -1;
- else
- return 1;
- }
- }
- return 0;
-}
-
-
-/* Return an importer object for a sys.path/pkg.__path__ item 'p',
- possibly by fetching it from the path_importer_cache dict. If it
- wasn't yet cached, traverse path_hooks until it a hook is found
- that can handle the path item. Return None if no hook could;
- this tells our caller it should fall back to the builtin
- import mechanism. Cache the result in path_importer_cache.
- Returns a borrowed reference. */
-
-static PyObject *
-get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks,
- PyObject *p)
-{
- PyObject *importer;
- Py_ssize_t j, nhooks;
-
- /* These conditions are the caller's responsibility: */
- assert(PyList_Check(path_hooks));
- assert(PyDict_Check(path_importer_cache));
-
- nhooks = PyList_Size(path_hooks);
- if (nhooks < 0)
- return NULL; /* Shouldn't happen */
-
- importer = PyDict_GetItem(path_importer_cache, p);
- if (importer != NULL)
- return importer;
-
- /* set path_importer_cache[p] to None to avoid recursion */
- if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0)
- return NULL;
-
- for (j = 0; j < nhooks; j++) {
- PyObject *hook = PyList_GetItem(path_hooks, j);
- if (hook == NULL)
- return NULL;
- importer = PyObject_CallFunctionObjArgs(hook, p, NULL);
- if (importer != NULL)
- break;
-
- if (!PyErr_ExceptionMatches(PyExc_ImportError)) {
- return NULL;
- }
- PyErr_Clear();
- }
- if (importer == NULL) {
- importer = PyObject_CallFunctionObjArgs(
- (PyObject *)&NullImporterType, p, NULL
- );
- if (importer == NULL) {
- if (PyErr_ExceptionMatches(PyExc_ImportError)) {
- PyErr_Clear();
- return Py_None;
- }
- }
- }
- if (importer != NULL) {
- int err = PyDict_SetItem(path_importer_cache, p, importer);
- Py_DECREF(importer);
- if (err != 0)
- return NULL;
- }
- return importer;
-}
-
-/* Search the path (default sys.path) for a module. Return the
- corresponding filedescr struct, and (via return arguments) the
- pathname and an open file. Return NULL if the module is not found. */
-
-#ifdef MS_COREDLL
-extern FILE *PyWin_FindRegisteredModule(const char *, struct filedescr **,
- char *, Py_ssize_t);
-#endif
-
-static int case_ok(char *, Py_ssize_t, Py_ssize_t, char *);
-static int find_init_module(char *); /* Forward */
-static struct filedescr importhookdescr = {"", "", IMP_HOOK};
-
-static struct filedescr *
-find_module(char *fullname, char *subname, PyObject *path, char *buf,
- size_t buflen, FILE **p_fp, PyObject **p_loader)
-{
- Py_ssize_t i, npath;
- size_t len, namelen;
- struct filedescr *fdp = NULL;
- char *filemode;
- FILE *fp = NULL;
- PyObject *path_hooks, *path_importer_cache;
-#ifndef RISCOS
- struct stat statbuf;
-#endif
- static struct filedescr fd_frozen = {"", "", PY_FROZEN};
- static struct filedescr fd_builtin = {"", "", C_BUILTIN};
- static struct filedescr fd_package = {"", "", PKG_DIRECTORY};
- char name[MAXPATHLEN+1];
-#if defined(PYOS_OS2)
- size_t saved_len;
- size_t saved_namelen;
- char *saved_buf = NULL;
-#endif
- if (p_loader != NULL)
- *p_loader = NULL;
-
- if (strlen(subname) > MAXPATHLEN) {
- PyErr_SetString(PyExc_OverflowError,
- "module name is too long");
- return NULL;
- }
- strcpy(name, subname);
-
- /* sys.meta_path import hook */
- if (p_loader != NULL) {
- PyObject *meta_path;
-
- meta_path = PySys_GetObject("meta_path");
- if (meta_path == NULL || !PyList_Check(meta_path)) {
- PyErr_SetString(PyExc_ImportError,
- "sys.meta_path must be a list of "
- "import hooks");
- return NULL;
- }
- Py_INCREF(meta_path); /* zap guard */
- npath = PyList_Size(meta_path);
- for (i = 0; i < npath; i++) {
- PyObject *loader;
- PyObject *hook = PyList_GetItem(meta_path, i);
- loader = PyObject_CallMethod(hook, "find_module",
- "sO", fullname,
- path != NULL ?
- path : Py_None);
- if (loader == NULL) {
- Py_DECREF(meta_path);
- return NULL; /* true error */
- }
- if (loader != Py_None) {
- /* a loader was found */
- *p_loader = loader;
- Py_DECREF(meta_path);
- return &importhookdescr;
- }
- Py_DECREF(loader);
- }
- Py_DECREF(meta_path);
- }
-
- if (path != NULL && PyString_Check(path)) {
- /* The only type of submodule allowed inside a "frozen"
- package are other frozen modules or packages. */
- if (PyString_Size(path) + 1 + strlen(name) >= (size_t)buflen) {
- PyErr_SetString(PyExc_ImportError,
- "full frozen module name too long");
- return NULL;
- }
- strcpy(buf, PyString_AsString(path));
- strcat(buf, ".");
- strcat(buf, name);
- strcpy(name, buf);
- if (find_frozen(name) != NULL) {
- strcpy(buf, name);
- return &fd_frozen;
- }
- PyErr_Format(PyExc_ImportError,
- "No frozen submodule named %.200s", name);
- return NULL;
- }
- if (path == NULL) {
- if (is_builtin(name)) {
- strcpy(buf, name);
- return &fd_builtin;
- }
- if ((find_frozen(name)) != NULL) {
- strcpy(buf, name);
- return &fd_frozen;
- }
-
-#ifdef MS_COREDLL
- fp = PyWin_FindRegisteredModule(name, &fdp, buf, buflen);
- if (fp != NULL) {
- *p_fp = fp;
- return fdp;
- }
-#endif
- path = PySys_GetObject("path");
- }
- if (path == NULL || !PyList_Check(path)) {
- PyErr_SetString(PyExc_ImportError,
- "sys.path must be a list of directory names");
- return NULL;
- }
-
- path_hooks = PySys_GetObject("path_hooks");
- if (path_hooks == NULL || !PyList_Check(path_hooks)) {
- PyErr_SetString(PyExc_ImportError,
- "sys.path_hooks must be a list of "
- "import hooks");
- return NULL;
- }
- path_importer_cache = PySys_GetObject("path_importer_cache");
- if (path_importer_cache == NULL ||
- !PyDict_Check(path_importer_cache)) {
- PyErr_SetString(PyExc_ImportError,
- "sys.path_importer_cache must be a dict");
- return NULL;
- }
-
- npath = PyList_Size(path);
- namelen = strlen(name);
- for (i = 0; i < npath; i++) {
- PyObject *copy = NULL;
- PyObject *v = PyList_GetItem(path, i);
- if (!v)
- return NULL;
-#ifdef Py_USING_UNICODE
- if (PyUnicode_Check(v)) {
- copy = PyUnicode_Encode(PyUnicode_AS_UNICODE(v),
- PyUnicode_GET_SIZE(v), Py_FileSystemDefaultEncoding, NULL);
- if (copy == NULL)
- return NULL;
- v = copy;
- }
- else
-#endif
- if (!PyString_Check(v))
- continue;
- len = PyString_GET_SIZE(v);
- if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen) {
- Py_XDECREF(copy);
- continue; /* Too long */
- }
- strcpy(buf, PyString_AS_STRING(v));
- if (strlen(buf) != len) {
- Py_XDECREF(copy);
- continue; /* v contains '\0' */
- }
-
- /* sys.path_hooks import hook */
- if (p_loader != NULL) {
- PyObject *importer;
-
- importer = get_path_importer(path_importer_cache,
- path_hooks, v);
- if (importer == NULL) {
- Py_XDECREF(copy);
- return NULL;
- }
- /* Note: importer is a borrowed reference */
- if (importer != Py_None) {
- PyObject *loader;
- loader = PyObject_CallMethod(importer,
- "find_module",
- "s", fullname);
- Py_XDECREF(copy);
- if (loader == NULL)
- return NULL; /* error */
- if (loader != Py_None) {
- /* a loader was found */
- *p_loader = loader;
- return &importhookdescr;
- }
- Py_DECREF(loader);
- continue;
- }
- }
- /* no hook was found, use builtin import */
-
- if (len > 0 && buf[len-1] != SEP
-#ifdef ALTSEP
- && buf[len-1] != ALTSEP
-#endif
- )
- buf[len++] = SEP;
- strcpy(buf+len, name);
- len += namelen;
-
- /* Check for package import (buf holds a directory name,
- and there's an __init__ module in that directory */
-#ifdef HAVE_STAT
- if (stat(buf, &statbuf) == 0 && /* it exists */
- S_ISDIR(statbuf.st_mode) && /* it's a directory */
- case_ok(buf, len, namelen, name)) { /* case matches */
- if (find_init_module(buf)) { /* and has __init__.py */
- Py_XDECREF(copy);
- return &fd_package;
- }
- else {
- char warnstr[MAXPATHLEN+80];
- sprintf(warnstr, "Not importing directory "
- "'%.*s': missing __init__.py",
- MAXPATHLEN, buf);
- if (PyErr_Warn(PyExc_ImportWarning,
- warnstr)) {
- Py_XDECREF(copy);
- return NULL;
- }
- }
- }
-#else
- /* XXX How are you going to test for directories? */
-#ifdef RISCOS
- if (isdir(buf) &&
- case_ok(buf, len, namelen, name)) {
- if (find_init_module(buf)) {
- Py_XDECREF(copy);
- return &fd_package;
- }
- else {
- char warnstr[MAXPATHLEN+80];
- sprintf(warnstr, "Not importing directory "
- "'%.*s': missing __init__.py",
- MAXPATHLEN, buf);
- if (PyErr_Warn(PyExc_ImportWarning,
- warnstr)) {
- Py_XDECREF(copy);
- return NULL;
- }
- }
-#endif
-#endif
-#if defined(PYOS_OS2)
- /* take a snapshot of the module spec for restoration
- * after the 8 character DLL hackery
- */
- saved_buf = strdup(buf);
- saved_len = len;
- saved_namelen = namelen;
-#endif /* PYOS_OS2 */
- for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
-#if defined(PYOS_OS2)
- /* OS/2 limits DLLs to 8 character names (w/o
- extension)
- * so if the name is longer than that and its a
- * dynamically loaded module we're going to try,
- * truncate the name before trying
- */
- if (strlen(subname) > 8) {
- /* is this an attempt to load a C extension? */
- const struct filedescr *scan;
- scan = _PyImport_DynLoadFiletab;
- while (scan->suffix != NULL) {
- if (!strcmp(scan->suffix, fdp->suffix))
- break;
- else
- scan++;
- }
- if (scan->suffix != NULL) {
- /* yes, so truncate the name */
- namelen = 8;
- len -= strlen(subname) - namelen;
- buf[len] = '\0';
- }
- }
-#endif /* PYOS_OS2 */
- strcpy(buf+len, fdp->suffix);
- if (Py_VerboseFlag > 1)
- PySys_WriteStderr("# trying %s\n", buf);
- filemode = fdp->mode;
- if (filemode[0] == 'U')
- filemode = "r" PY_STDIOTEXTMODE;
- fp = fopen(buf, filemode);
- if (fp != NULL) {
- if (case_ok(buf, len, namelen, name))
- break;
- else { /* continue search */
- fclose(fp);
- fp = NULL;
- }
- }
-#if defined(PYOS_OS2)
- /* restore the saved snapshot */
- strcpy(buf, saved_buf);
- len = saved_len;
- namelen = saved_namelen;
-#endif
- }
-#if defined(PYOS_OS2)
- /* don't need/want the module name snapshot anymore */
- if (saved_buf)
- {
- free(saved_buf);
- saved_buf = NULL;
- }
-#endif
- Py_XDECREF(copy);
- if (fp != NULL)
- break;
- }
- if (fp == NULL) {
- PyErr_Format(PyExc_ImportError,
- "No module named %.200s", name);
- return NULL;
- }
- *p_fp = fp;
- return fdp;
-}
-
-/* Helpers for main.c
- * Find the source file corresponding to a named module
- */
-struct filedescr *
-_PyImport_FindModule(const char *name, PyObject *path, char *buf,
- size_t buflen, FILE **p_fp, PyObject **p_loader)
-{
- return find_module((char *) name, (char *) name, path,
- buf, buflen, p_fp, p_loader);
-}
-
-PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr * fd)
-{
- return fd->type == PY_SOURCE || fd->type == PY_COMPILED;
-}
-
-/* case_ok(char* buf, Py_ssize_t len, Py_ssize_t namelen, char* name)
- * The arguments here are tricky, best shown by example:
- * /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
- * ^ ^ ^ ^
- * |--------------------- buf ---------------------|
- * |------------------- len ------------------|
- * |------ name -------|
- * |----- namelen -----|
- * buf is the full path, but len only counts up to (& exclusive of) the
- * extension. name is the module name, also exclusive of extension.
- *
- * We've already done a successful stat() or fopen() on buf, so know that
- * there's some match, possibly case-insensitive.
- *
- * case_ok() is to return 1 if there's a case-sensitive match for
- * name, else 0. case_ok() is also to return 1 if envar PYTHONCASEOK
- * exists.
- *
- * case_ok() is used to implement case-sensitive import semantics even
- * on platforms with case-insensitive filesystems. It's trivial to implement
- * for case-sensitive filesystems. It's pretty much a cross-platform
- * nightmare for systems with case-insensitive filesystems.
- */
-
-/* First we may need a pile of platform-specific header files; the sequence
- * of #if's here should match the sequence in the body of case_ok().
- */
-#if defined(MS_WINDOWS)
-#include <windows.h>
-
-#elif defined(DJGPP)
-#include <dir.h>
-
-#elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H)
-#include <sys/types.h>
-#include <dirent.h>
-
-#elif defined(PYOS_OS2)
-#define INCL_DOS
-#define INCL_DOSERRORS
-#define INCL_NOPMAPI
-#include <os2.h>
-
-#elif defined(RISCOS)
-#include "oslib/osfscontrol.h"
-#endif
-
-static int
-case_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, char *name)
-{
-/* Pick a platform-specific implementation; the sequence of #if's here should
- * match the sequence just above.
- */
-
-/* MS_WINDOWS */
-#if defined(MS_WINDOWS)
- WIN32_FIND_DATA data;
- HANDLE h;
-
- if (Py_GETENV("PYTHONCASEOK") != NULL)
- return 1;
-
- h = FindFirstFile(buf, &data);
- if (h == INVALID_HANDLE_VALUE) {
- PyErr_Format(PyExc_NameError,
- "Can't find file for module %.100s\n(filename %.300s)",
- name, buf);
- return 0;
- }
- FindClose(h);
- return strncmp(data.cFileName, name, namelen) == 0;
-
-/* DJGPP */
-#elif defined(DJGPP)
- struct ffblk ffblk;
- int done;
-
- if (Py_GETENV("PYTHONCASEOK") != NULL)
- return 1;
-
- done = findfirst(buf, &ffblk, FA_ARCH|FA_RDONLY|FA_HIDDEN|FA_DIREC);
- if (done) {
- PyErr_Format(PyExc_NameError,
- "Can't find file for module %.100s\n(filename %.300s)",
- name, buf);
- return 0;
- }
- return strncmp(ffblk.ff_name, name, namelen) == 0;
-
-/* new-fangled macintosh (macosx) or Cygwin */
-#elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H)
- DIR *dirp;
- struct dirent *dp;
- char dirname[MAXPATHLEN + 1];
- const int dirlen = len - namelen - 1; /* don't want trailing SEP */
-
- if (Py_GETENV("PYTHONCASEOK") != NULL)
- return 1;
-
- /* Copy the dir component into dirname; substitute "." if empty */
- if (dirlen <= 0) {
- dirname[0] = '.';
- dirname[1] = '\0';
- }
- else {
- assert(dirlen <= MAXPATHLEN);
- memcpy(dirname, buf, dirlen);
- dirname[dirlen] = '\0';
- }
- /* Open the directory and search the entries for an exact match. */
- dirp = opendir(dirname);
- if (dirp) {
- char *nameWithExt = buf + len - namelen;
- while ((dp = readdir(dirp)) != NULL) {
- const int thislen =
-#ifdef _DIRENT_HAVE_D_NAMELEN
- dp->d_namlen;
-#else
- strlen(dp->d_name);
-#endif
- if (thislen >= namelen &&
- strcmp(dp->d_name, nameWithExt) == 0) {
- (void)closedir(dirp);
- return 1; /* Found */
- }
- }
- (void)closedir(dirp);
- }
- return 0 ; /* Not found */
-
-/* RISC OS */
-#elif defined(RISCOS)
- char canon[MAXPATHLEN+1]; /* buffer for the canonical form of the path */
- char buf2[MAXPATHLEN+2];
- char *nameWithExt = buf+len-namelen;
- int canonlen;
- os_error *e;
-
- if (Py_GETENV("PYTHONCASEOK") != NULL)
- return 1;
-
- /* workaround:
- append wildcard, otherwise case of filename wouldn't be touched */
- strcpy(buf2, buf);
- strcat(buf2, "*");
-
- e = xosfscontrol_canonicalise_path(buf2,canon,0,0,MAXPATHLEN+1,&canonlen);
- canonlen = MAXPATHLEN+1-canonlen;
- if (e || canonlen<=0 || canonlen>(MAXPATHLEN+1) )
- return 0;
- if (strcmp(nameWithExt, canon+canonlen-strlen(nameWithExt))==0)
- return 1; /* match */
-
- return 0;
-
-/* OS/2 */
-#elif defined(PYOS_OS2)
- HDIR hdir = 1;
- ULONG srchcnt = 1;
- FILEFINDBUF3 ffbuf;
- APIRET rc;
-
- if (getenv("PYTHONCASEOK") != NULL)
- return 1;
-
- rc = DosFindFirst(buf,
- &hdir,
- FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
- &ffbuf, sizeof(ffbuf),
- &srchcnt,
- FIL_STANDARD);
- if (rc != NO_ERROR)
- return 0;
- return strncmp(ffbuf.achName, name, namelen) == 0;
-
-/* assuming it's a case-sensitive filesystem, so there's nothing to do! */
-#else
- return 1;
-
-#endif
-}
-
-
-#ifdef HAVE_STAT
-/* Helper to look for __init__.py or __init__.py[co] in potential package */
-static int
-find_init_module(char *buf)
-{
- const size_t save_len = strlen(buf);
- size_t i = save_len;
- char *pname; /* pointer to start of __init__ */
- struct stat statbuf;
-
-/* For calling case_ok(buf, len, namelen, name):
- * /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
- * ^ ^ ^ ^
- * |--------------------- buf ---------------------|
- * |------------------- len ------------------|
- * |------ name -------|
- * |----- namelen -----|
- */
- if (save_len + 13 >= MAXPATHLEN)
- return 0;
- buf[i++] = SEP;
- pname = buf + i;
- strcpy(pname, "__init__.py");
- if (stat(buf, &statbuf) == 0) {
- if (case_ok(buf,
- save_len + 9, /* len("/__init__") */
- 8, /* len("__init__") */
- pname)) {
- buf[save_len] = '\0';
- return 1;
- }
- }
- i += strlen(pname);
- strcpy(buf+i, Py_OptimizeFlag ? "o" : "c");
- if (stat(buf, &statbuf) == 0) {
- if (case_ok(buf,
- save_len + 9, /* len("/__init__") */
- 8, /* len("__init__") */
- pname)) {
- buf[save_len] = '\0';
- return 1;
- }
- }
- buf[save_len] = '\0';
- return 0;
-}
-
-#else
-
-#ifdef RISCOS
-static int
-find_init_module(buf)
- char *buf;
-{
- int save_len = strlen(buf);
- int i = save_len;
-
- if (save_len + 13 >= MAXPATHLEN)
- return 0;
- buf[i++] = SEP;
- strcpy(buf+i, "__init__/py");
- if (isfile(buf)) {
- buf[save_len] = '\0';
- return 1;
- }
-
- if (Py_OptimizeFlag)
- strcpy(buf+i, "o");
- else
- strcpy(buf+i, "c");
- if (isfile(buf)) {
- buf[save_len] = '\0';
- return 1;
- }
- buf[save_len] = '\0';
- return 0;
-}
-#endif /*RISCOS*/
-
-#endif /* HAVE_STAT */
-
-
-static int init_builtin(char *); /* Forward */
-
-/* Load an external module using the default search path and return
- its module object WITH INCREMENTED REFERENCE COUNT */
-
-static PyObject *
-load_module(char *name, FILE *fp, char *buf, int type, PyObject *loader)
-{
- PyObject *modules;
- PyObject *m;
- int err;
-
- /* First check that there's an open file (if we need one) */
- switch (type) {
- case PY_SOURCE:
- case PY_COMPILED:
- if (fp == NULL) {
- PyErr_Format(PyExc_ValueError,
- "file object required for import (type code %d)",
- type);
- return NULL;
- }
- }
-
- switch (type) {
-
- case PY_SOURCE:
- m = load_source_module(name, buf, fp);
- break;
-
- case PY_COMPILED:
- m = load_compiled_module(name, buf, fp);
- break;
-
-#ifdef HAVE_DYNAMIC_LOADING
- case C_EXTENSION:
- m = _PyImport_LoadDynamicModule(name, buf, fp);
- break;
-#endif
-
- case PKG_DIRECTORY:
- m = load_package(name, buf);
- break;
-
- case C_BUILTIN:
- case PY_FROZEN:
- if (buf != NULL && buf[0] != '\0')
- name = buf;
- if (type == C_BUILTIN)
- err = init_builtin(name);
- else
- err = PyImport_ImportFrozenModule(name);
- if (err < 0)
- return NULL;
- if (err == 0) {
- PyErr_Format(PyExc_ImportError,
- "Purported %s module %.200s not found",
- type == C_BUILTIN ?
- "builtin" : "frozen",
- name);
- return NULL;
- }
- modules = PyImport_GetModuleDict();
- m = PyDict_GetItemString(modules, name);
- if (m == NULL) {
- PyErr_Format(
- PyExc_ImportError,
- "%s module %.200s not properly initialized",
- type == C_BUILTIN ?
- "builtin" : "frozen",
- name);
- return NULL;
- }
- Py_INCREF(m);
- break;
-
- case IMP_HOOK: {
- if (loader == NULL) {
- PyErr_SetString(PyExc_ImportError,
- "import hook without loader");
- return NULL;
- }
- m = PyObject_CallMethod(loader, "load_module", "s", name);
- break;
- }
-
- default:
- PyErr_Format(PyExc_ImportError,
- "Don't know how to import %.200s (type code %d)",
- name, type);
- m = NULL;
-
- }
-
- return m;
-}
-
-
-/* Initialize a built-in module.
- Return 1 for succes, 0 if the module is not found, and -1 with
- an exception set if the initialization failed. */
-
-static int
-init_builtin(char *name)
-{
- struct _inittab *p;
-
- if (_PyImport_FindExtension(name, name) != NULL)
- return 1;
-
- for (p = PyImport_Inittab; p->name != NULL; p++) {
- if (strcmp(name, p->name) == 0) {
- if (p->initfunc == NULL) {
- PyErr_Format(PyExc_ImportError,
- "Cannot re-init internal module %.200s",
- name);
- return -1;
- }
- if (Py_VerboseFlag)
- PySys_WriteStderr("import %s # builtin\n", name);
- (*p->initfunc)();
- if (PyErr_Occurred())
- return -1;
- if (_PyImport_FixupExtension(name, name) == NULL)
- return -1;
- return 1;
- }
- }
- return 0;
-}
-
-
-/* Frozen modules */
-
-static struct _frozen *
-find_frozen(char *name)
-{
- struct _frozen *p;
-
- for (p = PyImport_FrozenModules; ; p++) {
- if (p->name == NULL)
- return NULL;
- if (strcmp(p->name, name) == 0)
- break;
- }
- return p;
-}
-
-static PyObject *
-get_frozen_object(char *name)
-{
- struct _frozen *p = find_frozen(name);
- int size;
-
- if (p == NULL) {
- PyErr_Format(PyExc_ImportError,
- "No such frozen object named %.200s",
- name);
- return NULL;
- }
- if (p->code == NULL) {
- PyErr_Format(PyExc_ImportError,
- "Excluded frozen object named %.200s",
- name);
- return NULL;
- }
- size = p->size;
- if (size < 0)
- size = -size;
- return PyMarshal_ReadObjectFromString((char *)p->code, size);
-}
-
-/* Initialize a frozen module.
- Return 1 for succes, 0 if the module is not found, and -1 with
- an exception set if the initialization failed.
- This function is also used from frozenmain.c */
-
-int
-PyImport_ImportFrozenModule(char *name)
-{
- struct _frozen *p = find_frozen(name);
- PyObject *co;
- PyObject *m;
- int ispackage;
- int size;
-
- if (p == NULL)
- return 0;
- if (p->code == NULL) {
- PyErr_Format(PyExc_ImportError,
- "Excluded frozen object named %.200s",
- name);
- return -1;
- }
- size = p->size;
- ispackage = (size < 0);
- if (ispackage)
- size = -size;
- if (Py_VerboseFlag)
- PySys_WriteStderr("import %s # frozen%s\n",
- name, ispackage ? " package" : "");
- co = PyMarshal_ReadObjectFromString((char *)p->code, size);
- if (co == NULL)
- return -1;
- if (!PyCode_Check(co)) {
- PyErr_Format(PyExc_TypeError,
- "frozen object %.200s is not a code object",
- name);
- goto err_return;
- }
- if (ispackage) {
- /* Set __path__ to the package name */
- PyObject *d, *s;
- int err;
- m = PyImport_AddModule(name);
- if (m == NULL)
- goto err_return;
- d = PyModule_GetDict(m);
- s = PyString_InternFromString(name);
- if (s == NULL)
- goto err_return;
- err = PyDict_SetItemString(d, "__path__", s);
- Py_DECREF(s);
- if (err != 0)
- goto err_return;
- }
- m = PyImport_ExecCodeModuleEx(name, co, "<frozen>");
- if (m == NULL)
- goto err_return;
- Py_DECREF(co);
- Py_DECREF(m);
- return 1;
-err_return:
- Py_DECREF(co);
- return -1;
-}
-
-
-/* Import a module, either built-in, frozen, or external, and return
- its module object WITH INCREMENTED REFERENCE COUNT */
-
-PyObject *
-PyImport_ImportModule(const char *name)
-{
- PyObject *pname;
- PyObject *result;
-
- pname = PyString_FromString(name);
- if (pname == NULL)
- return NULL;
- result = PyImport_Import(pname);
- Py_DECREF(pname);
- return result;
-}
-
-/* Forward declarations for helper routines */
-static PyObject *get_parent(PyObject *globals, char *buf,
- Py_ssize_t *p_buflen, int level);
-static PyObject *load_next(PyObject *mod, PyObject *altmod,
- char **p_name, char *buf, Py_ssize_t *p_buflen);
-static int mark_miss(char *name);
-static int ensure_fromlist(PyObject *mod, PyObject *fromlist,
- char *buf, Py_ssize_t buflen, int recursive);
-static PyObject * import_submodule(PyObject *mod, char *name, char *fullname);
-
-/* The Magnum Opus of dotted-name import :-) */
-
-static PyObject *
-import_module_level(char *name, PyObject *globals, PyObject *locals,
- PyObject *fromlist, int level)
-{
- char buf[MAXPATHLEN+1];
- Py_ssize_t buflen = 0;
- PyObject *parent, *head, *next, *tail;
-
- parent = get_parent(globals, buf, &buflen, level);
- if (parent == NULL)
- return NULL;
-
- head = load_next(parent, Py_None, &name, buf, &buflen);
- if (head == NULL)
- return NULL;
-
- tail = head;
- Py_INCREF(tail);
- while (name) {
- next = load_next(tail, tail, &name, buf, &buflen);
- Py_DECREF(tail);
- if (next == NULL) {
- Py_DECREF(head);
- return NULL;
- }
- tail = next;
- }
- if (tail == Py_None) {
- /* If tail is Py_None, both get_parent and load_next found
- an empty module name: someone called __import__("") or
- doctored faulty bytecode */
- Py_DECREF(tail);
- Py_DECREF(head);
- PyErr_SetString(PyExc_ValueError,
- "Empty module name");
- return NULL;
- }
-
- if (fromlist != NULL) {
- if (fromlist == Py_None || !PyObject_IsTrue(fromlist))
- fromlist = NULL;
- }
-
- if (fromlist == NULL) {
- Py_DECREF(tail);
- return head;
- }
-
- Py_DECREF(head);
- if (!ensure_fromlist(tail, fromlist, buf, buflen, 0)) {
- Py_DECREF(tail);
- return NULL;
- }
-
- return tail;
-}
-
-/* For DLL compatibility */
-#undef PyImport_ImportModuleEx
-PyObject *
-PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals,
- PyObject *fromlist)
-{
- PyObject *result;
- lock_import();
- result = import_module_level(name, globals, locals, fromlist, -1);
- if (unlock_import() < 0) {
- Py_XDECREF(result);
- PyErr_SetString(PyExc_RuntimeError,
- "not holding the import lock");
- return NULL;
- }
- return result;
-}
-#define PyImport_ImportModuleEx(n, g, l, f) \
- PyImport_ImportModuleLevel(n, g, l, f, -1);
-
-PyObject *
-PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
- PyObject *fromlist, int level)
-{
- PyObject *result;
- lock_import();
- result = import_module_level(name, globals, locals, fromlist, level);
- if (unlock_import() < 0) {
- Py_XDECREF(result);
- PyErr_SetString(PyExc_RuntimeError,
- "not holding the import lock");
- return NULL;
- }
- return result;
-}
-
-/* Return the package that an import is being performed in. If globals comes
- from the module foo.bar.bat (not itself a package), this returns the
- sys.modules entry for foo.bar. If globals is from a package's __init__.py,
- the package's entry in sys.modules is returned, as a borrowed reference.
-
- The *name* of the returned package is returned in buf, with the length of
- the name in *p_buflen.
-
- If globals doesn't come from a package or a module in a package, or a
- corresponding entry is not found in sys.modules, Py_None is returned.
-*/
-static PyObject *
-get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
-{
- static PyObject *namestr = NULL;
- static PyObject *pathstr = NULL;
- PyObject *modname, *modpath, *modules, *parent;
-
- if (globals == NULL || !PyDict_Check(globals) || !level)
- return Py_None;
-
- if (namestr == NULL) {
- namestr = PyString_InternFromString("__name__");
- if (namestr == NULL)
- return NULL;
- }
- if (pathstr == NULL) {
- pathstr = PyString_InternFromString("__path__");
- if (pathstr == NULL)
- return NULL;
- }
-
- *buf = '\0';
- *p_buflen = 0;
- modname = PyDict_GetItem(globals, namestr);
- if (modname == NULL || !PyString_Check(modname))
- return Py_None;
-
- modpath = PyDict_GetItem(globals, pathstr);
- if (modpath != NULL) {
- Py_ssize_t len = PyString_GET_SIZE(modname);
- if (len > MAXPATHLEN) {
- PyErr_SetString(PyExc_ValueError,
- "Module name too long");
- return NULL;
- }
- strcpy(buf, PyString_AS_STRING(modname));
- }
- else {
- char *start = PyString_AS_STRING(modname);
- char *lastdot = strrchr(start, '.');
- size_t len;
- if (lastdot == NULL && level > 0) {
- PyErr_SetString(PyExc_ValueError,
- "Attempted relative import in non-package");
- return NULL;
- }
- if (lastdot == NULL)
- return Py_None;
- len = lastdot - start;
- if (len >= MAXPATHLEN) {
- PyErr_SetString(PyExc_ValueError,
- "Module name too long");
- return NULL;
- }
- strncpy(buf, start, len);
- buf[len] = '\0';
- }
-
- while (--level > 0) {
- char *dot = strrchr(buf, '.');
- if (dot == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "Attempted relative import beyond "
- "toplevel package");
- return NULL;
- }
- *dot = '\0';
- }
- *p_buflen = strlen(buf);
-
- modules = PyImport_GetModuleDict();
- parent = PyDict_GetItemString(modules, buf);
- if (parent == NULL)
- PyErr_Format(PyExc_SystemError,
- "Parent module '%.200s' not loaded", buf);
- return parent;
- /* We expect, but can't guarantee, if parent != None, that:
- - parent.__name__ == buf
- - parent.__dict__ is globals
- If this is violated... Who cares? */
-}
-
-/* altmod is either None or same as mod */
-static PyObject *
-load_next(PyObject *mod, PyObject *altmod, char **p_name, char *buf,
- Py_ssize_t *p_buflen)
-{
- char *name = *p_name;
- char *dot = strchr(name, '.');
- size_t len;
- char *p;
- PyObject *result;
-
- if (strlen(name) == 0) {
- /* completely empty module name should only happen in
- 'from . import' (or '__import__("")')*/
- Py_INCREF(mod);
- *p_name = NULL;
- return mod;
- }
-
- if (dot == NULL) {
- *p_name = NULL;
- len = strlen(name);
- }
- else {
- *p_name = dot+1;
- len = dot-name;
- }
- if (len == 0) {
- PyErr_SetString(PyExc_ValueError,
- "Empty module name");
- return NULL;
- }
-
- p = buf + *p_buflen;
- if (p != buf)
- *p++ = '.';
- if (p+len-buf >= MAXPATHLEN) {
- PyErr_SetString(PyExc_ValueError,
- "Module name too long");
- return NULL;
- }
- strncpy(p, name, len);
- p[len] = '\0';
- *p_buflen = p+len-buf;
-
- result = import_submodule(mod, p, buf);
- if (result == Py_None && altmod != mod) {
- Py_DECREF(result);
- /* Here, altmod must be None and mod must not be None */
- result = import_submodule(altmod, p, p);
- if (result != NULL && result != Py_None) {
- if (mark_miss(buf) != 0) {
- Py_DECREF(result);
- return NULL;
- }
- strncpy(buf, name, len);
- buf[len] = '\0';
- *p_buflen = len;
- }
- }
- if (result == NULL)
- return NULL;
-
- if (result == Py_None) {
- Py_DECREF(result);
- PyErr_Format(PyExc_ImportError,
- "No module named %.200s", name);
- return NULL;
- }
-
- return result;
-}
-
-static int
-mark_miss(char *name)
-{
- PyObject *modules = PyImport_GetModuleDict();
- return PyDict_SetItemString(modules, name, Py_None);
-}
-
-static int
-ensure_fromlist(PyObject *mod, PyObject *fromlist, char *buf, Py_ssize_t buflen,
- int recursive)
-{
- int i;
-
- if (!PyObject_HasAttrString(mod, "__path__"))
- return 1;
-
- for (i = 0; ; i++) {
- PyObject *item = PySequence_GetItem(fromlist, i);
- int hasit;
- if (item == NULL) {
- if (PyErr_ExceptionMatches(PyExc_IndexError)) {
- PyErr_Clear();
- return 1;
- }
- return 0;
- }
- if (!PyString_Check(item)) {
- PyErr_SetString(PyExc_TypeError,
- "Item in ``from list'' not a string");
- Py_DECREF(item);
- return 0;
- }
- if (PyString_AS_STRING(item)[0] == '*') {
- PyObject *all;
- Py_DECREF(item);
- /* See if the package defines __all__ */
- if (recursive)
- continue; /* Avoid endless recursion */
- all = PyObject_GetAttrString(mod, "__all__");
- if (all == NULL)
- PyErr_Clear();
- else {
- int ret = ensure_fromlist(mod, all, buf, buflen, 1);
- Py_DECREF(all);
- if (!ret)
- return 0;
- }
- continue;
- }
- hasit = PyObject_HasAttr(mod, item);
- if (!hasit) {
- char *subname = PyString_AS_STRING(item);
- PyObject *submod;
- char *p;
- if (buflen + strlen(subname) >= MAXPATHLEN) {
- PyErr_SetString(PyExc_ValueError,
- "Module name too long");
- Py_DECREF(item);
- return 0;
- }
- p = buf + buflen;
- *p++ = '.';
- strcpy(p, subname);
- submod = import_submodule(mod, subname, buf);
- Py_XDECREF(submod);
- if (submod == NULL) {
- Py_DECREF(item);
- return 0;
- }
- }
- Py_DECREF(item);
- }
-
- /* NOTREACHED */
-}
-
-static int
-add_submodule(PyObject *mod, PyObject *submod, char *fullname, char *subname,
- PyObject *modules)
-{
- if (mod == Py_None)
- return 1;
- /* Irrespective of the success of this load, make a
- reference to it in the parent package module. A copy gets
- saved in the modules dictionary under the full name, so get a
- reference from there, if need be. (The exception is when the
- load failed with a SyntaxError -- then there's no trace in
- sys.modules. In that case, of course, do nothing extra.) */
- if (submod == NULL) {
- submod = PyDict_GetItemString(modules, fullname);
- if (submod == NULL)
- return 1;
- }
- if (PyModule_Check(mod)) {
- /* We can't use setattr here since it can give a
- * spurious warning if the submodule name shadows a
- * builtin name */
- PyObject *dict = PyModule_GetDict(mod);
- if (!dict)
- return 0;
- if (PyDict_SetItemString(dict, subname, submod) < 0)
- return 0;
- }
- else {
- if (PyObject_SetAttrString(mod, subname, submod) < 0)
- return 0;
- }
- return 1;
-}
-
-static PyObject *
-import_submodule(PyObject *mod, char *subname, char *fullname)
-{
- PyObject *modules = PyImport_GetModuleDict();
- PyObject *m = NULL;
-
- /* Require:
- if mod == None: subname == fullname
- else: mod.__name__ + "." + subname == fullname
- */
-
- if ((m = PyDict_GetItemString(modules, fullname)) != NULL) {
- Py_INCREF(m);
- }
- else {
- PyObject *path, *loader = NULL;
- char buf[MAXPATHLEN+1];
- struct filedescr *fdp;
- FILE *fp = NULL;
-
- if (mod == Py_None)
- path = NULL;
- else {
- path = PyObject_GetAttrString(mod, "__path__");
- if (path == NULL) {
- PyErr_Clear();
- Py_INCREF(Py_None);
- return Py_None;
- }
- }
-
- buf[0] = '\0';
- fdp = find_module(fullname, subname, path, buf, MAXPATHLEN+1,
- &fp, &loader);
- Py_XDECREF(path);
- if (fdp == NULL) {
- if (!PyErr_ExceptionMatches(PyExc_ImportError))
- return NULL;
- PyErr_Clear();
- Py_INCREF(Py_None);
- return Py_None;
- }
- m = load_module(fullname, fp, buf, fdp->type, loader);
- Py_XDECREF(loader);
- if (fp)
- fclose(fp);
- if (!add_submodule(mod, m, fullname, subname, modules)) {
- Py_XDECREF(m);
- m = NULL;
- }
- }
-
- return m;
-}
-
-
-/* Re-import a module of any kind and return its module object, WITH
- INCREMENTED REFERENCE COUNT */
-
-PyObject *
-PyImport_ReloadModule(PyObject *m)
-{
- PyInterpreterState *interp = PyThreadState_Get()->interp;
- PyObject *modules_reloading = interp->modules_reloading;
- PyObject *modules = PyImport_GetModuleDict();
- PyObject *path = NULL, *loader = NULL, *existing_m = NULL;
- char *name, *subname;
- char buf[MAXPATHLEN+1];
- struct filedescr *fdp;
- FILE *fp = NULL;
- PyObject *newm;
-
- if (modules_reloading == NULL) {
- Py_FatalError("PyImport_ReloadModule: "
- "no modules_reloading dictionary!");
- return NULL;
- }
-
- if (m == NULL || !PyModule_Check(m)) {
- PyErr_SetString(PyExc_TypeError,
- "reload() argument must be module");
- return NULL;
- }
- name = PyModule_GetName(m);
- if (name == NULL)
- return NULL;
- if (m != PyDict_GetItemString(modules, name)) {
- PyErr_Format(PyExc_ImportError,
- "reload(): module %.200s not in sys.modules",
- name);
- return NULL;
- }
- if ((existing_m = PyDict_GetItemString(modules_reloading, name)) != NULL) {
- /* Due to a recursive reload, this module is already being reloaded. */
- Py_INCREF(existing_m);
- return existing_m;
- }
- PyDict_SetItemString(modules_reloading, name, m);
-
- subname = strrchr(name, '.');
- if (subname == NULL)
- subname = name;
- else {
- PyObject *parentname, *parent;
- parentname = PyString_FromStringAndSize(name, (subname-name));
- if (parentname == NULL) {
- imp_modules_reloading_clear();
- return NULL;
- }
- parent = PyDict_GetItem(modules, parentname);
- if (parent == NULL) {
- PyErr_Format(PyExc_ImportError,
- "reload(): parent %.200s not in sys.modules",
- PyString_AS_STRING(parentname));
- Py_DECREF(parentname);
- imp_modules_reloading_clear();
- return NULL;
- }
- Py_DECREF(parentname);
- subname++;
- path = PyObject_GetAttrString(parent, "__path__");
- if (path == NULL)
- PyErr_Clear();
- }
- buf[0] = '\0';
- fdp = find_module(name, subname, path, buf, MAXPATHLEN+1, &fp, &loader);
- Py_XDECREF(path);
-
- if (fdp == NULL) {
- Py_XDECREF(loader);
- imp_modules_reloading_clear();
- return NULL;
- }
-
- newm = load_module(name, fp, buf, fdp->type, loader);
- Py_XDECREF(loader);
-
- if (fp)
- fclose(fp);
- if (newm == NULL) {
- /* load_module probably removed name from modules because of
- * the error. Put back the original module object. We're
- * going to return NULL in this case regardless of whether
- * replacing name succeeds, so the return value is ignored.
- */
- PyDict_SetItemString(modules, name, m);
- }
- imp_modules_reloading_clear();
- return newm;
-}
-
-
-/* Higher-level import emulator which emulates the "import" statement
- more accurately -- it invokes the __import__() function from the
- builtins of the current globals. This means that the import is
- done using whatever import hooks are installed in the current
- environment, e.g. by "rexec".
- A dummy list ["__doc__"] is passed as the 4th argument so that
- e.g. PyImport_Import(PyString_FromString("win32com.client.gencache"))
- will return <module "gencache"> instead of <module "win32com">. */
-
-PyObject *
-PyImport_Import(PyObject *module_name)
-{
- static PyObject *silly_list = NULL;
- static PyObject *builtins_str = NULL;
- static PyObject *import_str = NULL;
- PyObject *globals = NULL;
- PyObject *import = NULL;
- PyObject *builtins = NULL;
- PyObject *r = NULL;
-
- /* Initialize constant string objects */
- if (silly_list == NULL) {
- import_str = PyString_InternFromString("__import__");
- if (import_str == NULL)
- return NULL;
- builtins_str = PyString_InternFromString("__builtins__");
- if (builtins_str == NULL)
- return NULL;
- silly_list = Py_BuildValue("[s]", "__doc__");
- if (silly_list == NULL)
- return NULL;
- }
-
- /* Get the builtins from current globals */
- globals = PyEval_GetGlobals();
- if (globals != NULL) {
- Py_INCREF(globals);
- builtins = PyObject_GetItem(globals, builtins_str);
- if (builtins == NULL)
- goto err;
- }
- else {
- /* No globals -- use standard builtins, and fake globals */
- PyErr_Clear();
-
- builtins = PyImport_ImportModuleLevel("__builtin__",
- NULL, NULL, NULL, 0);
- if (builtins == NULL)
- return NULL;
- globals = Py_BuildValue("{OO}", builtins_str, builtins);
- if (globals == NULL)
- goto err;
- }
-
- /* Get the __import__ function from the builtins */
- if (PyDict_Check(builtins)) {
- import = PyObject_GetItem(builtins, import_str);
- if (import == NULL)
- PyErr_SetObject(PyExc_KeyError, import_str);
- }
- else
- import = PyObject_GetAttr(builtins, import_str);
- if (import == NULL)
- goto err;
-
- /* Call the _import__ function with the proper argument list */
- r = PyObject_CallFunctionObjArgs(import, module_name, globals,
- globals, silly_list, NULL);
-
- err:
- Py_XDECREF(globals);
- Py_XDECREF(builtins);
- Py_XDECREF(import);
-
- return r;
-}
-
-
-/* Module 'imp' provides Python access to the primitives used for
- importing modules.
-*/
-
-static PyObject *
-imp_get_magic(PyObject *self, PyObject *noargs)
-{
- char buf[4];
-
- buf[0] = (char) ((pyc_magic >> 0) & 0xff);
- buf[1] = (char) ((pyc_magic >> 8) & 0xff);
- buf[2] = (char) ((pyc_magic >> 16) & 0xff);
- buf[3] = (char) ((pyc_magic >> 24) & 0xff);
-
- return PyString_FromStringAndSize(buf, 4);
-}
-
-static PyObject *
-imp_get_suffixes(PyObject *self, PyObject *noargs)
-{
- PyObject *list;
- struct filedescr *fdp;
-
- list = PyList_New(0);
- if (list == NULL)
- return NULL;
- for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
- PyObject *item = Py_BuildValue("ssi",
- fdp->suffix, fdp->mode, fdp->type);
- if (item == NULL) {
- Py_DECREF(list);
- return NULL;
- }
- if (PyList_Append(list, item) < 0) {
- Py_DECREF(list);
- Py_DECREF(item);
- return NULL;
- }
- Py_DECREF(item);
- }
- return list;
-}
-
-static PyObject *
-call_find_module(char *name, PyObject *path)
-{
- extern int fclose(FILE *);
- PyObject *fob, *ret;
- struct filedescr *fdp;
- char pathname[MAXPATHLEN+1];
- FILE *fp = NULL;
-
- pathname[0] = '\0';
- if (path == Py_None)
- path = NULL;
- fdp = find_module(NULL, name, path, pathname, MAXPATHLEN+1, &fp, NULL);
- if (fdp == NULL)
- return NULL;
- if (fp != NULL) {
- fob = PyFile_FromFile(fp, pathname, fdp->mode, fclose);
- if (fob == NULL) {
- fclose(fp);
- return NULL;
- }
- }
- else {
- fob = Py_None;
- Py_INCREF(fob);
- }
- ret = Py_BuildValue("Os(ssi)",
- fob, pathname, fdp->suffix, fdp->mode, fdp->type);
- Py_DECREF(fob);
- return ret;
-}
-
-static PyObject *
-imp_find_module(PyObject *self, PyObject *args)
-{
- char *name;
- PyObject *path = NULL;
- if (!PyArg_ParseTuple(args, "s|O:find_module", &name, &path))
- return NULL;
- return call_find_module(name, path);
-}
-
-static PyObject *
-imp_init_builtin(PyObject *self, PyObject *args)
-{
- char *name;
- int ret;
- PyObject *m;
- if (!PyArg_ParseTuple(args, "s:init_builtin", &name))
- return NULL;
- ret = init_builtin(name);
- if (ret < 0)
- return NULL;
- if (ret == 0) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- m = PyImport_AddModule(name);
- Py_XINCREF(m);
- return m;
-}
-
-static PyObject *
-imp_init_frozen(PyObject *self, PyObject *args)
-{
- char *name;
- int ret;
- PyObject *m;
- if (!PyArg_ParseTuple(args, "s:init_frozen", &name))
- return NULL;
- ret = PyImport_ImportFrozenModule(name);
- if (ret < 0)
- return NULL;
- if (ret == 0) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- m = PyImport_AddModule(name);
- Py_XINCREF(m);
- return m;
-}
-
-static PyObject *
-imp_get_frozen_object(PyObject *self, PyObject *args)
-{
- char *name;
-
- if (!PyArg_ParseTuple(args, "s:get_frozen_object", &name))
- return NULL;
- return get_frozen_object(name);
-}
-
-static PyObject *
-imp_is_builtin(PyObject *self, PyObject *args)
-{
- char *name;
- if (!PyArg_ParseTuple(args, "s:is_builtin", &name))
- return NULL;
- return PyInt_FromLong(is_builtin(name));
-}
-
-static PyObject *
-imp_is_frozen(PyObject *self, PyObject *args)
-{
- char *name;
- struct _frozen *p;
- if (!PyArg_ParseTuple(args, "s:is_frozen", &name))
- return NULL;
- p = find_frozen(name);
- return PyBool_FromLong((long) (p == NULL ? 0 : p->size));
-}
-
-static FILE *
-get_file(char *pathname, PyObject *fob, char *mode)
-{
- FILE *fp;
- if (fob == NULL) {
- if (mode[0] == 'U')
- mode = "r" PY_STDIOTEXTMODE;
- fp = fopen(pathname, mode);
- if (fp == NULL)
- PyErr_SetFromErrno(PyExc_IOError);
- }
- else {
- fp = PyFile_AsFile(fob);
- if (fp == NULL)
- PyErr_SetString(PyExc_ValueError,
- "bad/closed file object");
- }
- return fp;
-}
-
-static PyObject *
-imp_load_compiled(PyObject *self, PyObject *args)
-{
- char *name;
- char *pathname;
- PyObject *fob = NULL;
- PyObject *m;
- FILE *fp;
- if (!PyArg_ParseTuple(args, "ss|O!:load_compiled", &name, &pathname,
- &PyFile_Type, &fob))
- return NULL;
- fp = get_file(pathname, fob, "rb");
- if (fp == NULL)
- return NULL;
- m = load_compiled_module(name, pathname, fp);
- if (fob == NULL)
- fclose(fp);
- return m;
-}
-
-#ifdef HAVE_DYNAMIC_LOADING
-
-static PyObject *
-imp_load_dynamic(PyObject *self, PyObject *args)
-{
- char *name;
- char *pathname;
- PyObject *fob = NULL;
- PyObject *m;
- FILE *fp = NULL;
- if (!PyArg_ParseTuple(args, "ss|O!:load_dynamic", &name, &pathname,
- &PyFile_Type, &fob))
- return NULL;
- if (fob) {
- fp = get_file(pathname, fob, "r");
- if (fp == NULL)
- return NULL;
- }
- m = _PyImport_LoadDynamicModule(name, pathname, fp);
- return m;
-}
-
-#endif /* HAVE_DYNAMIC_LOADING */
-
-static PyObject *
-imp_load_source(PyObject *self, PyObject *args)
-{
- char *name;
- char *pathname;
- PyObject *fob = NULL;
- PyObject *m;
- FILE *fp;
- if (!PyArg_ParseTuple(args, "ss|O!:load_source", &name, &pathname,
- &PyFile_Type, &fob))
- return NULL;
- fp = get_file(pathname, fob, "r");
- if (fp == NULL)
- return NULL;
- m = load_source_module(name, pathname, fp);
- if (fob == NULL)
- fclose(fp);
- return m;
-}
-
-static PyObject *
-imp_load_module(PyObject *self, PyObject *args)
-{
- char *name;
- PyObject *fob;
- char *pathname;
- char *suffix; /* Unused */
- char *mode;
- int type;
- FILE *fp;
-
- if (!PyArg_ParseTuple(args, "sOs(ssi):load_module",
- &name, &fob, &pathname,
- &suffix, &mode, &type))
- return NULL;
- if (*mode) {
- /* Mode must start with 'r' or 'U' and must not contain '+'.
- Implicit in this test is the assumption that the mode
- may contain other modifiers like 'b' or 't'. */
-
- if (!(*mode == 'r' || *mode == 'U') || strchr(mode, '+')) {
- PyErr_Format(PyExc_ValueError,
- "invalid file open mode %.200s", mode);
- return NULL;
- }
- }
- if (fob == Py_None)
- fp = NULL;
- else {
- if (!PyFile_Check(fob)) {
- PyErr_SetString(PyExc_ValueError,
- "load_module arg#2 should be a file or None");
- return NULL;
- }
- fp = get_file(pathname, fob, mode);
- if (fp == NULL)
- return NULL;
- }
- return load_module(name, fp, pathname, type, NULL);
-}
-
-static PyObject *
-imp_load_package(PyObject *self, PyObject *args)
-{
- char *name;
- char *pathname;
- if (!PyArg_ParseTuple(args, "ss:load_package", &name, &pathname))
- return NULL;
- return load_package(name, pathname);
-}
-
-static PyObject *
-imp_new_module(PyObject *self, PyObject *args)
-{
- char *name;
- if (!PyArg_ParseTuple(args, "s:new_module", &name))
- return NULL;
- return PyModule_New(name);
-}
-
-/* Doc strings */
-
-PyDoc_STRVAR(doc_imp,
-"This module provides the components needed to build your own\n\
-__import__ function. Undocumented functions are obsolete.");
-
-PyDoc_STRVAR(doc_find_module,
-"find_module(name, [path]) -> (file, filename, (suffix, mode, type))\n\
-Search for a module. If path is omitted or None, search for a\n\
-built-in, frozen or special module and continue search in sys.path.\n\
-The module name cannot contain '.'; to search for a submodule of a\n\
-package, pass the submodule name and the package's __path__.");
-
-PyDoc_STRVAR(doc_load_module,
-"load_module(name, file, filename, (suffix, mode, type)) -> module\n\
-Load a module, given information returned by find_module().\n\
-The module name must include the full package name, if any.");
-
-PyDoc_STRVAR(doc_get_magic,
-"get_magic() -> string\n\
-Return the magic number for .pyc or .pyo files.");
-
-PyDoc_STRVAR(doc_get_suffixes,
-"get_suffixes() -> [(suffix, mode, type), ...]\n\
-Return a list of (suffix, mode, type) tuples describing the files\n\
-that find_module() looks for.");
-
-PyDoc_STRVAR(doc_new_module,
-"new_module(name) -> module\n\
-Create a new module. Do not enter it in sys.modules.\n\
-The module name must include the full package name, if any.");
-
-PyDoc_STRVAR(doc_lock_held,
-"lock_held() -> boolean\n\
-Return True if the import lock is currently held, else False.\n\
-On platforms without threads, return False.");
-
-PyDoc_STRVAR(doc_acquire_lock,
-"acquire_lock() -> None\n\
-Acquires the interpreter's import lock for the current thread.\n\
-This lock should be used by import hooks to ensure thread-safety\n\
-when importing modules.\n\
-On platforms without threads, this function does nothing.");
-
-PyDoc_STRVAR(doc_release_lock,
-"release_lock() -> None\n\
-Release the interpreter's import lock.\n\
-On platforms without threads, this function does nothing.");
-
-static PyMethodDef imp_methods[] = {
- {"find_module", imp_find_module, METH_VARARGS, doc_find_module},
- {"get_magic", imp_get_magic, METH_NOARGS, doc_get_magic},
- {"get_suffixes", imp_get_suffixes, METH_NOARGS, doc_get_suffixes},
- {"load_module", imp_load_module, METH_VARARGS, doc_load_module},
- {"new_module", imp_new_module, METH_VARARGS, doc_new_module},
- {"lock_held", imp_lock_held, METH_NOARGS, doc_lock_held},
- {"acquire_lock", imp_acquire_lock, METH_NOARGS, doc_acquire_lock},
- {"release_lock", imp_release_lock, METH_NOARGS, doc_release_lock},
- /* The rest are obsolete */
- {"get_frozen_object", imp_get_frozen_object, METH_VARARGS},
- {"init_builtin", imp_init_builtin, METH_VARARGS},
- {"init_frozen", imp_init_frozen, METH_VARARGS},
- {"is_builtin", imp_is_builtin, METH_VARARGS},
- {"is_frozen", imp_is_frozen, METH_VARARGS},
- {"load_compiled", imp_load_compiled, METH_VARARGS},
-#ifdef HAVE_DYNAMIC_LOADING
- {"load_dynamic", imp_load_dynamic, METH_VARARGS},
-#endif
- {"load_package", imp_load_package, METH_VARARGS},
- {"load_source", imp_load_source, METH_VARARGS},
- {NULL, NULL} /* sentinel */
-};
-
-static int
-setint(PyObject *d, char *name, int value)
-{
- PyObject *v;
- int err;
-
- v = PyInt_FromLong((long)value);
- err = PyDict_SetItemString(d, name, v);
- Py_XDECREF(v);
- return err;
-}
-
-typedef struct {
- PyObject_HEAD
-} NullImporter;
-
-static int
-NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds)
-{
- char *path;
-
- if (!_PyArg_NoKeywords("NullImporter()", kwds))
- return -1;
-
- if (!PyArg_ParseTuple(args, "s:NullImporter",
- &path))
- return -1;
-
- if (strlen(path) == 0) {
- PyErr_SetString(PyExc_ImportError, "empty pathname");
- return -1;
- } else {
-#ifndef RISCOS
- struct stat statbuf;
- int rv;
-
- rv = stat(path, &statbuf);
- if (rv == 0) {
- /* it exists */
- if (S_ISDIR(statbuf.st_mode)) {
- /* it's a directory */
- PyErr_SetString(PyExc_ImportError,
- "existing directory");
- return -1;
- }
- }
-#else
- if (object_exists(path)) {
- /* it exists */
- if (isdir(path)) {
- /* it's a directory */
- PyErr_SetString(PyExc_ImportError,
- "existing directory");
- return -1;
- }
- }
-#endif
- }
- return 0;
-}
-
-static PyObject *
-NullImporter_find_module(NullImporter *self, PyObject *args)
-{
- Py_RETURN_NONE;
-}
-
-static PyMethodDef NullImporter_methods[] = {
- {"find_module", (PyCFunction)NullImporter_find_module, METH_VARARGS,
- "Always return None"
- },
- {NULL} /* Sentinel */
-};
-
-
-static PyTypeObject NullImporterType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "imp.NullImporter", /*tp_name*/
- sizeof(NullImporter), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- 0, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "Null importer object", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- NullImporter_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)NullImporter_init, /* tp_init */
- 0, /* tp_alloc */
- PyType_GenericNew /* tp_new */
-};
-
-
-PyMODINIT_FUNC
-initimp(void)
-{
- PyObject *m, *d;
-
- if (PyType_Ready(&NullImporterType) < 0)
- goto failure;
-
- m = Py_InitModule4("imp", imp_methods, doc_imp,
- NULL, PYTHON_API_VERSION);
- if (m == NULL)
- goto failure;
- d = PyModule_GetDict(m);
- if (d == NULL)
- goto failure;
-
- if (setint(d, "SEARCH_ERROR", SEARCH_ERROR) < 0) goto failure;
- if (setint(d, "PY_SOURCE", PY_SOURCE) < 0) goto failure;
- if (setint(d, "PY_COMPILED", PY_COMPILED) < 0) goto failure;
- if (setint(d, "C_EXTENSION", C_EXTENSION) < 0) goto failure;
- if (setint(d, "PY_RESOURCE", PY_RESOURCE) < 0) goto failure;
- if (setint(d, "PKG_DIRECTORY", PKG_DIRECTORY) < 0) goto failure;
- if (setint(d, "C_BUILTIN", C_BUILTIN) < 0) goto failure;
- if (setint(d, "PY_FROZEN", PY_FROZEN) < 0) goto failure;
- if (setint(d, "PY_CODERESOURCE", PY_CODERESOURCE) < 0) goto failure;
- if (setint(d, "IMP_HOOK", IMP_HOOK) < 0) goto failure;
-
- Py_INCREF(&NullImporterType);
- PyModule_AddObject(m, "NullImporter", (PyObject *)&NullImporterType);
- failure:
- ;
-}
-
-
-/* API for embedding applications that want to add their own entries
- to the table of built-in modules. This should normally be called
- *before* Py_Initialize(). When the table resize fails, -1 is
- returned and the existing table is unchanged.
-
- After a similar function by Just van Rossum. */
-
-int
-PyImport_ExtendInittab(struct _inittab *newtab)
-{
- static struct _inittab *our_copy = NULL;
- struct _inittab *p;
- int i, n;
-
- /* Count the number of entries in both tables */
- for (n = 0; newtab[n].name != NULL; n++)
- ;
- if (n == 0)
- return 0; /* Nothing to do */
- for (i = 0; PyImport_Inittab[i].name != NULL; i++)
- ;
-
- /* Allocate new memory for the combined table */
- p = our_copy;
- PyMem_RESIZE(p, struct _inittab, i+n+1);
- if (p == NULL)
- return -1;
-
- /* Copy the tables into the new memory */
- if (our_copy != PyImport_Inittab)
- memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab));
- PyImport_Inittab = our_copy = p;
- memcpy(p+i, newtab, (n+1) * sizeof(struct _inittab));
-
- return 0;
-}
-
-/* Shorthand to add a single entry given a name and a function */
-
-int
-PyImport_AppendInittab(char *name, void (*initfunc)(void))
-{
- struct _inittab newtab[2];
-
- memset(newtab, '\0', sizeof newtab);
-
- newtab[0].name = name;
- newtab[0].initfunc = initfunc;
-
- return PyImport_ExtendInittab(newtab);
-}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/sys/src/cmd/python/Python/importdl.c b/sys/src/cmd/python/Python/importdl.c
deleted file mode 100644
index 9c325e447..000000000
--- a/sys/src/cmd/python/Python/importdl.c
+++ /dev/null
@@ -1,78 +0,0 @@
-
-/* Support for dynamic loading of extension modules */
-
-#include "Python.h"
-
-/* ./configure sets HAVE_DYNAMIC_LOADING if dynamic loading of modules is
- supported on this platform. configure will then compile and link in one
- of the dynload_*.c files, as appropriate. We will call a function in
- those modules to get a function pointer to the module's init function.
-*/
-#ifdef HAVE_DYNAMIC_LOADING
-
-#include "importdl.h"
-
-extern dl_funcptr _PyImport_GetDynLoadFunc(const char *name,
- const char *shortname,
- const char *pathname, FILE *fp);
-
-
-
-PyObject *
-_PyImport_LoadDynamicModule(char *name, char *pathname, FILE *fp)
-{
- PyObject *m;
- char *lastdot, *shortname, *packagecontext, *oldcontext;
- dl_funcptr p;
-
- if ((m = _PyImport_FindExtension(name, pathname)) != NULL) {
- Py_INCREF(m);
- return m;
- }
- lastdot = strrchr(name, '.');
- if (lastdot == NULL) {
- packagecontext = NULL;
- shortname = name;
- }
- else {
- packagecontext = name;
- shortname = lastdot+1;
- }
-
- p = _PyImport_GetDynLoadFunc(name, shortname, pathname, fp);
- if (PyErr_Occurred())
- return NULL;
- if (p == NULL) {
- PyErr_Format(PyExc_ImportError,
- "dynamic module does not define init function (init%.200s)",
- shortname);
- return NULL;
- }
- oldcontext = _Py_PackageContext;
- _Py_PackageContext = packagecontext;
- (*p)();
- _Py_PackageContext = oldcontext;
- if (PyErr_Occurred())
- return NULL;
-
- m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
- if (m == NULL) {
- PyErr_SetString(PyExc_SystemError,
- "dynamic module not initialized properly");
- return NULL;
- }
- /* Remember the filename as the __file__ attribute */
- if (PyModule_AddStringConstant(m, "__file__", pathname) < 0)
- PyErr_Clear(); /* Not important enough to report */
-
- if (_PyImport_FixupExtension(name, pathname) == NULL)
- return NULL;
- if (Py_VerboseFlag)
- PySys_WriteStderr(
- "import %s # dynamically loaded from %s\n",
- name, pathname);
- Py_INCREF(m);
- return m;
-}
-
-#endif /* HAVE_DYNAMIC_LOADING */
diff --git a/sys/src/cmd/python/Python/importdl.h b/sys/src/cmd/python/Python/importdl.h
deleted file mode 100644
index 5a2d45c46..000000000
--- a/sys/src/cmd/python/Python/importdl.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef Py_IMPORTDL_H
-#define Py_IMPORTDL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* Definitions for dynamic loading of extension modules */
-enum filetype {
- SEARCH_ERROR,
- PY_SOURCE,
- PY_COMPILED,
- C_EXTENSION,
- PY_RESOURCE, /* Mac only */
- PKG_DIRECTORY,
- C_BUILTIN,
- PY_FROZEN,
- PY_CODERESOURCE, /* Mac only */
- IMP_HOOK
-};
-
-struct filedescr {
- char *suffix;
- char *mode;
- enum filetype type;
-};
-extern struct filedescr * _PyImport_Filetab;
-extern const struct filedescr _PyImport_DynLoadFiletab[];
-
-extern PyObject *_PyImport_LoadDynamicModule(char *name, char *pathname,
- FILE *);
-
-/* Max length of module suffix searched for -- accommodates "module.slb" */
-#define MAXSUFFIXSIZE 12
-
-#ifdef MS_WINDOWS
-#include <windows.h>
-typedef FARPROC dl_funcptr;
-#else
-#if defined(PYOS_OS2) && !defined(PYCC_GCC)
-#include <os2def.h>
-typedef int (* APIENTRY dl_funcptr)();
-#else
-typedef void (*dl_funcptr)(void);
-#endif
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* !Py_IMPORTDL_H */
diff --git a/sys/src/cmd/python/Python/mactoolboxglue.c b/sys/src/cmd/python/Python/mactoolboxglue.c
deleted file mode 100644
index 26a13083f..000000000
--- a/sys/src/cmd/python/Python/mactoolboxglue.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/***********************************************************
-Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
-The Netherlands.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the names of Stichting Mathematisch
-Centrum or CWI not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior permission.
-
-STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
-THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
-FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-******************************************************************/
-
-
-#include "Python.h"
-#include "pymactoolbox.h"
-#include <arpa/inet.h> /* for ntohl, htonl */
-
-
-/* Like strerror() but for Mac OS error numbers */
-char *
-PyMac_StrError(int err)
-{
- static char buf[256];
- PyObject *m;
- PyObject *rv;
-
- m = PyImport_ImportModule("MacOS");
- if (!m) {
- if (Py_VerboseFlag)
- PyErr_Print();
- PyErr_Clear();
- rv = NULL;
- }
- else {
- rv = PyObject_CallMethod(m, "GetErrorString", "i", err);
- if (!rv)
- PyErr_Clear();
- }
- if (!rv) {
- buf[0] = '\0';
- }
- else {
- char *input = PyString_AsString(rv);
- if (!input) {
- PyErr_Clear();
- buf[0] = '\0';
- } else {
- strncpy(buf, input, sizeof(buf) - 1);
- buf[sizeof(buf) - 1] = '\0';
- }
- Py_DECREF(rv);
- }
- Py_XDECREF(m);
- return buf;
-}
-
-/* Exception object shared by all Mac specific modules for Mac OS errors */
-PyObject *PyMac_OSErrException;
-
-/* Initialize and return PyMac_OSErrException */
-PyObject *
-PyMac_GetOSErrException(void)
-{
- if (PyMac_OSErrException == NULL)
- PyMac_OSErrException = PyErr_NewException("MacOS.Error", NULL, NULL);
- return PyMac_OSErrException;
-}
-
-/* Set a MAC-specific error from errno, and return NULL; return None if no error */
-PyObject *
-PyErr_Mac(PyObject *eobj, int err)
-{
- char *msg;
- PyObject *v;
-
- if (err == 0 && !PyErr_Occurred()) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- if (err == -1 && PyErr_Occurred())
- return NULL;
- msg = PyMac_StrError(err);
- v = Py_BuildValue("(is)", err, msg);
- PyErr_SetObject(eobj, v);
- Py_DECREF(v);
- return NULL;
-}
-
-/* Call PyErr_Mac with PyMac_OSErrException */
-PyObject *
-PyMac_Error(OSErr err)
-{
- return PyErr_Mac(PyMac_GetOSErrException(), err);
-}
-
-
-OSErr
-PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
-{
- PyObject *fs, *exc;
- PyObject *rv = NULL;
- char *input;
- OSErr err = noErr;
-
- *path = '\0';
-
- fs = PyMac_BuildFSSpec(fss);
- if (!fs)
- goto error;
-
- rv = PyObject_CallMethod(fs, "as_pathname", "");
- if (!rv)
- goto error;
-
- input = PyString_AsString(rv);
- if (!input)
- goto error;
-
- strncpy(path, input, len - 1);
- path[len - 1] = '\0';
-
- Py_XDECREF(rv);
- Py_XDECREF(fs);
- return err;
-
- error:
- exc = PyErr_Occurred();
- if (exc && PyErr_GivenExceptionMatches(exc,
- PyMac_GetOSErrException())) {
- PyObject *args = PyObject_GetAttrString(exc, "args");
- if (args) {
- char *ignore;
- PyArg_ParseTuple(args, "is", &err, &ignore);
- Py_XDECREF(args);
- }
- }
- if (err == noErr)
- err = -1;
- PyErr_Clear();
- Py_XDECREF(rv);
- Py_XDECREF(fs);
- return err;
-}
-
-/* Convert a 4-char string object argument to an OSType value */
-int
-PyMac_GetOSType(PyObject *v, OSType *pr)
-{
- uint32_t tmp;
- if (!PyString_Check(v) || PyString_Size(v) != 4) {
- PyErr_SetString(PyExc_TypeError,
- "OSType arg must be string of 4 chars");
- return 0;
- }
- memcpy((char *)&tmp, PyString_AsString(v), 4);
- *pr = (OSType)ntohl(tmp);
- return 1;
-}
-
-/* Convert an OSType value to a 4-char string object */
-PyObject *
-PyMac_BuildOSType(OSType t)
-{
- uint32_t tmp = htonl((uint32_t)t);
- return PyString_FromStringAndSize((char *)&tmp, 4);
-}
-
-/* Convert an NumVersion value to a 4-element tuple */
-PyObject *
-PyMac_BuildNumVersion(NumVersion t)
-{
- return Py_BuildValue("(hhhh)", t.majorRev, t.minorAndBugRev, t.stage, t.nonRelRev);
-}
-
-
-/* Convert a Python string object to a Str255 */
-int
-PyMac_GetStr255(PyObject *v, Str255 pbuf)
-{
- int len;
- if (!PyString_Check(v) || (len = PyString_Size(v)) > 255) {
- PyErr_SetString(PyExc_TypeError,
- "Str255 arg must be string of at most 255 chars");
- return 0;
- }
- pbuf[0] = len;
- memcpy((char *)(pbuf+1), PyString_AsString(v), len);
- return 1;
-}
-
-/* Convert a Str255 to a Python string object */
-PyObject *
-PyMac_BuildStr255(Str255 s)
-{
- if ( s == NULL ) {
- PyErr_SetString(PyExc_SystemError, "Str255 pointer is NULL");
- return NULL;
- }
- return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
-}
-
-PyObject *
-PyMac_BuildOptStr255(Str255 s)
-{
- if ( s == NULL ) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
-}
-
-
-
-/* Convert a Python object to a Rect.
- The object must be a (left, top, right, bottom) tuple.
- (This differs from the order in the struct but is consistent with
- the arguments to SetRect(), and also with STDWIN). */
-int
-PyMac_GetRect(PyObject *v, Rect *r)
-{
- return PyArg_Parse(v, "(hhhh)", &r->left, &r->top, &r->right, &r->bottom);
-}
-
-/* Convert a Rect to a Python object */
-PyObject *
-PyMac_BuildRect(Rect *r)
-{
- return Py_BuildValue("(hhhh)", r->left, r->top, r->right, r->bottom);
-}
-
-
-/* Convert a Python object to a Point.
- The object must be a (h, v) tuple.
- (This differs from the order in the struct but is consistent with
- the arguments to SetPoint(), and also with STDWIN). */
-int
-PyMac_GetPoint(PyObject *v, Point *p)
-{
- return PyArg_Parse(v, "(hh)", &p->h, &p->v);
-}
-
-/* Convert a Point to a Python object */
-PyObject *
-PyMac_BuildPoint(Point p)
-{
- return Py_BuildValue("(hh)", p.h, p.v);
-}
-
-
-/* Convert a Python object to an EventRecord.
- The object must be a (what, message, when, (v, h), modifiers) tuple. */
-int
-PyMac_GetEventRecord(PyObject *v, EventRecord *e)
-{
- return PyArg_Parse(v, "(Hkk(hh)H)",
- &e->what,
- &e->message,
- &e->when,
- &e->where.h,
- &e->where.v,
- &e->modifiers);
-}
-
-/* Convert a Rect to an EventRecord object */
-PyObject *
-PyMac_BuildEventRecord(EventRecord *e)
-{
- return Py_BuildValue("(hll(hh)h)",
- e->what,
- e->message,
- e->when,
- e->where.h,
- e->where.v,
- e->modifiers);
-}
-
-/* Convert Python object to Fixed */
-int
-PyMac_GetFixed(PyObject *v, Fixed *f)
-{
- double d;
-
- if( !PyArg_Parse(v, "d", &d))
- return 0;
- *f = (Fixed)(d * 0x10000);
- return 1;
-}
-
-/* Convert a Fixed to a Python object */
-PyObject *
-PyMac_BuildFixed(Fixed f)
-{
- double d;
-
- d = f;
- d = d / 0x10000;
- return Py_BuildValue("d", d);
-}
-
-/* Convert wide to/from Python int or (hi, lo) tuple. XXXX Should use Python longs */
-int
-PyMac_Getwide(PyObject *v, wide *rv)
-{
- if (PyInt_Check(v)) {
- rv->hi = 0;
- rv->lo = PyInt_AsLong(v);
- if( rv->lo & 0x80000000 )
- rv->hi = -1;
- return 1;
- }
- return PyArg_Parse(v, "(kk)", &rv->hi, &rv->lo);
-}
-
-
-PyObject *
-PyMac_Buildwide(wide *w)
-{
- if ( (w->hi == 0 && (w->lo & 0x80000000) == 0) ||
- (w->hi == -1 && (w->lo & 0x80000000) ) )
- return PyInt_FromLong(w->lo);
- return Py_BuildValue("(ll)", w->hi, w->lo);
-}
-
-#ifdef USE_TOOLBOX_OBJECT_GLUE
-/*
-** Glue together the toolbox objects.
-**
-** Because toolbox modules interdepend on each other, they use each others
-** object types, on MacOSX/MachO this leads to the situation that they
-** cannot be dynamically loaded (or they would all have to be lumped into
-** a single .so, but this would be bad for extensibility).
-**
-** This file defines wrappers for all the _New and _Convert functions,
-** which are the Py_BuildValue and PyArg_ParseTuple helpers. The wrappers
-** check an indirection function pointer, and if it isn't filled in yet
-** they import the appropriate module, whose init routine should fill in
-** the pointer.
-*/
-
-#define GLUE_NEW(object, routinename, module) \
-PyObject *(*PyMacGluePtr_##routinename)(object); \
-\
-PyObject *routinename(object cobj) { \
- if (!PyMacGluePtr_##routinename) { \
- if (!PyImport_ImportModule(module)) return NULL; \
- if (!PyMacGluePtr_##routinename) { \
- PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
- return NULL; \
- } \
- } \
- return (*PyMacGluePtr_##routinename)(cobj); \
-}
-
-#define GLUE_CONVERT(object, routinename, module) \
-int (*PyMacGluePtr_##routinename)(PyObject *, object *); \
-\
-int routinename(PyObject *pyobj, object *cobj) { \
- if (!PyMacGluePtr_##routinename) { \
- if (!PyImport_ImportModule(module)) return 0; \
- if (!PyMacGluePtr_##routinename) { \
- PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
- return 0; \
- } \
- } \
- return (*PyMacGluePtr_##routinename)(pyobj, cobj); \
-}
-
-GLUE_NEW(FSSpec *, PyMac_BuildFSSpec, "Carbon.File")
-GLUE_CONVERT(FSSpec, PyMac_GetFSSpec, "Carbon.File")
-GLUE_NEW(FSRef *, PyMac_BuildFSRef, "Carbon.File")
-GLUE_CONVERT(FSRef, PyMac_GetFSRef, "Carbon.File")
-
-GLUE_NEW(AppleEvent *, AEDesc_New, "Carbon.AE") /* XXXX Why by address? */
-GLUE_NEW(AppleEvent *, AEDesc_NewBorrowed, "Carbon.AE")
-GLUE_CONVERT(AppleEvent, AEDesc_Convert, "Carbon.AE")
-
-GLUE_NEW(Component, CmpObj_New, "Carbon.Cm")
-GLUE_CONVERT(Component, CmpObj_Convert, "Carbon.Cm")
-GLUE_NEW(ComponentInstance, CmpInstObj_New, "Carbon.Cm")
-GLUE_CONVERT(ComponentInstance, CmpInstObj_Convert, "Carbon.Cm")
-
-GLUE_NEW(ControlHandle, CtlObj_New, "Carbon.Ctl")
-GLUE_CONVERT(ControlHandle, CtlObj_Convert, "Carbon.Ctl")
-
-GLUE_NEW(DialogPtr, DlgObj_New, "Carbon.Dlg")
-GLUE_CONVERT(DialogPtr, DlgObj_Convert, "Carbon.Dlg")
-GLUE_NEW(DialogPtr, DlgObj_WhichDialog, "Carbon.Dlg")
-
-GLUE_NEW(DragReference, DragObj_New, "Carbon.Drag")
-GLUE_CONVERT(DragReference, DragObj_Convert, "Carbon.Drag")
-
-GLUE_NEW(ListHandle, ListObj_New, "Carbon.List")
-GLUE_CONVERT(ListHandle, ListObj_Convert, "Carbon.List")
-
-GLUE_NEW(MenuHandle, MenuObj_New, "Carbon.Menu")
-GLUE_CONVERT(MenuHandle, MenuObj_Convert, "Carbon.Menu")
-
-GLUE_NEW(GrafPtr, GrafObj_New, "Carbon.Qd")
-GLUE_CONVERT(GrafPtr, GrafObj_Convert, "Carbon.Qd")
-GLUE_NEW(BitMapPtr, BMObj_New, "Carbon.Qd")
-GLUE_CONVERT(BitMapPtr, BMObj_Convert, "Carbon.Qd")
-GLUE_NEW(RGBColor *, QdRGB_New, "Carbon.Qd") /* XXXX Why? */
-GLUE_CONVERT(RGBColor, QdRGB_Convert, "Carbon.Qd")
-
-GLUE_NEW(GWorldPtr, GWorldObj_New, "Carbon.Qdoffs")
-GLUE_CONVERT(GWorldPtr, GWorldObj_Convert, "Carbon.Qdoffs")
-
-GLUE_NEW(Track, TrackObj_New, "Carbon.Qt")
-GLUE_CONVERT(Track, TrackObj_Convert, "Carbon.Qt")
-GLUE_NEW(Movie, MovieObj_New, "Carbon.Qt")
-GLUE_CONVERT(Movie, MovieObj_Convert, "Carbon.Qt")
-GLUE_NEW(MovieController, MovieCtlObj_New, "Carbon.Qt")
-GLUE_CONVERT(MovieController, MovieCtlObj_Convert, "Carbon.Qt")
-GLUE_NEW(TimeBase, TimeBaseObj_New, "Carbon.Qt")
-GLUE_CONVERT(TimeBase, TimeBaseObj_Convert, "Carbon.Qt")
-GLUE_NEW(UserData, UserDataObj_New, "Carbon.Qt")
-GLUE_CONVERT(UserData, UserDataObj_Convert, "Carbon.Qt")
-GLUE_NEW(Media, MediaObj_New, "Carbon.Qt")
-GLUE_CONVERT(Media, MediaObj_Convert, "Carbon.Qt")
-
-GLUE_NEW(Handle, ResObj_New, "Carbon.Res")
-GLUE_CONVERT(Handle, ResObj_Convert, "Carbon.Res")
-GLUE_NEW(Handle, OptResObj_New, "Carbon.Res")
-GLUE_CONVERT(Handle, OptResObj_Convert, "Carbon.Res")
-
-GLUE_NEW(TEHandle, TEObj_New, "Carbon.TE")
-GLUE_CONVERT(TEHandle, TEObj_Convert, "Carbon.TE")
-
-GLUE_NEW(WindowPtr, WinObj_New, "Carbon.Win")
-GLUE_CONVERT(WindowPtr, WinObj_Convert, "Carbon.Win")
-GLUE_NEW(WindowPtr, WinObj_WhichWindow, "Carbon.Win")
-
-GLUE_CONVERT(CFTypeRef, CFObj_Convert, "Carbon.CF")
-GLUE_NEW(CFTypeRef, CFObj_New, "Carbon.CF")
-
-GLUE_CONVERT(CFTypeRef, CFTypeRefObj_Convert, "Carbon.CF")
-GLUE_NEW(CFTypeRef, CFTypeRefObj_New, "Carbon.CF")
-
-GLUE_CONVERT(CFStringRef, CFStringRefObj_Convert, "Carbon.CF")
-GLUE_NEW(CFStringRef, CFStringRefObj_New, "Carbon.CF")
-GLUE_CONVERT(CFMutableStringRef, CFMutableStringRefObj_Convert, "Carbon.CF")
-GLUE_NEW(CFMutableStringRef, CFMutableStringRefObj_New, "Carbon.CF")
-
-GLUE_CONVERT(CFArrayRef, CFArrayRefObj_Convert, "Carbon.CF")
-GLUE_NEW(CFArrayRef, CFArrayRefObj_New, "Carbon.CF")
-GLUE_CONVERT(CFMutableArrayRef, CFMutableArrayRefObj_Convert, "Carbon.CF")
-GLUE_NEW(CFMutableArrayRef, CFMutableArrayRefObj_New, "Carbon.CF")
-
-GLUE_CONVERT(CFDictionaryRef, CFDictionaryRefObj_Convert, "Carbon.CF")
-GLUE_NEW(CFDictionaryRef, CFDictionaryRefObj_New, "Carbon.CF")
-GLUE_CONVERT(CFMutableDictionaryRef, CFMutableDictionaryRefObj_Convert, "Carbon.CF")
-GLUE_NEW(CFMutableDictionaryRef, CFMutableDictionaryRefObj_New, "Carbon.CF")
-
-GLUE_CONVERT(CFURLRef, CFURLRefObj_Convert, "Carbon.CF")
-GLUE_CONVERT(CFURLRef, OptionalCFURLRefObj_Convert, "Carbon.CF")
-GLUE_NEW(CFURLRef, CFURLRefObj_New, "Carbon.CF")
-
-#endif /* USE_TOOLBOX_OBJECT_GLUE */
diff --git a/sys/src/cmd/python/Python/marshal.c b/sys/src/cmd/python/Python/marshal.c
deleted file mode 100644
index 7940ce18a..000000000
--- a/sys/src/cmd/python/Python/marshal.c
+++ /dev/null
@@ -1,1155 +0,0 @@
-
-/* Write Python objects to files and read them back.
- This is intended for writing and reading compiled Python code only;
- a true persistent storage facility would be much harder, since
- it would have to take circular links and sharing into account. */
-
-#define PY_SSIZE_T_CLEAN
-
-#include "Python.h"
-#include "longintrepr.h"
-#include "code.h"
-#include "marshal.h"
-
-/* High water mark to determine when the marshalled object is dangerously deep
- * and risks coring the interpreter. When the object stack gets this deep,
- * raise an exception instead of continuing.
- */
-#define MAX_MARSHAL_STACK_DEPTH 5000
-
-#define TYPE_NULL '0'
-#define TYPE_NONE 'N'
-#define TYPE_FALSE 'F'
-#define TYPE_TRUE 'T'
-#define TYPE_STOPITER 'S'
-#define TYPE_ELLIPSIS '.'
-#define TYPE_INT 'i'
-#define TYPE_INT64 'I'
-#define TYPE_FLOAT 'f'
-#define TYPE_BINARY_FLOAT 'g'
-#define TYPE_COMPLEX 'x'
-#define TYPE_BINARY_COMPLEX 'y'
-#define TYPE_LONG 'l'
-#define TYPE_STRING 's'
-#define TYPE_INTERNED 't'
-#define TYPE_STRINGREF 'R'
-#define TYPE_TUPLE '('
-#define TYPE_LIST '['
-#define TYPE_DICT '{'
-#define TYPE_CODE 'c'
-#define TYPE_UNICODE 'u'
-#define TYPE_UNKNOWN '?'
-#define TYPE_SET '<'
-#define TYPE_FROZENSET '>'
-
-typedef struct {
- FILE *fp;
- int error;
- int depth;
- /* If fp == NULL, the following are valid: */
- PyObject *str;
- char *ptr;
- char *end;
- PyObject *strings; /* dict on marshal, list on unmarshal */
- int version;
-} WFILE;
-
-#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
- else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
- else w_more(c, p)
-
-static void
-w_more(int c, WFILE *p)
-{
- Py_ssize_t size, newsize;
- if (p->str == NULL)
- return; /* An error already occurred */
- size = PyString_Size(p->str);
- newsize = size + 1024;
- if (_PyString_Resize(&p->str, newsize) != 0) {
- p->ptr = p->end = NULL;
- }
- else {
- p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
- p->end =
- PyString_AS_STRING((PyStringObject *)p->str) + newsize;
- *p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);
- }
-}
-
-static void
-w_string(char *s, int n, WFILE *p)
-{
- if (p->fp != NULL) {
- fwrite(s, 1, n, p->fp);
- }
- else {
- while (--n >= 0) {
- w_byte(*s, p);
- s++;
- }
- }
-}
-
-static void
-w_short(int x, WFILE *p)
-{
- w_byte((char)( x & 0xff), p);
- w_byte((char)((x>> 8) & 0xff), p);
-}
-
-static void
-w_long(long x, WFILE *p)
-{
- w_byte((char)( x & 0xff), p);
- w_byte((char)((x>> 8) & 0xff), p);
- w_byte((char)((x>>16) & 0xff), p);
- w_byte((char)((x>>24) & 0xff), p);
-}
-
-#if SIZEOF_LONG > 4
-static void
-w_long64(long x, WFILE *p)
-{
- w_long(x, p);
- w_long(x>>32, p);
-}
-#endif
-
-static void
-w_object(PyObject *v, WFILE *p)
-{
- Py_ssize_t i, n;
-
- p->depth++;
-
- if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
- p->error = 2;
- }
- else if (v == NULL) {
- w_byte(TYPE_NULL, p);
- }
- else if (v == Py_None) {
- w_byte(TYPE_NONE, p);
- }
- else if (v == PyExc_StopIteration) {
- w_byte(TYPE_STOPITER, p);
- }
- else if (v == Py_Ellipsis) {
- w_byte(TYPE_ELLIPSIS, p);
- }
- else if (v == Py_False) {
- w_byte(TYPE_FALSE, p);
- }
- else if (v == Py_True) {
- w_byte(TYPE_TRUE, p);
- }
- else if (PyInt_Check(v)) {
- long x = PyInt_AS_LONG((PyIntObject *)v);
-#if SIZEOF_LONG > 4
- long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
- if (y && y != -1) {
- w_byte(TYPE_INT64, p);
- w_long64(x, p);
- }
- else
-#endif
- {
- w_byte(TYPE_INT, p);
- w_long(x, p);
- }
- }
- else if (PyLong_Check(v)) {
- PyLongObject *ob = (PyLongObject *)v;
- w_byte(TYPE_LONG, p);
- n = ob->ob_size;
- w_long((long)n, p);
- if (n < 0)
- n = -n;
- for (i = 0; i < n; i++)
- w_short(ob->ob_digit[i], p);
- }
- else if (PyFloat_Check(v)) {
- if (p->version > 1) {
- unsigned char buf[8];
- if (_PyFloat_Pack8(PyFloat_AsDouble(v),
- buf, 1) < 0) {
- p->error = 1;
- return;
- }
- w_byte(TYPE_BINARY_FLOAT, p);
- w_string((char*)buf, 8, p);
- }
- else {
- char buf[256]; /* Plenty to format any double */
- PyFloat_AsReprString(buf, (PyFloatObject *)v);
- n = strlen(buf);
- w_byte(TYPE_FLOAT, p);
- w_byte((int)n, p);
- w_string(buf, (int)n, p);
- }
- }
-#ifndef WITHOUT_COMPLEX
- else if (PyComplex_Check(v)) {
- if (p->version > 1) {
- unsigned char buf[8];
- if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
- buf, 1) < 0) {
- p->error = 1;
- return;
- }
- w_byte(TYPE_BINARY_COMPLEX, p);
- w_string((char*)buf, 8, p);
- if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v),
- buf, 1) < 0) {
- p->error = 1;
- return;
- }
- w_string((char*)buf, 8, p);
- }
- else {
- char buf[256]; /* Plenty to format any double */
- PyFloatObject *temp;
- w_byte(TYPE_COMPLEX, p);
- temp = (PyFloatObject*)PyFloat_FromDouble(
- PyComplex_RealAsDouble(v));
- if (!temp) {
- p->error = 1;
- return;
- }
- PyFloat_AsReprString(buf, temp);
- Py_DECREF(temp);
- n = strlen(buf);
- w_byte((int)n, p);
- w_string(buf, (int)n, p);
- temp = (PyFloatObject*)PyFloat_FromDouble(
- PyComplex_ImagAsDouble(v));
- if (!temp) {
- p->error = 1;
- return;
- }
- PyFloat_AsReprString(buf, temp);
- Py_DECREF(temp);
- n = strlen(buf);
- w_byte((int)n, p);
- w_string(buf, (int)n, p);
- }
- }
-#endif
- else if (PyString_Check(v)) {
- if (p->strings && PyString_CHECK_INTERNED(v)) {
- PyObject *o = PyDict_GetItem(p->strings, v);
- if (o) {
- long w = PyInt_AsLong(o);
- w_byte(TYPE_STRINGREF, p);
- w_long(w, p);
- goto exit;
- }
- else {
- o = PyInt_FromSsize_t(PyDict_Size(p->strings));
- PyDict_SetItem(p->strings, v, o);
- Py_DECREF(o);
- w_byte(TYPE_INTERNED, p);
- }
- }
- else {
- w_byte(TYPE_STRING, p);
- }
- n = PyString_GET_SIZE(v);
- if (n > INT_MAX) {
- /* huge strings are not supported */
- p->depth--;
- p->error = 1;
- return;
- }
- w_long((long)n, p);
- w_string(PyString_AS_STRING(v), (int)n, p);
- }
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(v)) {
- PyObject *utf8;
- utf8 = PyUnicode_AsUTF8String(v);
- if (utf8 == NULL) {
- p->depth--;
- p->error = 1;
- return;
- }
- w_byte(TYPE_UNICODE, p);
- n = PyString_GET_SIZE(utf8);
- if (n > INT_MAX) {
- p->depth--;
- p->error = 1;
- return;
- }
- w_long((long)n, p);
- w_string(PyString_AS_STRING(utf8), (int)n, p);
- Py_DECREF(utf8);
- }
-#endif
- else if (PyTuple_Check(v)) {
- w_byte(TYPE_TUPLE, p);
- n = PyTuple_Size(v);
- w_long((long)n, p);
- for (i = 0; i < n; i++) {
- w_object(PyTuple_GET_ITEM(v, i), p);
- }
- }
- else if (PyList_Check(v)) {
- w_byte(TYPE_LIST, p);
- n = PyList_GET_SIZE(v);
- w_long((long)n, p);
- for (i = 0; i < n; i++) {
- w_object(PyList_GET_ITEM(v, i), p);
- }
- }
- else if (PyDict_Check(v)) {
- Py_ssize_t pos;
- PyObject *key, *value;
- w_byte(TYPE_DICT, p);
- /* This one is NULL object terminated! */
- pos = 0;
- while (PyDict_Next(v, &pos, &key, &value)) {
- w_object(key, p);
- w_object(value, p);
- }
- w_object((PyObject *)NULL, p);
- }
- else if (PyAnySet_Check(v)) {
- PyObject *value, *it;
-
- if (PyObject_TypeCheck(v, &PySet_Type))
- w_byte(TYPE_SET, p);
- else
- w_byte(TYPE_FROZENSET, p);
- n = PyObject_Size(v);
- if (n == -1) {
- p->depth--;
- p->error = 1;
- return;
- }
- w_long((long)n, p);
- it = PyObject_GetIter(v);
- if (it == NULL) {
- p->depth--;
- p->error = 1;
- return;
- }
- while ((value = PyIter_Next(it)) != NULL) {
- w_object(value, p);
- Py_DECREF(value);
- }
- Py_DECREF(it);
- if (PyErr_Occurred()) {
- p->depth--;
- p->error = 1;
- return;
- }
- }
- else if (PyCode_Check(v)) {
- PyCodeObject *co = (PyCodeObject *)v;
- w_byte(TYPE_CODE, p);
- w_long(co->co_argcount, p);
- w_long(co->co_nlocals, p);
- w_long(co->co_stacksize, p);
- w_long(co->co_flags, p);
- w_object(co->co_code, p);
- w_object(co->co_consts, p);
- w_object(co->co_names, p);
- w_object(co->co_varnames, p);
- w_object(co->co_freevars, p);
- w_object(co->co_cellvars, p);
- w_object(co->co_filename, p);
- w_object(co->co_name, p);
- w_long(co->co_firstlineno, p);
- w_object(co->co_lnotab, p);
- }
- else if (PyObject_CheckReadBuffer(v)) {
- /* Write unknown buffer-style objects as a string */
- char *s;
- PyBufferProcs *pb = v->ob_type->tp_as_buffer;
- w_byte(TYPE_STRING, p);
- n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
- if (n > INT_MAX) {
- p->depth--;
- p->error = 1;
- return;
- }
- w_long((long)n, p);
- w_string(s, (int)n, p);
- }
- else {
- w_byte(TYPE_UNKNOWN, p);
- p->error = 1;
- }
- exit:
- p->depth--;
-}
-
-/* version currently has no effect for writing longs. */
-void
-PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
-{
- WFILE wf;
- wf.fp = fp;
- wf.error = 0;
- wf.depth = 0;
- wf.strings = NULL;
- wf.version = version;
- w_long(x, &wf);
-}
-
-void
-PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
-{
- WFILE wf;
- wf.fp = fp;
- wf.error = 0;
- wf.depth = 0;
- wf.strings = (version > 0) ? PyDict_New() : NULL;
- wf.version = version;
- w_object(x, &wf);
- Py_XDECREF(wf.strings);
-}
-
-typedef WFILE RFILE; /* Same struct with different invariants */
-
-#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
-
-#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
-
-static int
-r_string(char *s, int n, RFILE *p)
-{
- if (p->fp != NULL)
- /* The result fits into int because it must be <=n. */
- return (int)fread(s, 1, n, p->fp);
- if (p->end - p->ptr < n)
- n = (int)(p->end - p->ptr);
- memcpy(s, p->ptr, n);
- p->ptr += n;
- return n;
-}
-
-static int
-r_short(RFILE *p)
-{
- register short x;
- x = r_byte(p);
- x |= r_byte(p) << 8;
- /* Sign-extension, in case short greater than 16 bits */
- x |= -(x & 0x8000);
- return x;
-}
-
-static long
-r_long(RFILE *p)
-{
- register long x;
- register FILE *fp = p->fp;
- if (fp) {
- x = getc(fp);
- x |= (long)getc(fp) << 8;
- x |= (long)getc(fp) << 16;
- x |= (long)getc(fp) << 24;
- }
- else {
- x = rs_byte(p);
- x |= (long)rs_byte(p) << 8;
- x |= (long)rs_byte(p) << 16;
- x |= (long)rs_byte(p) << 24;
- }
-#if SIZEOF_LONG > 4
- /* Sign extension for 64-bit machines */
- x |= -(x & 0x80000000L);
-#endif
- return x;
-}
-
-/* r_long64 deals with the TYPE_INT64 code. On a machine with
- sizeof(long) > 4, it returns a Python int object, else a Python long
- object. Note that w_long64 writes out TYPE_INT if 32 bits is enough,
- so there's no inefficiency here in returning a PyLong on 32-bit boxes
- for everything written via TYPE_INT64 (i.e., if an int is written via
- TYPE_INT64, it *needs* more than 32 bits).
-*/
-static PyObject *
-r_long64(RFILE *p)
-{
- long lo4 = r_long(p);
- long hi4 = r_long(p);
-#if SIZEOF_LONG > 4
- long x = (hi4 << 32) | (lo4 & 0xFFFFFFFFL);
- return PyInt_FromLong(x);
-#else
- unsigned char buf[8];
- int one = 1;
- int is_little_endian = (int)*(char*)&one;
- if (is_little_endian) {
- memcpy(buf, &lo4, 4);
- memcpy(buf+4, &hi4, 4);
- }
- else {
- memcpy(buf, &hi4, 4);
- memcpy(buf+4, &lo4, 4);
- }
- return _PyLong_FromByteArray(buf, 8, is_little_endian, 1);
-#endif
-}
-
-static PyObject *
-r_object(RFILE *p)
-{
- /* NULL is a valid return value, it does not necessarily means that
- an exception is set. */
- PyObject *v, *v2, *v3;
- long i, n;
- int type = r_byte(p);
-
- switch (type) {
-
- case EOF:
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
- return NULL;
-
- case TYPE_NULL:
- return NULL;
-
- case TYPE_NONE:
- Py_INCREF(Py_None);
- return Py_None;
-
- case TYPE_STOPITER:
- Py_INCREF(PyExc_StopIteration);
- return PyExc_StopIteration;
-
- case TYPE_ELLIPSIS:
- Py_INCREF(Py_Ellipsis);
- return Py_Ellipsis;
-
- case TYPE_FALSE:
- Py_INCREF(Py_False);
- return Py_False;
-
- case TYPE_TRUE:
- Py_INCREF(Py_True);
- return Py_True;
-
- case TYPE_INT:
- return PyInt_FromLong(r_long(p));
-
- case TYPE_INT64:
- return r_long64(p);
-
- case TYPE_LONG:
- {
- int size;
- PyLongObject *ob;
- n = r_long(p);
- if (n < -INT_MAX || n > INT_MAX) {
- PyErr_SetString(PyExc_ValueError,
- "bad marshal data");
- return NULL;
- }
- size = n<0 ? -n : n;
- ob = _PyLong_New(size);
- if (ob == NULL)
- return NULL;
- ob->ob_size = n;
- for (i = 0; i < size; i++) {
- int digit = r_short(p);
- if (digit < 0) {
- Py_DECREF(ob);
- PyErr_SetString(PyExc_ValueError,
- "bad marshal data");
- return NULL;
- }
- ob->ob_digit[i] = digit;
- }
- return (PyObject *)ob;
- }
-
- case TYPE_FLOAT:
- {
- char buf[256];
- double dx;
- n = r_byte(p);
- if (n == EOF || r_string(buf, (int)n, p) != n) {
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
- return NULL;
- }
- buf[n] = '\0';
- PyFPE_START_PROTECT("atof", return 0)
- dx = PyOS_ascii_atof(buf);
- PyFPE_END_PROTECT(dx)
- return PyFloat_FromDouble(dx);
- }
-
- case TYPE_BINARY_FLOAT:
- {
- unsigned char buf[8];
- double x;
- if (r_string((char*)buf, 8, p) != 8) {
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
- return NULL;
- }
- x = _PyFloat_Unpack8(buf, 1);
- if (x == -1.0 && PyErr_Occurred()) {
- return NULL;
- }
- return PyFloat_FromDouble(x);
- }
-
-#ifndef WITHOUT_COMPLEX
- case TYPE_COMPLEX:
- {
- char buf[256];
- Py_complex c;
- n = r_byte(p);
- if (n == EOF || r_string(buf, (int)n, p) != n) {
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
- return NULL;
- }
- buf[n] = '\0';
- PyFPE_START_PROTECT("atof", return 0)
- c.real = PyOS_ascii_atof(buf);
- PyFPE_END_PROTECT(c)
- n = r_byte(p);
- if (n == EOF || r_string(buf, (int)n, p) != n) {
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
- return NULL;
- }
- buf[n] = '\0';
- PyFPE_START_PROTECT("atof", return 0)
- c.imag = PyOS_ascii_atof(buf);
- PyFPE_END_PROTECT(c)
- return PyComplex_FromCComplex(c);
- }
-
- case TYPE_BINARY_COMPLEX:
- {
- unsigned char buf[8];
- Py_complex c;
- if (r_string((char*)buf, 8, p) != 8) {
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
- return NULL;
- }
- c.real = _PyFloat_Unpack8(buf, 1);
- if (c.real == -1.0 && PyErr_Occurred()) {
- return NULL;
- }
- if (r_string((char*)buf, 8, p) != 8) {
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
- return NULL;
- }
- c.imag = _PyFloat_Unpack8(buf, 1);
- if (c.imag == -1.0 && PyErr_Occurred()) {
- return NULL;
- }
- return PyComplex_FromCComplex(c);
- }
-#endif
-
- case TYPE_INTERNED:
- case TYPE_STRING:
- n = r_long(p);
- if (n < 0 || n > INT_MAX) {
- PyErr_SetString(PyExc_ValueError, "bad marshal data");
- return NULL;
- }
- v = PyString_FromStringAndSize((char *)NULL, n);
- if (v == NULL)
- return v;
- if (r_string(PyString_AS_STRING(v), (int)n, p) != n) {
- Py_DECREF(v);
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
- return NULL;
- }
- if (type == TYPE_INTERNED) {
- PyString_InternInPlace(&v);
- PyList_Append(p->strings, v);
- }
- return v;
-
- case TYPE_STRINGREF:
- n = r_long(p);
- if (n < 0 || n >= PyList_GET_SIZE(p->strings)) {
- PyErr_SetString(PyExc_ValueError, "bad marshal data");
- return NULL;
- }
- v = PyList_GET_ITEM(p->strings, n);
- Py_INCREF(v);
- return v;
-
-#ifdef Py_USING_UNICODE
- case TYPE_UNICODE:
- {
- char *buffer;
-
- n = r_long(p);
- if (n < 0 || n > INT_MAX) {
- PyErr_SetString(PyExc_ValueError, "bad marshal data");
- return NULL;
- }
- buffer = PyMem_NEW(char, n);
- if (buffer == NULL)
- return PyErr_NoMemory();
- if (r_string(buffer, (int)n, p) != n) {
- PyMem_DEL(buffer);
- PyErr_SetString(PyExc_EOFError,
- "EOF read where object expected");
- return NULL;
- }
- v = PyUnicode_DecodeUTF8(buffer, n, NULL);
- PyMem_DEL(buffer);
- return v;
- }
-#endif
-
- case TYPE_TUPLE:
- n = r_long(p);
- if (n < 0 || n > INT_MAX) {
- PyErr_SetString(PyExc_ValueError, "bad marshal data");
- return NULL;
- }
- v = PyTuple_New((int)n);
- if (v == NULL)
- return v;
- for (i = 0; i < n; i++) {
- v2 = r_object(p);
- if ( v2 == NULL ) {
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError,
- "NULL object in marshal data");
- Py_DECREF(v);
- v = NULL;
- break;
- }
- PyTuple_SET_ITEM(v, (int)i, v2);
- }
- return v;
-
- case TYPE_LIST:
- n = r_long(p);
- if (n < 0 || n > INT_MAX) {
- PyErr_SetString(PyExc_ValueError, "bad marshal data");
- return NULL;
- }
- v = PyList_New((int)n);
- if (v == NULL)
- return v;
- for (i = 0; i < n; i++) {
- v2 = r_object(p);
- if ( v2 == NULL ) {
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError,
- "NULL object in marshal data");
- Py_DECREF(v);
- v = NULL;
- break;
- }
- PyList_SetItem(v, (int)i, v2);
- }
- return v;
-
- case TYPE_DICT:
- v = PyDict_New();
- if (v == NULL)
- return NULL;
- for (;;) {
- PyObject *key, *val;
- key = r_object(p);
- if (key == NULL)
- break;
- val = r_object(p);
- if (val != NULL)
- PyDict_SetItem(v, key, val);
- Py_DECREF(key);
- Py_XDECREF(val);
- }
- if (PyErr_Occurred()) {
- Py_DECREF(v);
- v = NULL;
- }
- return v;
-
- case TYPE_SET:
- case TYPE_FROZENSET:
- n = r_long(p);
- if (n < 0) {
- PyErr_SetString(PyExc_ValueError, "bad marshal data");
- return NULL;
- }
- v = PyTuple_New((int)n);
- if (v == NULL)
- return v;
- for (i = 0; i < n; i++) {
- v2 = r_object(p);
- if ( v2 == NULL ) {
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError,
- "NULL object in marshal data");
- Py_DECREF(v);
- v = NULL;
- break;
- }
- PyTuple_SET_ITEM(v, (int)i, v2);
- }
- if (v == NULL)
- return v;
- if (type == TYPE_SET)
- v3 = PySet_New(v);
- else
- v3 = PyFrozenSet_New(v);
- Py_DECREF(v);
- return v3;
-
- case TYPE_CODE:
- if (PyEval_GetRestricted()) {
- PyErr_SetString(PyExc_RuntimeError,
- "cannot unmarshal code objects in "
- "restricted execution mode");
- return NULL;
- }
- else {
- int argcount;
- int nlocals;
- int stacksize;
- int flags;
- PyObject *code = NULL;
- PyObject *consts = NULL;
- PyObject *names = NULL;
- PyObject *varnames = NULL;
- PyObject *freevars = NULL;
- PyObject *cellvars = NULL;
- PyObject *filename = NULL;
- PyObject *name = NULL;
- int firstlineno;
- PyObject *lnotab = NULL;
-
- v = NULL;
-
- /* XXX ignore long->int overflows for now */
- argcount = (int)r_long(p);
- nlocals = (int)r_long(p);
- stacksize = (int)r_long(p);
- flags = (int)r_long(p);
- code = r_object(p);
- if (code == NULL)
- goto code_error;
- consts = r_object(p);
- if (consts == NULL)
- goto code_error;
- names = r_object(p);
- if (names == NULL)
- goto code_error;
- varnames = r_object(p);
- if (varnames == NULL)
- goto code_error;
- freevars = r_object(p);
- if (freevars == NULL)
- goto code_error;
- cellvars = r_object(p);
- if (cellvars == NULL)
- goto code_error;
- filename = r_object(p);
- if (filename == NULL)
- goto code_error;
- name = r_object(p);
- if (name == NULL)
- goto code_error;
- firstlineno = (int)r_long(p);
- lnotab = r_object(p);
- if (lnotab == NULL)
- goto code_error;
-
- v = (PyObject *) PyCode_New(
- argcount, nlocals, stacksize, flags,
- code, consts, names, varnames,
- freevars, cellvars, filename, name,
- firstlineno, lnotab);
-
- code_error:
- Py_XDECREF(code);
- Py_XDECREF(consts);
- Py_XDECREF(names);
- Py_XDECREF(varnames);
- Py_XDECREF(freevars);
- Py_XDECREF(cellvars);
- Py_XDECREF(filename);
- Py_XDECREF(name);
- Py_XDECREF(lnotab);
-
- }
- return v;
-
- default:
- /* Bogus data got written, which isn't ideal.
- This will let you keep working and recover. */
- PyErr_SetString(PyExc_ValueError, "bad marshal data");
- return NULL;
-
- }
-}
-
-static PyObject *
-read_object(RFILE *p)
-{
- PyObject *v;
- if (PyErr_Occurred()) {
- fprintf(stderr, "XXX readobject called with exception set\n");
- return NULL;
- }
- v = r_object(p);
- if (v == NULL && !PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError, "NULL object in marshal data");
- return v;
-}
-
-int
-PyMarshal_ReadShortFromFile(FILE *fp)
-{
- RFILE rf;
- assert(fp);
- rf.fp = fp;
- rf.strings = NULL;
- rf.end = rf.ptr = NULL;
- return r_short(&rf);
-}
-
-long
-PyMarshal_ReadLongFromFile(FILE *fp)
-{
- RFILE rf;
- rf.fp = fp;
- rf.strings = NULL;
- return r_long(&rf);
-}
-
-#ifdef HAVE_FSTAT
-/* Return size of file in bytes; < 0 if unknown. */
-static off_t
-getfilesize(FILE *fp)
-{
- struct stat st;
- if (fstat(fileno(fp), &st) != 0)
- return -1;
- else
- return st.st_size;
-}
-#endif
-
-/* If we can get the size of the file up-front, and it's reasonably small,
- * read it in one gulp and delegate to ...FromString() instead. Much quicker
- * than reading a byte at a time from file; speeds .pyc imports.
- * CAUTION: since this may read the entire remainder of the file, don't
- * call it unless you know you're done with the file.
- */
-PyObject *
-PyMarshal_ReadLastObjectFromFile(FILE *fp)
-{
-/* 75% of 2.1's .pyc files can exploit SMALL_FILE_LIMIT.
- * REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc.
- */
-#define SMALL_FILE_LIMIT (1L << 14)
-#define REASONABLE_FILE_LIMIT (1L << 18)
-#ifdef HAVE_FSTAT
- off_t filesize;
-#endif
-#ifdef HAVE_FSTAT
- filesize = getfilesize(fp);
- if (filesize > 0) {
- char buf[SMALL_FILE_LIMIT];
- char* pBuf = NULL;
- if (filesize <= SMALL_FILE_LIMIT)
- pBuf = buf;
- else if (filesize <= REASONABLE_FILE_LIMIT)
- pBuf = (char *)PyMem_MALLOC((int)filesize);
- if (pBuf != NULL) {
- PyObject* v;
- size_t n;
- /* filesize must fit into an int, because it
- is smaller than REASONABLE_FILE_LIMIT */
- n = fread(pBuf, 1, (int)filesize, fp);
- v = PyMarshal_ReadObjectFromString(pBuf, n);
- if (pBuf != buf)
- PyMem_FREE(pBuf);
- return v;
- }
-
- }
-#endif
- /* We don't have fstat, or we do but the file is larger than
- * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
- */
- return PyMarshal_ReadObjectFromFile(fp);
-
-#undef SMALL_FILE_LIMIT
-#undef REASONABLE_FILE_LIMIT
-}
-
-PyObject *
-PyMarshal_ReadObjectFromFile(FILE *fp)
-{
- RFILE rf;
- PyObject *result;
- rf.fp = fp;
- rf.strings = PyList_New(0);
- result = r_object(&rf);
- Py_DECREF(rf.strings);
- return result;
-}
-
-PyObject *
-PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
-{
- RFILE rf;
- PyObject *result;
- rf.fp = NULL;
- rf.ptr = str;
- rf.end = str + len;
- rf.strings = PyList_New(0);
- result = r_object(&rf);
- Py_DECREF(rf.strings);
- return result;
-}
-
-PyObject *
-PyMarshal_WriteObjectToString(PyObject *x, int version)
-{
- WFILE wf;
- wf.fp = NULL;
- wf.str = PyString_FromStringAndSize((char *)NULL, 50);
- if (wf.str == NULL)
- return NULL;
- wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
- wf.end = wf.ptr + PyString_Size(wf.str);
- wf.error = 0;
- wf.depth = 0;
- wf.version = version;
- wf.strings = (version > 0) ? PyDict_New() : NULL;
- w_object(x, &wf);
- Py_XDECREF(wf.strings);
- if (wf.str != NULL) {
- char *base = PyString_AS_STRING((PyStringObject *)wf.str);
- if (wf.ptr - base > PY_SSIZE_T_MAX) {
- Py_DECREF(wf.str);
- PyErr_SetString(PyExc_OverflowError,
- "too much marshall data for a string");
- return NULL;
- }
- _PyString_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base));
- }
- if (wf.error) {
- Py_XDECREF(wf.str);
- PyErr_SetString(PyExc_ValueError,
- (wf.error==1)?"unmarshallable object"
- :"object too deeply nested to marshal");
- return NULL;
- }
- return wf.str;
-}
-
-/* And an interface for Python programs... */
-
-static PyObject *
-marshal_dump(PyObject *self, PyObject *args)
-{
- WFILE wf;
- PyObject *x;
- PyObject *f;
- int version = Py_MARSHAL_VERSION;
- if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
- return NULL;
- if (!PyFile_Check(f)) {
- PyErr_SetString(PyExc_TypeError,
- "marshal.dump() 2nd arg must be file");
- return NULL;
- }
- wf.fp = PyFile_AsFile(f);
- wf.str = NULL;
- wf.ptr = wf.end = NULL;
- wf.error = 0;
- wf.depth = 0;
- wf.strings = (version > 0) ? PyDict_New() : 0;
- wf.version = version;
- w_object(x, &wf);
- Py_XDECREF(wf.strings);
- if (wf.error) {
- PyErr_SetString(PyExc_ValueError,
- (wf.error==1)?"unmarshallable object"
- :"object too deeply nested to marshal");
- return NULL;
- }
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *
-marshal_load(PyObject *self, PyObject *f)
-{
- RFILE rf;
- PyObject *result;
- if (!PyFile_Check(f)) {
- PyErr_SetString(PyExc_TypeError,
- "marshal.load() arg must be file");
- return NULL;
- }
- rf.fp = PyFile_AsFile(f);
- rf.strings = PyList_New(0);
- result = read_object(&rf);
- Py_DECREF(rf.strings);
- return result;
-}
-
-static PyObject *
-marshal_dumps(PyObject *self, PyObject *args)
-{
- PyObject *x;
- int version = Py_MARSHAL_VERSION;
- if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version))
- return NULL;
- return PyMarshal_WriteObjectToString(x, version);
-}
-
-static PyObject *
-marshal_loads(PyObject *self, PyObject *args)
-{
- RFILE rf;
- char *s;
- Py_ssize_t n;
- PyObject* result;
- if (!PyArg_ParseTuple(args, "s#:loads", &s, &n))
- return NULL;
- rf.fp = NULL;
- rf.ptr = s;
- rf.end = s + n;
- rf.strings = PyList_New(0);
- result = read_object(&rf);
- Py_DECREF(rf.strings);
- return result;
-}
-
-static PyMethodDef marshal_methods[] = {
- {"dump", marshal_dump, METH_VARARGS},
- {"load", marshal_load, METH_O},
- {"dumps", marshal_dumps, METH_VARARGS},
- {"loads", marshal_loads, METH_VARARGS},
- {NULL, NULL} /* sentinel */
-};
-
-PyMODINIT_FUNC
-PyMarshal_Init(void)
-{
- PyObject *mod = Py_InitModule("marshal", marshal_methods);
- if (mod == NULL)
- return;
- PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);
-}
diff --git a/sys/src/cmd/python/Python/memmove.c b/sys/src/cmd/python/Python/memmove.c
deleted file mode 100644
index 6fb0dad93..000000000
--- a/sys/src/cmd/python/Python/memmove.c
+++ /dev/null
@@ -1,25 +0,0 @@
-
-/* A perhaps slow but I hope correct implementation of memmove */
-
-extern char *memcpy(char *, char *, int);
-
-char *
-memmove(char *dst, char *src, int n)
-{
- char *realdst = dst;
- if (n <= 0)
- return dst;
- if (src >= dst+n || dst >= src+n)
- return memcpy(dst, src, n);
- if (src > dst) {
- while (--n >= 0)
- *dst++ = *src++;
- }
- else if (src < dst) {
- src += n;
- dst += n;
- while (--n >= 0)
- *--dst = *--src;
- }
- return realdst;
-}
diff --git a/sys/src/cmd/python/Python/mkfile b/sys/src/cmd/python/Python/mkfile
deleted file mode 100644
index 24bb56e72..000000000
--- a/sys/src/cmd/python/Python/mkfile
+++ /dev/null
@@ -1,62 +0,0 @@
-</$cputype/mkfile
-APE=/sys/src/ape
-<$APE/config
-
-LIB=../libpython.a$O
-
-OFILES=\
- Python-ast.$O\
- asdl.$O\
- ast.$O\
- bltinmodule.$O\
- ceval.$O\
- codecs.$O\
- compile.$O\
- dynload_stub.$O\
- errors.$O\
-# fmod.$O\
- frozen.$O\
- frozenmain.$O\
- future.$O\
- getargs.$O\
- getcompiler.$O\
- getcopyright.$O\
- getmtime.$O\
- getopt.$O\
- getplatform.$O\
- getversion.$O\
- import.$O\
- importdl.$O\
- marshal.$O\
- modsupport.$O\
- mysnprintf.$O\
- mystrtoul.$O\
- pyarena.$O\
- pyfpe.$O\
- pystate.$O\
- pystrtod.$O\
- pythonrun.$O\
-# sigcheck.$O\
- structmember.$O\
- symtable.$O\
- sysmodule.$O\
- thread.$O\
- traceback.$O\
- graminit.$O\
-
-CLEANFILES=graminit.c graminit.h
-
-</sys/src/cmd/mksyslib
-
-CFLAGS=-c -I.. -I../Include -DT$objtype -DPy_BUILD_CORE -DNDEBUG
-
-ast.$O future.$O: ../Include/graminit.h
-
-../Include/graminit.h: graminit.h
- cp graminit.h ../Include/graminit.h
-
-graminit.c graminit.h:D: ../Grammar/Grammar ../Parser/pgen.$cputype
- ../Parser/pgen.$cputype ../Grammar/Grammar graminit.h graminit.c
-
-../Parser/pgen.$cputype:D:
- @{cd ../Parser && objtype=$cputype mk pgen.$cputype}
diff --git a/sys/src/cmd/python/Python/modsupport.c b/sys/src/cmd/python/Python/modsupport.c
deleted file mode 100644
index 1aa3df285..000000000
--- a/sys/src/cmd/python/Python/modsupport.c
+++ /dev/null
@@ -1,631 +0,0 @@
-
-/* Module support implementation */
-
-#include "Python.h"
-
-#define FLAG_SIZE_T 1
-typedef double va_double;
-
-static PyObject *va_build_value(const char *, va_list, int);
-
-/* Package context -- the full module name for package imports */
-char *_Py_PackageContext = NULL;
-
-/* Py_InitModule4() parameters:
- - name is the module name
- - methods is the list of top-level functions
- - doc is the documentation string
- - passthrough is passed as self to functions defined in the module
- - api_version is the value of PYTHON_API_VERSION at the time the
- module was compiled
-
- Return value is a borrowed reference to the module object; or NULL
- if an error occurred (in Python 1.4 and before, errors were fatal).
- Errors may still leak memory.
-*/
-
-static char api_version_warning[] =
-"Python C API version mismatch for module %.100s:\
- This Python has API version %d, module %.100s has version %d.";
-
-PyObject *
-Py_InitModule4(const char *name, PyMethodDef *methods, const char *doc,
- PyObject *passthrough, int module_api_version)
-{
- PyObject *m, *d, *v, *n;
- PyMethodDef *ml;
- if (!Py_IsInitialized())
- Py_FatalError("Interpreter not initialized (version mismatch?)");
- if (module_api_version != PYTHON_API_VERSION) {
- char message[512];
- PyOS_snprintf(message, sizeof(message),
- api_version_warning, name,
- PYTHON_API_VERSION, name,
- module_api_version);
- if (PyErr_Warn(PyExc_RuntimeWarning, message))
- return NULL;
- }
- /* Make sure name is fully qualified.
-
- This is a bit of a hack: when the shared library is loaded,
- the module name is "package.module", but the module calls
- Py_InitModule*() with just "module" for the name. The shared
- library loader squirrels away the true name of the module in
- _Py_PackageContext, and Py_InitModule*() will substitute this
- (if the name actually matches).
- */
- if (_Py_PackageContext != NULL) {
- char *p = strrchr(_Py_PackageContext, '.');
- if (p != NULL && strcmp(name, p+1) == 0) {
- name = _Py_PackageContext;
- _Py_PackageContext = NULL;
- }
- }
- if ((m = PyImport_AddModule(name)) == NULL)
- return NULL;
- d = PyModule_GetDict(m);
- if (methods != NULL) {
- n = PyString_FromString(name);
- if (n == NULL)
- return NULL;
- for (ml = methods; ml->ml_name != NULL; ml++) {
- if ((ml->ml_flags & METH_CLASS) ||
- (ml->ml_flags & METH_STATIC)) {
- PyErr_SetString(PyExc_ValueError,
- "module functions cannot set"
- " METH_CLASS or METH_STATIC");
- Py_DECREF(n);
- return NULL;
- }
- v = PyCFunction_NewEx(ml, passthrough, n);
- if (v == NULL) {
- Py_DECREF(n);
- return NULL;
- }
- if (PyDict_SetItemString(d, ml->ml_name, v) != 0) {
- Py_DECREF(v);
- Py_DECREF(n);
- return NULL;
- }
- Py_DECREF(v);
- }
- Py_DECREF(n);
- }
- if (doc != NULL) {
- v = PyString_FromString(doc);
- if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) {
- Py_XDECREF(v);
- return NULL;
- }
- Py_DECREF(v);
- }
- return m;
-}
-
-
-/* Helper for mkvalue() to scan the length of a format */
-
-static int
-countformat(const char *format, int endchar)
-{
- int count = 0;
- int level = 0;
- while (level > 0 || *format != endchar) {
- switch (*format) {
- case '\0':
- /* Premature end */
- PyErr_SetString(PyExc_SystemError,
- "unmatched paren in format");
- return -1;
- case '(':
- case '[':
- case '{':
- if (level == 0)
- count++;
- level++;
- break;
- case ')':
- case ']':
- case '}':
- level--;
- break;
- case '#':
- case '&':
- case ',':
- case ':':
- case ' ':
- case '\t':
- break;
- default:
- if (level == 0)
- count++;
- }
- format++;
- }
- return count;
-}
-
-
-/* Generic function to create a value -- the inverse of getargs() */
-/* After an original idea and first implementation by Steven Miale */
-
-static PyObject *do_mktuple(const char**, va_list *, int, int, int);
-static PyObject *do_mklist(const char**, va_list *, int, int, int);
-static PyObject *do_mkdict(const char**, va_list *, int, int, int);
-static PyObject *do_mkvalue(const char**, va_list *, int);
-
-
-static PyObject *
-do_mkdict(const char **p_format, va_list *p_va, int endchar, int n, int flags)
-{
- PyObject *d;
- int i;
- int itemfailed = 0;
- if (n < 0)
- return NULL;
- if ((d = PyDict_New()) == NULL)
- return NULL;
- /* Note that we can't bail immediately on error as this will leak
- refcounts on any 'N' arguments. */
- for (i = 0; i < n; i+= 2) {
- PyObject *k, *v;
- int err;
- k = do_mkvalue(p_format, p_va, flags);
- if (k == NULL) {
- itemfailed = 1;
- Py_INCREF(Py_None);
- k = Py_None;
- }
- v = do_mkvalue(p_format, p_va, flags);
- if (v == NULL) {
- itemfailed = 1;
- Py_INCREF(Py_None);
- v = Py_None;
- }
- err = PyDict_SetItem(d, k, v);
- Py_DECREF(k);
- Py_DECREF(v);
- if (err < 0 || itemfailed) {
- Py_DECREF(d);
- return NULL;
- }
- }
- if (d != NULL && **p_format != endchar) {
- Py_DECREF(d);
- d = NULL;
- PyErr_SetString(PyExc_SystemError,
- "Unmatched paren in format");
- }
- else if (endchar)
- ++*p_format;
- return d;
-}
-
-static PyObject *
-do_mklist(const char **p_format, va_list *p_va, int endchar, int n, int flags)
-{
- PyObject *v;
- int i;
- int itemfailed = 0;
- if (n < 0)
- return NULL;
- v = PyList_New(n);
- if (v == NULL)
- return NULL;
- /* Note that we can't bail immediately on error as this will leak
- refcounts on any 'N' arguments. */
- for (i = 0; i < n; i++) {
- PyObject *w = do_mkvalue(p_format, p_va, flags);
- if (w == NULL) {
- itemfailed = 1;
- Py_INCREF(Py_None);
- w = Py_None;
- }
- PyList_SET_ITEM(v, i, w);
- }
-
- if (itemfailed) {
- /* do_mkvalue() should have already set an error */
- Py_DECREF(v);
- return NULL;
- }
- if (**p_format != endchar) {
- Py_DECREF(v);
- PyErr_SetString(PyExc_SystemError,
- "Unmatched paren in format");
- return NULL;
- }
- if (endchar)
- ++*p_format;
- return v;
-}
-
-#ifdef Py_USING_UNICODE
-static int
-_ustrlen(Py_UNICODE *u)
-{
- int i = 0;
- Py_UNICODE *v = u;
- while (*v != 0) { i++; v++; }
- return i;
-}
-#endif
-
-static PyObject *
-do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags)
-{
- PyObject *v;
- int i;
- int itemfailed = 0;
- if (n < 0)
- return NULL;
- if ((v = PyTuple_New(n)) == NULL)
- return NULL;
- /* Note that we can't bail immediately on error as this will leak
- refcounts on any 'N' arguments. */
- for (i = 0; i < n; i++) {
- PyObject *w = do_mkvalue(p_format, p_va, flags);
- if (w == NULL) {
- itemfailed = 1;
- Py_INCREF(Py_None);
- w = Py_None;
- }
- PyTuple_SET_ITEM(v, i, w);
- }
- if (itemfailed) {
- /* do_mkvalue() should have already set an error */
- Py_DECREF(v);
- return NULL;
- }
- if (**p_format != endchar) {
- Py_DECREF(v);
- PyErr_SetString(PyExc_SystemError,
- "Unmatched paren in format");
- return NULL;
- }
- if (endchar)
- ++*p_format;
- return v;
-}
-
-static PyObject *
-do_mkvalue(const char **p_format, va_list *p_va, int flags)
-{
- for (;;) {
- switch (*(*p_format)++) {
- case '(':
- return do_mktuple(p_format, p_va, ')',
- countformat(*p_format, ')'), flags);
-
- case '[':
- return do_mklist(p_format, p_va, ']',
- countformat(*p_format, ']'), flags);
-
- case '{':
- return do_mkdict(p_format, p_va, '}',
- countformat(*p_format, '}'), flags);
-
- case 'b':
- case 'B':
- case 'h':
- case 'i':
- return PyInt_FromLong((long)va_arg(*p_va, int));
-
- case 'H':
- return PyInt_FromLong((long)va_arg(*p_va, unsigned int));
-
- case 'I':
- {
- unsigned int n;
- n = va_arg(*p_va, unsigned int);
- if (n > (unsigned long)PyInt_GetMax())
- return PyLong_FromUnsignedLong((unsigned long)n);
- else
- return PyInt_FromLong(n);
- }
-
- case 'n':
-#if SIZEOF_SIZE_T!=SIZEOF_LONG
- return PyInt_FromSsize_t(va_arg(*p_va, Py_ssize_t));
-#endif
- /* Fall through from 'n' to 'l' if Py_ssize_t is long */
- case 'l':
- return PyInt_FromLong(va_arg(*p_va, long));
-
- case 'k':
- {
- unsigned long n;
- n = va_arg(*p_va, unsigned long);
- if (n > (unsigned long)PyInt_GetMax())
- return PyLong_FromUnsignedLong(n);
- else
- return PyInt_FromLong(n);
- }
-
-#ifdef HAVE_LONG_LONG
- case 'L':
- return PyLong_FromLongLong((PY_LONG_LONG)va_arg(*p_va, PY_LONG_LONG));
-
- case 'K':
- return PyLong_FromUnsignedLongLong((PY_LONG_LONG)va_arg(*p_va, unsigned PY_LONG_LONG));
-#endif
-#ifdef Py_USING_UNICODE
- case 'u':
- {
- PyObject *v;
- Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *);
- Py_ssize_t n;
- if (**p_format == '#') {
- ++*p_format;
- if (flags & FLAG_SIZE_T)
- n = va_arg(*p_va, Py_ssize_t);
- else
- n = va_arg(*p_va, int);
- }
- else
- n = -1;
- if (u == NULL) {
- v = Py_None;
- Py_INCREF(v);
- }
- else {
- if (n < 0)
- n = _ustrlen(u);
- v = PyUnicode_FromUnicode(u, n);
- }
- return v;
- }
-#endif
- case 'f':
- case 'd':
- return PyFloat_FromDouble(
- (double)va_arg(*p_va, va_double));
-
-#ifndef WITHOUT_COMPLEX
- case 'D':
- return PyComplex_FromCComplex(
- *((Py_complex *)va_arg(*p_va, Py_complex *)));
-#endif /* WITHOUT_COMPLEX */
-
- case 'c':
- {
- char p[1];
- p[0] = (char)va_arg(*p_va, int);
- return PyString_FromStringAndSize(p, 1);
- }
-
- case 's':
- case 'z':
- {
- PyObject *v;
- char *str = va_arg(*p_va, char *);
- Py_ssize_t n;
- if (**p_format == '#') {
- ++*p_format;
- if (flags & FLAG_SIZE_T)
- n = va_arg(*p_va, Py_ssize_t);
- else
- n = va_arg(*p_va, int);
- }
- else
- n = -1;
- if (str == NULL) {
- v = Py_None;
- Py_INCREF(v);
- }
- else {
- if (n < 0) {
- size_t m = strlen(str);
- if (m > PY_SSIZE_T_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "string too long for Python string");
- return NULL;
- }
- n = (Py_ssize_t)m;
- }
- v = PyString_FromStringAndSize(str, n);
- }
- return v;
- }
-
- case 'N':
- case 'S':
- case 'O':
- if (**p_format == '&') {
- typedef PyObject *(*converter)(void *);
- converter func = va_arg(*p_va, converter);
- void *arg = va_arg(*p_va, void *);
- ++*p_format;
- return (*func)(arg);
- }
- else {
- PyObject *v;
- v = va_arg(*p_va, PyObject *);
- if (v != NULL) {
- if (*(*p_format - 1) != 'N')
- Py_INCREF(v);
- }
- else if (!PyErr_Occurred())
- /* If a NULL was passed
- * because a call that should
- * have constructed a value
- * failed, that's OK, and we
- * pass the error on; but if
- * no error occurred it's not
- * clear that the caller knew
- * what she was doing. */
- PyErr_SetString(PyExc_SystemError,
- "NULL object passed to Py_BuildValue");
- return v;
- }
-
- case ':':
- case ',':
- case ' ':
- case '\t':
- break;
-
- default:
- PyErr_SetString(PyExc_SystemError,
- "bad format char passed to Py_BuildValue");
- return NULL;
-
- }
- }
-}
-
-
-PyObject *
-Py_BuildValue(const char *format, ...)
-{
- va_list va;
- PyObject* retval;
- va_start(va, format);
- retval = va_build_value(format, va, 0);
- va_end(va);
- return retval;
-}
-
-PyObject *
-_Py_BuildValue_SizeT(const char *format, ...)
-{
- va_list va;
- PyObject* retval;
- va_start(va, format);
- retval = va_build_value(format, va, FLAG_SIZE_T);
- va_end(va);
- return retval;
-}
-
-PyObject *
-Py_VaBuildValue(const char *format, va_list va)
-{
- return va_build_value(format, va, 0);
-}
-
-PyObject *
-_Py_VaBuildValue_SizeT(const char *format, va_list va)
-{
- return va_build_value(format, va, FLAG_SIZE_T);
-}
-
-static PyObject *
-va_build_value(const char *format, va_list va, int flags)
-{
- const char *f = format;
- int n = countformat(f, '\0');
- va_list lva;
-
-#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(lva, va);
-#else
- lva = va;
-#endif
-#endif
-
- if (n < 0)
- return NULL;
- if (n == 0) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- if (n == 1)
- return do_mkvalue(&f, &lva, flags);
- return do_mktuple(&f, &lva, '\0', n, flags);
-}
-
-
-PyObject *
-PyEval_CallFunction(PyObject *obj, const char *format, ...)
-{
- va_list vargs;
- PyObject *args;
- PyObject *res;
-
- va_start(vargs, format);
-
- args = Py_VaBuildValue(format, vargs);
- va_end(vargs);
-
- if (args == NULL)
- return NULL;
-
- res = PyEval_CallObject(obj, args);
- Py_DECREF(args);
-
- return res;
-}
-
-
-PyObject *
-PyEval_CallMethod(PyObject *obj, const char *methodname, const char *format, ...)
-{
- va_list vargs;
- PyObject *meth;
- PyObject *args;
- PyObject *res;
-
- meth = PyObject_GetAttrString(obj, methodname);
- if (meth == NULL)
- return NULL;
-
- va_start(vargs, format);
-
- args = Py_VaBuildValue(format, vargs);
- va_end(vargs);
-
- if (args == NULL) {
- Py_DECREF(meth);
- return NULL;
- }
-
- res = PyEval_CallObject(meth, args);
- Py_DECREF(meth);
- Py_DECREF(args);
-
- return res;
-}
-
-int
-PyModule_AddObject(PyObject *m, const char *name, PyObject *o)
-{
- PyObject *dict;
- if (!PyModule_Check(m)) {
- PyErr_SetString(PyExc_TypeError,
- "PyModule_AddObject() needs module as first arg");
- return -1;
- }
- if (!o) {
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError,
- "PyModule_AddObject() needs non-NULL value");
- return -1;
- }
-
- dict = PyModule_GetDict(m);
- if (dict == NULL) {
- /* Internal error -- modules must have a dict! */
- PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
- PyModule_GetName(m));
- return -1;
- }
- if (PyDict_SetItemString(dict, name, o))
- return -1;
- Py_DECREF(o);
- return 0;
-}
-
-int
-PyModule_AddIntConstant(PyObject *m, const char *name, long value)
-{
- return PyModule_AddObject(m, name, PyInt_FromLong(value));
-}
-
-int
-PyModule_AddStringConstant(PyObject *m, const char *name, const char *value)
-{
- return PyModule_AddObject(m, name, PyString_FromString(value));
-}
diff --git a/sys/src/cmd/python/Python/mysnprintf.c b/sys/src/cmd/python/Python/mysnprintf.c
deleted file mode 100644
index 4d3770d89..000000000
--- a/sys/src/cmd/python/Python/mysnprintf.c
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "Python.h"
-#include <ctype.h>
-
-/* snprintf() wrappers. If the platform has vsnprintf, we use it, else we
- emulate it in a half-hearted way. Even if the platform has it, we wrap
- it because platforms differ in what vsnprintf does in case the buffer
- is too small: C99 behavior is to return the number of characters that
- would have been written had the buffer not been too small, and to set
- the last byte of the buffer to \0. At least MS _vsnprintf returns a
- negative value instead, and fills the entire buffer with non-\0 data.
-
- The wrappers ensure that str[size-1] is always \0 upon return.
-
- PyOS_snprintf and PyOS_vsnprintf never write more than size bytes
- (including the trailing '\0') into str.
-
- If the platform doesn't have vsnprintf, and the buffer size needed to
- avoid truncation exceeds size by more than 512, Python aborts with a
- Py_FatalError.
-
- Return value (rv):
-
- When 0 <= rv < size, the output conversion was unexceptional, and
- rv characters were written to str (excluding a trailing \0 byte at
- str[rv]).
-
- When rv >= size, output conversion was truncated, and a buffer of
- size rv+1 would have been needed to avoid truncation. str[size-1]
- is \0 in this case.
-
- When rv < 0, "something bad happened". str[size-1] is \0 in this
- case too, but the rest of str is unreliable. It could be that
- an error in format codes was detected by libc, or on platforms
- with a non-C99 vsnprintf simply that the buffer wasn't big enough
- to avoid truncation, or on platforms without any vsnprintf that
- PyMem_Malloc couldn't obtain space for a temp buffer.
-
- CAUTION: Unlike C99, str != NULL and size > 0 are required.
-*/
-
-int
-PyOS_snprintf(char *str, size_t size, const char *format, ...)
-{
- int rc;
- va_list va;
-
- va_start(va, format);
- rc = PyOS_vsnprintf(str, size, format, va);
- va_end(va);
- return rc;
-}
-
-int
-PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
-{
- int len; /* # bytes written, excluding \0 */
-#ifndef HAVE_SNPRINTF
- char *buffer;
-#endif
- assert(str != NULL);
- assert(size > 0);
- assert(format != NULL);
-
-#ifdef HAVE_SNPRINTF
- len = vsnprintf(str, size, format, va);
-#else
- /* Emulate it. */
- buffer = PyMem_MALLOC(size + 512);
- if (buffer == NULL) {
- len = -666;
- goto Done;
- }
-
- len = vsprintf(buffer, format, va);
- if (len < 0)
- /* ignore the error */;
-
- else if ((size_t)len >= size + 512)
- Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
-
- else {
- const size_t to_copy = (size_t)len < size ?
- (size_t)len : size - 1;
- assert(to_copy < size);
- memcpy(str, buffer, to_copy);
- str[to_copy] = '\0';
- }
- PyMem_FREE(buffer);
-Done:
-#endif
- str[size-1] = '\0';
- return len;
-}
diff --git a/sys/src/cmd/python/Python/mystrtoul.c b/sys/src/cmd/python/Python/mystrtoul.c
deleted file mode 100644
index f0070575d..000000000
--- a/sys/src/cmd/python/Python/mystrtoul.c
+++ /dev/null
@@ -1,232 +0,0 @@
-
-#include "Python.h"
-
-#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
-#define _SGI_MP_SOURCE
-#endif
-
-/* Convert a possibly signed character to a nonnegative int */
-/* XXX This assumes characters are 8 bits wide */
-#ifdef __CHAR_UNSIGNED__
-#define Py_CHARMASK(c) (c)
-#else
-#define Py_CHARMASK(c) ((c) & 0xff)
-#endif
-
-/* strtol and strtoul, renamed to avoid conflicts */
-
-
-#include <ctype.h>
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-/* Static overflow check values for bases 2 through 36.
- * smallmax[base] is the largest unsigned long i such that
- * i * base doesn't overflow unsigned long.
- */
-static unsigned long smallmax[] = {
- 0, /* bases 0 and 1 are invalid */
- 0,
- ULONG_MAX / 2,
- ULONG_MAX / 3,
- ULONG_MAX / 4,
- ULONG_MAX / 5,
- ULONG_MAX / 6,
- ULONG_MAX / 7,
- ULONG_MAX / 8,
- ULONG_MAX / 9,
- ULONG_MAX / 10,
- ULONG_MAX / 11,
- ULONG_MAX / 12,
- ULONG_MAX / 13,
- ULONG_MAX / 14,
- ULONG_MAX / 15,
- ULONG_MAX / 16,
- ULONG_MAX / 17,
- ULONG_MAX / 18,
- ULONG_MAX / 19,
- ULONG_MAX / 20,
- ULONG_MAX / 21,
- ULONG_MAX / 22,
- ULONG_MAX / 23,
- ULONG_MAX / 24,
- ULONG_MAX / 25,
- ULONG_MAX / 26,
- ULONG_MAX / 27,
- ULONG_MAX / 28,
- ULONG_MAX / 29,
- ULONG_MAX / 30,
- ULONG_MAX / 31,
- ULONG_MAX / 32,
- ULONG_MAX / 33,
- ULONG_MAX / 34,
- ULONG_MAX / 35,
- ULONG_MAX / 36,
-};
-
-/* maximum digits that can't ever overflow for bases 2 through 36,
- * calculated by [int(math.floor(math.log(2**32, i))) for i in range(2, 37)].
- * Note that this is pessimistic if sizeof(long) > 4.
- */
-#if SIZEOF_LONG == 4
-static int digitlimit[] = {
- 0, 0, 32, 20, 16, 13, 12, 11, 10, 10, /* 0 - 9 */
- 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, /* 10 - 19 */
- 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, /* 20 - 29 */
- 6, 6, 6, 6, 6, 6, 6}; /* 30 - 36 */
-#elif SIZEOF_LONG == 8
-/* [int(math.floor(math.log(2**64, i))) for i in range(2, 37)] */
-static int digitlimit[] = {
- 0, 0, 64, 40, 32, 27, 24, 22, 21, 20, /* 0 - 9 */
- 19, 18, 17, 17, 16, 16, 16, 15, 15, 15, /* 10 - 19 */
- 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, /* 20 - 29 */
- 13, 12, 12, 12, 12, 12, 12}; /* 30 - 36 */
-#else
-#error "Need table for SIZEOF_LONG"
-#endif
-
-/*
-** strtoul
-** This is a general purpose routine for converting
-** an ascii string to an integer in an arbitrary base.
-** Leading white space is ignored. If 'base' is zero
-** it looks for a leading 0, 0x or 0X to tell which
-** base. If these are absent it defaults to 10.
-** Base must be 0 or between 2 and 36 (inclusive).
-** If 'ptr' is non-NULL it will contain a pointer to
-** the end of the scan.
-** Errors due to bad pointers will probably result in
-** exceptions - we don't check for them.
-*/
-unsigned long
-PyOS_strtoul(register char *str, char **ptr, int base)
-{
- register unsigned long result = 0; /* return value of the function */
- register int c; /* current input character */
- register int ovlimit; /* required digits to overflow */
-
- /* skip leading white space */
- while (*str && isspace(Py_CHARMASK(*str)))
- ++str;
-
- /* check for leading 0 or 0x for auto-base or base 16 */
- switch (base) {
- case 0: /* look for leading 0, 0x or 0X */
- if (*str == '0') {
- ++str;
- if (*str == 'x' || *str == 'X') {
- ++str;
- base = 16;
- }
- else
- base = 8;
- }
- else
- base = 10;
- break;
-
- case 16: /* skip leading 0x or 0X */
- if (*str == '0') {
- ++str;
- if (*str == 'x' || *str == 'X')
- ++str;
- }
- break;
- }
-
- /* catch silly bases */
- if (base < 2 || base > 36) {
- if (ptr)
- *ptr = str;
- return 0;
- }
-
- /* skip leading zeroes */
- while (*str == '0')
- ++str;
-
- /* base is guaranteed to be in [2, 36] at this point */
- ovlimit = digitlimit[base];
-
- /* do the conversion until non-digit character encountered */
- while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) {
- if (ovlimit > 0) /* no overflow check required */
- result = result * base + c;
- else { /* requires overflow check */
- register unsigned long temp_result;
-
- if (ovlimit < 0) /* guaranteed overflow */
- goto overflowed;
-
- /* there could be an overflow */
- /* check overflow just from shifting */
- if (result > smallmax[base])
- goto overflowed;
-
- result *= base;
-
- /* check overflow from the digit's value */
- temp_result = result + c;
- if (temp_result < result)
- goto overflowed;
-
- result = temp_result;
- }
-
- ++str;
- --ovlimit;
- }
-
- /* set pointer to point to the last character scanned */
- if (ptr)
- *ptr = str;
-
- return result;
-
-overflowed:
- if (ptr) {
- /* spool through remaining digit characters */
- while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base)
- ++str;
- *ptr = str;
- }
- errno = ERANGE;
- return (unsigned long)-1;
-}
-
-/* Checking for overflow in PyOS_strtol is a PITA; see comments
- * about PY_ABS_LONG_MIN in longobject.c.
- */
-#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
-
-long
-PyOS_strtol(char *str, char **ptr, int base)
-{
- long result;
- unsigned long uresult;
- char sign;
-
- while (*str && isspace(Py_CHARMASK(*str)))
- str++;
-
- sign = *str;
- if (sign == '+' || sign == '-')
- str++;
-
- uresult = PyOS_strtoul(str, ptr, base);
-
- if (uresult <= (unsigned long)LONG_MAX) {
- result = (long)uresult;
- if (sign == '-')
- result = -result;
- }
- else if (sign == '-' && uresult == PY_ABS_LONG_MIN) {
- result = LONG_MIN;
- }
- else {
- errno = ERANGE;
- result = LONG_MAX;
- }
- return result;
-}
diff --git a/sys/src/cmd/python/Python/pyarena.c b/sys/src/cmd/python/Python/pyarena.c
deleted file mode 100644
index f4cc474f4..000000000
--- a/sys/src/cmd/python/Python/pyarena.c
+++ /dev/null
@@ -1,220 +0,0 @@
-#include "Python.h"
-#include "pyarena.h"
-
-/* A simple arena block structure.
-
- Measurements with standard library modules suggest the average
- allocation is about 20 bytes and that most compiles use a single
- block.
-
- TODO(jhylton): Think about a realloc API, maybe just for the last
- allocation?
-*/
-
-#define DEFAULT_BLOCK_SIZE 8192
-#define ALIGNMENT 8
-#define ALIGNMENT_MASK (ALIGNMENT - 1)
-#define ROUNDUP(x) (((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
-
-typedef struct _block {
- /* Total number of bytes owned by this block available to pass out.
- * Read-only after initialization. The first such byte starts at
- * ab_mem.
- */
- size_t ab_size;
-
- /* Total number of bytes already passed out. The next byte available
- * to pass out starts at ab_mem + ab_offset.
- */
- size_t ab_offset;
-
- /* An arena maintains a singly-linked, NULL-terminated list of
- * all blocks owned by the arena. These are linked via the
- * ab_next member.
- */
- struct _block *ab_next;
-
- /* Pointer to the first allocatable byte owned by this block. Read-
- * only after initialization.
- */
- void *ab_mem;
-} block;
-
-/* The arena manages two kinds of memory, blocks of raw memory
- and a list of PyObject* pointers. PyObjects are decrefed
- when the arena is freed.
-*/
-
-struct _arena {
- /* Pointer to the first block allocated for the arena, never NULL.
- It is used only to find the first block when the arena is
- being freed.
- */
- block *a_head;
-
- /* Pointer to the block currently used for allocation. It's
- ab_next field should be NULL. If it is not-null after a
- call to block_alloc(), it means a new block has been allocated
- and a_cur should be reset to point it.
- */
- block *a_cur;
-
- /* A Python list object containing references to all the PyObject
- pointers associated with this area. They will be DECREFed
- when the arena is freed.
- */
- PyObject *a_objects;
-
-#if defined(Py_DEBUG)
- /* Debug output */
- size_t total_allocs;
- size_t total_size;
- size_t total_blocks;
- size_t total_block_size;
- size_t total_big_blocks;
-#endif
-};
-
-static block *
-block_new(size_t size)
-{
- /* Allocate header and block as one unit.
- ab_mem points just past header. */
- block *b = (block *)malloc(sizeof(block) + size);
- if (!b)
- return NULL;
- b->ab_size = size;
- b->ab_mem = (void *)(b + 1);
- b->ab_next = NULL;
- b->ab_offset = ROUNDUP((Py_uintptr_t)(b->ab_mem)) -
- (Py_uintptr_t)(b->ab_mem);
- return b;
-}
-
-static void
-block_free(block *b) {
- while (b) {
- block *next = b->ab_next;
- free(b);
- b = next;
- }
-}
-
-static void *
-block_alloc(block *b, size_t size)
-{
- void *p;
- assert(b);
- size = ROUNDUP(size);
- if (b->ab_offset + size > b->ab_size) {
- /* If we need to allocate more memory than will fit in
- the default block, allocate a one-off block that is
- exactly the right size. */
- /* TODO(jhylton): Think about space waste at end of block */
- block *newbl = block_new(
- size < DEFAULT_BLOCK_SIZE ?
- DEFAULT_BLOCK_SIZE : size);
- if (!newbl)
- return NULL;
- assert(!b->ab_next);
- b->ab_next = newbl;
- b = newbl;
- }
-
- assert(b->ab_offset + size <= b->ab_size);
- p = (void *)(((char *)b->ab_mem) + b->ab_offset);
- b->ab_offset += size;
- return p;
-}
-
-PyArena *
-PyArena_New()
-{
- PyArena* arena = (PyArena *)malloc(sizeof(PyArena));
- if (!arena)
- return (PyArena*)PyErr_NoMemory();
-
- arena->a_head = block_new(DEFAULT_BLOCK_SIZE);
- arena->a_cur = arena->a_head;
- if (!arena->a_head) {
- free((void *)arena);
- return (PyArena*)PyErr_NoMemory();
- }
- arena->a_objects = PyList_New(0);
- if (!arena->a_objects) {
- block_free(arena->a_head);
- free((void *)arena);
- return (PyArena*)PyErr_NoMemory();
- }
-#if defined(Py_DEBUG)
- arena->total_allocs = 0;
- arena->total_size = 0;
- arena->total_blocks = 1;
- arena->total_block_size = DEFAULT_BLOCK_SIZE;
- arena->total_big_blocks = 0;
-#endif
- return arena;
-}
-
-void
-PyArena_Free(PyArena *arena)
-{
- int r;
- assert(arena);
-#if defined(Py_DEBUG)
- /*
- fprintf(stderr,
- "alloc=%d size=%d blocks=%d block_size=%d big=%d objects=%d\n",
- arena->total_allocs, arena->total_size, arena->total_blocks,
- arena->total_block_size, arena->total_big_blocks,
- PyList_Size(arena->a_objects));
- */
-#endif
- block_free(arena->a_head);
- /* This property normally holds, except when the code being compiled
- is sys.getobjects(0), in which case there will be two references.
- assert(arena->a_objects->ob_refcnt == 1);
- */
-
- /* Clear all the elements from the list. This is necessary
- to guarantee that they will be DECREFed. */
- r = PyList_SetSlice(arena->a_objects,
- 0, PyList_GET_SIZE(arena->a_objects), NULL);
- assert(r == 0);
- assert(PyList_GET_SIZE(arena->a_objects) == 0);
- Py_DECREF(arena->a_objects);
- free(arena);
-}
-
-void *
-PyArena_Malloc(PyArena *arena, size_t size)
-{
- void *p = block_alloc(arena->a_cur, size);
- if (!p)
- return PyErr_NoMemory();
-#if defined(Py_DEBUG)
- arena->total_allocs++;
- arena->total_size += size;
-#endif
- /* Reset cur if we allocated a new block. */
- if (arena->a_cur->ab_next) {
- arena->a_cur = arena->a_cur->ab_next;
-#if defined(Py_DEBUG)
- arena->total_blocks++;
- arena->total_block_size += arena->a_cur->ab_size;
- if (arena->a_cur->ab_size > DEFAULT_BLOCK_SIZE)
- ++arena->total_big_blocks;
-#endif
- }
- return p;
-}
-
-int
-PyArena_AddPyObject(PyArena *arena, PyObject *obj)
-{
- int r = PyList_Append(arena->a_objects, obj);
- if (r >= 0) {
- Py_DECREF(obj);
- }
- return r;
-}
diff --git a/sys/src/cmd/python/Python/pyfpe.c b/sys/src/cmd/python/Python/pyfpe.c
deleted file mode 100644
index 4b7f5bae1..000000000
--- a/sys/src/cmd/python/Python/pyfpe.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include "pyconfig.h"
-#include "pyfpe.h"
-/*
- * The signal handler for SIGFPE is actually declared in an external
- * module fpectl, or as preferred by the user. These variable
- * definitions are required in order to compile Python without
- * getting missing externals, but to actually handle SIGFPE requires
- * defining a handler and enabling generation of SIGFPE.
- */
-
-#ifdef WANT_SIGFPE_HANDLER
-jmp_buf PyFPE_jbuf;
-int PyFPE_counter = 0;
-#endif
-
-/* Have this outside the above #ifdef, since some picky ANSI compilers issue a
- warning when compiling an empty file. */
-
-double
-PyFPE_dummy(void *dummy)
-{
- return 1.0;
-}
diff --git a/sys/src/cmd/python/Python/pystate.c b/sys/src/cmd/python/Python/pystate.c
deleted file mode 100644
index 086789d35..000000000
--- a/sys/src/cmd/python/Python/pystate.c
+++ /dev/null
@@ -1,632 +0,0 @@
-
-/* Thread and interpreter state structures and their interfaces */
-
-#include "Python.h"
-
-/* --------------------------------------------------------------------------
-CAUTION
-
-Always use malloc() and free() directly in this file. A number of these
-functions are advertised as safe to call when the GIL isn't held, and in
-a debug build Python redirects (e.g.) PyMem_NEW (etc) to Python's debugging
-obmalloc functions. Those aren't thread-safe (they rely on the GIL to avoid
-the expense of doing their own locking).
--------------------------------------------------------------------------- */
-
-#ifdef HAVE_DLOPEN
-#ifdef HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-#ifndef RTLD_LAZY
-#define RTLD_LAZY 1
-#endif
-#endif
-
-
-#ifdef WITH_THREAD
-#include "pythread.h"
-static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
-#define HEAD_INIT() (void)(head_mutex || (head_mutex = PyThread_allocate_lock()))
-#define HEAD_LOCK() PyThread_acquire_lock(head_mutex, WAIT_LOCK)
-#define HEAD_UNLOCK() PyThread_release_lock(head_mutex)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The single PyInterpreterState used by this process'
- GILState implementation
-*/
-static PyInterpreterState *autoInterpreterState = NULL;
-static int autoTLSkey = 0;
-#else
-#define HEAD_INIT() /* Nothing */
-#define HEAD_LOCK() /* Nothing */
-#define HEAD_UNLOCK() /* Nothing */
-#endif
-
-static PyInterpreterState *interp_head = NULL;
-
-PyThreadState *_PyThreadState_Current = NULL;
-PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
-
-#ifdef WITH_THREAD
-static void _PyGILState_NoteThreadState(PyThreadState* tstate);
-#endif
-
-
-PyInterpreterState *
-PyInterpreterState_New(void)
-{
- PyInterpreterState *interp = (PyInterpreterState *)
- malloc(sizeof(PyInterpreterState));
-
- if (interp != NULL) {
- HEAD_INIT();
-#ifdef WITH_THREAD
- if (head_mutex == NULL)
- Py_FatalError("Can't initialize threads for interpreter");
-#endif
- interp->modules = NULL;
- interp->modules_reloading = NULL;
- interp->sysdict = NULL;
- interp->builtins = NULL;
- interp->tstate_head = NULL;
- interp->codec_search_path = NULL;
- interp->codec_search_cache = NULL;
- interp->codec_error_registry = NULL;
-#ifdef HAVE_DLOPEN
-#ifdef RTLD_NOW
- interp->dlopenflags = RTLD_NOW;
-#else
- interp->dlopenflags = RTLD_LAZY;
-#endif
-#endif
-#ifdef WITH_TSC
- interp->tscdump = 0;
-#endif
-
- HEAD_LOCK();
- interp->next = interp_head;
- interp_head = interp;
- HEAD_UNLOCK();
- }
-
- return interp;
-}
-
-
-void
-PyInterpreterState_Clear(PyInterpreterState *interp)
-{
- PyThreadState *p;
- HEAD_LOCK();
- for (p = interp->tstate_head; p != NULL; p = p->next)
- PyThreadState_Clear(p);
- HEAD_UNLOCK();
- Py_CLEAR(interp->codec_search_path);
- Py_CLEAR(interp->codec_search_cache);
- Py_CLEAR(interp->codec_error_registry);
- Py_CLEAR(interp->modules);
- Py_CLEAR(interp->modules_reloading);
- Py_CLEAR(interp->sysdict);
- Py_CLEAR(interp->builtins);
-}
-
-
-static void
-zapthreads(PyInterpreterState *interp)
-{
- PyThreadState *p;
- /* No need to lock the mutex here because this should only happen
- when the threads are all really dead (XXX famous last words). */
- while ((p = interp->tstate_head) != NULL) {
- PyThreadState_Delete(p);
- }
-}
-
-
-void
-PyInterpreterState_Delete(PyInterpreterState *interp)
-{
- PyInterpreterState **p;
- zapthreads(interp);
- HEAD_LOCK();
- for (p = &interp_head; ; p = &(*p)->next) {
- if (*p == NULL)
- Py_FatalError(
- "PyInterpreterState_Delete: invalid interp");
- if (*p == interp)
- break;
- }
- if (interp->tstate_head != NULL)
- Py_FatalError("PyInterpreterState_Delete: remaining threads");
- *p = interp->next;
- HEAD_UNLOCK();
- free(interp);
-}
-
-
-/* Default implementation for _PyThreadState_GetFrame */
-static struct _frame *
-threadstate_getframe(PyThreadState *self)
-{
- return self->frame;
-}
-
-PyThreadState *
-PyThreadState_New(PyInterpreterState *interp)
-{
- PyThreadState *tstate = (PyThreadState *)malloc(sizeof(PyThreadState));
-
- if (_PyThreadState_GetFrame == NULL)
- _PyThreadState_GetFrame = threadstate_getframe;
-
- if (tstate != NULL) {
- tstate->interp = interp;
-
- tstate->frame = NULL;
- tstate->recursion_depth = 0;
- tstate->tracing = 0;
- tstate->use_tracing = 0;
- tstate->tick_counter = 0;
- tstate->gilstate_counter = 0;
- tstate->async_exc = NULL;
-#ifdef WITH_THREAD
- tstate->thread_id = PyThread_get_thread_ident();
-#else
- tstate->thread_id = 0;
-#endif
-
- tstate->dict = NULL;
-
- tstate->curexc_type = NULL;
- tstate->curexc_value = NULL;
- tstate->curexc_traceback = NULL;
-
- tstate->exc_type = NULL;
- tstate->exc_value = NULL;
- tstate->exc_traceback = NULL;
-
- tstate->c_profilefunc = NULL;
- tstate->c_tracefunc = NULL;
- tstate->c_profileobj = NULL;
- tstate->c_traceobj = NULL;
-
-#ifdef WITH_THREAD
- _PyGILState_NoteThreadState(tstate);
-#endif
-
- HEAD_LOCK();
- tstate->next = interp->tstate_head;
- interp->tstate_head = tstate;
- HEAD_UNLOCK();
- }
-
- return tstate;
-}
-
-
-void
-PyThreadState_Clear(PyThreadState *tstate)
-{
- if (Py_VerboseFlag && tstate->frame != NULL)
- fprintf(stderr,
- "PyThreadState_Clear: warning: thread still has a frame\n");
-
- Py_CLEAR(tstate->frame);
-
- Py_CLEAR(tstate->dict);
- Py_CLEAR(tstate->async_exc);
-
- Py_CLEAR(tstate->curexc_type);
- Py_CLEAR(tstate->curexc_value);
- Py_CLEAR(tstate->curexc_traceback);
-
- Py_CLEAR(tstate->exc_type);
- Py_CLEAR(tstate->exc_value);
- Py_CLEAR(tstate->exc_traceback);
-
- tstate->c_profilefunc = NULL;
- tstate->c_tracefunc = NULL;
- Py_CLEAR(tstate->c_profileobj);
- Py_CLEAR(tstate->c_traceobj);
-}
-
-
-/* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */
-static void
-tstate_delete_common(PyThreadState *tstate)
-{
- PyInterpreterState *interp;
- PyThreadState **p;
- if (tstate == NULL)
- Py_FatalError("PyThreadState_Delete: NULL tstate");
- interp = tstate->interp;
- if (interp == NULL)
- Py_FatalError("PyThreadState_Delete: NULL interp");
- HEAD_LOCK();
- for (p = &interp->tstate_head; ; p = &(*p)->next) {
- if (*p == NULL)
- Py_FatalError(
- "PyThreadState_Delete: invalid tstate");
- if (*p == tstate)
- break;
- }
- *p = tstate->next;
- HEAD_UNLOCK();
- free(tstate);
-}
-
-
-void
-PyThreadState_Delete(PyThreadState *tstate)
-{
- if (tstate == _PyThreadState_Current)
- Py_FatalError("PyThreadState_Delete: tstate is still current");
- tstate_delete_common(tstate);
-#ifdef WITH_THREAD
- if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
- PyThread_delete_key_value(autoTLSkey);
-#endif /* WITH_THREAD */
-}
-
-
-#ifdef WITH_THREAD
-void
-PyThreadState_DeleteCurrent()
-{
- PyThreadState *tstate = _PyThreadState_Current;
- if (tstate == NULL)
- Py_FatalError(
- "PyThreadState_DeleteCurrent: no current tstate");
- _PyThreadState_Current = NULL;
- tstate_delete_common(tstate);
- if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
- PyThread_delete_key_value(autoTLSkey);
- PyEval_ReleaseLock();
-}
-#endif /* WITH_THREAD */
-
-
-PyThreadState *
-PyThreadState_Get(void)
-{
- if (_PyThreadState_Current == NULL)
- Py_FatalError("PyThreadState_Get: no current thread");
-
- return _PyThreadState_Current;
-}
-
-
-PyThreadState *
-PyThreadState_Swap(PyThreadState *newts)
-{
- PyThreadState *oldts = _PyThreadState_Current;
-
- _PyThreadState_Current = newts;
- /* It should not be possible for more than one thread state
- to be used for a thread. Check this the best we can in debug
- builds.
- */
-#if defined(Py_DEBUG) && defined(WITH_THREAD)
- if (newts) {
- /* This can be called from PyEval_RestoreThread(). Similar
- to it, we need to ensure errno doesn't change.
- */
- int err = errno;
- PyThreadState *check = PyGILState_GetThisThreadState();
- if (check && check->interp == newts->interp && check != newts)
- Py_FatalError("Invalid thread state for this thread");
- errno = err;
- }
-#endif
- return oldts;
-}
-
-/* An extension mechanism to store arbitrary additional per-thread state.
- PyThreadState_GetDict() returns a dictionary that can be used to hold such
- state; the caller should pick a unique key and store its state there. If
- PyThreadState_GetDict() returns NULL, an exception has *not* been raised
- and the caller should assume no per-thread state is available. */
-
-PyObject *
-PyThreadState_GetDict(void)
-{
- if (_PyThreadState_Current == NULL)
- return NULL;
-
- if (_PyThreadState_Current->dict == NULL) {
- PyObject *d;
- _PyThreadState_Current->dict = d = PyDict_New();
- if (d == NULL)
- PyErr_Clear();
- }
- return _PyThreadState_Current->dict;
-}
-
-
-/* Asynchronously raise an exception in a thread.
- Requested by Just van Rossum and Alex Martelli.
- To prevent naive misuse, you must write your own extension
- to call this, or use ctypes. Must be called with the GIL held.
- Returns the number of tstates modified (normally 1, but 0 if `id` didn't
- match any known thread id). Can be called with exc=NULL to clear an
- existing async exception. This raises no exceptions. */
-
-int
-PyThreadState_SetAsyncExc(long id, PyObject *exc) {
- PyThreadState *tstate = PyThreadState_GET();
- PyInterpreterState *interp = tstate->interp;
- PyThreadState *p;
-
- /* Although the GIL is held, a few C API functions can be called
- * without the GIL held, and in particular some that create and
- * destroy thread and interpreter states. Those can mutate the
- * list of thread states we're traversing, so to prevent that we lock
- * head_mutex for the duration.
- */
- HEAD_LOCK();
- for (p = interp->tstate_head; p != NULL; p = p->next) {
- if (p->thread_id == id) {
- /* Tricky: we need to decref the current value
- * (if any) in p->async_exc, but that can in turn
- * allow arbitrary Python code to run, including
- * perhaps calls to this function. To prevent
- * deadlock, we need to release head_mutex before
- * the decref.
- */
- PyObject *old_exc = p->async_exc;
- Py_XINCREF(exc);
- p->async_exc = exc;
- HEAD_UNLOCK();
- Py_XDECREF(old_exc);
- return 1;
- }
- }
- HEAD_UNLOCK();
- return 0;
-}
-
-
-/* Routines for advanced debuggers, requested by David Beazley.
- Don't use unless you know what you are doing! */
-
-PyInterpreterState *
-PyInterpreterState_Head(void)
-{
- return interp_head;
-}
-
-PyInterpreterState *
-PyInterpreterState_Next(PyInterpreterState *interp) {
- return interp->next;
-}
-
-PyThreadState *
-PyInterpreterState_ThreadHead(PyInterpreterState *interp) {
- return interp->tstate_head;
-}
-
-PyThreadState *
-PyThreadState_Next(PyThreadState *tstate) {
- return tstate->next;
-}
-
-/* The implementation of sys._current_frames(). This is intended to be
- called with the GIL held, as it will be when called via
- sys._current_frames(). It's possible it would work fine even without
- the GIL held, but haven't thought enough about that.
-*/
-PyObject *
-_PyThread_CurrentFrames(void)
-{
- PyObject *result;
- PyInterpreterState *i;
-
- result = PyDict_New();
- if (result == NULL)
- return NULL;
-
- /* for i in all interpreters:
- * for t in all of i's thread states:
- * if t's frame isn't NULL, map t's id to its frame
- * Because these lists can mutute even when the GIL is held, we
- * need to grab head_mutex for the duration.
- */
- HEAD_LOCK();
- for (i = interp_head; i != NULL; i = i->next) {
- PyThreadState *t;
- for (t = i->tstate_head; t != NULL; t = t->next) {
- PyObject *id;
- int stat;
- struct _frame *frame = t->frame;
- if (frame == NULL)
- continue;
- id = PyInt_FromLong(t->thread_id);
- if (id == NULL)
- goto Fail;
- stat = PyDict_SetItem(result, id, (PyObject *)frame);
- Py_DECREF(id);
- if (stat < 0)
- goto Fail;
- }
- }
- HEAD_UNLOCK();
- return result;
-
- Fail:
- HEAD_UNLOCK();
- Py_DECREF(result);
- return NULL;
-}
-
-/* Python "auto thread state" API. */
-#ifdef WITH_THREAD
-
-/* Keep this as a static, as it is not reliable! It can only
- ever be compared to the state for the *current* thread.
- * If not equal, then it doesn't matter that the actual
- value may change immediately after comparison, as it can't
- possibly change to the current thread's state.
- * If equal, then the current thread holds the lock, so the value can't
- change until we yield the lock.
-*/
-static int
-PyThreadState_IsCurrent(PyThreadState *tstate)
-{
- /* Must be the tstate for this thread */
- assert(PyGILState_GetThisThreadState()==tstate);
- /* On Windows at least, simple reads and writes to 32 bit values
- are atomic.
- */
- return tstate == _PyThreadState_Current;
-}
-
-/* Internal initialization/finalization functions called by
- Py_Initialize/Py_Finalize
-*/
-void
-_PyGILState_Init(PyInterpreterState *i, PyThreadState *t)
-{
- assert(i && t); /* must init with valid states */
- autoTLSkey = PyThread_create_key();
- autoInterpreterState = i;
- assert(PyThread_get_key_value(autoTLSkey) == NULL);
- assert(t->gilstate_counter == 0);
-
- _PyGILState_NoteThreadState(t);
-}
-
-void
-_PyGILState_Fini(void)
-{
- PyThread_delete_key(autoTLSkey);
- autoTLSkey = 0;
- autoInterpreterState = NULL;
-}
-
-/* When a thread state is created for a thread by some mechanism other than
- PyGILState_Ensure, it's important that the GILState machinery knows about
- it so it doesn't try to create another thread state for the thread (this is
- a better fix for SF bug #1010677 than the first one attempted).
-*/
-static void
-_PyGILState_NoteThreadState(PyThreadState* tstate)
-{
- /* If autoTLSkey is 0, this must be the very first threadstate created
- in Py_Initialize(). Don't do anything for now (we'll be back here
- when _PyGILState_Init is called). */
- if (!autoTLSkey)
- return;
-
- /* Stick the thread state for this thread in thread local storage.
-
- The only situation where you can legitimately have more than one
- thread state for an OS level thread is when there are multiple
- interpreters, when:
-
- a) You shouldn't really be using the PyGILState_ APIs anyway,
- and:
-
- b) The slightly odd way PyThread_set_key_value works (see
- comments by its implementation) means that the first thread
- state created for that given OS level thread will "win",
- which seems reasonable behaviour.
- */
- if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0)
- Py_FatalError("Couldn't create autoTLSkey mapping");
-
- /* PyGILState_Release must not try to delete this thread state. */
- tstate->gilstate_counter = 1;
-}
-
-/* The public functions */
-PyThreadState *
-PyGILState_GetThisThreadState(void)
-{
- if (autoInterpreterState == NULL || autoTLSkey == 0)
- return NULL;
- return (PyThreadState *)PyThread_get_key_value(autoTLSkey);
-}
-
-PyGILState_STATE
-PyGILState_Ensure(void)
-{
- int current;
- PyThreadState *tcur;
- /* Note that we do not auto-init Python here - apart from
- potential races with 2 threads auto-initializing, pep-311
- spells out other issues. Embedders are expected to have
- called Py_Initialize() and usually PyEval_InitThreads().
- */
- assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */
- tcur = (PyThreadState *)PyThread_get_key_value(autoTLSkey);
- if (tcur == NULL) {
- /* Create a new thread state for this thread */
- tcur = PyThreadState_New(autoInterpreterState);
- if (tcur == NULL)
- Py_FatalError("Couldn't create thread-state for new thread");
- /* This is our thread state! We'll need to delete it in the
- matching call to PyGILState_Release(). */
- tcur->gilstate_counter = 0;
- current = 0; /* new thread state is never current */
- }
- else
- current = PyThreadState_IsCurrent(tcur);
- if (current == 0)
- PyEval_RestoreThread(tcur);
- /* Update our counter in the thread-state - no need for locks:
- - tcur will remain valid as we hold the GIL.
- - the counter is safe as we are the only thread "allowed"
- to modify this value
- */
- ++tcur->gilstate_counter;
- return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
-}
-
-void
-PyGILState_Release(PyGILState_STATE oldstate)
-{
- PyThreadState *tcur = (PyThreadState *)PyThread_get_key_value(
- autoTLSkey);
- if (tcur == NULL)
- Py_FatalError("auto-releasing thread-state, "
- "but no thread-state for this thread");
- /* We must hold the GIL and have our thread state current */
- /* XXX - remove the check - the assert should be fine,
- but while this is very new (April 2003), the extra check
- by release-only users can't hurt.
- */
- if (! PyThreadState_IsCurrent(tcur))
- Py_FatalError("This thread state must be current when releasing");
- assert(PyThreadState_IsCurrent(tcur));
- --tcur->gilstate_counter;
- assert(tcur->gilstate_counter >= 0); /* illegal counter value */
-
- /* If we're going to destroy this thread-state, we must
- * clear it while the GIL is held, as destructors may run.
- */
- if (tcur->gilstate_counter == 0) {
- /* can't have been locked when we created it */
- assert(oldstate == PyGILState_UNLOCKED);
- PyThreadState_Clear(tcur);
- /* Delete the thread-state. Note this releases the GIL too!
- * It's vital that the GIL be held here, to avoid shutdown
- * races; see bugs 225673 and 1061968 (that nasty bug has a
- * habit of coming back).
- */
- PyThreadState_DeleteCurrent();
- }
- /* Release the lock if necessary */
- else if (oldstate == PyGILState_UNLOCKED)
- PyEval_SaveThread();
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* WITH_THREAD */
-
-
diff --git a/sys/src/cmd/python/Python/pystrtod.c b/sys/src/cmd/python/Python/pystrtod.c
deleted file mode 100644
index 6c19b45fd..000000000
--- a/sys/src/cmd/python/Python/pystrtod.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/* -*- Mode: C; c-file-style: "python" -*- */
-
-#include <Python.h>
-#include <locale.h>
-
-/* ascii character tests (as opposed to locale tests) */
-#define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \
- (c) == '\r' || (c) == '\t' || (c) == '\v')
-#define ISDIGIT(c) ((c) >= '0' && (c) <= '9')
-#define ISXDIGIT(c) (ISDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
-
-
-/**
- * PyOS_ascii_strtod:
- * @nptr: the string to convert to a numeric value.
- * @endptr: if non-%NULL, it returns the character after
- * the last character used in the conversion.
- *
- * Converts a string to a #gdouble value.
- * This function behaves like the standard strtod() function
- * does in the C locale. It does this without actually
- * changing the current locale, since that would not be
- * thread-safe.
- *
- * This function is typically used when reading configuration
- * files or other non-user input that should be locale independent.
- * To handle input from the user you should normally use the
- * locale-sensitive system strtod() function.
- *
- * If the correct value would cause overflow, plus or minus %HUGE_VAL
- * is returned (according to the sign of the value), and %ERANGE is
- * stored in %errno. If the correct value would cause underflow,
- * zero is returned and %ERANGE is stored in %errno.
- * If memory allocation fails, %ENOMEM is stored in %errno.
- *
- * This function resets %errno before calling strtod() so that
- * you can reliably detect overflow and underflow.
- *
- * Return value: the #gdouble value.
- **/
-double
-PyOS_ascii_strtod(const char *nptr, char **endptr)
-{
- char *fail_pos;
- double val = -1.0;
- struct lconv *locale_data;
- const char *decimal_point;
- size_t decimal_point_len;
- const char *p, *decimal_point_pos;
- const char *end = NULL; /* Silence gcc */
-
- assert(nptr != NULL);
-
- fail_pos = NULL;
-
- locale_data = localeconv();
- decimal_point = locale_data->decimal_point;
- decimal_point_len = strlen(decimal_point);
-
- assert(decimal_point_len != 0);
-
- decimal_point_pos = NULL;
- if (decimal_point[0] != '.' ||
- decimal_point[1] != 0)
- {
- p = nptr;
- /* Skip leading space */
- while (ISSPACE(*p))
- p++;
-
- /* Skip leading optional sign */
- if (*p == '+' || *p == '-')
- p++;
-
- while (ISDIGIT(*p))
- p++;
-
- if (*p == '.')
- {
- decimal_point_pos = p++;
-
- while (ISDIGIT(*p))
- p++;
-
- if (*p == 'e' || *p == 'E')
- p++;
- if (*p == '+' || *p == '-')
- p++;
- while (ISDIGIT(*p))
- p++;
- end = p;
- }
- else if (strncmp(p, decimal_point, decimal_point_len) == 0)
- {
- /* Python bug #1417699 */
- *endptr = (char*)nptr;
- errno = EINVAL;
- return val;
- }
- /* For the other cases, we need not convert the decimal point */
- }
-
- /* Set errno to zero, so that we can distinguish zero results
- and underflows */
- errno = 0;
-
- if (decimal_point_pos)
- {
- char *copy, *c;
-
- /* We need to convert the '.' to the locale specific decimal point */
- copy = (char *)PyMem_MALLOC(end - nptr + 1 + decimal_point_len);
- if (copy == NULL) {
- if (endptr)
- *endptr = (char *)nptr;
- errno = ENOMEM;
- return val;
- }
-
- c = copy;
- memcpy(c, nptr, decimal_point_pos - nptr);
- c += decimal_point_pos - nptr;
- memcpy(c, decimal_point, decimal_point_len);
- c += decimal_point_len;
- memcpy(c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
- c += end - (decimal_point_pos + 1);
- *c = 0;
-
- val = strtod(copy, &fail_pos);
-
- if (fail_pos)
- {
- if (fail_pos > decimal_point_pos)
- fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
- else
- fail_pos = (char *)nptr + (fail_pos - copy);
- }
-
- PyMem_FREE(copy);
-
- }
- else {
- unsigned i = 0;
- if (nptr[i] == '-')
- i++;
- if (nptr[i] == '0' && (nptr[i+1] == 'x' || nptr[i+1] == 'X'))
- fail_pos = (char*)nptr;
- else
- val = strtod(nptr, &fail_pos);
- }
-
- if (endptr)
- *endptr = fail_pos;
-
- return val;
-}
-
-
-/**
- * PyOS_ascii_formatd:
- * @buffer: A buffer to place the resulting string in
- * @buf_len: The length of the buffer.
- * @format: The printf()-style format to use for the
- * code to use for converting.
- * @d: The #gdouble to convert
- *
- * Converts a #gdouble to a string, using the '.' as
- * decimal point. To format the number you pass in
- * a printf()-style format string. Allowed conversion
- * specifiers are 'e', 'E', 'f', 'F', 'g' and 'G'.
- *
- * Return value: The pointer to the buffer with the converted string.
- **/
-char *
-PyOS_ascii_formatd(char *buffer,
- size_t buf_len,
- const char *format,
- double d)
-{
- struct lconv *locale_data;
- const char *decimal_point;
- size_t decimal_point_len, rest_len;
- char *p;
- char format_char;
-
-/* g_return_val_if_fail (buffer != NULL, NULL); */
-/* g_return_val_if_fail (format[0] == '%', NULL); */
-/* g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL); */
-
- format_char = format[strlen(format) - 1];
-
-/* g_return_val_if_fail (format_char == 'e' || format_char == 'E' || */
-/* format_char == 'f' || format_char == 'F' || */
-/* format_char == 'g' || format_char == 'G', */
-/* NULL); */
-
- if (format[0] != '%')
- return NULL;
-
- if (strpbrk(format + 1, "'l%"))
- return NULL;
-
- if (!(format_char == 'e' || format_char == 'E' ||
- format_char == 'f' || format_char == 'F' ||
- format_char == 'g' || format_char == 'G'))
- return NULL;
-
-
- PyOS_snprintf(buffer, buf_len, format, d);
-
- locale_data = localeconv();
- decimal_point = locale_data->decimal_point;
- decimal_point_len = strlen(decimal_point);
-
- assert(decimal_point_len != 0);
-
- if (decimal_point[0] != '.' ||
- decimal_point[1] != 0)
- {
- p = buffer;
-
- if (*p == '+' || *p == '-')
- p++;
-
- while (isdigit((unsigned char)*p))
- p++;
-
- if (strncmp(p, decimal_point, decimal_point_len) == 0)
- {
- *p = '.';
- p++;
- if (decimal_point_len > 1) {
- rest_len = strlen(p + (decimal_point_len - 1));
- memmove(p, p + (decimal_point_len - 1),
- rest_len);
- p[rest_len] = 0;
- }
- }
- }
-
- return buffer;
-}
-
-double
-PyOS_ascii_atof(const char *nptr)
-{
- return PyOS_ascii_strtod(nptr, NULL);
-}
diff --git a/sys/src/cmd/python/Python/pythonrun.c b/sys/src/cmd/python/Python/pythonrun.c
deleted file mode 100644
index 75241fe91..000000000
--- a/sys/src/cmd/python/Python/pythonrun.c
+++ /dev/null
@@ -1,1857 +0,0 @@
-
-/* Python interpreter top-level routines, including init/exit */
-
-#include "Python.h"
-
-#include "Python-ast.h"
-#include "grammar.h"
-#include "node.h"
-#include "token.h"
-#include "parsetok.h"
-#include "errcode.h"
-#include "code.h"
-#include "compile.h"
-#include "symtable.h"
-#include "pyarena.h"
-#include "ast.h"
-#include "eval.h"
-#include "marshal.h"
-
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-
-#ifdef HAVE_LANGINFO_H
-#include <locale.h>
-#include <langinfo.h>
-#endif
-
-#ifdef MS_WINDOWS
-#undef BYTE
-#include "windows.h"
-#endif
-
-#ifndef Py_REF_DEBUG
-#define PRINT_TOTAL_REFS()
-#else /* Py_REF_DEBUG */
-#define PRINT_TOTAL_REFS() fprintf(stderr, \
- "[%" PY_FORMAT_SIZE_T "d refs]\n", \
- _Py_GetRefTotal())
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern char *Py_GetPath(void);
-
-extern grammar _PyParser_Grammar; /* From graminit.c */
-
-/* Forward */
-static void initmain(void);
-static void initsite(void);
-static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,
- PyCompilerFlags *, PyArena *);
-static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
- PyCompilerFlags *);
-static void err_input(perrdetail *);
-static void initsigs(void);
-static void call_sys_exitfunc(void);
-static void call_ll_exitfuncs(void);
-extern void _PyUnicode_Init(void);
-extern void _PyUnicode_Fini(void);
-
-#ifdef WITH_THREAD
-extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *);
-extern void _PyGILState_Fini(void);
-#endif /* WITH_THREAD */
-
-int Py_DebugFlag; /* Needed by parser.c */
-int Py_VerboseFlag; /* Needed by import.c */
-int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */
-int Py_NoSiteFlag; /* Suppress 'import site' */
-int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */
-int Py_FrozenFlag; /* Needed by getpath.c */
-int Py_UnicodeFlag = 0; /* Needed by compile.c */
-int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
-/* _XXX Py_QnewFlag should go away in 2.3. It's true iff -Qnew is passed,
- on the command line, and is used in 2.2 by ceval.c to make all "/" divisions
- true divisions (which they will be in 2.3). */
-int _Py_QnewFlag = 0;
-
-/* Reference to 'warnings' module, to avoid importing it
- on the fly when the import lock may be held. See 683658/771097
-*/
-static PyObject *warnings_module = NULL;
-
-/* Returns a borrowed reference to the 'warnings' module, or NULL.
- If the module is returned, it is guaranteed to have been obtained
- without acquiring the import lock
-*/
-PyObject *PyModule_GetWarningsModule(void)
-{
- PyObject *typ, *val, *tb;
- PyObject *all_modules;
- /* If we managed to get the module at init time, just use it */
- if (warnings_module)
- return warnings_module;
- /* If it wasn't available at init time, it may be available
- now in sys.modules (common scenario is frozen apps: import
- at init time fails, but the frozen init code sets up sys.path
- correctly, then does an implicit import of warnings for us
- */
- /* Save and restore any exceptions */
- PyErr_Fetch(&typ, &val, &tb);
-
- all_modules = PySys_GetObject("modules");
- if (all_modules) {
- warnings_module = PyDict_GetItemString(all_modules, "warnings");
- /* We keep a ref in the global */
- Py_XINCREF(warnings_module);
- }
- PyErr_Restore(typ, val, tb);
- return warnings_module;
-}
-
-static int initialized = 0;
-
-/* API to access the initialized flag -- useful for esoteric use */
-
-int
-Py_IsInitialized(void)
-{
- return initialized;
-}
-
-/* Global initializations. Can be undone by Py_Finalize(). Don't
- call this twice without an intervening Py_Finalize() call. When
- initializations fail, a fatal error is issued and the function does
- not return. On return, the first thread and interpreter state have
- been created.
-
- Locking: you must hold the interpreter lock while calling this.
- (If the lock has not yet been initialized, that's equivalent to
- having the lock, but you cannot use multiple threads.)
-
-*/
-
-static int
-add_flag(int flag, const char *envs)
-{
- int env = atoi(envs);
- if (flag < env)
- flag = env;
- if (flag < 1)
- flag = 1;
- return flag;
-}
-
-void
-Py_InitializeEx(int install_sigs)
-{
- PyInterpreterState *interp;
- PyThreadState *tstate;
- PyObject *bimod, *sysmod;
- char *p;
-#if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET)
- char *codeset;
- char *saved_locale;
- PyObject *sys_stream, *sys_isatty;
-#endif
- extern void _Py_ReadyTypes(void);
-
- if (initialized)
- return;
- initialized = 1;
-
- if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0')
- Py_DebugFlag = add_flag(Py_DebugFlag, p);
- if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0')
- Py_VerboseFlag = add_flag(Py_VerboseFlag, p);
- if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0')
- Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p);
-
- interp = PyInterpreterState_New();
- if (interp == NULL)
- Py_FatalError("Py_Initialize: can't make first interpreter");
-
- tstate = PyThreadState_New(interp);
- if (tstate == NULL)
- Py_FatalError("Py_Initialize: can't make first thread");
- (void) PyThreadState_Swap(tstate);
-
- _Py_ReadyTypes();
-
- if (!_PyFrame_Init())
- Py_FatalError("Py_Initialize: can't init frames");
-
- if (!_PyInt_Init())
- Py_FatalError("Py_Initialize: can't init ints");
-
- _PyFloat_Init();
-
- interp->modules = PyDict_New();
- if (interp->modules == NULL)
- Py_FatalError("Py_Initialize: can't make modules dictionary");
- interp->modules_reloading = PyDict_New();
- if (interp->modules_reloading == NULL)
- Py_FatalError("Py_Initialize: can't make modules_reloading dictionary");
-
-#ifdef Py_USING_UNICODE
- /* Init Unicode implementation; relies on the codec registry */
- _PyUnicode_Init();
-#endif
-
- bimod = _PyBuiltin_Init();
- if (bimod == NULL)
- Py_FatalError("Py_Initialize: can't initialize __builtin__");
- interp->builtins = PyModule_GetDict(bimod);
- if (interp->builtins == NULL)
- Py_FatalError("Py_Initialize: can't initialize builtins dict");
- Py_INCREF(interp->builtins);
-
- sysmod = _PySys_Init();
- if (sysmod == NULL)
- Py_FatalError("Py_Initialize: can't initialize sys");
- interp->sysdict = PyModule_GetDict(sysmod);
- if (interp->sysdict == NULL)
- Py_FatalError("Py_Initialize: can't initialize sys dict");
- Py_INCREF(interp->sysdict);
- _PyImport_FixupExtension("sys", "sys");
- PySys_SetPath(Py_GetPath());
- PyDict_SetItemString(interp->sysdict, "modules",
- interp->modules);
-
- _PyImport_Init();
-
- /* initialize builtin exceptions */
- _PyExc_Init();
- _PyImport_FixupExtension("exceptions", "exceptions");
-
- /* phase 2 of builtins */
- _PyImport_FixupExtension("__builtin__", "__builtin__");
-
- _PyImportHooks_Init();
-
- if (install_sigs)
- initsigs(); /* Signal handling stuff, including initintr() */
-
- initmain(); /* Module __main__ */
- if (!Py_NoSiteFlag)
- initsite(); /* Module site */
-
- /* auto-thread-state API, if available */
-#ifdef WITH_THREAD
- _PyGILState_Init(interp, tstate);
-#endif /* WITH_THREAD */
-
- warnings_module = PyImport_ImportModule("warnings");
- if (!warnings_module)
- PyErr_Clear();
-
-#if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET)
- /* On Unix, set the file system encoding according to the
- user's preference, if the CODESET names a well-known
- Python codec, and Py_FileSystemDefaultEncoding isn't
- initialized by other means. Also set the encoding of
- stdin and stdout if these are terminals. */
-
- saved_locale = strdup(setlocale(LC_CTYPE, NULL));
- setlocale(LC_CTYPE, "");
- codeset = nl_langinfo(CODESET);
- if (codeset && *codeset) {
- PyObject *enc = PyCodec_Encoder(codeset);
- if (enc) {
- codeset = strdup(codeset);
- Py_DECREF(enc);
- } else {
- codeset = NULL;
- PyErr_Clear();
- }
- } else
- codeset = NULL;
- setlocale(LC_CTYPE, saved_locale);
- free(saved_locale);
-
- if (codeset) {
- sys_stream = PySys_GetObject("stdin");
- sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
- if (!sys_isatty)
- PyErr_Clear();
- if(sys_isatty && PyObject_IsTrue(sys_isatty) &&
- PyFile_Check(sys_stream)) {
- if (!PyFile_SetEncoding(sys_stream, codeset))
- Py_FatalError("Cannot set codeset of stdin");
- }
- Py_XDECREF(sys_isatty);
-
- sys_stream = PySys_GetObject("stdout");
- sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
- if (!sys_isatty)
- PyErr_Clear();
- if(sys_isatty && PyObject_IsTrue(sys_isatty) &&
- PyFile_Check(sys_stream)) {
- if (!PyFile_SetEncoding(sys_stream, codeset))
- Py_FatalError("Cannot set codeset of stdout");
- }
- Py_XDECREF(sys_isatty);
-
- sys_stream = PySys_GetObject("stderr");
- sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
- if (!sys_isatty)
- PyErr_Clear();
- if(sys_isatty && PyObject_IsTrue(sys_isatty) &&
- PyFile_Check(sys_stream)) {
- if (!PyFile_SetEncoding(sys_stream, codeset))
- Py_FatalError("Cannot set codeset of stderr");
- }
- Py_XDECREF(sys_isatty);
-
- if (!Py_FileSystemDefaultEncoding)
- Py_FileSystemDefaultEncoding = codeset;
- else
- free(codeset);
- }
-#endif
-}
-
-void
-Py_Initialize(void)
-{
- Py_InitializeEx(1);
-}
-
-
-#ifdef COUNT_ALLOCS
-extern void dump_counts(FILE*);
-#endif
-
-/* Undo the effect of Py_Initialize().
-
- Beware: if multiple interpreter and/or thread states exist, these
- are not wiped out; only the current thread and interpreter state
- are deleted. But since everything else is deleted, those other
- interpreter and thread states should no longer be used.
-
- (XXX We should do better, e.g. wipe out all interpreters and
- threads.)
-
- Locking: as above.
-
-*/
-
-void
-Py_Finalize(void)
-{
- PyInterpreterState *interp;
- PyThreadState *tstate;
-
- if (!initialized)
- return;
-
- /* The interpreter is still entirely intact at this point, and the
- * exit funcs may be relying on that. In particular, if some thread
- * or exit func is still waiting to do an import, the import machinery
- * expects Py_IsInitialized() to return true. So don't say the
- * interpreter is uninitialized until after the exit funcs have run.
- * Note that Threading.py uses an exit func to do a join on all the
- * threads created thru it, so this also protects pending imports in
- * the threads created via Threading.
- */
- call_sys_exitfunc();
- initialized = 0;
-
- /* Get current thread state and interpreter pointer */
- tstate = PyThreadState_GET();
- interp = tstate->interp;
-
- /* Disable signal handling */
- PyOS_FiniInterrupts();
-
- /* drop module references we saved */
- Py_XDECREF(warnings_module);
- warnings_module = NULL;
-
- /* Collect garbage. This may call finalizers; it's nice to call these
- * before all modules are destroyed.
- * XXX If a __del__ or weakref callback is triggered here, and tries to
- * XXX import a module, bad things can happen, because Python no
- * XXX longer believes it's initialized.
- * XXX Fatal Python error: Interpreter not initialized (version mismatch?)
- * XXX is easy to provoke that way. I've also seen, e.g.,
- * XXX Exception exceptions.ImportError: 'No module named sha'
- * XXX in <function callback at 0x008F5718> ignored
- * XXX but I'm unclear on exactly how that one happens. In any case,
- * XXX I haven't seen a real-life report of either of these.
- */
- PyGC_Collect();
-#ifdef COUNT_ALLOCS
- /* With COUNT_ALLOCS, it helps to run GC multiple times:
- each collection might release some types from the type
- list, so they become garbage. */
- while (PyGC_Collect() > 0)
- /* nothing */;
-#endif
-
- /* Destroy all modules */
- PyImport_Cleanup();
-
- /* Collect final garbage. This disposes of cycles created by
- * new-style class definitions, for example.
- * XXX This is disabled because it caused too many problems. If
- * XXX a __del__ or weakref callback triggers here, Python code has
- * XXX a hard time running, because even the sys module has been
- * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc).
- * XXX One symptom is a sequence of information-free messages
- * XXX coming from threads (if a __del__ or callback is invoked,
- * XXX other threads can execute too, and any exception they encounter
- * XXX triggers a comedy of errors as subsystem after subsystem
- * XXX fails to find what it *expects* to find in sys to help report
- * XXX the exception and consequent unexpected failures). I've also
- * XXX seen segfaults then, after adding print statements to the
- * XXX Python code getting called.
- */
-#if 0
- PyGC_Collect();
-#endif
-
- /* Destroy the database used by _PyImport_{Fixup,Find}Extension */
- _PyImport_Fini();
-
- /* Debugging stuff */
-#ifdef COUNT_ALLOCS
- dump_counts(stdout);
-#endif
-
- PRINT_TOTAL_REFS();
-
-#ifdef Py_TRACE_REFS
- /* Display all objects still alive -- this can invoke arbitrary
- * __repr__ overrides, so requires a mostly-intact interpreter.
- * Alas, a lot of stuff may still be alive now that will be cleaned
- * up later.
- */
- if (Py_GETENV("PYTHONDUMPREFS"))
- _Py_PrintReferences(stderr);
-#endif /* Py_TRACE_REFS */
-
- /* Cleanup auto-thread-state */
-#ifdef WITH_THREAD
- _PyGILState_Fini();
-#endif /* WITH_THREAD */
-
- /* Clear interpreter state */
- PyInterpreterState_Clear(interp);
-
- /* Now we decref the exception classes. After this point nothing
- can raise an exception. That's okay, because each Fini() method
- below has been checked to make sure no exceptions are ever
- raised.
- */
-
- _PyExc_Fini();
-
- /* Delete current thread */
- PyThreadState_Swap(NULL);
- PyInterpreterState_Delete(interp);
-
- /* Sundry finalizers */
- PyMethod_Fini();
- PyFrame_Fini();
- PyCFunction_Fini();
- PyTuple_Fini();
- PyList_Fini();
- PySet_Fini();
- PyString_Fini();
- PyInt_Fini();
- PyFloat_Fini();
-
-#ifdef Py_USING_UNICODE
- /* Cleanup Unicode implementation */
- _PyUnicode_Fini();
-#endif
-
- /* XXX Still allocated:
- - various static ad-hoc pointers to interned strings
- - int and float free list blocks
- - whatever various modules and libraries allocate
- */
-
- PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
-
-#ifdef Py_TRACE_REFS
- /* Display addresses (& refcnts) of all objects still alive.
- * An address can be used to find the repr of the object, printed
- * above by _Py_PrintReferences.
- */
- if (Py_GETENV("PYTHONDUMPREFS"))
- _Py_PrintReferenceAddresses(stderr);
-#endif /* Py_TRACE_REFS */
-#ifdef PYMALLOC_DEBUG
- if (Py_GETENV("PYTHONMALLOCSTATS"))
- _PyObject_DebugMallocStats();
-#endif
-
- call_ll_exitfuncs();
-}
-
-/* Create and initialize a new interpreter and thread, and return the
- new thread. This requires that Py_Initialize() has been called
- first.
-
- Unsuccessful initialization yields a NULL pointer. Note that *no*
- exception information is available even in this case -- the
- exception information is held in the thread, and there is no
- thread.
-
- Locking: as above.
-
-*/
-
-PyThreadState *
-Py_NewInterpreter(void)
-{
- PyInterpreterState *interp;
- PyThreadState *tstate, *save_tstate;
- PyObject *bimod, *sysmod;
-
- if (!initialized)
- Py_FatalError("Py_NewInterpreter: call Py_Initialize first");
-
- interp = PyInterpreterState_New();
- if (interp == NULL)
- return NULL;
-
- tstate = PyThreadState_New(interp);
- if (tstate == NULL) {
- PyInterpreterState_Delete(interp);
- return NULL;
- }
-
- save_tstate = PyThreadState_Swap(tstate);
-
- /* XXX The following is lax in error checking */
-
- interp->modules = PyDict_New();
- interp->modules_reloading = PyDict_New();
-
- bimod = _PyImport_FindExtension("__builtin__", "__builtin__");
- if (bimod != NULL) {
- interp->builtins = PyModule_GetDict(bimod);
- if (interp->builtins == NULL)
- goto handle_error;
- Py_INCREF(interp->builtins);
- }
- sysmod = _PyImport_FindExtension("sys", "sys");
- if (bimod != NULL && sysmod != NULL) {
- interp->sysdict = PyModule_GetDict(sysmod);
- if (interp->sysdict == NULL)
- goto handle_error;
- Py_INCREF(interp->sysdict);
- PySys_SetPath(Py_GetPath());
- PyDict_SetItemString(interp->sysdict, "modules",
- interp->modules);
- _PyImportHooks_Init();
- initmain();
- if (!Py_NoSiteFlag)
- initsite();
- }
-
- if (!PyErr_Occurred())
- return tstate;
-
-handle_error:
- /* Oops, it didn't work. Undo it all. */
-
- PyErr_Print();
- PyThreadState_Clear(tstate);
- PyThreadState_Swap(save_tstate);
- PyThreadState_Delete(tstate);
- PyInterpreterState_Delete(interp);
-
- return NULL;
-}
-
-/* Delete an interpreter and its last thread. This requires that the
- given thread state is current, that the thread has no remaining
- frames, and that it is its interpreter's only remaining thread.
- It is a fatal error to violate these constraints.
-
- (Py_Finalize() doesn't have these constraints -- it zaps
- everything, regardless.)
-
- Locking: as above.
-
-*/
-
-void
-Py_EndInterpreter(PyThreadState *tstate)
-{
- PyInterpreterState *interp = tstate->interp;
-
- if (tstate != PyThreadState_GET())
- Py_FatalError("Py_EndInterpreter: thread is not current");
- if (tstate->frame != NULL)
- Py_FatalError("Py_EndInterpreter: thread still has a frame");
- if (tstate != interp->tstate_head || tstate->next != NULL)
- Py_FatalError("Py_EndInterpreter: not the last thread");
-
- PyImport_Cleanup();
- PyInterpreterState_Clear(interp);
- PyThreadState_Swap(NULL);
- PyInterpreterState_Delete(interp);
-}
-
-static char *progname = "python";
-
-void
-Py_SetProgramName(char *pn)
-{
- if (pn && *pn)
- progname = pn;
-}
-
-char *
-Py_GetProgramName(void)
-{
- return progname;
-}
-
-static char *default_home = NULL;
-
-void
-Py_SetPythonHome(char *home)
-{
- default_home = home;
-}
-
-char *
-Py_GetPythonHome(void)
-{
- char *home = default_home;
- if (home == NULL && !Py_IgnoreEnvironmentFlag)
- home = Py_GETENV("PYTHONHOME");
- return home;
-}
-
-/* Create __main__ module */
-
-static void
-initmain(void)
-{
- PyObject *m, *d;
- m = PyImport_AddModule("__main__");
- if (m == NULL)
- Py_FatalError("can't create __main__ module");
- d = PyModule_GetDict(m);
- if (PyDict_GetItemString(d, "__builtins__") == NULL) {
- PyObject *bimod = PyImport_ImportModule("__builtin__");
- if (bimod == NULL ||
- PyDict_SetItemString(d, "__builtins__", bimod) != 0)
- Py_FatalError("can't add __builtins__ to __main__");
- Py_DECREF(bimod);
- }
-}
-
-/* Import the site module (not into __main__ though) */
-
-static void
-initsite(void)
-{
- PyObject *m, *f;
- m = PyImport_ImportModule("site");
- if (m == NULL) {
- f = PySys_GetObject("stderr");
- if (Py_VerboseFlag) {
- PyFile_WriteString(
- "'import site' failed; traceback:\n", f);
- PyErr_Print();
- }
- else {
- PyFile_WriteString(
- "'import site' failed; use -v for traceback\n", f);
- PyErr_Clear();
- }
- }
- else {
- Py_DECREF(m);
- }
-}
-
-/* Parse input from a file and execute it */
-
-int
-PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
- PyCompilerFlags *flags)
-{
- if (filename == NULL)
- filename = "???";
- if (Py_FdIsInteractive(fp, filename)) {
- int err = PyRun_InteractiveLoopFlags(fp, filename, flags);
- if (closeit)
- fclose(fp);
- return err;
- }
- else
- return PyRun_SimpleFileExFlags(fp, filename, closeit, flags);
-}
-
-int
-PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
-{
- PyObject *v;
- int ret;
- PyCompilerFlags local_flags;
-
- if (flags == NULL) {
- flags = &local_flags;
- local_flags.cf_flags = 0;
- }
- v = PySys_GetObject("ps1");
- if (v == NULL) {
- PySys_SetObject("ps1", v = PyString_FromString(">>> "));
- Py_XDECREF(v);
- }
- v = PySys_GetObject("ps2");
- if (v == NULL) {
- PySys_SetObject("ps2", v = PyString_FromString("... "));
- Py_XDECREF(v);
- }
- for (;;) {
- ret = PyRun_InteractiveOneFlags(fp, filename, flags);
- PRINT_TOTAL_REFS();
- if (ret == E_EOF)
- return 0;
- /*
- if (ret == E_NOMEM)
- return -1;
- */
- }
-}
-
-/* compute parser flags based on compiler flags */
-#define PARSER_FLAGS(flags) \
- ((flags) ? ((((flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \
- PyPARSE_DONT_IMPLY_DEDENT : 0) \
- | ((flags)->cf_flags & CO_FUTURE_WITH_STATEMENT ? \
- PyPARSE_WITH_IS_KEYWORD : 0)) : 0)
-
-int
-PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
-{
- PyObject *m, *d, *v, *w;
- mod_ty mod;
- PyArena *arena;
- char *ps1 = "", *ps2 = "";
- int errcode = 0;
-
- v = PySys_GetObject("ps1");
- if (v != NULL) {
- v = PyObject_Str(v);
- if (v == NULL)
- PyErr_Clear();
- else if (PyString_Check(v))
- ps1 = PyString_AsString(v);
- }
- w = PySys_GetObject("ps2");
- if (w != NULL) {
- w = PyObject_Str(w);
- if (w == NULL)
- PyErr_Clear();
- else if (PyString_Check(w))
- ps2 = PyString_AsString(w);
- }
- arena = PyArena_New();
- if (arena == NULL) {
- Py_XDECREF(v);
- Py_XDECREF(w);
- return -1;
- }
- mod = PyParser_ASTFromFile(fp, filename,
- Py_single_input, ps1, ps2,
- flags, &errcode, arena);
- Py_XDECREF(v);
- Py_XDECREF(w);
- if (mod == NULL) {
- PyArena_Free(arena);
- if (errcode == E_EOF) {
- PyErr_Clear();
- return E_EOF;
- }
- PyErr_Print();
- return -1;
- }
- m = PyImport_AddModule("__main__");
- if (m == NULL) {
- PyArena_Free(arena);
- return -1;
- }
- d = PyModule_GetDict(m);
- v = run_mod(mod, filename, d, d, flags, arena);
- PyArena_Free(arena);
- if (v == NULL) {
- PyErr_Print();
- return -1;
- }
- Py_DECREF(v);
- if (Py_FlushLine())
- PyErr_Clear();
- return 0;
-}
-
-/* Check whether a file maybe a pyc file: Look at the extension,
- the file type, and, if we may close it, at the first few bytes. */
-
-static int
-maybe_pyc_file(FILE *fp, const char* filename, const char* ext, int closeit)
-{
- if (strcmp(ext, ".pyc") == 0 || strcmp(ext, ".pyo") == 0)
- return 1;
-
- /* Only look into the file if we are allowed to close it, since
- it then should also be seekable. */
- if (closeit) {
- /* Read only two bytes of the magic. If the file was opened in
- text mode, the bytes 3 and 4 of the magic (\r\n) might not
- be read as they are on disk. */
- unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF;
- unsigned char buf[2];
- /* Mess: In case of -x, the stream is NOT at its start now,
- and ungetc() was used to push back the first newline,
- which makes the current stream position formally undefined,
- and a x-platform nightmare.
- Unfortunately, we have no direct way to know whether -x
- was specified. So we use a terrible hack: if the current
- stream position is not 0, we assume -x was specified, and
- give up. Bug 132850 on SourceForge spells out the
- hopelessness of trying anything else (fseek and ftell
- don't work predictably x-platform for text-mode files).
- */
- int ispyc = 0;
- if (ftell(fp) == 0) {
- if (fread(buf, 1, 2, fp) == 2 &&
- ((unsigned int)buf[1]<<8 | buf[0]) == halfmagic)
- ispyc = 1;
- rewind(fp);
- }
- return ispyc;
- }
- return 0;
-}
-
-int
-PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
- PyCompilerFlags *flags)
-{
- PyObject *m, *d, *v;
- const char *ext;
-
- m = PyImport_AddModule("__main__");
- if (m == NULL)
- return -1;
- d = PyModule_GetDict(m);
- if (PyDict_GetItemString(d, "__file__") == NULL) {
- PyObject *f = PyString_FromString(filename);
- if (f == NULL)
- return -1;
- if (PyDict_SetItemString(d, "__file__", f) < 0) {
- Py_DECREF(f);
- return -1;
- }
- Py_DECREF(f);
- }
- ext = filename + strlen(filename) - 4;
- if (maybe_pyc_file(fp, filename, ext, closeit)) {
- /* Try to run a pyc file. First, re-open in binary */
- if (closeit)
- fclose(fp);
- if ((fp = fopen(filename, "rb")) == NULL) {
- fprintf(stderr, "python: Can't reopen .pyc file\n");
- return -1;
- }
- /* Turn on optimization if a .pyo file is given */
- if (strcmp(ext, ".pyo") == 0)
- Py_OptimizeFlag = 1;
- v = run_pyc_file(fp, filename, d, d, flags);
- } else {
- v = PyRun_FileExFlags(fp, filename, Py_file_input, d, d,
- closeit, flags);
- }
- if (v == NULL) {
- PyErr_Print();
- return -1;
- }
- Py_DECREF(v);
- if (Py_FlushLine())
- PyErr_Clear();
- return 0;
-}
-
-int
-PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
-{
- PyObject *m, *d, *v;
- m = PyImport_AddModule("__main__");
- if (m == NULL)
- return -1;
- d = PyModule_GetDict(m);
- v = PyRun_StringFlags(command, Py_file_input, d, d, flags);
- if (v == NULL) {
- PyErr_Print();
- return -1;
- }
- Py_DECREF(v);
- if (Py_FlushLine())
- PyErr_Clear();
- return 0;
-}
-
-static int
-parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
- int *lineno, int *offset, const char **text)
-{
- long hold;
- PyObject *v;
-
- /* old style errors */
- if (PyTuple_Check(err))
- return PyArg_ParseTuple(err, "O(ziiz)", message, filename,
- lineno, offset, text);
-
- /* new style errors. `err' is an instance */
-
- if (! (v = PyObject_GetAttrString(err, "msg")))
- goto finally;
- *message = v;
-
- if (!(v = PyObject_GetAttrString(err, "filename")))
- goto finally;
- if (v == Py_None)
- *filename = NULL;
- else if (! (*filename = PyString_AsString(v)))
- goto finally;
-
- Py_DECREF(v);
- if (!(v = PyObject_GetAttrString(err, "lineno")))
- goto finally;
- hold = PyInt_AsLong(v);
- Py_DECREF(v);
- v = NULL;
- if (hold < 0 && PyErr_Occurred())
- goto finally;
- *lineno = (int)hold;
-
- if (!(v = PyObject_GetAttrString(err, "offset")))
- goto finally;
- if (v == Py_None) {
- *offset = -1;
- Py_DECREF(v);
- v = NULL;
- } else {
- hold = PyInt_AsLong(v);
- Py_DECREF(v);
- v = NULL;
- if (hold < 0 && PyErr_Occurred())
- goto finally;
- *offset = (int)hold;
- }
-
- if (!(v = PyObject_GetAttrString(err, "text")))
- goto finally;
- if (v == Py_None)
- *text = NULL;
- else if (! (*text = PyString_AsString(v)))
- goto finally;
- Py_DECREF(v);
- return 1;
-
-finally:
- Py_XDECREF(v);
- return 0;
-}
-
-void
-PyErr_Print(void)
-{
- PyErr_PrintEx(1);
-}
-
-static void
-print_error_text(PyObject *f, int offset, const char *text)
-{
- char *nl;
- if (offset >= 0) {
- if (offset > 0 && offset == (int)strlen(text))
- offset--;
- for (;;) {
- nl = strchr(text, '\n');
- if (nl == NULL || nl-text >= offset)
- break;
- offset -= (int)(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);
- if (offset == -1)
- return;
- PyFile_WriteString(" ", f);
- offset--;
- while (offset > 0) {
- PyFile_WriteString(" ", f);
- offset--;
- }
- PyFile_WriteString("^\n", f);
-}
-
-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 */
-}
-
-void
-PyErr_PrintEx(int set_sys_last_vars)
-{
- PyObject *exception, *v, *tb, *hook;
-
- if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
- handle_system_exit();
- }
- PyErr_Fetch(&exception, &v, &tb);
- if (exception == NULL)
- return;
- PyErr_NormalizeException(&exception, &v, &tb);
- if (exception == NULL)
- return;
- /* Now we know v != NULL too */
- if (set_sys_last_vars) {
- PySys_SetObject("last_type", exception);
- PySys_SetObject("last_value", v);
- PySys_SetObject("last_traceback", tb);
- }
- hook = PySys_GetObject("excepthook");
- if (hook) {
- PyObject *args = PyTuple_Pack(3,
- exception, v, tb ? tb : Py_None);
- PyObject *result = PyEval_CallObject(hook, args);
- if (result == NULL) {
- PyObject *exception2, *v2, *tb2;
- if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
- handle_system_exit();
- }
- PyErr_Fetch(&exception2, &v2, &tb2);
- PyErr_NormalizeException(&exception2, &v2, &tb2);
- /* It should not be possible for exception2 or v2
- to be NULL. However PyErr_Display() can't
- tolerate NULLs, so just be safe. */
- if (exception2 == NULL) {
- exception2 = Py_None;
- Py_INCREF(exception2);
- }
- if (v2 == NULL) {
- v2 = Py_None;
- Py_INCREF(v2);
- }
- if (Py_FlushLine())
- PyErr_Clear();
- fflush(stdout);
- PySys_WriteStderr("Error in sys.excepthook:\n");
- PyErr_Display(exception2, v2, tb2);
- PySys_WriteStderr("\nOriginal exception was:\n");
- PyErr_Display(exception, v, tb);
- Py_DECREF(exception2);
- Py_DECREF(v2);
- Py_XDECREF(tb2);
- }
- Py_XDECREF(result);
- Py_XDECREF(args);
- } else {
- PySys_WriteStderr("sys.excepthook is missing\n");
- PyErr_Display(exception, v, tb);
- }
- Py_XDECREF(exception);
- Py_XDECREF(v);
- Py_XDECREF(tb);
-}
-
-void
-PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
-{
- int err = 0;
- PyObject *f = PySys_GetObject("stderr");
- Py_INCREF(value);
- if (f == NULL)
- fprintf(stderr, "lost sys.stderr\n");
- else {
- if (Py_FlushLine())
- PyErr_Clear();
- fflush(stdout);
- if (tb && tb != Py_None)
- err = PyTraceBack_Print(tb, f);
- if (err == 0 &&
- PyObject_HasAttrString(value, "print_file_and_line"))
- {
- PyObject *message;
- const char *filename, *text;
- int lineno, offset;
- if (!parse_syntax_error(value, &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);
- PyOS_snprintf(buf, sizeof(buf), "%d", lineno);
- PyFile_WriteString(buf, f);
- PyFile_WriteString("\n", f);
- if (text != NULL)
- print_error_text(f, offset, text);
- Py_DECREF(value);
- value = 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 (PyExceptionClass_Check(exception)) {
- PyObject* moduleName;
- char* className = PyExceptionClass_Name(exception);
- if (className != NULL) {
- char *dot = strrchr(className, '.');
- if (dot != NULL)
- className = dot+1;
- }
-
- moduleName = PyObject_GetAttrString(exception, "__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);
- }
- Py_DECREF(moduleName);
- }
- if (err == 0) {
- if (className == NULL)
- err = PyFile_WriteString("<unknown>", f);
- else
- err = PyFile_WriteString(className, f);
- }
- }
- else
- err = PyFile_WriteObject(exception, f, Py_PRINT_RAW);
- if (err == 0 && (value != Py_None)) {
- PyObject *s = PyObject_Str(value);
- /* 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_DECREF(value);
- /* 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();
-}
-
-PyObject *
-PyRun_StringFlags(const char *str, int start, PyObject *globals,
- PyObject *locals, PyCompilerFlags *flags)
-{
- PyObject *ret = NULL;
- mod_ty mod;
- PyArena *arena = PyArena_New();
- if (arena == NULL)
- return NULL;
-
- mod = PyParser_ASTFromString(str, "<string>", start, flags, arena);
- if (mod != NULL)
- ret = run_mod(mod, "<string>", globals, locals, flags, arena);
- PyArena_Free(arena);
- return ret;
-}
-
-PyObject *
-PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
- PyObject *locals, int closeit, PyCompilerFlags *flags)
-{
- PyObject *ret;
- mod_ty mod;
- PyArena *arena = PyArena_New();
- if (arena == NULL)
- return NULL;
-
- mod = PyParser_ASTFromFile(fp, filename, start, 0, 0,
- flags, NULL, arena);
- if (closeit)
- fclose(fp);
- if (mod == NULL) {
- PyArena_Free(arena);
- return NULL;
- }
- ret = run_mod(mod, filename, globals, locals, flags, arena);
- PyArena_Free(arena);
- return ret;
-}
-
-static PyObject *
-run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals,
- PyCompilerFlags *flags, PyArena *arena)
-{
- PyCodeObject *co;
- PyObject *v;
- co = PyAST_Compile(mod, filename, flags, arena);
- if (co == NULL)
- return NULL;
- v = PyEval_EvalCode(co, globals, locals);
- Py_DECREF(co);
- return v;
-}
-
-static PyObject *
-run_pyc_file(FILE *fp, const char *filename, PyObject *globals,
- PyObject *locals, PyCompilerFlags *flags)
-{
- PyCodeObject *co;
- PyObject *v;
- long magic;
- long PyImport_GetMagicNumber(void);
-
- magic = PyMarshal_ReadLongFromFile(fp);
- if (magic != PyImport_GetMagicNumber()) {
- PyErr_SetString(PyExc_RuntimeError,
- "Bad magic number in .pyc file");
- return NULL;
- }
- (void) PyMarshal_ReadLongFromFile(fp);
- v = PyMarshal_ReadLastObjectFromFile(fp);
- fclose(fp);
- if (v == NULL || !PyCode_Check(v)) {
- Py_XDECREF(v);
- PyErr_SetString(PyExc_RuntimeError,
- "Bad code object in .pyc file");
- return NULL;
- }
- co = (PyCodeObject *)v;
- v = PyEval_EvalCode(co, globals, locals);
- if (v && flags)
- flags->cf_flags |= (co->co_flags & PyCF_MASK);
- Py_DECREF(co);
- return v;
-}
-
-PyObject *
-Py_CompileStringFlags(const char *str, const char *filename, int start,
- PyCompilerFlags *flags)
-{
- PyCodeObject *co;
- mod_ty mod;
- PyArena *arena = PyArena_New();
- if (arena == NULL)
- return NULL;
-
- mod = PyParser_ASTFromString(str, filename, start, flags, arena);
- if (mod == NULL) {
- PyArena_Free(arena);
- return NULL;
- }
- if (flags && (flags->cf_flags & PyCF_ONLY_AST)) {
- PyObject *result = PyAST_mod2obj(mod);
- PyArena_Free(arena);
- return result;
- }
- co = PyAST_Compile(mod, filename, flags, arena);
- PyArena_Free(arena);
- return (PyObject *)co;
-}
-
-struct symtable *
-Py_SymtableString(const char *str, const char *filename, int start)
-{
- struct symtable *st;
- mod_ty mod;
- PyArena *arena = PyArena_New();
- if (arena == NULL)
- return NULL;
-
- mod = PyParser_ASTFromString(str, filename, start, NULL, arena);
- if (mod == NULL) {
- PyArena_Free(arena);
- return NULL;
- }
- st = PySymtable_Build(mod, filename, 0);
- PyArena_Free(arena);
- return st;
-}
-
-/* Preferred access to parser is through AST. */
-mod_ty
-PyParser_ASTFromString(const char *s, const char *filename, int start,
- PyCompilerFlags *flags, PyArena *arena)
-{
- mod_ty mod;
- perrdetail err;
- node *n = PyParser_ParseStringFlagsFilename(s, filename,
- &_PyParser_Grammar, start, &err,
- PARSER_FLAGS(flags));
- if (n) {
- mod = PyAST_FromNode(n, flags, filename, arena);
- PyNode_Free(n);
- return mod;
- }
- else {
- err_input(&err);
- return NULL;
- }
-}
-
-mod_ty
-PyParser_ASTFromFile(FILE *fp, const char *filename, int start, char *ps1,
- char *ps2, PyCompilerFlags *flags, int *errcode,
- PyArena *arena)
-{
- mod_ty mod;
- perrdetail err;
- node *n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar,
- start, ps1, ps2, &err, PARSER_FLAGS(flags));
- if (n) {
- mod = PyAST_FromNode(n, flags, filename, arena);
- PyNode_Free(n);
- return mod;
- }
- else {
- err_input(&err);
- if (errcode)
- *errcode = err.error;
- return NULL;
- }
-}
-
-/* Simplified interface to parsefile -- return node or set exception */
-
-node *
-PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags)
-{
- perrdetail err;
- node *n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar,
- start, NULL, NULL, &err, flags);
- if (n == NULL)
- err_input(&err);
-
- return n;
-}
-
-/* Simplified interface to parsestring -- return node or set exception */
-
-node *
-PyParser_SimpleParseStringFlags(const char *str, int start, int flags)
-{
- perrdetail err;
- node *n = PyParser_ParseStringFlags(str, &_PyParser_Grammar,
- start, &err, flags);
- if (n == NULL)
- err_input(&err);
- return n;
-}
-
-node *
-PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename,
- int start, int flags)
-{
- perrdetail err;
- node *n = PyParser_ParseStringFlagsFilename(str, filename,
- &_PyParser_Grammar, start, &err, flags);
- if (n == NULL)
- err_input(&err);
- return n;
-}
-
-node *
-PyParser_SimpleParseStringFilename(const char *str, const char *filename, int start)
-{
- return PyParser_SimpleParseStringFlagsFilename(str, filename, start, 0);
-}
-
-/* May want to move a more generalized form of this to parsetok.c or
- even parser modules. */
-
-void
-PyParser_SetError(perrdetail *err)
-{
- err_input(err);
-}
-
-/* Set the error appropriate to the given input error code (see errcode.h) */
-
-static void
-err_input(perrdetail *err)
-{
- PyObject *v, *w, *errtype;
- PyObject* u = NULL;
- char *msg = NULL;
- errtype = PyExc_SyntaxError;
- switch (err->error) {
- case E_SYNTAX:
- errtype = PyExc_IndentationError;
- if (err->expected == INDENT)
- msg = "expected an indented block";
- else if (err->token == INDENT)
- msg = "unexpected indent";
- else if (err->token == DEDENT)
- msg = "unexpected unindent";
- else {
- errtype = PyExc_SyntaxError;
- msg = "invalid syntax";
- }
- break;
- case E_TOKEN:
- msg = "invalid token";
- break;
- case E_EOFS:
- msg = "EOF while scanning triple-quoted string";
- break;
- case E_EOLS:
- msg = "EOL while scanning single-quoted string";
- break;
- case E_INTR:
- if (!PyErr_Occurred())
- PyErr_SetNone(PyExc_KeyboardInterrupt);
- return;
- case E_NOMEM:
- PyErr_NoMemory();
- return;
- case E_EOF:
- msg = "unexpected EOF while parsing";
- break;
- case E_TABSPACE:
- errtype = PyExc_TabError;
- msg = "inconsistent use of tabs and spaces in indentation";
- break;
- case E_OVERFLOW:
- msg = "expression too long";
- break;
- case E_DEDENT:
- errtype = PyExc_IndentationError;
- msg = "unindent does not match any outer indentation level";
- break;
- case E_TOODEEP:
- errtype = PyExc_IndentationError;
- msg = "too many levels of indentation";
- break;
- case E_DECODE: {
- PyObject *type, *value, *tb;
- PyErr_Fetch(&type, &value, &tb);
- if (value != NULL) {
- u = PyObject_Str(value);
- if (u != NULL) {
- msg = PyString_AsString(u);
- }
- }
- if (msg == NULL)
- msg = "unknown decode error";
- Py_XDECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(tb);
- break;
- }
- case E_LINECONT:
- msg = "unexpected character after line continuation character";
- break;
- default:
- fprintf(stderr, "error=%d\n", err->error);
- msg = "unknown parsing error";
- break;
- }
- v = Py_BuildValue("(ziiz)", err->filename,
- err->lineno, err->offset, err->text);
- if (err->text != NULL) {
- PyObject_FREE(err->text);
- err->text = NULL;
- }
- w = NULL;
- if (v != NULL)
- w = Py_BuildValue("(sO)", msg, v);
- Py_XDECREF(u);
- Py_XDECREF(v);
- PyErr_SetObject(errtype, w);
- Py_XDECREF(w);
-}
-
-/* Print fatal error message and abort */
-
-void
-Py_FatalError(const char *msg)
-{
- fprintf(stderr, "Fatal Python error: %s\n", msg);
-#ifdef MS_WINDOWS
- OutputDebugString("Fatal Python error: ");
- OutputDebugString(msg);
- OutputDebugString("\n");
-#ifdef _DEBUG
- DebugBreak();
-#endif
-#endif /* MS_WINDOWS */
- abort();
-}
-
-/* Clean up and exit */
-
-#ifdef WITH_THREAD
-#include "pythread.h"
-#endif
-
-#define NEXITFUNCS 32
-static void (*exitfuncs[NEXITFUNCS])(void);
-static int nexitfuncs = 0;
-
-int Py_AtExit(void (*func)(void))
-{
- if (nexitfuncs >= NEXITFUNCS)
- return -1;
- exitfuncs[nexitfuncs++] = func;
- return 0;
-}
-
-static void
-call_sys_exitfunc(void)
-{
- PyObject *exitfunc = PySys_GetObject("exitfunc");
-
- if (exitfunc) {
- PyObject *res;
- Py_INCREF(exitfunc);
- PySys_SetObject("exitfunc", (PyObject *)NULL);
- res = PyEval_CallObject(exitfunc, (PyObject *)NULL);
- if (res == NULL) {
- if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
- PySys_WriteStderr("Error in sys.exitfunc:\n");
- }
- PyErr_Print();
- }
- Py_DECREF(exitfunc);
- }
-
- if (Py_FlushLine())
- PyErr_Clear();
-}
-
-static void
-call_ll_exitfuncs(void)
-{
- while (nexitfuncs > 0)
- (*exitfuncs[--nexitfuncs])();
-
- fflush(stdout);
- fflush(stderr);
-}
-
-void
-Py_Exit(int sts)
-{
- Py_Finalize();
-
- exit(sts);
-}
-
-static void
-initsigs(void)
-{
-#ifdef SIGPIPE
- PyOS_setsig(SIGPIPE, SIG_IGN);
-#endif
-#ifdef SIGXFZ
- PyOS_setsig(SIGXFZ, SIG_IGN);
-#endif
-#ifdef SIGXFSZ
- PyOS_setsig(SIGXFSZ, SIG_IGN);
-#endif
- PyOS_InitInterrupts(); /* May imply initsignal() */
-}
-
-
-/*
- * The file descriptor fd is considered ``interactive'' if either
- * a) isatty(fd) is TRUE, or
- * b) the -i flag was given, and the filename associated with
- * the descriptor is NULL or "<stdin>" or "???".
- */
-int
-Py_FdIsInteractive(FILE *fp, const char *filename)
-{
- if (isatty((int)fileno(fp)))
- return 1;
- if (!Py_InteractiveFlag)
- return 0;
- return (filename == NULL) ||
- (strcmp(filename, "<stdin>") == 0) ||
- (strcmp(filename, "???") == 0);
-}
-
-
-#if defined(USE_STACKCHECK)
-#if defined(WIN32) && defined(_MSC_VER)
-
-/* Stack checking for Microsoft C */
-
-#include <malloc.h>
-#include <excpt.h>
-
-/*
- * Return non-zero when we run out of memory on the stack; zero otherwise.
- */
-int
-PyOS_CheckStack(void)
-{
- __try {
- /* alloca throws a stack overflow exception if there's
- not enough space left on the stack */
- alloca(PYOS_STACK_MARGIN * sizeof(void*));
- return 0;
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- /* just ignore all errors */
- }
- return 1;
-}
-
-#endif /* WIN32 && _MSC_VER */
-
-/* Alternate implementations can be added here... */
-
-#endif /* USE_STACKCHECK */
-
-
-/* Wrappers around sigaction() or signal(). */
-
-PyOS_sighandler_t
-PyOS_getsig(int sig)
-{
-#ifdef HAVE_SIGACTION
- struct sigaction context;
- if (sigaction(sig, NULL, &context) == -1)
- return SIG_ERR;
- return context.sa_handler;
-#else
- PyOS_sighandler_t handler;
-/* Special signal handling for the secure CRT in Visual Studio 2005 */
-#if defined(_MSC_VER) && _MSC_VER >= 1400
- switch (sig) {
- /* Only these signals are valid */
- case SIGINT:
- case SIGILL:
- case SIGFPE:
- case SIGSEGV:
- case SIGTERM:
- case SIGBREAK:
- case SIGABRT:
- break;
- /* Don't call signal() with other values or it will assert */
- default:
- return SIG_ERR;
- }
-#endif /* _MSC_VER && _MSC_VER >= 1400 */
- handler = signal(sig, SIG_IGN);
- if (handler != SIG_ERR)
- signal(sig, handler);
- return handler;
-#endif
-}
-
-PyOS_sighandler_t
-PyOS_setsig(int sig, PyOS_sighandler_t handler)
-{
-#ifdef HAVE_SIGACTION
- struct sigaction context, ocontext;
- context.sa_handler = handler;
- sigemptyset(&context.sa_mask);
- context.sa_flags = 0;
- if (sigaction(sig, &context, &ocontext) == -1)
- return SIG_ERR;
- return ocontext.sa_handler;
-#else
- PyOS_sighandler_t oldhandler;
- oldhandler = signal(sig, handler);
-#ifdef HAVE_SIGINTERRUPT
- siginterrupt(sig, 1);
-#endif
- return oldhandler;
-#endif
-}
-
-/* Deprecated C API functions still provided for binary compatiblity */
-
-#undef PyParser_SimpleParseFile
-PyAPI_FUNC(node *)
-PyParser_SimpleParseFile(FILE *fp, const char *filename, int start)
-{
- return PyParser_SimpleParseFileFlags(fp, filename, start, 0);
-}
-
-#undef PyParser_SimpleParseString
-PyAPI_FUNC(node *)
-PyParser_SimpleParseString(const char *str, int start)
-{
- return PyParser_SimpleParseStringFlags(str, start, 0);
-}
-
-#undef PyRun_AnyFile
-PyAPI_FUNC(int)
-PyRun_AnyFile(FILE *fp, const char *name)
-{
- return PyRun_AnyFileExFlags(fp, name, 0, NULL);
-}
-
-#undef PyRun_AnyFileEx
-PyAPI_FUNC(int)
-PyRun_AnyFileEx(FILE *fp, const char *name, int closeit)
-{
- return PyRun_AnyFileExFlags(fp, name, closeit, NULL);
-}
-
-#undef PyRun_AnyFileFlags
-PyAPI_FUNC(int)
-PyRun_AnyFileFlags(FILE *fp, const char *name, PyCompilerFlags *flags)
-{
- return PyRun_AnyFileExFlags(fp, name, 0, flags);
-}
-
-#undef PyRun_File
-PyAPI_FUNC(PyObject *)
-PyRun_File(FILE *fp, const char *p, int s, PyObject *g, PyObject *l)
-{
- return PyRun_FileExFlags(fp, p, s, g, l, 0, NULL);
-}
-
-#undef PyRun_FileEx
-PyAPI_FUNC(PyObject *)
-PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, int c)
-{
- return PyRun_FileExFlags(fp, p, s, g, l, c, NULL);
-}
-
-#undef PyRun_FileFlags
-PyAPI_FUNC(PyObject *)
-PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l,
- PyCompilerFlags *flags)
-{
- return PyRun_FileExFlags(fp, p, s, g, l, 0, flags);
-}
-
-#undef PyRun_SimpleFile
-PyAPI_FUNC(int)
-PyRun_SimpleFile(FILE *f, const char *p)
-{
- return PyRun_SimpleFileExFlags(f, p, 0, NULL);
-}
-
-#undef PyRun_SimpleFileEx
-PyAPI_FUNC(int)
-PyRun_SimpleFileEx(FILE *f, const char *p, int c)
-{
- return PyRun_SimpleFileExFlags(f, p, c, NULL);
-}
-
-
-#undef PyRun_String
-PyAPI_FUNC(PyObject *)
-PyRun_String(const char *str, int s, PyObject *g, PyObject *l)
-{
- return PyRun_StringFlags(str, s, g, l, NULL);
-}
-
-#undef PyRun_SimpleString
-PyAPI_FUNC(int)
-PyRun_SimpleString(const char *s)
-{
- return PyRun_SimpleStringFlags(s, NULL);
-}
-
-#undef Py_CompileString
-PyAPI_FUNC(PyObject *)
-Py_CompileString(const char *str, const char *p, int s)
-{
- return Py_CompileStringFlags(str, p, s, NULL);
-}
-
-#undef PyRun_InteractiveOne
-PyAPI_FUNC(int)
-PyRun_InteractiveOne(FILE *f, const char *p)
-{
- return PyRun_InteractiveOneFlags(f, p, NULL);
-}
-
-#undef PyRun_InteractiveLoop
-PyAPI_FUNC(int)
-PyRun_InteractiveLoop(FILE *f, const char *p)
-{
- return PyRun_InteractiveLoopFlags(f, p, NULL);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
diff --git a/sys/src/cmd/python/Python/sigcheck.c b/sys/src/cmd/python/Python/sigcheck.c
deleted file mode 100644
index 022d0e8ac..000000000
--- a/sys/src/cmd/python/Python/sigcheck.c
+++ /dev/null
@@ -1,19 +0,0 @@
-
-/* Sigcheck is similar to intrcheck() but sets an exception when an
- interrupt occurs. It can't be in the intrcheck.c file since that
- file (and the whole directory it is in) doesn't know about objects
- or exceptions. It can't be in errors.c because it can be
- overridden (at link time) by a more powerful version implemented in
- signalmodule.c. */
-
-#include "Python.h"
-
-/* ARGSUSED */
-int
-PyErr_CheckSignals(void)
-{
- if (!PyOS_InterruptOccurred())
- return 0;
- PyErr_SetNone(PyExc_KeyboardInterrupt);
- return -1;
-}
diff --git a/sys/src/cmd/python/Python/strdup.c b/sys/src/cmd/python/Python/strdup.c
deleted file mode 100644
index 20187e0f0..000000000
--- a/sys/src/cmd/python/Python/strdup.c
+++ /dev/null
@@ -1,14 +0,0 @@
-/* strdup() replacement (from stdwin, if you must know) */
-
-#include "pgenheaders.h"
-
-char *
-strdup(const char *str)
-{
- if (str != NULL) {
- register char *copy = malloc(strlen(str) + 1);
- if (copy != NULL)
- return strcpy(copy, str);
- }
- return NULL;
-}
diff --git a/sys/src/cmd/python/Python/strerror.c b/sys/src/cmd/python/Python/strerror.c
deleted file mode 100644
index 55f8342ec..000000000
--- a/sys/src/cmd/python/Python/strerror.c
+++ /dev/null
@@ -1,19 +0,0 @@
-
-/* PD implementation of strerror() for systems that don't have it.
- Author: Guido van Rossum, CWI Amsterdam, Oct. 1990, <guido@cwi.nl>. */
-
-#include <stdio.h>
-#include "Python.h"
-
-extern int sys_nerr;
-extern char *sys_errlist[];
-
-char *
-strerror(int err)
-{
- static char buf[20];
- if (err >= 0 && err < sys_nerr)
- return sys_errlist[err];
- PyOS_snprintf(buf, sizeof(buf), "Unknown errno %d", err);
- return buf;
-}
diff --git a/sys/src/cmd/python/Python/strtod.c b/sys/src/cmd/python/Python/strtod.c
deleted file mode 100644
index 5c084a4de..000000000
--- a/sys/src/cmd/python/Python/strtod.c
+++ /dev/null
@@ -1,156 +0,0 @@
-#include "pyconfig.h"
-
-/* comp.sources.misc strtod(), as posted in comp.lang.tcl,
- with bugfix for "123000.0" and acceptance of space after 'e' sign nuked.
-
- ************************************************************
- * YOU MUST EDIT THE MACHINE-DEPENDENT DEFINITIONS BELOW!!! *
- ************************************************************
-*/
-
-/* File : stdtod.c (Modified version of str2dbl.c)
- Author : Richard A. O'Keefe @ Quintus Computer Systems, Inc.
- Updated: Tuesday August 2nd, 1988
- Defines: double strtod (char *str, char**ptr)
-*/
-
-/* This is an implementation of the strtod() function described in the
- System V manuals, with a different name to avoid linker problems.
- All that str2dbl() does itself is check that the argument is well-formed
- and is in range. It leaves the work of conversion to atof(), which is
- assumed to exist and deliver correct results (if they can be represented).
-
- There are two reasons why this should be provided to the net:
- (a) some UNIX systems do not yet have strtod(), or do not have it
- available in the BSD "universe" (but they do have atof()).
- (b) some of the UNIX systems that *do* have it get it wrong.
- (some crash with large arguments, some assign the wrong *ptr value).
- There is a reason why *we* are providing it: we need a correct version
- of strtod(), and if we give this one away maybe someone will look for
- mistakes in it and fix them for us (:-).
-*/
-
-/* The following constants are machine-specific. MD{MIN,MAX}EXPT are
- integers and MD{MIN,MAX}FRAC are strings such that
- 0.${MDMAXFRAC}e${MDMAXEXPT} is the largest representable double,
- 0.${MDMINFRAC}e${MDMINEXPT} is the smallest representable +ve double
- MD{MIN,MAX}FRAC must not have any trailing zeros.
- The values here are for IEEE-754 64-bit floats.
- It is not perfectly clear to me whether an IEEE infinity should be
- returned for overflow, nor what a portable way of writing one is,
- so HUGE is just 0.MAXFRAC*10**MAXEXPT (this seems still to be the
- UNIX convention).
-
- I do know about <values.h>, but the whole point of this file is that
- we can't always trust that stuff to be there or to be correct.
-*/
-static int MDMINEXPT = {-323};
-static char MDMINFRAC[] = "494065645841246544";
-static double ZERO = 0.0;
-
-static int MDMAXEXPT = { 309};
-static char MDMAXFRAC[] = "17976931348623157";
-static double HUGE = 1.7976931348623157e308;
-
-extern double atof(const char *); /* Only called when result known to be ok */
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-extern int errno;
-
-double strtod(char *str, char **ptr)
-{
- int sign, scale, dotseen;
- int esign, expt;
- char *save;
- register char *sp, *dp;
- register int c;
- char *buforg, *buflim;
- char buffer[64]; /* 45-digit significant + */
- /* 13-digit exponent */
- sp = str;
- while (*sp == ' ') sp++;
- sign = 1;
- if (*sp == '-') sign -= 2, sp++;
- dotseen = 0, scale = 0;
- dp = buffer;
- *dp++ = '0'; *dp++ = '.';
- buforg = dp, buflim = buffer+48;
- for (save = sp; c = *sp; sp++)
- if (c == '.') {
- if (dotseen) break;
- dotseen++;
- } else
- if ((unsigned)(c-'0') > (unsigned)('9'-'0')) {
- break;
- } else
- if (c == '0') {
- if (dp != buforg) {
- /* This is not the first digit, so we want to keep it */
- if (dp < buflim) *dp++ = c;
- if (!dotseen) scale++;
- } else {
- /* No non-zero digits seen yet */
- /* If a . has been seen, scale must be adjusted */
- if (dotseen) scale--;
- }
- } else {
- /* This is a nonzero digit, so we want to keep it */
- if (dp < buflim) *dp++ = c;
- /* If it precedes a ., scale must be adjusted */
- if (!dotseen) scale++;
- }
- if (sp == save) {
- if (ptr) *ptr = str;
- errno = EDOM; /* what should this be? */
- return ZERO;
- }
-
- while (dp > buforg && dp[-1] == '0') --dp;
- if (dp == buforg) *dp++ = '0';
- *dp = '\0';
- /* Now the contents of buffer are
- +--+--------+-+--------+
- |0.|fraction|\|leftover|
- +--+--------+-+--------+
- ^dp points here
- where fraction begins with 0 iff it is "0", and has at most
- 45 digits in it, and leftover is at least 16 characters.
- */
- save = sp, expt = 0, esign = 1;
- do {
- c = *sp++;
- if (c != 'e' && c != 'E') break;
- c = *sp++;
- if (c == '-') esign -= 2, c = *sp++; else
- if (c == '+' /* || c == ' ' */ ) c = *sp++;
- if ((unsigned)(c-'0') > (unsigned)('9'-'0')) break;
- while (c == '0') c = *sp++;
- for (; (unsigned)(c-'0') <= (unsigned)('9'-'0'); c = *sp++)
- expt = expt*10 + c-'0';
- if (esign < 0) expt = -expt;
- save = sp-1;
- } while (0);
- if (ptr) *ptr = save;
- expt += scale;
- /* Now the number is sign*0.fraction*10**expt */
- errno = ERANGE;
- if (expt > MDMAXEXPT) {
- return HUGE*sign;
- } else
- if (expt == MDMAXEXPT) {
- if (strcmp(buforg, MDMAXFRAC) > 0) return HUGE*sign;
- } else
- if (expt < MDMINEXPT) {
- return ZERO*sign;
- } else
- if (expt == MDMINEXPT) {
- if (strcmp(buforg, MDMINFRAC) < 0) return ZERO*sign;
- }
- /* We have now established that the number can be */
- /* represented without overflow or underflow */
- (void) sprintf(dp, "E%d", expt);
- errno = 0;
- return atof(buffer)*sign;
-}
diff --git a/sys/src/cmd/python/Python/structmember.c b/sys/src/cmd/python/Python/structmember.c
deleted file mode 100644
index 03934c0c8..000000000
--- a/sys/src/cmd/python/Python/structmember.c
+++ /dev/null
@@ -1,312 +0,0 @@
-
-/* Map C struct members to Python object attributes */
-
-#include "Python.h"
-
-#include "structmember.h"
-
-static PyObject *
-listmembers(struct memberlist *mlist)
-{
- int i, n;
- PyObject *v;
- for (n = 0; mlist[n].name != NULL; n++)
- ;
- v = PyList_New(n);
- if (v != NULL) {
- for (i = 0; i < n; i++)
- PyList_SetItem(v, i,
- PyString_FromString(mlist[i].name));
- if (PyErr_Occurred()) {
- Py_DECREF(v);
- v = NULL;
- }
- else {
- PyList_Sort(v);
- }
- }
- return v;
-}
-
-PyObject *
-PyMember_Get(const char *addr, struct memberlist *mlist, const char *name)
-{
- struct memberlist *l;
-
- if (strcmp(name, "__members__") == 0)
- return listmembers(mlist);
- for (l = mlist; l->name != NULL; l++) {
- if (strcmp(l->name, name) == 0) {
- PyMemberDef copy;
- copy.name = l->name;
- copy.type = l->type;
- copy.offset = l->offset;
- copy.flags = l->flags;
- copy.doc = NULL;
- return PyMember_GetOne(addr, &copy);
- }
- }
- PyErr_SetString(PyExc_AttributeError, name);
- return NULL;
-}
-
-PyObject *
-PyMember_GetOne(const char *addr, PyMemberDef *l)
-{
- PyObject *v;
- if ((l->flags & READ_RESTRICTED) &&
- PyEval_GetRestricted()) {
- PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
- return NULL;
- }
- addr += l->offset;
- switch (l->type) {
- case T_BYTE:
- v = PyInt_FromLong(*(char*)addr);
- break;
- case T_UBYTE:
- v = PyLong_FromUnsignedLong(*(unsigned char*)addr);
- break;
- case T_SHORT:
- v = PyInt_FromLong(*(short*)addr);
- break;
- case T_USHORT:
- v = PyLong_FromUnsignedLong(*(unsigned short*)addr);
- break;
- case T_INT:
- v = PyInt_FromLong(*(int*)addr);
- break;
- case T_UINT:
- v = PyLong_FromUnsignedLong(*(unsigned int*)addr);
- break;
- case T_LONG:
- v = PyInt_FromLong(*(long*)addr);
- break;
- case T_ULONG:
- v = PyLong_FromUnsignedLong(*(unsigned long*)addr);
- break;
- case T_FLOAT:
- v = PyFloat_FromDouble((double)*(float*)addr);
- break;
- case T_DOUBLE:
- v = PyFloat_FromDouble(*(double*)addr);
- break;
- case T_STRING:
- if (*(char**)addr == NULL) {
- Py_INCREF(Py_None);
- v = Py_None;
- }
- else
- v = PyString_FromString(*(char**)addr);
- break;
- case T_STRING_INPLACE:
- v = PyString_FromString((char*)addr);
- break;
- case T_CHAR:
- v = PyString_FromStringAndSize((char*)addr, 1);
- break;
- case T_OBJECT:
- v = *(PyObject **)addr;
- if (v == NULL)
- v = Py_None;
- Py_INCREF(v);
- break;
- case T_OBJECT_EX:
- v = *(PyObject **)addr;
- if (v == NULL)
- PyErr_SetString(PyExc_AttributeError, l->name);
- Py_XINCREF(v);
- break;
-#ifdef HAVE_LONG_LONG
- case T_LONGLONG:
- v = PyLong_FromLongLong(*(PY_LONG_LONG *)addr);
- break;
- case T_ULONGLONG:
- v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr);
- break;
-#endif /* HAVE_LONG_LONG */
- default:
- PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
- v = NULL;
- }
- return v;
-}
-
-int
-PyMember_Set(char *addr, struct memberlist *mlist, const char *name, PyObject *v)
-{
- struct memberlist *l;
-
- for (l = mlist; l->name != NULL; l++) {
- if (strcmp(l->name, name) == 0) {
- PyMemberDef copy;
- copy.name = l->name;
- copy.type = l->type;
- copy.offset = l->offset;
- copy.flags = l->flags;
- copy.doc = NULL;
- return PyMember_SetOne(addr, &copy, v);
- }
- }
-
- PyErr_SetString(PyExc_AttributeError, name);
- return -1;
-}
-
-int
-PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
-{
- PyObject *oldv;
-
- if ((l->flags & READONLY) || l->type == T_STRING)
- {
- PyErr_SetString(PyExc_TypeError, "readonly attribute");
- return -1;
- }
- if ((l->flags & WRITE_RESTRICTED) && PyEval_GetRestricted()) {
- PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
- return -1;
- }
- if (v == NULL && l->type != T_OBJECT_EX && l->type != T_OBJECT) {
- PyErr_SetString(PyExc_TypeError,
- "can't delete numeric/char attribute");
- return -1;
- }
- addr += l->offset;
- switch (l->type) {
- case T_BYTE:{
- long long_val;
- long_val = PyInt_AsLong(v);
- if ((long_val == -1) && PyErr_Occurred())
- return -1;
- *(char*)addr = (char)long_val;
- break;
- }
- case T_UBYTE:{
- long long_val;
- long_val = PyInt_AsLong(v);
- if ((long_val == -1) && PyErr_Occurred())
- return -1;
- *(unsigned char*)addr = (unsigned char)long_val;
- break;
- }
- case T_SHORT:{
- long long_val;
- long_val = PyInt_AsLong(v);
- if ((long_val == -1) && PyErr_Occurred())
- return -1;
- *(short*)addr = (short)long_val;
- break;
- }
- case T_USHORT:{
- long long_val;
- long_val = PyInt_AsLong(v);
- if ((long_val == -1) && PyErr_Occurred())
- return -1;
- *(unsigned short*)addr = (unsigned short)long_val;
- break;
- }
- case T_INT:{
- long long_val;
- long_val = PyInt_AsLong(v);
- if ((long_val == -1) && PyErr_Occurred())
- return -1;
- *(int *)addr = (int)long_val;
- break;
- }
- case T_UINT:{
- unsigned long ulong_val;
- ulong_val = PyLong_AsUnsignedLong(v);
- if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) {
- /* XXX: For compatibility, accept negative int values
- as well. */
- PyErr_Clear();
- ulong_val = PyLong_AsLong(v);
- if ((ulong_val == (unsigned int)-1) && PyErr_Occurred())
- return -1;
- }
- *(unsigned int *)addr = (unsigned int)ulong_val;
- break;
- }
- case T_LONG:{
- *(long*)addr = PyLong_AsLong(v);
- if ((*(long*)addr == -1) && PyErr_Occurred())
- return -1;
- break;
- }
- case T_ULONG:{
- *(unsigned long*)addr = PyLong_AsUnsignedLong(v);
- if ((*(unsigned long*)addr == (unsigned long)-1)
- && PyErr_Occurred()) {
- /* XXX: For compatibility, accept negative int values
- as well. */
- PyErr_Clear();
- *(unsigned long*)addr = PyLong_AsLong(v);
- if ((*(unsigned long*)addr == (unsigned int)-1) && PyErr_Occurred())
- return -1;
- }
- break;
- }
- case T_FLOAT:{
- double double_val;
- double_val = PyFloat_AsDouble(v);
- if ((double_val == -1) && PyErr_Occurred())
- return -1;
- *(float*)addr = (float)double_val;
- break;
- }
- case T_DOUBLE:
- *(double*)addr = PyFloat_AsDouble(v);
- if ((*(double*)addr == -1) && PyErr_Occurred())
- return -1;
- break;
- case T_OBJECT:
- case T_OBJECT_EX:
- Py_XINCREF(v);
- oldv = *(PyObject **)addr;
- *(PyObject **)addr = v;
- Py_XDECREF(oldv);
- break;
- case T_CHAR:
- if (PyString_Check(v) && PyString_Size(v) == 1) {
- *(char*)addr = PyString_AsString(v)[0];
- }
- else {
- PyErr_BadArgument();
- return -1;
- }
- break;
-#ifdef HAVE_LONG_LONG
- case T_LONGLONG:
- if (!PyLong_Check(v)) {
- PyErr_BadArgument();
- return -1;
- } else {
- PY_LONG_LONG value;
- *(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v);
- if ((value == -1) && PyErr_Occurred()) {
- return -1;
- }
- }
- break;
- case T_ULONGLONG:
- if (!PyLong_Check(v)) {
- PyErr_BadArgument();
- return -1;
- } else {
- unsigned PY_LONG_LONG value;
- *(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v);
- if ((value == (unsigned PY_LONG_LONG)-1) &&
- PyErr_Occurred()) {
- return -1;
- }
- }
- break;
-#endif /* HAVE_LONG_LONG */
- default:
- PyErr_Format(PyExc_SystemError,
- "bad memberdescr type for %s", l->name);
- return -1;
- }
- return 0;
-}
diff --git a/sys/src/cmd/python/Python/symtable.c b/sys/src/cmd/python/Python/symtable.c
deleted file mode 100644
index 3e58b5034..000000000
--- a/sys/src/cmd/python/Python/symtable.c
+++ /dev/null
@@ -1,1425 +0,0 @@
-#include "Python.h"
-#include "Python-ast.h"
-#include "code.h"
-#include "symtable.h"
-#include "structmember.h"
-
-/* error strings used for warnings */
-#define GLOBAL_AFTER_ASSIGN \
-"name '%.400s' is assigned to before global declaration"
-
-#define GLOBAL_AFTER_USE \
-"name '%.400s' is used prior to global declaration"
-
-#define IMPORT_STAR_WARNING "import * only allowed at module level"
-
-#define RETURN_VAL_IN_GENERATOR \
- "'return' with argument inside generator"
-
-/* XXX(nnorwitz): change name since static? */
-static PySTEntryObject *
-PySTEntry_New(struct symtable *st, identifier name, _Py_block_ty block,
- void *key, int lineno)
-{
- PySTEntryObject *ste = NULL;
- PyObject *k;
-
- k = PyLong_FromVoidPtr(key);
- if (k == NULL)
- goto fail;
- ste = (PySTEntryObject *)PyObject_New(PySTEntryObject,
- &PySTEntry_Type);
- ste->ste_table = st;
- ste->ste_id = k;
- ste->ste_tmpname = 0;
-
- ste->ste_name = name;
- Py_INCREF(name);
-
- ste->ste_symbols = NULL;
- ste->ste_varnames = NULL;
- ste->ste_children = NULL;
-
- ste->ste_symbols = PyDict_New();
- if (ste->ste_symbols == NULL)
- goto fail;
-
- ste->ste_varnames = PyList_New(0);
- if (ste->ste_varnames == NULL)
- goto fail;
-
- ste->ste_children = PyList_New(0);
- if (ste->ste_children == NULL)
- goto fail;
-
- ste->ste_type = block;
- ste->ste_unoptimized = 0;
- ste->ste_nested = 0;
- ste->ste_free = 0;
- ste->ste_varargs = 0;
- ste->ste_varkeywords = 0;
- ste->ste_opt_lineno = 0;
- ste->ste_tmpname = 0;
- ste->ste_lineno = lineno;
-
- if (st->st_cur != NULL &&
- (st->st_cur->ste_nested ||
- st->st_cur->ste_type == FunctionBlock))
- ste->ste_nested = 1;
- ste->ste_child_free = 0;
- ste->ste_generator = 0;
- ste->ste_returns_value = 0;
-
- if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0)
- goto fail;
-
- return ste;
- fail:
- Py_XDECREF(ste);
- return NULL;
-}
-
-static PyObject *
-ste_repr(PySTEntryObject *ste)
-{
- char buf[256];
-
- PyOS_snprintf(buf, sizeof(buf),
- "<symtable entry %.100s(%ld), line %d>",
- PyString_AS_STRING(ste->ste_name),
- PyInt_AS_LONG(ste->ste_id), ste->ste_lineno);
- return PyString_FromString(buf);
-}
-
-static void
-ste_dealloc(PySTEntryObject *ste)
-{
- ste->ste_table = NULL;
- Py_XDECREF(ste->ste_id);
- Py_XDECREF(ste->ste_name);
- Py_XDECREF(ste->ste_symbols);
- Py_XDECREF(ste->ste_varnames);
- Py_XDECREF(ste->ste_children);
- PyObject_Del(ste);
-}
-
-#define OFF(x) offsetof(PySTEntryObject, x)
-
-static PyMemberDef ste_memberlist[] = {
- {"id", T_OBJECT, OFF(ste_id), READONLY},
- {"name", T_OBJECT, OFF(ste_name), READONLY},
- {"symbols", T_OBJECT, OFF(ste_symbols), READONLY},
- {"varnames", T_OBJECT, OFF(ste_varnames), READONLY},
- {"children", T_OBJECT, OFF(ste_children), READONLY},
- {"type", T_INT, OFF(ste_type), READONLY},
- {"lineno", T_INT, OFF(ste_lineno), READONLY},
- {NULL}
-};
-
-PyTypeObject PySTEntry_Type = {
- PyObject_HEAD_INIT(&PyType_Type)
- 0,
- "symtable entry",
- sizeof(PySTEntryObject),
- 0,
- (destructor)ste_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- (reprfunc)ste_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- 0, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- ste_memberlist, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
-};
-
-static int symtable_analyze(struct symtable *st);
-static int symtable_warn(struct symtable *st, char *msg, int lineno);
-static int symtable_enter_block(struct symtable *st, identifier name,
- _Py_block_ty block, void *ast, int lineno);
-static int symtable_exit_block(struct symtable *st, void *ast);
-static int symtable_visit_stmt(struct symtable *st, stmt_ty s);
-static int symtable_visit_expr(struct symtable *st, expr_ty s);
-static int symtable_visit_genexp(struct symtable *st, expr_ty s);
-static int symtable_visit_arguments(struct symtable *st, arguments_ty);
-static int symtable_visit_excepthandler(struct symtable *st, excepthandler_ty);
-static int symtable_visit_alias(struct symtable *st, alias_ty);
-static int symtable_visit_comprehension(struct symtable *st, comprehension_ty);
-static int symtable_visit_keyword(struct symtable *st, keyword_ty);
-static int symtable_visit_slice(struct symtable *st, slice_ty);
-static int symtable_visit_params(struct symtable *st, asdl_seq *args, int top);
-static int symtable_visit_params_nested(struct symtable *st, asdl_seq *args);
-static int symtable_implicit_arg(struct symtable *st, int pos);
-
-
-static identifier top = NULL, lambda = NULL, genexpr = NULL;
-
-#define GET_IDENTIFIER(VAR) \
- ((VAR) ? (VAR) : ((VAR) = PyString_InternFromString(# VAR)))
-
-#define DUPLICATE_ARGUMENT \
-"duplicate argument '%s' in function definition"
-
-static struct symtable *
-symtable_new(void)
-{
- struct symtable *st;
-
- st = (struct symtable *)PyMem_Malloc(sizeof(struct symtable));
- if (st == NULL)
- return NULL;
-
- st->st_filename = NULL;
- st->st_symbols = NULL;
-
- if ((st->st_stack = PyList_New(0)) == NULL)
- goto fail;
- if ((st->st_symbols = PyDict_New()) == NULL)
- goto fail;
- st->st_cur = NULL;
- st->st_tmpname = 0;
- st->st_private = NULL;
- return st;
- fail:
- PySymtable_Free(st);
- return NULL;
-}
-
-struct symtable *
-PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)
-{
- struct symtable *st = symtable_new();
- asdl_seq *seq;
- int i;
-
- if (st == NULL)
- return st;
- st->st_filename = filename;
- st->st_future = future;
- if (!symtable_enter_block(st, GET_IDENTIFIER(top), ModuleBlock,
- (void *)mod, 0)) {
- PySymtable_Free(st);
- return NULL;
- }
-
- st->st_top = st->st_cur;
- st->st_cur->ste_unoptimized = OPT_TOPLEVEL;
- /* Any other top-level initialization? */
- switch (mod->kind) {
- case Module_kind:
- seq = mod->v.Module.body;
- for (i = 0; i < asdl_seq_LEN(seq); i++)
- if (!symtable_visit_stmt(st,
- (stmt_ty)asdl_seq_GET(seq, i)))
- goto error;
- break;
- case Expression_kind:
- if (!symtable_visit_expr(st, mod->v.Expression.body))
- goto error;
- break;
- case Interactive_kind:
- seq = mod->v.Interactive.body;
- for (i = 0; i < asdl_seq_LEN(seq); i++)
- if (!symtable_visit_stmt(st,
- (stmt_ty)asdl_seq_GET(seq, i)))
- goto error;
- break;
- case Suite_kind:
- PyErr_SetString(PyExc_RuntimeError,
- "this compiler does not handle Suites");
- goto error;
- }
- if (!symtable_exit_block(st, (void *)mod)) {
- PySymtable_Free(st);
- return NULL;
- }
- if (symtable_analyze(st))
- return st;
- PySymtable_Free(st);
- return NULL;
- error:
- (void) symtable_exit_block(st, (void *)mod);
- PySymtable_Free(st);
- return NULL;
-}
-
-void
-PySymtable_Free(struct symtable *st)
-{
- Py_XDECREF(st->st_symbols);
- Py_XDECREF(st->st_stack);
- PyMem_Free((void *)st);
-}
-
-PySTEntryObject *
-PySymtable_Lookup(struct symtable *st, void *key)
-{
- PyObject *k, *v;
-
- k = PyLong_FromVoidPtr(key);
- if (k == NULL)
- return NULL;
- v = PyDict_GetItem(st->st_symbols, k);
- if (v) {
- assert(PySTEntry_Check(v));
- Py_INCREF(v);
- }
- else {
- PyErr_SetString(PyExc_KeyError,
- "unknown symbol table entry");
- }
-
- Py_DECREF(k);
- return (PySTEntryObject *)v;
-}
-
-int
-PyST_GetScope(PySTEntryObject *ste, PyObject *name)
-{
- PyObject *v = PyDict_GetItem(ste->ste_symbols, name);
- if (!v)
- return 0;
- assert(PyInt_Check(v));
- return (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK;
-}
-
-
-/* Analyze raw symbol information to determine scope of each name.
-
- The next several functions are helpers for PySymtable_Analyze(),
- which determines whether a name is local, global, or free. In addition,
- it determines which local variables are cell variables; they provide
- bindings that are used for free variables in enclosed blocks.
-
- There are also two kinds of free variables, implicit and explicit. An
- explicit global is declared with the global statement. An implicit
- global is a free variable for which the compiler has found no binding
- in an enclosing function scope. The implicit global is either a global
- or a builtin. Python's module and class blocks use the xxx_NAME opcodes
- to handle these names to implement slightly odd semantics. In such a
- block, the name is treated as global until it is assigned to; then it
- is treated as a local.
-
- The symbol table requires two passes to determine the scope of each name.
- The first pass collects raw facts from the AST: the name is a parameter
- here, the name is used by not defined here, etc. The second pass analyzes
- these facts during a pass over the PySTEntryObjects created during pass 1.
-
- When a function is entered during the second pass, the parent passes
- the set of all name bindings visible to its children. These bindings
- are used to determine if the variable is free or an implicit global.
- After doing the local analysis, it analyzes each of its child blocks
- using an updated set of name bindings.
-
- The children update the free variable set. If a local variable is free
- in a child, the variable is marked as a cell. The current function must
- provide runtime storage for the variable that may outlive the function's
- frame. Cell variables are removed from the free set before the analyze
- function returns to its parent.
-
- The sets of bound and free variables are implemented as dictionaries
- mapping strings to None.
-*/
-
-#define SET_SCOPE(DICT, NAME, I) { \
- PyObject *o = PyInt_FromLong(I); \
- if (!o) \
- return 0; \
- if (PyDict_SetItem((DICT), (NAME), o) < 0) { \
- Py_DECREF(o); \
- return 0; \
- } \
- Py_DECREF(o); \
-}
-
-/* Decide on scope of name, given flags.
-
- The dicts passed in as arguments are modified as necessary.
- ste is passed so that flags can be updated.
-*/
-
-static int
-analyze_name(PySTEntryObject *ste, PyObject *dict, PyObject *name, long flags,
- PyObject *bound, PyObject *local, PyObject *free,
- PyObject *global)
-{
- if (flags & DEF_GLOBAL) {
- if (flags & DEF_PARAM) {
- PyErr_Format(PyExc_SyntaxError,
- "name '%s' is local and global",
- PyString_AS_STRING(name));
- return 0;
- }
- SET_SCOPE(dict, name, GLOBAL_EXPLICIT);
- if (PyDict_SetItem(global, name, Py_None) < 0)
- return 0;
- if (bound && PyDict_GetItem(bound, name)) {
- if (PyDict_DelItem(bound, name) < 0)
- return 0;
- }
- return 1;
- }
- if (flags & DEF_BOUND) {
- SET_SCOPE(dict, name, LOCAL);
- if (PyDict_SetItem(local, name, Py_None) < 0)
- return 0;
- if (PyDict_GetItem(global, name)) {
- if (PyDict_DelItem(global, name) < 0)
- return 0;
- }
- return 1;
- }
- /* If an enclosing block has a binding for this name, it
- is a free variable rather than a global variable.
- Note that having a non-NULL bound implies that the block
- is nested.
- */
- if (bound && PyDict_GetItem(bound, name)) {
- SET_SCOPE(dict, name, FREE);
- ste->ste_free = 1;
- if (PyDict_SetItem(free, name, Py_None) < 0)
- return 0;
- return 1;
- }
- /* If a parent has a global statement, then call it global
- explicit? It could also be global implicit.
- */
- else if (global && PyDict_GetItem(global, name)) {
- SET_SCOPE(dict, name, GLOBAL_EXPLICIT);
- return 1;
- }
- else {
- if (ste->ste_nested)
- ste->ste_free = 1;
- SET_SCOPE(dict, name, GLOBAL_IMPLICIT);
- return 1;
- }
- return 0; /* Can't get here */
-}
-
-#undef SET_SCOPE
-
-/* If a name is defined in free and also in locals, then this block
- provides the binding for the free variable. The name should be
- marked CELL in this block and removed from the free list.
-
- Note that the current block's free variables are included in free.
- That's safe because no name can be free and local in the same scope.
-*/
-
-static int
-analyze_cells(PyObject *scope, PyObject *free)
-{
- PyObject *name, *v, *w;
- int success = 0;
- Py_ssize_t pos = 0;
-
- w = PyInt_FromLong(CELL);
- if (!w)
- return 0;
- while (PyDict_Next(scope, &pos, &name, &v)) {
- long flags;
- assert(PyInt_Check(v));
- flags = PyInt_AS_LONG(v);
- if (flags != LOCAL)
- continue;
- if (!PyDict_GetItem(free, name))
- continue;
- /* Replace LOCAL with CELL for this name, and remove
- from free. It is safe to replace the value of name
- in the dict, because it will not cause a resize.
- */
- if (PyDict_SetItem(scope, name, w) < 0)
- goto error;
- if (!PyDict_DelItem(free, name) < 0)
- goto error;
- }
- success = 1;
- error:
- Py_DECREF(w);
- return success;
-}
-
-/* Check for illegal statements in unoptimized namespaces */
-static int
-check_unoptimized(const PySTEntryObject* ste) {
- char buf[300];
- const char* trailer;
-
- if (ste->ste_type != FunctionBlock || !ste->ste_unoptimized
- || !(ste->ste_free || ste->ste_child_free))
- return 1;
-
- trailer = (ste->ste_child_free ?
- "contains a nested function with free variables" :
- "is a nested function");
-
- switch (ste->ste_unoptimized) {
- case OPT_TOPLEVEL: /* exec / import * at top-level is fine */
- case OPT_EXEC: /* qualified exec is fine */
- return 1;
- case OPT_IMPORT_STAR:
- PyOS_snprintf(buf, sizeof(buf),
- "import * is not allowed in function '%.100s' "
- "because it is %s",
- PyString_AS_STRING(ste->ste_name), trailer);
- break;
- case OPT_BARE_EXEC:
- PyOS_snprintf(buf, sizeof(buf),
- "unqualified exec is not allowed in function "
- "'%.100s' it %s",
- PyString_AS_STRING(ste->ste_name), trailer);
- break;
- default:
- PyOS_snprintf(buf, sizeof(buf),
- "function '%.100s' uses import * and bare exec, "
- "which are illegal because it %s",
- PyString_AS_STRING(ste->ste_name), trailer);
- break;
- }
-
- PyErr_SetString(PyExc_SyntaxError, buf);
- PyErr_SyntaxLocation(ste->ste_table->st_filename,
- ste->ste_opt_lineno);
- return 0;
-}
-
-/* Enter the final scope information into the st_symbols dict.
- *
- * All arguments are dicts. Modifies symbols, others are read-only.
-*/
-static int
-update_symbols(PyObject *symbols, PyObject *scope,
- PyObject *bound, PyObject *free, int classflag)
-{
- PyObject *name, *v, *u, *w, *free_value = NULL;
- Py_ssize_t pos = 0;
-
- while (PyDict_Next(symbols, &pos, &name, &v)) {
- long i, flags;
- assert(PyInt_Check(v));
- flags = PyInt_AS_LONG(v);
- w = PyDict_GetItem(scope, name);
- assert(w && PyInt_Check(w));
- i = PyInt_AS_LONG(w);
- flags |= (i << SCOPE_OFF);
- u = PyInt_FromLong(flags);
- if (!u)
- return 0;
- if (PyDict_SetItem(symbols, name, u) < 0) {
- Py_DECREF(u);
- return 0;
- }
- Py_DECREF(u);
- }
-
- free_value = PyInt_FromLong(FREE << SCOPE_OFF);
- if (!free_value)
- return 0;
-
- /* add a free variable when it's only use is for creating a closure */
- pos = 0;
- while (PyDict_Next(free, &pos, &name, &v)) {
- PyObject *o = PyDict_GetItem(symbols, name);
-
- if (o) {
- /* It could be a free variable in a method of
- the class that has the same name as a local
- or global in the class scope.
- */
- if (classflag &&
- PyInt_AS_LONG(o) & (DEF_BOUND | DEF_GLOBAL)) {
- long i = PyInt_AS_LONG(o) | DEF_FREE_CLASS;
- o = PyInt_FromLong(i);
- if (!o) {
- Py_DECREF(free_value);
- return 0;
- }
- if (PyDict_SetItem(symbols, name, o) < 0) {
- Py_DECREF(o);
- Py_DECREF(free_value);
- return 0;
- }
- Py_DECREF(o);
- }
- /* else it's not free, probably a cell */
- continue;
- }
- if (!PyDict_GetItem(bound, name))
- continue; /* it's a global */
-
- if (PyDict_SetItem(symbols, name, free_value) < 0) {
- Py_DECREF(free_value);
- return 0;
- }
- }
- Py_DECREF(free_value);
- return 1;
-}
-
-/* Make final symbol table decisions for block of ste.
- Arguments:
- ste -- current symtable entry (input/output)
- bound -- set of variables bound in enclosing scopes (input)
- free -- set of free variables in enclosed scopes (output)
- globals -- set of declared global variables in enclosing scopes (input)
-*/
-
-static int
-analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
- PyObject *global)
-{
- PyObject *name, *v, *local = NULL, *scope = NULL, *newbound = NULL;
- PyObject *newglobal = NULL, *newfree = NULL;
- int i, success = 0;
- Py_ssize_t pos = 0;
-
- local = PyDict_New();
- if (!local)
- goto error;
- scope = PyDict_New();
- if (!scope)
- goto error;
- newglobal = PyDict_New();
- if (!newglobal)
- goto error;
- newfree = PyDict_New();
- if (!newfree)
- goto error;
- newbound = PyDict_New();
- if (!newbound)
- goto error;
-
- if (ste->ste_type == ClassBlock) {
- /* make a copy of globals before calling analyze_name(),
- because global statements in the class have no effect
- on nested functions.
- */
- if (PyDict_Update(newglobal, global) < 0)
- goto error;
- if (bound)
- if (PyDict_Update(newbound, bound) < 0)
- goto error;
- }
-
- assert(PySTEntry_Check(ste));
- assert(PyDict_Check(ste->ste_symbols));
- while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) {
- long flags = PyInt_AS_LONG(v);
- if (!analyze_name(ste, scope, name, flags, bound, local, free,
- global))
- goto error;
- }
-
- if (ste->ste_type != ClassBlock) {
- if (ste->ste_type == FunctionBlock) {
- if (PyDict_Update(newbound, local) < 0)
- goto error;
- }
- if (bound) {
- if (PyDict_Update(newbound, bound) < 0)
- goto error;
- }
- if (PyDict_Update(newglobal, global) < 0)
- goto error;
- }
-
- /* Recursively call analyze_block() on each child block */
- for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) {
- PyObject *c = PyList_GET_ITEM(ste->ste_children, i);
- PySTEntryObject* entry;
- assert(c && PySTEntry_Check(c));
- entry = (PySTEntryObject*)c;
- if (!analyze_block(entry, newbound, newfree, newglobal))
- goto error;
- if (entry->ste_free || entry->ste_child_free)
- ste->ste_child_free = 1;
- }
-
- if (ste->ste_type == FunctionBlock && !analyze_cells(scope, newfree))
- goto error;
- if (!update_symbols(ste->ste_symbols, scope, bound, newfree,
- ste->ste_type == ClassBlock))
- goto error;
- if (!check_unoptimized(ste))
- goto error;
-
- if (PyDict_Update(free, newfree) < 0)
- goto error;
- success = 1;
- error:
- Py_XDECREF(local);
- Py_XDECREF(scope);
- Py_XDECREF(newbound);
- Py_XDECREF(newglobal);
- Py_XDECREF(newfree);
- if (!success)
- assert(PyErr_Occurred());
- return success;
-}
-
-static int
-symtable_analyze(struct symtable *st)
-{
- PyObject *free, *global;
- int r;
-
- free = PyDict_New();
- if (!free)
- return 0;
- global = PyDict_New();
- if (!global) {
- Py_DECREF(free);
- return 0;
- }
- r = analyze_block(st->st_top, NULL, free, global);
- Py_DECREF(free);
- Py_DECREF(global);
- return r;
-}
-
-
-static int
-symtable_warn(struct symtable *st, char *msg, int lineno)
-{
- if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, st->st_filename,
- lineno, NULL, NULL) < 0) {
- if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
- PyErr_SetString(PyExc_SyntaxError, msg);
- PyErr_SyntaxLocation(st->st_filename,
- st->st_cur->ste_lineno);
- }
- return 0;
- }
- return 1;
-}
-
-/* symtable_enter_block() gets a reference via PySTEntry_New().
- This reference is released when the block is exited, via the DECREF
- in symtable_exit_block().
-*/
-
-static int
-symtable_exit_block(struct symtable *st, void *ast)
-{
- Py_ssize_t end;
-
- Py_CLEAR(st->st_cur);
- end = PyList_GET_SIZE(st->st_stack) - 1;
- if (end >= 0) {
- st->st_cur = (PySTEntryObject *)PyList_GET_ITEM(st->st_stack,
- end);
- if (st->st_cur == NULL)
- return 0;
- Py_INCREF(st->st_cur);
- if (PySequence_DelItem(st->st_stack, end) < 0)
- return 0;
- }
- return 1;
-}
-
-static int
-symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
- void *ast, int lineno)
-{
- PySTEntryObject *prev = NULL;
-
- if (st->st_cur) {
- prev = st->st_cur;
- if (PyList_Append(st->st_stack, (PyObject *)st->st_cur) < 0) {
- return 0;
- }
- Py_DECREF(st->st_cur);
- }
- st->st_cur = PySTEntry_New(st, name, block, ast, lineno);
- if (st->st_cur == NULL)
- return 0;
- if (name == GET_IDENTIFIER(top))
- st->st_global = st->st_cur->ste_symbols;
- if (prev) {
- if (PyList_Append(prev->ste_children,
- (PyObject *)st->st_cur) < 0) {
- return 0;
- }
- }
- return 1;
-}
-
-static long
-symtable_lookup(struct symtable *st, PyObject *name)
-{
- PyObject *o;
- PyObject *mangled = _Py_Mangle(st->st_private, name);
- if (!mangled)
- return 0;
- o = PyDict_GetItem(st->st_cur->ste_symbols, mangled);
- Py_DECREF(mangled);
- if (!o)
- return 0;
- return PyInt_AsLong(o);
-}
-
-static int
-symtable_add_def(struct symtable *st, PyObject *name, int flag)
-{
- PyObject *o;
- PyObject *dict;
- long val;
- PyObject *mangled = _Py_Mangle(st->st_private, name);
-
- if (!mangled)
- return 0;
- dict = st->st_cur->ste_symbols;
- if ((o = PyDict_GetItem(dict, mangled))) {
- val = PyInt_AS_LONG(o);
- if ((flag & DEF_PARAM) && (val & DEF_PARAM)) {
- /* Is it better to use 'mangled' or 'name' here? */
- PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT,
- PyString_AsString(name));
- PyErr_SyntaxLocation(st->st_filename,
- st->st_cur->ste_lineno);
- goto error;
- }
- val |= flag;
- } else
- val = flag;
- o = PyInt_FromLong(val);
- if (o == NULL)
- goto error;
- if (PyDict_SetItem(dict, mangled, o) < 0) {
- Py_DECREF(o);
- goto error;
- }
- Py_DECREF(o);
-
- if (flag & DEF_PARAM) {
- if (PyList_Append(st->st_cur->ste_varnames, mangled) < 0)
- goto error;
- } else if (flag & DEF_GLOBAL) {
- /* XXX need to update DEF_GLOBAL for other flags too;
- perhaps only DEF_FREE_GLOBAL */
- val = flag;
- if ((o = PyDict_GetItem(st->st_global, mangled))) {
- val |= PyInt_AS_LONG(o);
- }
- o = PyInt_FromLong(val);
- if (o == NULL)
- goto error;
- if (PyDict_SetItem(st->st_global, mangled, o) < 0) {
- Py_DECREF(o);
- goto error;
- }
- Py_DECREF(o);
- }
- Py_DECREF(mangled);
- return 1;
-
-error:
- Py_DECREF(mangled);
- return 0;
-}
-
-/* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument.
- They use the ASDL name to synthesize the name of the C type and the visit
- function.
-
- VISIT_SEQ_TAIL permits the start of an ASDL sequence to be skipped, which is
- useful if the first node in the sequence requires special treatment.
-*/
-
-#define VISIT(ST, TYPE, V) \
- if (!symtable_visit_ ## TYPE((ST), (V))) \
- return 0;
-
-#define VISIT_IN_BLOCK(ST, TYPE, V, S) \
- if (!symtable_visit_ ## TYPE((ST), (V))) { \
- symtable_exit_block((ST), (S)); \
- return 0; \
- }
-
-#define VISIT_SEQ(ST, TYPE, SEQ) { \
- int i; \
- asdl_seq *seq = (SEQ); /* avoid variable capture */ \
- for (i = 0; i < asdl_seq_LEN(seq); i++) { \
- TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
- if (!symtable_visit_ ## TYPE((ST), elt)) \
- return 0; \
- } \
-}
-
-#define VISIT_SEQ_IN_BLOCK(ST, TYPE, SEQ, S) { \
- int i; \
- asdl_seq *seq = (SEQ); /* avoid variable capture */ \
- for (i = 0; i < asdl_seq_LEN(seq); i++) { \
- TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
- if (!symtable_visit_ ## TYPE((ST), elt)) { \
- symtable_exit_block((ST), (S)); \
- return 0; \
- } \
- } \
-}
-
-#define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) { \
- int i; \
- asdl_seq *seq = (SEQ); /* avoid variable capture */ \
- for (i = (START); i < asdl_seq_LEN(seq); i++) { \
- TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
- if (!symtable_visit_ ## TYPE((ST), elt)) \
- return 0; \
- } \
-}
-
-#define VISIT_SEQ_TAIL_IN_BLOCK(ST, TYPE, SEQ, START, S) { \
- int i; \
- asdl_seq *seq = (SEQ); /* avoid variable capture */ \
- for (i = (START); i < asdl_seq_LEN(seq); i++) { \
- TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
- if (!symtable_visit_ ## TYPE((ST), elt)) { \
- symtable_exit_block((ST), (S)); \
- return 0; \
- } \
- } \
-}
-
-static int
-symtable_new_tmpname(struct symtable *st)
-{
- char tmpname[256];
- identifier tmp;
-
- PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]",
- ++st->st_cur->ste_tmpname);
- tmp = PyString_InternFromString(tmpname);
- if (!tmp)
- return 0;
- if (!symtable_add_def(st, tmp, DEF_LOCAL))
- return 0;
- Py_DECREF(tmp);
- return 1;
-}
-
-static int
-symtable_visit_stmt(struct symtable *st, stmt_ty s)
-{
- switch (s->kind) {
- case FunctionDef_kind:
- if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL))
- return 0;
- if (s->v.FunctionDef.args->defaults)
- VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults);
- if (s->v.FunctionDef.decorators)
- VISIT_SEQ(st, expr, s->v.FunctionDef.decorators);
- if (!symtable_enter_block(st, s->v.FunctionDef.name,
- FunctionBlock, (void *)s, s->lineno))
- return 0;
- VISIT_IN_BLOCK(st, arguments, s->v.FunctionDef.args, s);
- VISIT_SEQ_IN_BLOCK(st, stmt, s->v.FunctionDef.body, s);
- if (!symtable_exit_block(st, s))
- return 0;
- break;
- case ClassDef_kind: {
- PyObject *tmp;
- if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL))
- return 0;
- VISIT_SEQ(st, expr, s->v.ClassDef.bases);
- if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,
- (void *)s, s->lineno))
- return 0;
- tmp = st->st_private;
- st->st_private = s->v.ClassDef.name;
- VISIT_SEQ_IN_BLOCK(st, stmt, s->v.ClassDef.body, s);
- st->st_private = tmp;
- if (!symtable_exit_block(st, s))
- return 0;
- break;
- }
- case Return_kind:
- if (s->v.Return.value) {
- VISIT(st, expr, s->v.Return.value);
- st->st_cur->ste_returns_value = 1;
- if (st->st_cur->ste_generator) {
- PyErr_SetString(PyExc_SyntaxError,
- RETURN_VAL_IN_GENERATOR);
- PyErr_SyntaxLocation(st->st_filename,
- s->lineno);
- return 0;
- }
- }
- break;
- case Delete_kind:
- VISIT_SEQ(st, expr, s->v.Delete.targets);
- break;
- case Assign_kind:
- VISIT_SEQ(st, expr, s->v.Assign.targets);
- VISIT(st, expr, s->v.Assign.value);
- break;
- case AugAssign_kind:
- VISIT(st, expr, s->v.AugAssign.target);
- VISIT(st, expr, s->v.AugAssign.value);
- break;
- case Print_kind:
- if (s->v.Print.dest)
- VISIT(st, expr, s->v.Print.dest);
- VISIT_SEQ(st, expr, s->v.Print.values);
- break;
- case For_kind:
- VISIT(st, expr, s->v.For.target);
- VISIT(st, expr, s->v.For.iter);
- VISIT_SEQ(st, stmt, s->v.For.body);
- if (s->v.For.orelse)
- VISIT_SEQ(st, stmt, s->v.For.orelse);
- break;
- case While_kind:
- VISIT(st, expr, s->v.While.test);
- VISIT_SEQ(st, stmt, s->v.While.body);
- if (s->v.While.orelse)
- VISIT_SEQ(st, stmt, s->v.While.orelse);
- break;
- case If_kind:
- /* XXX if 0: and lookup_yield() hacks */
- VISIT(st, expr, s->v.If.test);
- VISIT_SEQ(st, stmt, s->v.If.body);
- if (s->v.If.orelse)
- VISIT_SEQ(st, stmt, s->v.If.orelse);
- break;
- case Raise_kind:
- if (s->v.Raise.type) {
- VISIT(st, expr, s->v.Raise.type);
- if (s->v.Raise.inst) {
- VISIT(st, expr, s->v.Raise.inst);
- if (s->v.Raise.tback)
- VISIT(st, expr, s->v.Raise.tback);
- }
- }
- break;
- case TryExcept_kind:
- VISIT_SEQ(st, stmt, s->v.TryExcept.body);
- VISIT_SEQ(st, stmt, s->v.TryExcept.orelse);
- VISIT_SEQ(st, excepthandler, s->v.TryExcept.handlers);
- break;
- case TryFinally_kind:
- VISIT_SEQ(st, stmt, s->v.TryFinally.body);
- VISIT_SEQ(st, stmt, s->v.TryFinally.finalbody);
- break;
- case Assert_kind:
- VISIT(st, expr, s->v.Assert.test);
- if (s->v.Assert.msg)
- VISIT(st, expr, s->v.Assert.msg);
- break;
- case Import_kind:
- VISIT_SEQ(st, alias, s->v.Import.names);
- /* XXX Don't have the lineno available inside
- visit_alias */
- if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno)
- st->st_cur->ste_opt_lineno = s->lineno;
- break;
- case ImportFrom_kind:
- VISIT_SEQ(st, alias, s->v.ImportFrom.names);
- /* XXX Don't have the lineno available inside
- visit_alias */
- if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno)
- st->st_cur->ste_opt_lineno = s->lineno;
- break;
- case Exec_kind:
- VISIT(st, expr, s->v.Exec.body);
- if (!st->st_cur->ste_opt_lineno)
- st->st_cur->ste_opt_lineno = s->lineno;
- if (s->v.Exec.globals) {
- st->st_cur->ste_unoptimized |= OPT_EXEC;
- VISIT(st, expr, s->v.Exec.globals);
- if (s->v.Exec.locals)
- VISIT(st, expr, s->v.Exec.locals);
- } else {
- st->st_cur->ste_unoptimized |= OPT_BARE_EXEC;
- }
- break;
- case Global_kind: {
- int i;
- asdl_seq *seq = s->v.Global.names;
- for (i = 0; i < asdl_seq_LEN(seq); i++) {
- identifier name = (identifier)asdl_seq_GET(seq, i);
- char *c_name = PyString_AS_STRING(name);
- long cur = symtable_lookup(st, name);
- if (cur < 0)
- return 0;
- if (cur & (DEF_LOCAL | USE)) {
- char buf[256];
- if (cur & DEF_LOCAL)
- PyOS_snprintf(buf, sizeof(buf),
- GLOBAL_AFTER_ASSIGN,
- c_name);
- else
- PyOS_snprintf(buf, sizeof(buf),
- GLOBAL_AFTER_USE,
- c_name);
- if (!symtable_warn(st, buf, s->lineno))
- return 0;
- }
- if (!symtable_add_def(st, name, DEF_GLOBAL))
- return 0;
- }
- break;
- }
- case Expr_kind:
- VISIT(st, expr, s->v.Expr.value);
- break;
- case Pass_kind:
- case Break_kind:
- case Continue_kind:
- /* nothing to do here */
- break;
- case With_kind:
- if (!symtable_new_tmpname(st))
- return 0;
- VISIT(st, expr, s->v.With.context_expr);
- if (s->v.With.optional_vars) {
- if (!symtable_new_tmpname(st))
- return 0;
- VISIT(st, expr, s->v.With.optional_vars);
- }
- VISIT_SEQ(st, stmt, s->v.With.body);
- break;
- }
- return 1;
-}
-
-static int
-symtable_visit_expr(struct symtable *st, expr_ty e)
-{
- switch (e->kind) {
- case BoolOp_kind:
- VISIT_SEQ(st, expr, e->v.BoolOp.values);
- break;
- case BinOp_kind:
- VISIT(st, expr, e->v.BinOp.left);
- VISIT(st, expr, e->v.BinOp.right);
- break;
- case UnaryOp_kind:
- VISIT(st, expr, e->v.UnaryOp.operand);
- break;
- case Lambda_kind: {
- if (!symtable_add_def(st, GET_IDENTIFIER(lambda), DEF_LOCAL))
- return 0;
- if (e->v.Lambda.args->defaults)
- VISIT_SEQ(st, expr, e->v.Lambda.args->defaults);
- /* XXX how to get line numbers for expressions */
- if (!symtable_enter_block(st, GET_IDENTIFIER(lambda),
- FunctionBlock, (void *)e, 0))
- return 0;
- VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e);
- VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e);
- if (!symtable_exit_block(st, (void *)e))
- return 0;
- break;
- }
- case IfExp_kind:
- VISIT(st, expr, e->v.IfExp.test);
- VISIT(st, expr, e->v.IfExp.body);
- VISIT(st, expr, e->v.IfExp.orelse);
- break;
- case Dict_kind:
- VISIT_SEQ(st, expr, e->v.Dict.keys);
- VISIT_SEQ(st, expr, e->v.Dict.values);
- break;
- case ListComp_kind:
- if (!symtable_new_tmpname(st))
- return 0;
- VISIT(st, expr, e->v.ListComp.elt);
- VISIT_SEQ(st, comprehension, e->v.ListComp.generators);
- break;
- case GeneratorExp_kind:
- if (!symtable_visit_genexp(st, e))
- return 0;
- break;
- case Yield_kind:
- if (e->v.Yield.value)
- VISIT(st, expr, e->v.Yield.value);
- st->st_cur->ste_generator = 1;
- if (st->st_cur->ste_returns_value) {
- PyErr_SetString(PyExc_SyntaxError,
- RETURN_VAL_IN_GENERATOR);
- PyErr_SyntaxLocation(st->st_filename,
- e->lineno);
- return 0;
- }
- break;
- case Compare_kind:
- VISIT(st, expr, e->v.Compare.left);
- VISIT_SEQ(st, expr, e->v.Compare.comparators);
- break;
- case Call_kind:
- VISIT(st, expr, e->v.Call.func);
- VISIT_SEQ(st, expr, e->v.Call.args);
- VISIT_SEQ(st, keyword, e->v.Call.keywords);
- if (e->v.Call.starargs)
- VISIT(st, expr, e->v.Call.starargs);
- if (e->v.Call.kwargs)
- VISIT(st, expr, e->v.Call.kwargs);
- break;
- case Repr_kind:
- VISIT(st, expr, e->v.Repr.value);
- break;
- case Num_kind:
- case Str_kind:
- /* Nothing to do here. */
- break;
- /* The following exprs can be assignment targets. */
- case Attribute_kind:
- VISIT(st, expr, e->v.Attribute.value);
- break;
- case Subscript_kind:
- VISIT(st, expr, e->v.Subscript.value);
- VISIT(st, slice, e->v.Subscript.slice);
- break;
- case Name_kind:
- if (!symtable_add_def(st, e->v.Name.id,
- e->v.Name.ctx == Load ? USE : DEF_LOCAL))
- return 0;
- break;
- /* child nodes of List and Tuple will have expr_context set */
- case List_kind:
- VISIT_SEQ(st, expr, e->v.List.elts);
- break;
- case Tuple_kind:
- VISIT_SEQ(st, expr, e->v.Tuple.elts);
- break;
- }
- return 1;
-}
-
-static int
-symtable_implicit_arg(struct symtable *st, int pos)
-{
- PyObject *id = PyString_FromFormat(".%d", pos);
- if (id == NULL)
- return 0;
- if (!symtable_add_def(st, id, DEF_PARAM)) {
- Py_DECREF(id);
- return 0;
- }
- Py_DECREF(id);
- return 1;
-}
-
-static int
-symtable_visit_params(struct symtable *st, asdl_seq *args, int toplevel)
-{
- int i;
-
- /* go through all the toplevel arguments first */
- for (i = 0; i < asdl_seq_LEN(args); i++) {
- expr_ty arg = (expr_ty)asdl_seq_GET(args, i);
- if (arg->kind == Name_kind) {
- assert(arg->v.Name.ctx == Param ||
- (arg->v.Name.ctx == Store && !toplevel));
- if (!symtable_add_def(st, arg->v.Name.id, DEF_PARAM))
- return 0;
- }
- else if (arg->kind == Tuple_kind) {
- assert(arg->v.Tuple.ctx == Store);
- if (toplevel) {
- if (!symtable_implicit_arg(st, i))
- return 0;
- }
- }
- else {
- PyErr_SetString(PyExc_SyntaxError,
- "invalid expression in parameter list");
- PyErr_SyntaxLocation(st->st_filename,
- st->st_cur->ste_lineno);
- return 0;
- }
- }
-
- if (!toplevel) {
- if (!symtable_visit_params_nested(st, args))
- return 0;
- }
-
- return 1;
-}
-
-static int
-symtable_visit_params_nested(struct symtable *st, asdl_seq *args)
-{
- int i;
- for (i = 0; i < asdl_seq_LEN(args); i++) {
- expr_ty arg = (expr_ty)asdl_seq_GET(args, i);
- if (arg->kind == Tuple_kind &&
- !symtable_visit_params(st, arg->v.Tuple.elts, 0))
- return 0;
- }
-
- return 1;
-}
-
-static int
-symtable_visit_arguments(struct symtable *st, arguments_ty a)
-{
- /* skip default arguments inside function block
- XXX should ast be different?
- */
- if (a->args && !symtable_visit_params(st, a->args, 1))
- return 0;
- if (a->vararg) {
- if (!symtable_add_def(st, a->vararg, DEF_PARAM))
- return 0;
- st->st_cur->ste_varargs = 1;
- }
- if (a->kwarg) {
- if (!symtable_add_def(st, a->kwarg, DEF_PARAM))
- return 0;
- st->st_cur->ste_varkeywords = 1;
- }
- if (a->args && !symtable_visit_params_nested(st, a->args))
- return 0;
- return 1;
-}
-
-
-static int
-symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh)
-{
- if (eh->type)
- VISIT(st, expr, eh->type);
- if (eh->name)
- VISIT(st, expr, eh->name);
- VISIT_SEQ(st, stmt, eh->body);
- return 1;
-}
-
-
-static int
-symtable_visit_alias(struct symtable *st, alias_ty a)
-{
- /* Compute store_name, the name actually bound by the import
- operation. It is diferent than a->name when a->name is a
- dotted package name (e.g. spam.eggs)
- */
- PyObject *store_name;
- PyObject *name = (a->asname == NULL) ? a->name : a->asname;
- const char *base = PyString_AS_STRING(name);
- char *dot = strchr(base, '.');
- if (dot) {
- store_name = PyString_FromStringAndSize(base, dot - base);
- if (!store_name)
- return 0;
- }
- else {
- store_name = name;
- Py_INCREF(store_name);
- }
- if (strcmp(PyString_AS_STRING(name), "*")) {
- int r = symtable_add_def(st, store_name, DEF_IMPORT);
- Py_DECREF(store_name);
- return r;
- }
- else {
- if (st->st_cur->ste_type != ModuleBlock) {
- int lineno = st->st_cur->ste_lineno;
- if (!symtable_warn(st, IMPORT_STAR_WARNING, lineno)) {
- Py_DECREF(store_name);
- return 0;
- }
- }
- st->st_cur->ste_unoptimized |= OPT_IMPORT_STAR;
- Py_DECREF(store_name);
- return 1;
- }
-}
-
-
-static int
-symtable_visit_comprehension(struct symtable *st, comprehension_ty lc)
-{
- VISIT(st, expr, lc->target);
- VISIT(st, expr, lc->iter);
- VISIT_SEQ(st, expr, lc->ifs);
- return 1;
-}
-
-
-static int
-symtable_visit_keyword(struct symtable *st, keyword_ty k)
-{
- VISIT(st, expr, k->value);
- return 1;
-}
-
-
-static int
-symtable_visit_slice(struct symtable *st, slice_ty s)
-{
- switch (s->kind) {
- case Slice_kind:
- if (s->v.Slice.lower)
- VISIT(st, expr, s->v.Slice.lower)
- if (s->v.Slice.upper)
- VISIT(st, expr, s->v.Slice.upper)
- if (s->v.Slice.step)
- VISIT(st, expr, s->v.Slice.step)
- break;
- case ExtSlice_kind:
- VISIT_SEQ(st, slice, s->v.ExtSlice.dims)
- break;
- case Index_kind:
- VISIT(st, expr, s->v.Index.value)
- break;
- case Ellipsis_kind:
- break;
- }
- return 1;
-}
-
-static int
-symtable_visit_genexp(struct symtable *st, expr_ty e)
-{
- comprehension_ty outermost = ((comprehension_ty)
- (asdl_seq_GET(e->v.GeneratorExp.generators, 0)));
- /* Outermost iterator is evaluated in current scope */
- VISIT(st, expr, outermost->iter);
- /* Create generator scope for the rest */
- if (!symtable_enter_block(st, GET_IDENTIFIER(genexpr),
- FunctionBlock, (void *)e, 0)) {
- return 0;
- }
- st->st_cur->ste_generator = 1;
- /* Outermost iter is received as an argument */
- if (!symtable_implicit_arg(st, 0)) {
- symtable_exit_block(st, (void *)e);
- return 0;
- }
- VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e);
- VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e);
- VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension,
- e->v.GeneratorExp.generators, 1, (void*)e);
- VISIT_IN_BLOCK(st, expr, e->v.GeneratorExp.elt, (void*)e);
- if (!symtable_exit_block(st, (void *)e))
- return 0;
- return 1;
-}
diff --git a/sys/src/cmd/python/Python/sysmodule.c b/sys/src/cmd/python/Python/sysmodule.c
deleted file mode 100644
index f2c42b962..000000000
--- a/sys/src/cmd/python/Python/sysmodule.c
+++ /dev/null
@@ -1,1468 +0,0 @@
-
-/* System module */
-
-/*
-Various bits of information used by the interpreter are collected in
-module 'sys'.
-Function member:
-- exit(sts): raise SystemExit
-Data members:
-- stdin, stdout, stderr: standard file objects
-- modules: the table of modules (dictionary)
-- path: module search path (list of strings)
-- argv: script arguments (list of strings)
-- ps1, ps2: optional primary and secondary prompts (strings)
-*/
-
-#include "Python.h"
-#include "code.h"
-#include "frameobject.h"
-#include "eval.h"
-
-#include "osdefs.h"
-
-#ifdef MS_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include "windows.h"
-#endif /* MS_WINDOWS */
-
-#ifdef MS_COREDLL
-extern void *PyWin_DLLhModule;
-/* A string loaded from the DLL at startup: */
-extern const char *PyWin_DLLVersionString;
-#endif
-
-#ifdef __VMS
-#include <unixlib.h>
-#endif
-
-#ifdef MS_WINDOWS
-#include <windows.h>
-#endif
-
-#ifdef HAVE_LANGINFO_H
-#include <locale.h>
-#include <langinfo.h>
-#endif
-
-PyObject *
-PySys_GetObject(char *name)
-{
- PyThreadState *tstate = PyThreadState_GET();
- PyObject *sd = tstate->interp->sysdict;
- if (sd == NULL)
- return NULL;
- return PyDict_GetItemString(sd, name);
-}
-
-FILE *
-PySys_GetFile(char *name, FILE *def)
-{
- FILE *fp = NULL;
- PyObject *v = PySys_GetObject(name);
- if (v != NULL && PyFile_Check(v))
- fp = PyFile_AsFile(v);
- if (fp == NULL)
- fp = def;
- return fp;
-}
-
-int
-PySys_SetObject(char *name, PyObject *v)
-{
- PyThreadState *tstate = PyThreadState_GET();
- PyObject *sd = tstate->interp->sysdict;
- if (v == NULL) {
- if (PyDict_GetItemString(sd, name) == NULL)
- return 0;
- else
- return PyDict_DelItemString(sd, name);
- }
- else
- return PyDict_SetItemString(sd, name, v);
-}
-
-static PyObject *
-sys_displayhook(PyObject *self, PyObject *o)
-{
- PyObject *outf;
- PyInterpreterState *interp = PyThreadState_GET()->interp;
- PyObject *modules = interp->modules;
- PyObject *builtins = PyDict_GetItemString(modules, "__builtin__");
-
- if (builtins == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "lost __builtin__");
- return NULL;
- }
-
- /* Print value except if None */
- /* After printing, also assign to '_' */
- /* Before, set '_' to None to avoid recursion */
- if (o == Py_None) {
- Py_INCREF(Py_None);
- return Py_None;
- }
- if (PyObject_SetAttrString(builtins, "_", Py_None) != 0)
- return NULL;
- if (Py_FlushLine() != 0)
- return NULL;
- outf = PySys_GetObject("stdout");
- if (outf == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
- return NULL;
- }
- if (PyFile_WriteObject(o, outf, 0) != 0)
- return NULL;
- PyFile_SoftSpace(outf, 1);
- if (Py_FlushLine() != 0)
- return NULL;
- if (PyObject_SetAttrString(builtins, "_", o) != 0)
- return NULL;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(displayhook_doc,
-"displayhook(object) -> None\n"
-"\n"
-"Print an object to sys.stdout and also save it in __builtin__.\n"
-);
-
-static PyObject *
-sys_excepthook(PyObject* self, PyObject* args)
-{
- PyObject *exc, *value, *tb;
- if (!PyArg_UnpackTuple(args, "excepthook", 3, 3, &exc, &value, &tb))
- return NULL;
- PyErr_Display(exc, value, tb);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(excepthook_doc,
-"excepthook(exctype, value, traceback) -> None\n"
-"\n"
-"Handle an exception by displaying it with a traceback on sys.stderr.\n"
-);
-
-static PyObject *
-sys_exc_info(PyObject *self, PyObject *noargs)
-{
- PyThreadState *tstate;
- tstate = PyThreadState_GET();
- return Py_BuildValue(
- "(OOO)",
- tstate->exc_type != NULL ? tstate->exc_type : Py_None,
- tstate->exc_value != NULL ? tstate->exc_value : Py_None,
- tstate->exc_traceback != NULL ?
- tstate->exc_traceback : Py_None);
-}
-
-PyDoc_STRVAR(exc_info_doc,
-"exc_info() -> (type, value, traceback)\n\
-\n\
-Return information about the most recent exception caught by an except\n\
-clause in the current stack frame or in an older stack frame."
-);
-
-static PyObject *
-sys_exc_clear(PyObject *self, PyObject *noargs)
-{
- PyThreadState *tstate = PyThreadState_GET();
- PyObject *tmp_type, *tmp_value, *tmp_tb;
- tmp_type = tstate->exc_type;
- tmp_value = tstate->exc_value;
- tmp_tb = tstate->exc_traceback;
- tstate->exc_type = NULL;
- tstate->exc_value = NULL;
- tstate->exc_traceback = NULL;
- Py_XDECREF(tmp_type);
- Py_XDECREF(tmp_value);
- Py_XDECREF(tmp_tb);
- /* For b/w compatibility */
- PySys_SetObject("exc_type", Py_None);
- PySys_SetObject("exc_value", Py_None);
- PySys_SetObject("exc_traceback", Py_None);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(exc_clear_doc,
-"exc_clear() -> None\n\
-\n\
-Clear global information on the current exception. Subsequent calls to\n\
-exc_info() will return (None,None,None) until another exception is raised\n\
-in the current thread or the execution stack returns to a frame where\n\
-another exception is being handled."
-);
-
-static PyObject *
-sys_exit(PyObject *self, PyObject *args)
-{
- PyObject *exit_code = 0;
- if (!PyArg_UnpackTuple(args, "exit", 0, 1, &exit_code))
- return NULL;
- /* Raise SystemExit so callers may catch it or clean up. */
- PyErr_SetObject(PyExc_SystemExit, exit_code);
- return NULL;
-}
-
-PyDoc_STRVAR(exit_doc,
-"exit([status])\n\
-\n\
-Exit the interpreter by raising SystemExit(status).\n\
-If the status is omitted or None, it defaults to zero (i.e., success).\n\
-If the status is numeric, it will be used as the system exit status.\n\
-If it is another kind of object, it will be printed and the system\n\
-exit status will be one (i.e., failure)."
-);
-
-#ifdef Py_USING_UNICODE
-
-static PyObject *
-sys_getdefaultencoding(PyObject *self)
-{
- return PyString_FromString(PyUnicode_GetDefaultEncoding());
-}
-
-PyDoc_STRVAR(getdefaultencoding_doc,
-"getdefaultencoding() -> string\n\
-\n\
-Return the current default string encoding used by the Unicode \n\
-implementation."
-);
-
-static PyObject *
-sys_setdefaultencoding(PyObject *self, PyObject *args)
-{
- char *encoding;
- if (!PyArg_ParseTuple(args, "s:setdefaultencoding", &encoding))
- return NULL;
- if (PyUnicode_SetDefaultEncoding(encoding))
- return NULL;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(setdefaultencoding_doc,
-"setdefaultencoding(encoding)\n\
-\n\
-Set the current default string encoding used by the Unicode implementation."
-);
-
-static PyObject *
-sys_getfilesystemencoding(PyObject *self)
-{
- if (Py_FileSystemDefaultEncoding)
- return PyString_FromString(Py_FileSystemDefaultEncoding);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(getfilesystemencoding_doc,
-"getfilesystemencoding() -> string\n\
-\n\
-Return the encoding used to convert Unicode filenames in\n\
-operating system filenames."
-);
-
-#endif
-
-/*
- * Cached interned string objects used for calling the profile and
- * trace functions. Initialized by trace_init().
- */
-static PyObject *whatstrings[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
-
-static int
-trace_init(void)
-{
- static char *whatnames[7] = {"call", "exception", "line", "return",
- "c_call", "c_exception", "c_return"};
- PyObject *name;
- int i;
- for (i = 0; i < 7; ++i) {
- if (whatstrings[i] == NULL) {
- name = PyString_InternFromString(whatnames[i]);
- if (name == NULL)
- return -1;
- whatstrings[i] = name;
- }
- }
- return 0;
-}
-
-
-static PyObject *
-call_trampoline(PyThreadState *tstate, PyObject* callback,
- PyFrameObject *frame, int what, PyObject *arg)
-{
- PyObject *args = PyTuple_New(3);
- PyObject *whatstr;
- PyObject *result;
-
- if (args == NULL)
- return NULL;
- Py_INCREF(frame);
- whatstr = whatstrings[what];
- Py_INCREF(whatstr);
- if (arg == NULL)
- arg = Py_None;
- Py_INCREF(arg);
- PyTuple_SET_ITEM(args, 0, (PyObject *)frame);
- PyTuple_SET_ITEM(args, 1, whatstr);
- PyTuple_SET_ITEM(args, 2, arg);
-
- /* call the Python-level function */
- PyFrame_FastToLocals(frame);
- result = PyEval_CallObject(callback, args);
- PyFrame_LocalsToFast(frame, 1);
- if (result == NULL)
- PyTraceBack_Here(frame);
-
- /* cleanup */
- Py_DECREF(args);
- return result;
-}
-
-static int
-profile_trampoline(PyObject *self, PyFrameObject *frame,
- int what, PyObject *arg)
-{
- PyThreadState *tstate = frame->f_tstate;
- PyObject *result;
-
- if (arg == NULL)
- arg = Py_None;
- result = call_trampoline(tstate, self, frame, what, arg);
- if (result == NULL) {
- PyEval_SetProfile(NULL, NULL);
- return -1;
- }
- Py_DECREF(result);
- return 0;
-}
-
-static int
-trace_trampoline(PyObject *self, PyFrameObject *frame,
- int what, PyObject *arg)
-{
- PyThreadState *tstate = frame->f_tstate;
- PyObject *callback;
- PyObject *result;
-
- if (what == PyTrace_CALL)
- callback = self;
- else
- callback = frame->f_trace;
- if (callback == NULL)
- return 0;
- result = call_trampoline(tstate, callback, frame, what, arg);
- if (result == NULL) {
- PyEval_SetTrace(NULL, NULL);
- Py_XDECREF(frame->f_trace);
- frame->f_trace = NULL;
- return -1;
- }
- if (result != Py_None) {
- PyObject *temp = frame->f_trace;
- frame->f_trace = NULL;
- Py_XDECREF(temp);
- frame->f_trace = result;
- }
- else {
- Py_DECREF(result);
- }
- return 0;
-}
-
-static PyObject *
-sys_settrace(PyObject *self, PyObject *args)
-{
- if (trace_init() == -1)
- return NULL;
- if (args == Py_None)
- PyEval_SetTrace(NULL, NULL);
- else
- PyEval_SetTrace(trace_trampoline, args);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(settrace_doc,
-"settrace(function)\n\
-\n\
-Set the global debug tracing function. It will be called on each\n\
-function call. See the debugger chapter in the library manual."
-);
-
-static PyObject *
-sys_setprofile(PyObject *self, PyObject *args)
-{
- if (trace_init() == -1)
- return NULL;
- if (args == Py_None)
- PyEval_SetProfile(NULL, NULL);
- else
- PyEval_SetProfile(profile_trampoline, args);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(setprofile_doc,
-"setprofile(function)\n\
-\n\
-Set the profiling function. It will be called on each function call\n\
-and return. See the profiler chapter in the library manual."
-);
-
-static PyObject *
-sys_setcheckinterval(PyObject *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_Py_CheckInterval))
- return NULL;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(setcheckinterval_doc,
-"setcheckinterval(n)\n\
-\n\
-Tell the Python interpreter to check for asynchronous events every\n\
-n instructions. This also affects how often thread switches occur."
-);
-
-static PyObject *
-sys_getcheckinterval(PyObject *self, PyObject *args)
-{
- return PyInt_FromLong(_Py_CheckInterval);
-}
-
-PyDoc_STRVAR(getcheckinterval_doc,
-"getcheckinterval() -> current check interval; see setcheckinterval()."
-);
-
-#ifdef WITH_TSC
-static PyObject *
-sys_settscdump(PyObject *self, PyObject *args)
-{
- int bool;
- PyThreadState *tstate = PyThreadState_Get();
-
- if (!PyArg_ParseTuple(args, "i:settscdump", &bool))
- return NULL;
- if (bool)
- tstate->interp->tscdump = 1;
- else
- tstate->interp->tscdump = 0;
- Py_INCREF(Py_None);
- return Py_None;
-
-}
-
-PyDoc_STRVAR(settscdump_doc,
-"settscdump(bool)\n\
-\n\
-If true, tell the Python interpreter to dump VM measurements to\n\
-stderr. If false, turn off dump. The measurements are based on the\n\
-processor's time-stamp counter."
-);
-#endif /* TSC */
-
-static PyObject *
-sys_setrecursionlimit(PyObject *self, PyObject *args)
-{
- int new_limit;
- if (!PyArg_ParseTuple(args, "i:setrecursionlimit", &new_limit))
- return NULL;
- if (new_limit <= 0) {
- PyErr_SetString(PyExc_ValueError,
- "recursion limit must be positive");
- return NULL;
- }
- Py_SetRecursionLimit(new_limit);
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(setrecursionlimit_doc,
-"setrecursionlimit(n)\n\
-\n\
-Set the maximum depth of the Python interpreter stack to n. This\n\
-limit prevents infinite recursion from causing an overflow of the C\n\
-stack and crashing Python. The highest possible limit is platform-\n\
-dependent."
-);
-
-static PyObject *
-sys_getrecursionlimit(PyObject *self)
-{
- return PyInt_FromLong(Py_GetRecursionLimit());
-}
-
-PyDoc_STRVAR(getrecursionlimit_doc,
-"getrecursionlimit()\n\
-\n\
-Return the current value of the recursion limit, the maximum depth\n\
-of the Python interpreter stack. This limit prevents infinite\n\
-recursion from causing an overflow of the C stack and crashing Python."
-);
-
-#ifdef MS_WINDOWS
-PyDoc_STRVAR(getwindowsversion_doc,
-"getwindowsversion()\n\
-\n\
-Return information about the running version of Windows.\n\
-The result is a tuple of (major, minor, build, platform, text)\n\
-All elements are numbers, except text which is a string.\n\
-Platform may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP\n\
-"
-);
-
-static PyObject *
-sys_getwindowsversion(PyObject *self)
-{
- OSVERSIONINFO ver;
- ver.dwOSVersionInfoSize = sizeof(ver);
- if (!GetVersionEx(&ver))
- return PyErr_SetFromWindowsErr(0);
- return Py_BuildValue("HHHHs",
- ver.dwMajorVersion,
- ver.dwMinorVersion,
- ver.dwBuildNumber,
- ver.dwPlatformId,
- ver.szCSDVersion);
-}
-
-#endif /* MS_WINDOWS */
-
-#ifdef HAVE_DLOPEN
-static PyObject *
-sys_setdlopenflags(PyObject *self, PyObject *args)
-{
- int new_val;
- PyThreadState *tstate = PyThreadState_GET();
- if (!PyArg_ParseTuple(args, "i:setdlopenflags", &new_val))
- return NULL;
- if (!tstate)
- return NULL;
- tstate->interp->dlopenflags = new_val;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(setdlopenflags_doc,
-"setdlopenflags(n) -> None\n\
-\n\
-Set the flags that will be used for dlopen() calls. Among other\n\
-things, this will enable a lazy resolving of symbols when importing\n\
-a module, if called as sys.setdlopenflags(0)\n\
-To share symbols across extension modules, call as\n\
-sys.setdlopenflags(dl.RTLD_NOW|dl.RTLD_GLOBAL)"
-);
-
-static PyObject *
-sys_getdlopenflags(PyObject *self, PyObject *args)
-{
- PyThreadState *tstate = PyThreadState_GET();
- if (!tstate)
- return NULL;
- return PyInt_FromLong(tstate->interp->dlopenflags);
-}
-
-PyDoc_STRVAR(getdlopenflags_doc,
-"getdlopenflags() -> int\n\
-\n\
-Return the current value of the flags that are used for dlopen()\n\
-calls. The flag constants are defined in the dl module."
-);
-#endif
-
-#ifdef USE_MALLOPT
-/* Link with -lmalloc (or -lmpc) on an SGI */
-#include <malloc.h>
-
-static PyObject *
-sys_mdebug(PyObject *self, PyObject *args)
-{
- int flag;
- if (!PyArg_ParseTuple(args, "i:mdebug", &flag))
- return NULL;
- mallopt(M_DEBUG, flag);
- Py_INCREF(Py_None);
- return Py_None;
-}
-#endif /* USE_MALLOPT */
-
-static PyObject *
-sys_getrefcount(PyObject *self, PyObject *arg)
-{
- return PyInt_FromSsize_t(arg->ob_refcnt);
-}
-
-#ifdef Py_REF_DEBUG
-static PyObject *
-sys_gettotalrefcount(PyObject *self)
-{
- return PyInt_FromSsize_t(_Py_GetRefTotal());
-}
-#endif /* Py_REF_DEBUG */
-
-PyDoc_STRVAR(getrefcount_doc,
-"getrefcount(object) -> integer\n\
-\n\
-Return the reference count of object. The count returned is generally\n\
-one higher than you might expect, because it includes the (temporary)\n\
-reference as an argument to getrefcount()."
-);
-
-#ifdef COUNT_ALLOCS
-static PyObject *
-sys_getcounts(PyObject *self)
-{
- extern PyObject *get_counts(void);
-
- return get_counts();
-}
-#endif
-
-PyDoc_STRVAR(getframe_doc,
-"_getframe([depth]) -> frameobject\n\
-\n\
-Return a frame object from the call stack. If optional integer depth is\n\
-given, return the frame object that many calls below the top of the stack.\n\
-If that is deeper than the call stack, ValueError is raised. The default\n\
-for depth is zero, returning the frame at the top of the call stack.\n\
-\n\
-This function should be used for internal and specialized\n\
-purposes only."
-);
-
-static PyObject *
-sys_getframe(PyObject *self, PyObject *args)
-{
- PyFrameObject *f = PyThreadState_GET()->frame;
- int depth = -1;
-
- if (!PyArg_ParseTuple(args, "|i:_getframe", &depth))
- return NULL;
-
- while (depth > 0 && f != NULL) {
- f = f->f_back;
- --depth;
- }
- if (f == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "call stack is not deep enough");
- return NULL;
- }
- Py_INCREF(f);
- return (PyObject*)f;
-}
-
-PyDoc_STRVAR(current_frames_doc,
-"_current_frames() -> dictionary\n\
-\n\
-Return a dictionary mapping each current thread T's thread id to T's\n\
-current stack frame.\n\
-\n\
-This function should be used for specialized purposes only."
-);
-
-static PyObject *
-sys_current_frames(PyObject *self, PyObject *noargs)
-{
- return _PyThread_CurrentFrames();
-}
-
-PyDoc_STRVAR(call_tracing_doc,
-"call_tracing(func, args) -> object\n\
-\n\
-Call func(*args), while tracing is enabled. The tracing state is\n\
-saved, and restored afterwards. This is intended to be called from\n\
-a debugger from a checkpoint, to recursively debug some other code."
-);
-
-static PyObject *
-sys_call_tracing(PyObject *self, PyObject *args)
-{
- PyObject *func, *funcargs;
- if (!PyArg_UnpackTuple(args, "call_tracing", 2, 2, &func, &funcargs))
- return NULL;
- return _PyEval_CallTracing(func, funcargs);
-}
-
-PyDoc_STRVAR(callstats_doc,
-"callstats() -> tuple of integers\n\
-\n\
-Return a tuple of function call statistics, if CALL_PROFILE was defined\n\
-when Python was built. Otherwise, return None.\n\
-\n\
-When enabled, this function returns detailed, implementation-specific\n\
-details about the number of function calls executed. The return value is\n\
-a 11-tuple where the entries in the tuple are counts of:\n\
-0. all function calls\n\
-1. calls to PyFunction_Type objects\n\
-2. PyFunction calls that do not create an argument tuple\n\
-3. PyFunction calls that do not create an argument tuple\n\
- and bypass PyEval_EvalCodeEx()\n\
-4. PyMethod calls\n\
-5. PyMethod calls on bound methods\n\
-6. PyType calls\n\
-7. PyCFunction calls\n\
-8. generator calls\n\
-9. All other calls\n\
-10. Number of stack pops performed by call_function()"
-);
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef Py_TRACE_REFS
-/* Defined in objects.c because it uses static globals if that file */
-extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
-#endif
-
-#ifdef DYNAMIC_EXECUTION_PROFILE
-/* Defined in ceval.c because it uses static globals if that file */
-extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-static PyMethodDef sys_methods[] = {
- /* Might as well keep this in alphabetic order */
- {"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,
- callstats_doc},
- {"_current_frames", sys_current_frames, METH_NOARGS,
- current_frames_doc},
- {"displayhook", sys_displayhook, METH_O, displayhook_doc},
- {"exc_info", sys_exc_info, METH_NOARGS, exc_info_doc},
- {"exc_clear", sys_exc_clear, METH_NOARGS, exc_clear_doc},
- {"excepthook", sys_excepthook, METH_VARARGS, excepthook_doc},
- {"exit", sys_exit, METH_VARARGS, exit_doc},
-#ifdef Py_USING_UNICODE
- {"getdefaultencoding", (PyCFunction)sys_getdefaultencoding,
- METH_NOARGS, getdefaultencoding_doc},
-#endif
-#ifdef HAVE_DLOPEN
- {"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS,
- getdlopenflags_doc},
-#endif
-#ifdef COUNT_ALLOCS
- {"getcounts", (PyCFunction)sys_getcounts, METH_NOARGS},
-#endif
-#ifdef DYNAMIC_EXECUTION_PROFILE
- {"getdxp", _Py_GetDXProfile, METH_VARARGS},
-#endif
-#ifdef Py_USING_UNICODE
- {"getfilesystemencoding", (PyCFunction)sys_getfilesystemencoding,
- METH_NOARGS, getfilesystemencoding_doc},
-#endif
-#ifdef Py_TRACE_REFS
- {"getobjects", _Py_GetObjects, METH_VARARGS},
-#endif
-#ifdef Py_REF_DEBUG
- {"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS},
-#endif
- {"getrefcount", (PyCFunction)sys_getrefcount, METH_O, getrefcount_doc},
- {"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS,
- getrecursionlimit_doc},
- {"_getframe", sys_getframe, METH_VARARGS, getframe_doc},
-#ifdef MS_WINDOWS
- {"getwindowsversion", (PyCFunction)sys_getwindowsversion, METH_NOARGS,
- getwindowsversion_doc},
-#endif /* MS_WINDOWS */
-#ifdef USE_MALLOPT
- {"mdebug", sys_mdebug, METH_VARARGS},
-#endif
-#ifdef Py_USING_UNICODE
- {"setdefaultencoding", sys_setdefaultencoding, METH_VARARGS,
- setdefaultencoding_doc},
-#endif
- {"setcheckinterval", sys_setcheckinterval, METH_VARARGS,
- setcheckinterval_doc},
- {"getcheckinterval", sys_getcheckinterval, METH_NOARGS,
- getcheckinterval_doc},
-#ifdef HAVE_DLOPEN
- {"setdlopenflags", sys_setdlopenflags, METH_VARARGS,
- setdlopenflags_doc},
-#endif
- {"setprofile", sys_setprofile, METH_O, setprofile_doc},
- {"setrecursionlimit", sys_setrecursionlimit, METH_VARARGS,
- setrecursionlimit_doc},
-#ifdef WITH_TSC
- {"settscdump", sys_settscdump, METH_VARARGS, settscdump_doc},
-#endif
- {"settrace", sys_settrace, METH_O, settrace_doc},
- {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc},
- {NULL, NULL} /* sentinel */
-};
-
-static PyObject *
-list_builtin_module_names(void)
-{
- PyObject *list = PyList_New(0);
- int i;
- if (list == NULL)
- return NULL;
- for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
- PyObject *name = PyString_FromString(
- PyImport_Inittab[i].name);
- if (name == NULL)
- break;
- PyList_Append(list, name);
- Py_DECREF(name);
- }
- if (PyList_Sort(list) != 0) {
- Py_DECREF(list);
- list = NULL;
- }
- if (list) {
- PyObject *v = PyList_AsTuple(list);
- Py_DECREF(list);
- list = v;
- }
- return list;
-}
-
-static PyObject *warnoptions = NULL;
-
-void
-PySys_ResetWarnOptions(void)
-{
- if (warnoptions == NULL || !PyList_Check(warnoptions))
- return;
- PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
-}
-
-void
-PySys_AddWarnOption(char *s)
-{
- PyObject *str;
-
- if (warnoptions == NULL || !PyList_Check(warnoptions)) {
- Py_XDECREF(warnoptions);
- warnoptions = PyList_New(0);
- if (warnoptions == NULL)
- return;
- }
- str = PyString_FromString(s);
- if (str != NULL) {
- PyList_Append(warnoptions, str);
- Py_DECREF(str);
- }
-}
-
-/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
- Two literals concatenated works just fine. If you have a K&R compiler
- or other abomination that however *does* understand longer strings,
- get rid of the !!! comment in the middle and the quotes that surround it. */
-PyDoc_VAR(sys_doc) =
-PyDoc_STR(
-"This module provides access to some objects used or maintained by the\n\
-interpreter and to functions that interact strongly with the interpreter.\n\
-\n\
-Dynamic objects:\n\
-\n\
-argv -- command line arguments; argv[0] is the script pathname if known\n\
-path -- module search path; path[0] is the script directory, else ''\n\
-modules -- dictionary of loaded modules\n\
-\n\
-displayhook -- called to show results in an interactive session\n\
-excepthook -- called to handle any uncaught exception other than SystemExit\n\
- To customize printing in an interactive session or to install a custom\n\
- top-level exception handler, assign other functions to replace these.\n\
-\n\
-exitfunc -- if sys.exitfunc exists, this routine is called when Python exits\n\
- Assigning to sys.exitfunc is deprecated; use the atexit module instead.\n\
-\n\
-stdin -- standard input file object; used by raw_input() and input()\n\
-stdout -- standard output file object; used by the print statement\n\
-stderr -- standard error object; used for error messages\n\
- By assigning other file objects (or objects that behave like files)\n\
- to these, it is possible to redirect all of the interpreter's I/O.\n\
-\n\
-last_type -- type of last uncaught exception\n\
-last_value -- value of last uncaught exception\n\
-last_traceback -- traceback of last uncaught exception\n\
- These three are only available in an interactive session after a\n\
- traceback has been printed.\n\
-\n\
-exc_type -- type of exception currently being handled\n\
-exc_value -- value of exception currently being handled\n\
-exc_traceback -- traceback of exception currently being handled\n\
- The function exc_info() should be used instead of these three,\n\
- because it is thread-safe.\n\
-"
-)
-/* concatenating string here */
-PyDoc_STR(
-"\n\
-Static objects:\n\
-\n\
-maxint -- the largest supported integer (the smallest is -maxint-1)\n\
-maxunicode -- the largest supported character\n\
-builtin_module_names -- tuple of module names built into this interpreter\n\
-version -- the version of this interpreter as a string\n\
-version_info -- version information as a tuple\n\
-hexversion -- version information encoded as a single integer\n\
-copyright -- copyright notice pertaining to this interpreter\n\
-platform -- platform identifier\n\
-executable -- pathname of this Python interpreter\n\
-prefix -- prefix used to find the Python library\n\
-exec_prefix -- prefix used to find the machine-specific Python library\n\
-"
-)
-#ifdef MS_WINDOWS
-/* concatenating string here */
-PyDoc_STR(
-"dllhandle -- [Windows only] integer handle of the Python DLL\n\
-winver -- [Windows only] version number of the Python DLL\n\
-"
-)
-#endif /* MS_WINDOWS */
-PyDoc_STR(
-"__stdin__ -- the original stdin; don't touch!\n\
-__stdout__ -- the original stdout; don't touch!\n\
-__stderr__ -- the original stderr; don't touch!\n\
-__displayhook__ -- the original displayhook; don't touch!\n\
-__excepthook__ -- the original excepthook; don't touch!\n\
-\n\
-Functions:\n\
-\n\
-displayhook() -- print an object to the screen, and save it in __builtin__._\n\
-excepthook() -- print an exception and its traceback to sys.stderr\n\
-exc_info() -- return thread-safe information about the current exception\n\
-exc_clear() -- clear the exception state for the current thread\n\
-exit() -- exit the interpreter by raising SystemExit\n\
-getdlopenflags() -- returns flags to be used for dlopen() calls\n\
-getrefcount() -- return the reference count for an object (plus one :-)\n\
-getrecursionlimit() -- return the max recursion depth for the interpreter\n\
-setcheckinterval() -- control how often the interpreter checks for events\n\
-setdlopenflags() -- set the flags to be used for dlopen() calls\n\
-setprofile() -- set the global profiling function\n\
-setrecursionlimit() -- set the max recursion depth for the interpreter\n\
-settrace() -- set the global debug tracing function\n\
-"
-)
-/* end of sys_doc */ ;
-
-static int
-_check_and_flush (FILE *stream)
-{
- int prev_fail = ferror (stream);
- return fflush (stream) || prev_fail ? EOF : 0;
-}
-
-/* Subversion branch and revision management */
-static const char _patchlevel_revision[] = PY_PATCHLEVEL_REVISION;
-static const char headurl[] = "$HeadURL: svn+ssh://pythondev@svn.python.org/python/tags/r251/Python/sysmodule.c $";
-static int svn_initialized;
-static char patchlevel_revision[50]; /* Just the number */
-static char branch[50];
-static char shortbranch[50];
-static const char *svn_revision;
-
-static void
-svnversion_init(void)
-{
- const char *python, *br_start, *br_end, *br_end2, *svnversion;
- Py_ssize_t len;
- int istag;
-
- if (svn_initialized)
- return;
-
- python = strstr(headurl, "/python/");
- if (!python)
- Py_FatalError("subversion keywords missing");
-
- br_start = python + 8;
- br_end = strchr(br_start, '/');
- assert(br_end);
-
- /* Works even for trunk,
- as we are in trunk/Python/sysmodule.c */
- br_end2 = strchr(br_end+1, '/');
-
- istag = strncmp(br_start, "tags", 4) == 0;
- if (strncmp(br_start, "trunk", 5) == 0) {
- strcpy(branch, "trunk");
- strcpy(shortbranch, "trunk");
-
- }
- else if (istag || strncmp(br_start, "branches", 8) == 0) {
- len = br_end2 - br_start;
- strncpy(branch, br_start, len);
- branch[len] = '\0';
-
- len = br_end2 - (br_end + 1);
- strncpy(shortbranch, br_end + 1, len);
- shortbranch[len] = '\0';
- }
- else {
- Py_FatalError("bad HeadURL");
- return;
- }
-
-
- svnversion = _Py_svnversion();
- if (strcmp(svnversion, "exported") != 0)
- svn_revision = svnversion;
- else if (istag) {
- len = strlen(_patchlevel_revision);
- strncpy(patchlevel_revision, _patchlevel_revision + 11,
- len - 13);
- patchlevel_revision[len - 13] = '\0';
- svn_revision = patchlevel_revision;
- }
- else
- svn_revision = "";
-
- svn_initialized = 1;
-}
-
-/* Return svnversion output if available.
- Else return Revision of patchlevel.h if on branch.
- Else return empty string */
-const char*
-Py_SubversionRevision()
-{
- svnversion_init();
- return svn_revision;
-}
-
-const char*
-Py_SubversionShortBranch()
-{
- svnversion_init();
- return shortbranch;
-}
-
-PyObject *
-_PySys_Init(void)
-{
- PyObject *m, *v, *sysdict;
- PyObject *sysin, *sysout, *syserr;
- char *s;
-#ifdef MS_WINDOWS
- char buf[128];
-#endif
-
- m = Py_InitModule3("sys", sys_methods, sys_doc);
- if (m == NULL)
- return NULL;
- sysdict = PyModule_GetDict(m);
-
- {
- /* XXX: does this work on Win/Win64? (see posix_fstat) */
- struct stat sb;
- if (fstat(fileno(stdin), &sb) == 0 &&
- S_ISDIR(sb.st_mode)) {
- /* There's nothing more we can do. */
- /* Py_FatalError() will core dump, so just exit. */
- PySys_WriteStderr("Python error: <stdin> is a directory, cannot continue\n");
- exit(EXIT_FAILURE);
- }
- }
-
- /* Closing the standard FILE* if sys.std* goes aways causes problems
- * for embedded Python usages. Closing them when somebody explicitly
- * invokes .close() might be possible, but the FAQ promises they get
- * never closed. However, we still need to get write errors when
- * writing fails (e.g. because stdout is redirected), so we flush the
- * streams and check for errors before the file objects are deleted.
- * On OS X, fflush()ing stdin causes an error, so we exempt stdin
- * from that procedure.
- */
- sysin = PyFile_FromFile(stdin, "<stdin>", "r", NULL);
- sysout = PyFile_FromFile(stdout, "<stdout>", "w", _check_and_flush);
- syserr = PyFile_FromFile(stderr, "<stderr>", "w", _check_and_flush);
- if (PyErr_Occurred())
- return NULL;
-#ifdef MS_WINDOWS
- if(isatty(_fileno(stdin)) && PyFile_Check(sysin)) {
- sprintf(buf, "cp%d", GetConsoleCP());
- if (!PyFile_SetEncoding(sysin, buf))
- return NULL;
- }
- if(isatty(_fileno(stdout)) && PyFile_Check(sysout)) {
- sprintf(buf, "cp%d", GetConsoleOutputCP());
- if (!PyFile_SetEncoding(sysout, buf))
- return NULL;
- }
- if(isatty(_fileno(stderr)) && PyFile_Check(syserr)) {
- sprintf(buf, "cp%d", GetConsoleOutputCP());
- if (!PyFile_SetEncoding(syserr, buf))
- return NULL;
- }
-#endif
-
- PyDict_SetItemString(sysdict, "stdin", sysin);
- PyDict_SetItemString(sysdict, "stdout", sysout);
- PyDict_SetItemString(sysdict, "stderr", syserr);
- /* Make backup copies for cleanup */
- PyDict_SetItemString(sysdict, "__stdin__", sysin);
- PyDict_SetItemString(sysdict, "__stdout__", sysout);
- PyDict_SetItemString(sysdict, "__stderr__", syserr);
- PyDict_SetItemString(sysdict, "__displayhook__",
- PyDict_GetItemString(sysdict, "displayhook"));
- PyDict_SetItemString(sysdict, "__excepthook__",
- PyDict_GetItemString(sysdict, "excepthook"));
- Py_XDECREF(sysin);
- Py_XDECREF(sysout);
- Py_XDECREF(syserr);
- PyDict_SetItemString(sysdict, "version",
- v = PyString_FromString(Py_GetVersion()));
- Py_XDECREF(v);
- PyDict_SetItemString(sysdict, "hexversion",
- v = PyInt_FromLong(PY_VERSION_HEX));
- Py_XDECREF(v);
- svnversion_init();
- v = Py_BuildValue("(ssz)", "CPython", branch, svn_revision);
- PyDict_SetItemString(sysdict, "subversion", v);
- Py_XDECREF(v);
- /*
- * These release level checks are mutually exclusive and cover
- * the field, so don't get too fancy with the pre-processor!
- */
-#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
- s = "alpha";
-#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
- s = "beta";
-#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
- s = "candidate";
-#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
- s = "final";
-#endif
-
-#define SET_SYS_FROM_STRING(key, value) \
- v = value; \
- if (v != NULL) \
- PyDict_SetItemString(sysdict, key, v); \
- Py_XDECREF(v)
-
- SET_SYS_FROM_STRING("version_info",
- Py_BuildValue("iiisi", PY_MAJOR_VERSION,
- PY_MINOR_VERSION,
- PY_MICRO_VERSION, s,
- PY_RELEASE_SERIAL));
- SET_SYS_FROM_STRING("api_version",
- PyInt_FromLong(PYTHON_API_VERSION));
- SET_SYS_FROM_STRING("copyright",
- PyString_FromString(Py_GetCopyright()));
- SET_SYS_FROM_STRING("platform",
- PyString_FromString(Py_GetPlatform()));
- SET_SYS_FROM_STRING("executable",
- PyString_FromString(Py_GetProgramFullPath()));
- SET_SYS_FROM_STRING("prefix",
- PyString_FromString(Py_GetPrefix()));
- SET_SYS_FROM_STRING("exec_prefix",
- PyString_FromString(Py_GetExecPrefix()));
- SET_SYS_FROM_STRING("maxint",
- PyInt_FromLong(PyInt_GetMax()));
-#ifdef Py_USING_UNICODE
- SET_SYS_FROM_STRING("maxunicode",
- PyInt_FromLong(PyUnicode_GetMax()));
-#endif
- SET_SYS_FROM_STRING("builtin_module_names",
- list_builtin_module_names());
- {
- /* Assumes that longs are at least 2 bytes long.
- Should be safe! */
- unsigned long number = 1;
- char *value;
-
- s = (char *) &number;
- if (s[0] == 0)
- value = "big";
- else
- value = "little";
- SET_SYS_FROM_STRING("byteorder",
- PyString_FromString(value));
- }
-#ifdef MS_COREDLL
- SET_SYS_FROM_STRING("dllhandle",
- PyLong_FromVoidPtr(PyWin_DLLhModule));
- SET_SYS_FROM_STRING("winver",
- PyString_FromString(PyWin_DLLVersionString));
-#endif
-#undef SET_SYS_FROM_STRING
- if (warnoptions == NULL) {
- warnoptions = PyList_New(0);
- }
- else {
- Py_INCREF(warnoptions);
- }
- if (warnoptions != NULL) {
- PyDict_SetItemString(sysdict, "warnoptions", warnoptions);
- }
-
- if (PyErr_Occurred())
- return NULL;
- return m;
-}
-
-static PyObject *
-makepathobject(char *path, int delim)
-{
- int i, n;
- char *p;
- PyObject *v, *w;
-
- n = 1;
- p = path;
- while ((p = strchr(p, delim)) != NULL) {
- n++;
- p++;
- }
- v = PyList_New(n);
- if (v == NULL)
- return NULL;
- for (i = 0; ; i++) {
- p = strchr(path, delim);
- if (p == NULL)
- p = strchr(path, '\0'); /* End of string */
- w = PyString_FromStringAndSize(path, (Py_ssize_t) (p - path));
- if (w == NULL) {
- Py_DECREF(v);
- return NULL;
- }
- PyList_SetItem(v, i, w);
- if (*p == '\0')
- break;
- path = p+1;
- }
- return v;
-}
-
-void
-PySys_SetPath(char *path)
-{
- PyObject *v;
- if ((v = makepathobject(path, DELIM)) == NULL)
- Py_FatalError("can't create sys.path");
- if (PySys_SetObject("path", v) != 0)
- Py_FatalError("can't assign sys.path");
- Py_DECREF(v);
-}
-
-static PyObject *
-makeargvobject(int argc, char **argv)
-{
- PyObject *av;
- if (argc <= 0 || argv == NULL) {
- /* Ensure at least one (empty) argument is seen */
- static char *empty_argv[1] = {""};
- argv = empty_argv;
- argc = 1;
- }
- av = PyList_New(argc);
- if (av != NULL) {
- int i;
- for (i = 0; i < argc; i++) {
-#ifdef __VMS
- PyObject *v;
-
- /* argv[0] is the script pathname if known */
- if (i == 0) {
- char* fn = decc$translate_vms(argv[0]);
- if ((fn == (char *)0) || fn == (char *)-1)
- v = PyString_FromString(argv[0]);
- else
- v = PyString_FromString(
- decc$translate_vms(argv[0]));
- } else
- v = PyString_FromString(argv[i]);
-#else
- PyObject *v = PyString_FromString(argv[i]);
-#endif
- if (v == NULL) {
- Py_DECREF(av);
- av = NULL;
- break;
- }
- PyList_SetItem(av, i, v);
- }
- }
- return av;
-}
-
-void
-PySys_SetArgv(int argc, char **argv)
-{
-#if defined(HAVE_REALPATH)
- char fullpath[MAXPATHLEN];
-#elif defined(MS_WINDOWS)
- char fullpath[MAX_PATH];
-#endif
- PyObject *av = makeargvobject(argc, argv);
- PyObject *path = PySys_GetObject("path");
- if (av == NULL)
- Py_FatalError("no mem for sys.argv");
- if (PySys_SetObject("argv", av) != 0)
- Py_FatalError("can't assign sys.argv");
- if (path != NULL) {
- char *argv0 = argv[0];
- char *p = NULL;
- Py_ssize_t n = 0;
- PyObject *a;
-#ifdef HAVE_READLINK
- char link[MAXPATHLEN+1];
- char argv0copy[2*MAXPATHLEN+1];
- int nr = 0;
- if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0)
- nr = readlink(argv0, link, MAXPATHLEN);
- if (nr > 0) {
- /* It's a symlink */
- link[nr] = '\0';
- if (link[0] == SEP)
- argv0 = link; /* Link to absolute path */
- else if (strchr(link, SEP) == NULL)
- ; /* Link without path */
- else {
- /* Must join(dirname(argv0), link) */
- char *q = strrchr(argv0, SEP);
- if (q == NULL)
- argv0 = link; /* argv0 without path */
- else {
- /* Must make a copy */
- strcpy(argv0copy, argv0);
- q = strrchr(argv0copy, SEP);
- strcpy(q+1, link);
- argv0 = argv0copy;
- }
- }
- }
-#endif /* HAVE_READLINK */
-#if SEP == '\\' /* Special case for MS filename syntax */
- if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) {
- char *q;
-#ifdef MS_WINDOWS
- char *ptemp;
- if (GetFullPathName(argv0,
- sizeof(fullpath),
- fullpath,
- &ptemp)) {
- argv0 = fullpath;
- }
-#endif
- p = strrchr(argv0, SEP);
- /* Test for alternate separator */
- q = strrchr(p ? p : argv0, '/');
- if (q != NULL)
- p = q;
- if (p != NULL) {
- n = p + 1 - argv0;
- if (n > 1 && p[-1] != ':')
- n--; /* Drop trailing separator */
- }
- }
-#else /* All other filename syntaxes */
- if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) {
-#if defined(HAVE_REALPATH)
- if (realpath(argv0, fullpath)) {
- argv0 = fullpath;
- }
-#endif
- p = strrchr(argv0, SEP);
- }
- if (p != NULL) {
-#ifndef RISCOS
- n = p + 1 - argv0;
-#else /* don't include trailing separator */
- n = p - argv0;
-#endif /* RISCOS */
-#if SEP == '/' /* Special case for Unix filename syntax */
- if (n > 1)
- n--; /* Drop trailing separator */
-#endif /* Unix */
- }
-#endif /* All others */
- a = PyString_FromStringAndSize(argv0, n);
- if (a == NULL)
- Py_FatalError("no mem for sys.path insertion");
- if (PyList_Insert(path, 0, a) < 0)
- Py_FatalError("sys.path.insert(0) failed");
- Py_DECREF(a);
- }
- Py_DECREF(av);
-}
-
-
-/* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
- Adapted from code submitted by Just van Rossum.
-
- PySys_WriteStdout(format, ...)
- PySys_WriteStderr(format, ...)
-
- The first function writes to sys.stdout; the second to sys.stderr. When
- there is a problem, they write to the real (C level) stdout or stderr;
- no exceptions are raised.
-
- Both take a printf-style format string as their first argument followed
- by a variable length argument list determined by the format string.
-
- *** WARNING ***
-
- The format should limit the total size of the formatted output string to
- 1000 bytes. In particular, this means that no unrestricted "%s" formats
- should occur; these should be limited using "%.<N>s where <N> is a
- decimal number calculated so that <N> plus the maximum size of other
- formatted text does not exceed 1000 bytes. Also watch out for "%f",
- which can print hundreds of digits for very large numbers.
-
- */
-
-static void
-mywrite(char *name, FILE *fp, const char *format, va_list va)
-{
- PyObject *file;
- PyObject *error_type, *error_value, *error_traceback;
-
- PyErr_Fetch(&error_type, &error_value, &error_traceback);
- file = PySys_GetObject(name);
- if (file == NULL || PyFile_AsFile(file) == fp)
- vfprintf(fp, format, va);
- else {
- char buffer[1001];
- const int written = PyOS_vsnprintf(buffer, sizeof(buffer),
- format, va);
- if (PyFile_WriteString(buffer, file) != 0) {
- PyErr_Clear();
- fputs(buffer, fp);
- }
- if (written < 0 || (size_t)written >= sizeof(buffer)) {
- const char *truncated = "... truncated";
- if (PyFile_WriteString(truncated, file) != 0) {
- PyErr_Clear();
- fputs(truncated, fp);
- }
- }
- }
- PyErr_Restore(error_type, error_value, error_traceback);
-}
-
-void
-PySys_WriteStdout(const char *format, ...)
-{
- va_list va;
-
- va_start(va, format);
- mywrite("stdout", stdout, format, va);
- va_end(va);
-}
-
-void
-PySys_WriteStderr(const char *format, ...)
-{
- va_list va;
-
- va_start(va, format);
- mywrite("stderr", stderr, format, va);
- va_end(va);
-}
diff --git a/sys/src/cmd/python/Python/thread.c b/sys/src/cmd/python/Python/thread.c
deleted file mode 100644
index 3a2c7af6f..000000000
--- a/sys/src/cmd/python/Python/thread.c
+++ /dev/null
@@ -1,384 +0,0 @@
-
-/* Thread package.
- This is intended to be usable independently from Python.
- The implementation for system foobar is in a file thread_foobar.h
- which is included by this file dependent on config settings.
- Stuff shared by all thread_*.h files is collected here. */
-
-#include "Python.h"
-
-
-#ifndef _POSIX_THREADS
-/* This means pthreads are not implemented in libc headers, hence the macro
- not present in unistd.h. But they still can be implemented as an external
- library (e.g. gnu pth in pthread emulation) */
-# ifdef HAVE_PTHREAD_H
-# include <pthread.h> /* _POSIX_THREADS */
-# endif
-#endif
-
-#ifndef DONT_HAVE_STDIO_H
-#include <stdio.h>
-#endif
-
-#include <stdlib.h>
-
-#ifdef __sgi
-#ifndef HAVE_PTHREAD_H /* XXX Need to check in configure.in */
-#undef _POSIX_THREADS
-#endif
-#endif
-
-#include "pythread.h"
-
-#ifndef _POSIX_THREADS
-
-#ifdef __sgi
-#define SGI_THREADS
-#endif
-
-#ifdef HAVE_THREAD_H
-#define SOLARIS_THREADS
-#endif
-
-#if defined(sun) && !defined(SOLARIS_THREADS)
-#define SUN_LWP
-#endif
-
-/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
- enough of the Posix threads package is implimented to support python
- threads.
-
- This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
- a check of __ia64 to verify that we're running on a ia64 system instead
- of a pa-risc system.
-*/
-#ifdef __hpux
-#ifdef _SC_THREADS
-#define _POSIX_THREADS
-#endif
-#endif
-
-#endif /* _POSIX_THREADS */
-
-
-#ifdef Py_DEBUG
-static int thread_debug = 0;
-#define dprintf(args) (void)((thread_debug & 1) && printf args)
-#define d2printf(args) ((thread_debug & 8) && printf args)
-#else
-#define dprintf(args)
-#define d2printf(args)
-#endif
-
-static int initialized;
-
-static void PyThread__init_thread(void); /* Forward */
-
-void
-PyThread_init_thread(void)
-{
-#ifdef Py_DEBUG
- char *p = getenv("THREADDEBUG");
-
- if (p) {
- if (*p)
- thread_debug = atoi(p);
- else
- thread_debug = 1;
- }
-#endif /* Py_DEBUG */
- if (initialized)
- return;
- initialized = 1;
- dprintf(("PyThread_init_thread called\n"));
- PyThread__init_thread();
-}
-
-/* Support for runtime thread stack size tuning.
- A value of 0 means using the platform's default stack size
- or the size specified by the THREAD_STACK_SIZE macro. */
-static size_t _pythread_stacksize = 0;
-
-#ifdef SGI_THREADS
-#include "thread_sgi.h"
-#endif
-
-#ifdef SOLARIS_THREADS
-#include "thread_solaris.h"
-#endif
-
-#ifdef SUN_LWP
-#include "thread_lwp.h"
-#endif
-
-#ifdef HAVE_PTH
-#include "thread_pth.h"
-#undef _POSIX_THREADS
-#endif
-
-#ifdef _POSIX_THREADS
-#include "thread_pthread.h"
-#endif
-
-#ifdef C_THREADS
-#include "thread_cthread.h"
-#endif
-
-#ifdef NT_THREADS
-#include "thread_nt.h"
-#endif
-
-#ifdef OS2_THREADS
-#include "thread_os2.h"
-#endif
-
-#ifdef BEOS_THREADS
-#include "thread_beos.h"
-#endif
-
-#ifdef WINCE_THREADS
-#include "thread_wince.h"
-#endif
-
-#ifdef PLAN9_THREADS
-#include "thread_plan9.h"
-#endif
-
-#ifdef ATHEOS_THREADS
-#include "thread_atheos.h"
-#endif
-
-/*
-#ifdef FOOBAR_THREADS
-#include "thread_foobar.h"
-#endif
-*/
-
-/* return the current thread stack size */
-size_t
-PyThread_get_stacksize(void)
-{
- return _pythread_stacksize;
-}
-
-/* Only platforms defining a THREAD_SET_STACKSIZE() macro
- in thread_<platform>.h support changing the stack size.
- Return 0 if stack size is valid,
- -1 if stack size value is invalid,
- -2 if setting stack size is not supported. */
-int
-PyThread_set_stacksize(size_t size)
-{
-#if defined(THREAD_SET_STACKSIZE)
- return THREAD_SET_STACKSIZE(size);
-#else
- return -2;
-#endif
-}
-
-#ifndef Py_HAVE_NATIVE_TLS
-/* If the platform has not supplied a platform specific
- TLS implementation, provide our own.
-
- This code stolen from "thread_sgi.h", where it was the only
- implementation of an existing Python TLS API.
-*/
-/* ------------------------------------------------------------------------
-Per-thread data ("key") support.
-
-Use PyThread_create_key() to create a new key. This is typically shared
-across threads.
-
-Use PyThread_set_key_value(thekey, value) to associate void* value with
-thekey in the current thread. Each thread has a distinct mapping of thekey
-to a void* value. Caution: if the current thread already has a mapping
-for thekey, value is ignored.
-
-Use PyThread_get_key_value(thekey) to retrieve the void* value associated
-with thekey in the current thread. This returns NULL if no value is
-associated with thekey in the current thread.
-
-Use PyThread_delete_key_value(thekey) to forget the current thread's associated
-value for thekey. PyThread_delete_key(thekey) forgets the values associated
-with thekey across *all* threads.
-
-While some of these functions have error-return values, none set any
-Python exception.
-
-None of the functions does memory management on behalf of the void* values.
-You need to allocate and deallocate them yourself. If the void* values
-happen to be PyObject*, these functions don't do refcount operations on
-them either.
-
-The GIL does not need to be held when calling these functions; they supply
-their own locking. This isn't true of PyThread_create_key(), though (see
-next paragraph).
-
-There's a hidden assumption that PyThread_create_key() will be called before
-any of the other functions are called. There's also a hidden assumption
-that calls to PyThread_create_key() are serialized externally.
------------------------------------------------------------------------- */
-
-/* A singly-linked list of struct key objects remembers all the key->value
- * associations. File static keyhead heads the list. keymutex is used
- * to enforce exclusion internally.
- */
-struct key {
- /* Next record in the list, or NULL if this is the last record. */
- struct key *next;
-
- /* The thread id, according to PyThread_get_thread_ident(). */
- long id;
-
- /* The key and its associated value. */
- int key;
- void *value;
-};
-
-static struct key *keyhead = NULL;
-static PyThread_type_lock keymutex = NULL;
-static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */
-
-/* Internal helper.
- * If the current thread has a mapping for key, the appropriate struct key*
- * is returned. NB: value is ignored in this case!
- * If there is no mapping for key in the current thread, then:
- * If value is NULL, NULL is returned.
- * Else a mapping of key to value is created for the current thread,
- * and a pointer to a new struct key* is returned; except that if
- * malloc() can't find room for a new struct key*, NULL is returned.
- * So when value==NULL, this acts like a pure lookup routine, and when
- * value!=NULL, this acts like dict.setdefault(), returning an existing
- * mapping if one exists, else creating a new mapping.
- *
- * Caution: this used to be too clever, trying to hold keymutex only
- * around the "p->next = keyhead; keyhead = p" pair. That allowed
- * another thread to mutate the list, via key deletion, concurrent with
- * find_key() crawling over the list. Hilarity ensued. For example, when
- * the for-loop here does "p = p->next", p could end up pointing at a
- * record that PyThread_delete_key_value() was concurrently free()'ing.
- * That could lead to anything, from failing to find a key that exists, to
- * segfaults. Now we lock the whole routine.
- */
-static struct key *
-find_key(int key, void *value)
-{
- struct key *p;
- long id = PyThread_get_thread_ident();
-
- if (!keymutex)
- return NULL;
- PyThread_acquire_lock(keymutex, 1);
- for (p = keyhead; p != NULL; p = p->next) {
- if (p->id == id && p->key == key)
- goto Done;
- }
- if (value == NULL) {
- assert(p == NULL);
- goto Done;
- }
- p = (struct key *)malloc(sizeof(struct key));
- if (p != NULL) {
- p->id = id;
- p->key = key;
- p->value = value;
- p->next = keyhead;
- keyhead = p;
- }
- Done:
- PyThread_release_lock(keymutex);
- return p;
-}
-
-/* Return a new key. This must be called before any other functions in
- * this family, and callers must arrange to serialize calls to this
- * function. No violations are detected.
- */
-int
-PyThread_create_key(void)
-{
- /* All parts of this function are wrong if it's called by multiple
- * threads simultaneously.
- */
- if (keymutex == NULL)
- keymutex = PyThread_allocate_lock();
- return ++nkeys;
-}
-
-/* Forget the associations for key across *all* threads. */
-void
-PyThread_delete_key(int key)
-{
- struct key *p, **q;
-
- PyThread_acquire_lock(keymutex, 1);
- q = &keyhead;
- while ((p = *q) != NULL) {
- if (p->key == key) {
- *q = p->next;
- free((void *)p);
- /* NB This does *not* free p->value! */
- }
- else
- q = &p->next;
- }
- PyThread_release_lock(keymutex);
-}
-
-/* Confusing: If the current thread has an association for key,
- * value is ignored, and 0 is returned. Else an attempt is made to create
- * an association of key to value for the current thread. 0 is returned
- * if that succeeds, but -1 is returned if there's not enough memory
- * to create the association. value must not be NULL.
- */
-int
-PyThread_set_key_value(int key, void *value)
-{
- struct key *p;
-
- assert(value != NULL);
- p = find_key(key, value);
- if (p == NULL)
- return -1;
- else
- return 0;
-}
-
-/* Retrieve the value associated with key in the current thread, or NULL
- * if the current thread doesn't have an association for key.
- */
-void *
-PyThread_get_key_value(int key)
-{
- struct key *p = find_key(key, NULL);
-
- if (p == NULL)
- return NULL;
- else
- return p->value;
-}
-
-/* Forget the current thread's association for key, if any. */
-void
-PyThread_delete_key_value(int key)
-{
- long id = PyThread_get_thread_ident();
- struct key *p, **q;
-
- PyThread_acquire_lock(keymutex, 1);
- q = &keyhead;
- while ((p = *q) != NULL) {
- if (p->key == key && p->id == id) {
- *q = p->next;
- free((void *)p);
- /* NB This does *not* free p->value! */
- break;
- }
- else
- q = &p->next;
- }
- PyThread_release_lock(keymutex);
-}
-
-#endif /* Py_HAVE_NATIVE_TLS */
diff --git a/sys/src/cmd/python/Python/thread_atheos.h b/sys/src/cmd/python/Python/thread_atheos.h
deleted file mode 100644
index c9f5e2318..000000000
--- a/sys/src/cmd/python/Python/thread_atheos.h
+++ /dev/null
@@ -1,300 +0,0 @@
-/* Threading for AtheOS.
- Based on thread_beos.h. */
-
-#include <atheos/threads.h>
-#include <atheos/semaphore.h>
-#include <atheos/atomic.h>
-#include <errno.h>
-#include <string.h>
-
-/* Missing decl from threads.h */
-extern int exit_thread(int);
-
-
-/* Undefine FASTLOCK to play with simple semaphores. */
-#define FASTLOCK
-
-
-#ifdef FASTLOCK
-
-/* Use an atomic counter and a semaphore for maximum speed. */
-typedef struct fastmutex {
- sem_id sem;
- atomic_t count;
-} fastmutex_t;
-
-
-static int fastmutex_create(const char *name, fastmutex_t * mutex);
-static int fastmutex_destroy(fastmutex_t * mutex);
-static int fastmutex_lock(fastmutex_t * mutex);
-static int fastmutex_timedlock(fastmutex_t * mutex, bigtime_t timeout);
-static int fastmutex_unlock(fastmutex_t * mutex);
-
-
-static int fastmutex_create(const char *name, fastmutex_t * mutex)
-{
- mutex->count = 0;
- mutex->sem = create_semaphore(name, 0, 0);
- return (mutex->sem < 0) ? -1 : 0;
-}
-
-
-static int fastmutex_destroy(fastmutex_t * mutex)
-{
- if (fastmutex_timedlock(mutex, 0) == 0 || errno == EWOULDBLOCK) {
- return delete_semaphore(mutex->sem);
- }
- return 0;
-}
-
-
-static int fastmutex_lock(fastmutex_t * mutex)
-{
- atomic_t prev = atomic_add(&mutex->count, 1);
- if (prev > 0)
- return lock_semaphore(mutex->sem);
- return 0;
-}
-
-
-static int fastmutex_timedlock(fastmutex_t * mutex, bigtime_t timeout)
-{
- atomic_t prev = atomic_add(&mutex->count, 1);
- if (prev > 0)
- return lock_semaphore_x(mutex->sem, 1, 0, timeout);
- return 0;
-}
-
-
-static int fastmutex_unlock(fastmutex_t * mutex)
-{
- atomic_t prev = atomic_add(&mutex->count, -1);
- if (prev > 1)
- return unlock_semaphore(mutex->sem);
- return 0;
-}
-
-
-#endif /* FASTLOCK */
-
-
-/*
- * Initialization.
- *
- */
-static void PyThread__init_thread(void)
-{
- /* Do nothing. */
- return;
-}
-
-
-/*
- * Thread support.
- *
- */
-
-static atomic_t thread_count = 0;
-
-long PyThread_start_new_thread(void (*func) (void *), void *arg)
-{
- status_t success = -1;
- thread_id tid;
- char name[OS_NAME_LENGTH];
- atomic_t this_thread;
-
- dprintf(("PyThread_start_new_thread called\n"));
-
- this_thread = atomic_add(&thread_count, 1);
- PyOS_snprintf(name, sizeof(name), "python thread (%d)", this_thread);
-
- tid = spawn_thread(name, func, NORMAL_PRIORITY, 0, arg);
- if (tid < 0) {
- dprintf(("PyThread_start_new_thread spawn_thread failed: %s\n", strerror(errno)));
- } else {
- success = resume_thread(tid);
- if (success < 0) {
- dprintf(("PyThread_start_new_thread resume_thread failed: %s\n", strerror(errno)));
- }
- }
-
- return (success < 0 ? -1 : tid);
-}
-
-
-long PyThread_get_thread_ident(void)
-{
- return get_thread_id(NULL);
-}
-
-
-static void do_PyThread_exit_thread(int no_cleanup)
-{
- dprintf(("PyThread_exit_thread called\n"));
-
- /* Thread-safe way to read a variable without a mutex: */
- if (atomic_add(&thread_count, 0) == 0) {
- /* No threads around, so exit main(). */
- if (no_cleanup)
- _exit(0);
- else
- exit(0);
- } else {
- /* We're a thread */
- exit_thread(0);
- }
-}
-
-
-void PyThread_exit_thread(void)
-{
- do_PyThread_exit_thread(0);
-}
-
-
-void PyThread__exit_thread(void)
-{
- do_PyThread_exit_thread(1);
-}
-
-
-#ifndef NO_EXIT_PROG
-static void do_PyThread_exit_prog(int status, int no_cleanup)
-{
- dprintf(("PyThread_exit_prog(%d) called\n", status));
-
- /* No need to do anything, the threads get torn down if main()exits. */
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
-}
-
-
-void PyThread_exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-
-void PyThread__exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-
-/*
- * Lock support.
- *
- */
-
-static atomic_t lock_count = 0;
-
-PyThread_type_lock PyThread_allocate_lock(void)
-{
-#ifdef FASTLOCK
- fastmutex_t *lock;
-#else
- sem_id sema;
-#endif
- char name[OS_NAME_LENGTH];
- atomic_t this_lock;
-
- dprintf(("PyThread_allocate_lock called\n"));
-
-#ifdef FASTLOCK
- lock = (fastmutex_t *) malloc(sizeof(fastmutex_t));
- if (lock == NULL) {
- dprintf(("PyThread_allocate_lock failed: out of memory\n"));
- return (PyThread_type_lock) NULL;
- }
-#endif
- this_lock = atomic_add(&lock_count, 1);
- PyOS_snprintf(name, sizeof(name), "python lock (%d)", this_lock);
-
-#ifdef FASTLOCK
- if (fastmutex_create(name, lock) < 0) {
- dprintf(("PyThread_allocate_lock failed: %s\n",
- strerror(errno)));
- free(lock);
- lock = NULL;
- }
- dprintf(("PyThread_allocate_lock()-> %p\n", lock));
- return (PyThread_type_lock) lock;
-#else
- sema = create_semaphore(name, 1, 0);
- if (sema < 0) {
- dprintf(("PyThread_allocate_lock failed: %s\n",
- strerror(errno)));
- sema = 0;
- }
- dprintf(("PyThread_allocate_lock()-> %p\n", sema));
- return (PyThread_type_lock) sema;
-#endif
-}
-
-
-void PyThread_free_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_free_lock(%p) called\n", lock));
-
-#ifdef FASTLOCK
- if (fastmutex_destroy((fastmutex_t *) lock) < 0) {
- dprintf(("PyThread_free_lock(%p) failed: %s\n", lock,
- strerror(errno)));
- }
- free(lock);
-#else
- if (delete_semaphore((sem_id) lock) < 0) {
- dprintf(("PyThread_free_lock(%p) failed: %s\n", lock,
- strerror(errno)));
- }
-#endif
-}
-
-
-int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
-{
- int retval;
-
- dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock,
- waitflag));
-
-#ifdef FASTLOCK
- if (waitflag)
- retval = fastmutex_lock((fastmutex_t *) lock);
- else
- retval = fastmutex_timedlock((fastmutex_t *) lock, 0);
-#else
- if (waitflag)
- retval = lock_semaphore((sem_id) lock);
- else
- retval = lock_semaphore_x((sem_id) lock, 1, 0, 0);
-#endif
- if (retval < 0) {
- dprintf(("PyThread_acquire_lock(%p, %d) failed: %s\n",
- lock, waitflag, strerror(errno)));
- }
- dprintf(("PyThread_acquire_lock(%p, %d)-> %d\n", lock, waitflag,
- retval));
- return retval < 0 ? 0 : 1;
-}
-
-
-void PyThread_release_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_release_lock(%p) called\n", lock));
-
-#ifdef FASTLOCK
- if (fastmutex_unlock((fastmutex_t *) lock) < 0) {
- dprintf(("PyThread_release_lock(%p) failed: %s\n", lock,
- strerror(errno)));
- }
-#else
- if (unlock_semaphore((sem_id) lock) < 0) {
- dprintf(("PyThread_release_lock(%p) failed: %s\n", lock,
- strerror(errno)));
- }
-#endif
-}
diff --git a/sys/src/cmd/python/Python/thread_beos.h b/sys/src/cmd/python/Python/thread_beos.h
deleted file mode 100644
index 82f99ded3..000000000
--- a/sys/src/cmd/python/Python/thread_beos.h
+++ /dev/null
@@ -1,287 +0,0 @@
-#include <kernel/OS.h>
-#include <support/SupportDefs.h>
-#include <errno.h>
-
-/* ----------------------------------------------------------------------
- * Fast locking mechanism described by Benoit Schillings (benoit@be.com)
- * in the Be Developer's Newsletter, Issue #26 (http://www.be.com/).
- */
-typedef struct benaphore {
- sem_id _sem;
- int32 _atom;
-} benaphore_t;
-
-static status_t benaphore_create( const char *name, benaphore_t *ben );
-static status_t benaphore_destroy( benaphore_t *ben );
-static status_t benaphore_lock( benaphore_t *ben );
-static status_t benaphore_timedlock( benaphore_t *ben, bigtime_t micros );
-static status_t benaphore_unlock( benaphore_t *ben );
-
-static status_t benaphore_create( const char *name, benaphore_t *ben )
-{
- if( ben != NULL ) {
- ben->_atom = 0;
- ben->_sem = create_sem( 0, name );
-
- if( ben->_sem < B_NO_ERROR ) {
- return B_BAD_SEM_ID;
- }
- } else {
- return EFAULT;
- }
-
- return EOK;
-}
-
-static status_t benaphore_destroy( benaphore_t *ben )
-{
- if( ben->_sem >= B_NO_ERROR ) {
- status_t retval = benaphore_timedlock( ben, 0 );
-
- if( retval == EOK || retval == EWOULDBLOCK ) {
- status_t del_retval = delete_sem( ben->_sem );
-
- return del_retval;
- }
- }
-
- return B_BAD_SEM_ID;
-}
-
-static status_t benaphore_lock( benaphore_t *ben )
-{
- int32 prev = atomic_add( &(ben->_atom), 1 );
-
- if( prev > 0 ) {
- return acquire_sem( ben->_sem );
- }
-
- return EOK;
-}
-
-static status_t benaphore_timedlock( benaphore_t *ben, bigtime_t micros )
-{
- int32 prev = atomic_add( &(ben->_atom), 1 );
-
- if( prev > 0 ) {
- status_t retval = acquire_sem_etc( ben->_sem, 1, B_TIMEOUT, micros );
-
- switch( retval ) {
- case B_WOULD_BLOCK: /* Fall through... */
- case B_TIMED_OUT:
- return EWOULDBLOCK;
- break;
- case B_OK:
- return EOK;
- break;
- default:
- return retval;
- break;
- }
- }
-
- return EOK;
-}
-
-static status_t benaphore_unlock( benaphore_t *ben )
-{
- int32 prev = atomic_add( &(ben->_atom), -1 );
-
- if( prev > 1 ) {
- return release_sem( ben->_sem );
- }
-
- return EOK;
-}
-
-/* ----------------------------------------------------------------------
- * Initialization.
- */
-static void PyThread__init_thread( void )
-{
- /* Do nothing. */
- return;
-}
-
-/* ----------------------------------------------------------------------
- * Thread support.
- *
- * Only ANSI C, renamed functions here; you can't use K&R on BeOS,
- * and there's no legacy thread module to support.
- */
-
-static int32 thread_count = 0;
-
-long PyThread_start_new_thread( void (*func)(void *), void *arg )
-{
- status_t success = 0;
- thread_id tid;
- char name[B_OS_NAME_LENGTH];
- int32 this_thread;
-
- dprintf(("PyThread_start_new_thread called\n"));
-
- /* We are so very thread-safe... */
- this_thread = atomic_add( &thread_count, 1 );
- PyOS_snprintf(name, sizeof(name),
- "python thread (%d)", this_thread );
-
- tid = spawn_thread( (thread_func)func, name,
- B_NORMAL_PRIORITY, arg );
- if( tid > B_NO_ERROR ) {
- success = resume_thread( tid );
- }
-
- return ( success == B_NO_ERROR ? tid : -1 );
-}
-
-long PyThread_get_thread_ident( void )
-{
- /* Presumed to return the current thread's ID... */
- thread_id tid;
- tid = find_thread( NULL );
-
- return ( tid != B_NAME_NOT_FOUND ? tid : -1 );
-}
-
-static void do_PyThread_exit_thread( int no_cleanup )
-{
- int32 threads;
-
- dprintf(("PyThread_exit_thread called\n"));
-
- /* Thread-safe way to read a variable without a mutex: */
- threads = atomic_add( &thread_count, 0 );
-
- if( threads == 0 ) {
- /* No threads around, so exit main(). */
- if( no_cleanup ) {
- _exit(0);
- } else {
- exit(0);
- }
- } else {
- /* Oh, we're a thread, let's try to exit gracefully... */
- exit_thread( B_NO_ERROR );
- }
-}
-
-void PyThread_exit_thread( void )
-{
- do_PyThread_exit_thread(0);
-}
-
-void PyThread__exit_thread( void )
-{
- do_PyThread_exit_thread(1);
-}
-
-#ifndef NO_EXIT_PROG
-static void do_PyThread_exit_prog( int status, int no_cleanup )
-{
- dprintf(("PyThread_exit_prog(%d) called\n", status));
-
- /* No need to do anything, the threads get torn down if main() exits. */
-
- if (no_cleanup) {
- _exit(status);
- } else {
- exit(status);
- }
-}
-
-void PyThread_exit_prog( int status )
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-void PyThread__exit_prog( int status )
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-/* ----------------------------------------------------------------------
- * Lock support.
- */
-
-static int32 lock_count = 0;
-
-PyThread_type_lock PyThread_allocate_lock( void )
-{
- benaphore_t *lock;
- status_t retval;
- char name[B_OS_NAME_LENGTH];
- int32 this_lock;
-
- dprintf(("PyThread_allocate_lock called\n"));
-
- lock = (benaphore_t *)malloc( sizeof( benaphore_t ) );
- if( lock == NULL ) {
- /* TODO: that's bad, raise MemoryError */
- return (PyThread_type_lock)NULL;
- }
-
- this_lock = atomic_add( &lock_count, 1 );
- PyOS_snprintf(name, sizeof(name), "python lock (%d)", this_lock);
-
- retval = benaphore_create( name, lock );
- if( retval != EOK ) {
- /* TODO: that's bad, raise an exception */
- return (PyThread_type_lock)NULL;
- }
-
- dprintf(("PyThread_allocate_lock() -> %p\n", lock));
- return (PyThread_type_lock) lock;
-}
-
-void PyThread_free_lock( PyThread_type_lock lock )
-{
- status_t retval;
-
- dprintf(("PyThread_free_lock(%p) called\n", lock));
-
- retval = benaphore_destroy( (benaphore_t *)lock );
- if( retval != EOK ) {
- /* TODO: that's bad, raise an exception */
- return;
- }
-}
-
-int PyThread_acquire_lock( PyThread_type_lock lock, int waitflag )
-{
- int success;
- status_t retval;
-
- dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
-
- if( waitflag ) {
- retval = benaphore_lock( (benaphore_t *)lock );
- } else {
- retval = benaphore_timedlock( (benaphore_t *)lock, 0 );
- }
-
- if( retval == EOK ) {
- success = 1;
- } else {
- success = 0;
-
- /* TODO: that's bad, raise an exception */
- }
-
- dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
- return success;
-}
-
-void PyThread_release_lock( PyThread_type_lock lock )
-{
- status_t retval;
-
- dprintf(("PyThread_release_lock(%p) called\n", lock));
-
- retval = benaphore_unlock( (benaphore_t *)lock );
- if( retval != EOK ) {
- /* TODO: that's bad, raise an exception */
- return;
- }
-}
diff --git a/sys/src/cmd/python/Python/thread_cthread.h b/sys/src/cmd/python/Python/thread_cthread.h
deleted file mode 100644
index ca776c636..000000000
--- a/sys/src/cmd/python/Python/thread_cthread.h
+++ /dev/null
@@ -1,156 +0,0 @@
-
-#ifdef MACH_C_THREADS
-#include <mach/cthreads.h>
-#endif
-
-#ifdef HURD_C_THREADS
-#include <cthreads.h>
-#endif
-
-/*
- * Initialization.
- */
-static void
-PyThread__init_thread(void)
-{
-#ifndef HURD_C_THREADS
- /* Roland McGrath said this should not be used since this is
- done while linking to threads */
- cthread_init();
-#else
-/* do nothing */
- ;
-#endif
-}
-
-/*
- * Thread support.
- */
-long
-PyThread_start_new_thread(void (*func)(void *), void *arg)
-{
- int success = 0; /* init not needed when SOLARIS_THREADS and */
- /* C_THREADS implemented properly */
-
- dprintf(("PyThread_start_new_thread called\n"));
- if (!initialized)
- PyThread_init_thread();
- /* looks like solaris detaches the thread to never rejoin
- * so well do it here
- */
- cthread_detach(cthread_fork((cthread_fn_t) func, arg));
- return success < 0 ? -1 : 0;
-}
-
-long
-PyThread_get_thread_ident(void)
-{
- if (!initialized)
- PyThread_init_thread();
- return (long) cthread_self();
-}
-
-static void
-do_PyThread_exit_thread(int no_cleanup)
-{
- dprintf(("PyThread_exit_thread called\n"));
- if (!initialized)
- if (no_cleanup)
- _exit(0);
- else
- exit(0);
- cthread_exit(0);
-}
-
-void
-PyThread_exit_thread(void)
-{
- do_PyThread_exit_thread(0);
-}
-
-void
-PyThread__exit_thread(void)
-{
- do_PyThread_exit_thread(1);
-}
-
-#ifndef NO_EXIT_PROG
-static
-void do_PyThread_exit_prog(int status, int no_cleanup)
-{
- dprintf(("PyThread_exit_prog(%d) called\n", status));
- if (!initialized)
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
-}
-
-void
-PyThread_exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-void
-PyThread__exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-/*
- * Lock support.
- */
-PyThread_type_lock
-PyThread_allocate_lock(void)
-{
- mutex_t lock;
-
- dprintf(("PyThread_allocate_lock called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- lock = mutex_alloc();
- if (mutex_init(lock)) {
- perror("mutex_init");
- free((void *) lock);
- lock = 0;
- }
- dprintf(("PyThread_allocate_lock() -> %p\n", lock));
- return (PyThread_type_lock) lock;
-}
-
-void
-PyThread_free_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_free_lock(%p) called\n", lock));
- mutex_free(lock);
-}
-
-int
-PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
-{
- int success = FALSE;
-
- dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
- if (waitflag) { /* blocking */
- mutex_lock((mutex_t)lock);
- success = TRUE;
- } else { /* non blocking */
- success = mutex_try_lock((mutex_t)lock);
- }
- dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
- return success;
-}
-
-void
-PyThread_release_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_release_lock(%p) called\n", lock));
- mutex_unlock((mutex_t )lock);
-}
diff --git a/sys/src/cmd/python/Python/thread_foobar.h b/sys/src/cmd/python/Python/thread_foobar.h
deleted file mode 100644
index 67491a167..000000000
--- a/sys/src/cmd/python/Python/thread_foobar.h
+++ /dev/null
@@ -1,115 +0,0 @@
-
-/*
- * Initialization.
- */
-static void
-PyThread__init_thread(void)
-{
-}
-
-/*
- * Thread support.
- */
-long
-PyThread_start_new_thread(void (*func)(void *), void *arg)
-{
- int success = 0; /* init not needed when SOLARIS_THREADS and */
- /* C_THREADS implemented properly */
-
- dprintf(("PyThread_start_new_thread called\n"));
- if (!initialized)
- PyThread_init_thread();
- return success < 0 ? -1 : 0;
-}
-
-long
-PyThread_get_thread_ident(void)
-{
- if (!initialized)
- PyThread_init_thread();
-}
-
-static
-void do_PyThread_exit_thread(int no_cleanup)
-{
- dprintf(("PyThread_exit_thread called\n"));
- if (!initialized)
- if (no_cleanup)
- _exit(0);
- else
- exit(0);
-}
-
-void
-PyThread_exit_thread(void)
-{
- do_PyThread_exit_thread(0);
-}
-
-void
-PyThread__exit_thread(void)
-{
- do_PyThread_exit_thread(1);
-}
-
-#ifndef NO_EXIT_PROG
-static
-void do_PyThread_exit_prog(int status, int no_cleanup)
-{
- dprintf(("PyThread_exit_prog(%d) called\n", status));
- if (!initialized)
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
-}
-
-void
-PyThread_exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-void
-PyThread__exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-/*
- * Lock support.
- */
-PyThread_type_lock
-PyThread_allocate_lock(void)
-{
-
- dprintf(("PyThread_allocate_lock called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- dprintf(("PyThread_allocate_lock() -> %p\n", lock));
- return (PyThread_type_lock) lock;
-}
-
-void
-PyThread_free_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_free_lock(%p) called\n", lock));
-}
-
-int
-PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
-{
- int success;
-
- dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
- dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
- return success;
-}
-
-void
-PyThread_release_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_release_lock(%p) called\n", lock));
-}
diff --git a/sys/src/cmd/python/Python/thread_lwp.h b/sys/src/cmd/python/Python/thread_lwp.h
deleted file mode 100644
index e93d65aa3..000000000
--- a/sys/src/cmd/python/Python/thread_lwp.h
+++ /dev/null
@@ -1,149 +0,0 @@
-
-#include <stdlib.h>
-#include <lwp/lwp.h>
-#include <lwp/stackdep.h>
-
-#define STACKSIZE 1000 /* stacksize for a thread */
-#define NSTACKS 2 /* # stacks to be put in cache initially */
-
-struct lock {
- int lock_locked;
- cv_t lock_condvar;
- mon_t lock_monitor;
-};
-
-
-/*
- * Initialization.
- */
-static void PyThread__init_thread(void)
-{
- lwp_setstkcache(STACKSIZE, NSTACKS);
-}
-
-/*
- * Thread support.
- */
-
-
-long PyThread_start_new_thread(void (*func)(void *), void *arg)
-{
- thread_t tid;
- int success;
- dprintf(("PyThread_start_new_thread called\n"));
- if (!initialized)
- PyThread_init_thread();
- success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg);
- return success < 0 ? -1 : 0;
-}
-
-long PyThread_get_thread_ident(void)
-{
- thread_t tid;
- if (!initialized)
- PyThread_init_thread();
- if (lwp_self(&tid) < 0)
- return -1;
- return tid.thread_id;
-}
-
-static void do_PyThread_exit_thread(int no_cleanup)
-{
- dprintf(("PyThread_exit_thread called\n"));
- if (!initialized)
- if (no_cleanup)
- _exit(0);
- else
- exit(0);
- lwp_destroy(SELF);
-}
-
-void PyThread_exit_thread(void)
-{
- do_PyThread_exit_thread(0);
-}
-
-void PyThread__exit_thread(void)
-{
- do_PyThread_exit_thread(1);
-}
-
-#ifndef NO_EXIT_PROG
-static void do_PyThread_exit_prog(int status, int no_cleanup)
-{
- dprintf(("PyThread_exit_prog(%d) called\n", status));
- if (!initialized)
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
- pod_exit(status);
-}
-
-void PyThread_exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-void PyThread__exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-/*
- * Lock support.
- */
-PyThread_type_lock PyThread_allocate_lock(void)
-{
- struct lock *lock;
- extern char *malloc(size_t);
-
- dprintf(("PyThread_allocate_lock called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- lock = (struct lock *) malloc(sizeof(struct lock));
- lock->lock_locked = 0;
- (void) mon_create(&lock->lock_monitor);
- (void) cv_create(&lock->lock_condvar, lock->lock_monitor);
- dprintf(("PyThread_allocate_lock() -> %p\n", lock));
- return (PyThread_type_lock) lock;
-}
-
-void PyThread_free_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_free_lock(%p) called\n", lock));
- mon_destroy(((struct lock *) lock)->lock_monitor);
- free((char *) lock);
-}
-
-int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
-{
- int success;
-
- dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
- success = 0;
-
- (void) mon_enter(((struct lock *) lock)->lock_monitor);
- if (waitflag)
- while (((struct lock *) lock)->lock_locked)
- cv_wait(((struct lock *) lock)->lock_condvar);
- if (!((struct lock *) lock)->lock_locked) {
- success = 1;
- ((struct lock *) lock)->lock_locked = 1;
- }
- cv_broadcast(((struct lock *) lock)->lock_condvar);
- mon_exit(((struct lock *) lock)->lock_monitor);
- dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
- return success;
-}
-
-void PyThread_release_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_release_lock(%p) called\n", lock));
- (void) mon_enter(((struct lock *) lock)->lock_monitor);
- ((struct lock *) lock)->lock_locked = 0;
- cv_broadcast(((struct lock *) lock)->lock_condvar);
- mon_exit(((struct lock *) lock)->lock_monitor);
-}
diff --git a/sys/src/cmd/python/Python/thread_nt.h b/sys/src/cmd/python/Python/thread_nt.h
deleted file mode 100644
index 67f5ed517..000000000
--- a/sys/src/cmd/python/Python/thread_nt.h
+++ /dev/null
@@ -1,364 +0,0 @@
-
-/* This code implemented by Dag.Gruneau@elsa.preseco.comm.se */
-/* Fast NonRecursiveMutex support by Yakov Markovitch, markovitch@iso.ru */
-/* Eliminated some memory leaks, gsw@agere.com */
-
-#include <windows.h>
-#include <limits.h>
-#ifdef HAVE_PROCESS_H
-#include <process.h>
-#endif
-
-typedef struct NRMUTEX {
- LONG owned ;
- DWORD thread_id ;
- HANDLE hevent ;
-} NRMUTEX, *PNRMUTEX ;
-
-typedef PVOID WINAPI interlocked_cmp_xchg_t(PVOID *dest, PVOID exc, PVOID comperand) ;
-
-/* Sorry mate, but we haven't got InterlockedCompareExchange in Win95! */
-static PVOID WINAPI
-interlocked_cmp_xchg(PVOID *dest, PVOID exc, PVOID comperand)
-{
- static LONG spinlock = 0 ;
- PVOID result ;
- DWORD dwSleep = 0;
-
- /* Acqire spinlock (yielding control to other threads if cant aquire for the moment) */
- while(InterlockedExchange(&spinlock, 1))
- {
- // Using Sleep(0) can cause a priority inversion.
- // Sleep(0) only yields the processor if there's
- // another thread of the same priority that's
- // ready to run. If a high-priority thread is
- // trying to acquire the lock, which is held by
- // a low-priority thread, then the low-priority
- // thread may never get scheduled and hence never
- // free the lock. NT attempts to avoid priority
- // inversions by temporarily boosting the priority
- // of low-priority runnable threads, but the problem
- // can still occur if there's a medium-priority
- // thread that's always runnable. If Sleep(1) is used,
- // then the thread unconditionally yields the CPU. We
- // only do this for the second and subsequent even
- // iterations, since a millisecond is a long time to wait
- // if the thread can be scheduled in again sooner
- // (~100,000 instructions).
- // Avoid priority inversion: 0, 1, 0, 1,...
- Sleep(dwSleep);
- dwSleep = !dwSleep;
- }
- result = *dest ;
- if (result == comperand)
- *dest = exc ;
- /* Release spinlock */
- spinlock = 0 ;
- return result ;
-} ;
-
-static interlocked_cmp_xchg_t *ixchg;
-
-BOOL
-InitializeNonRecursiveMutex(PNRMUTEX mutex)
-{
- if (!ixchg)
- {
- /* Sorely, Win95 has no InterlockedCompareExchange API (Win98 has), so we have to use emulation */
- HANDLE kernel = GetModuleHandle("kernel32.dll") ;
- if (!kernel || (ixchg = (interlocked_cmp_xchg_t *)GetProcAddress(kernel, "InterlockedCompareExchange")) == NULL)
- ixchg = interlocked_cmp_xchg ;
- }
-
- mutex->owned = -1 ; /* No threads have entered NonRecursiveMutex */
- mutex->thread_id = 0 ;
- mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL) ;
- return mutex->hevent != NULL ; /* TRUE if the mutex is created */
-}
-
-#ifdef InterlockedCompareExchange
-#undef InterlockedCompareExchange
-#endif
-#define InterlockedCompareExchange(dest,exchange,comperand) (ixchg((dest), (exchange), (comperand)))
-
-VOID
-DeleteNonRecursiveMutex(PNRMUTEX mutex)
-{
- /* No in-use check */
- CloseHandle(mutex->hevent) ;
- mutex->hevent = NULL ; /* Just in case */
-}
-
-DWORD
-EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait)
-{
- /* Assume that the thread waits successfully */
- DWORD ret ;
-
- /* InterlockedIncrement(&mutex->owned) == 0 means that no thread currently owns the mutex */
- if (!wait)
- {
- if (InterlockedCompareExchange((PVOID *)&mutex->owned, (PVOID)0, (PVOID)-1) != (PVOID)-1)
- return WAIT_TIMEOUT ;
- ret = WAIT_OBJECT_0 ;
- }
- else
- ret = InterlockedIncrement(&mutex->owned) ?
- /* Some thread owns the mutex, let's wait... */
- WaitForSingleObject(mutex->hevent, INFINITE) : WAIT_OBJECT_0 ;
-
- mutex->thread_id = GetCurrentThreadId() ; /* We own it */
- return ret ;
-}
-
-BOOL
-LeaveNonRecursiveMutex(PNRMUTEX mutex)
-{
- /* We don't own the mutex */
- mutex->thread_id = 0 ;
- return
- InterlockedDecrement(&mutex->owned) < 0 ||
- SetEvent(mutex->hevent) ; /* Other threads are waiting, wake one on them up */
-}
-
-PNRMUTEX
-AllocNonRecursiveMutex(void)
-{
- PNRMUTEX mutex = (PNRMUTEX)malloc(sizeof(NRMUTEX)) ;
- if (mutex && !InitializeNonRecursiveMutex(mutex))
- {
- free(mutex) ;
- mutex = NULL ;
- }
- return mutex ;
-}
-
-void
-FreeNonRecursiveMutex(PNRMUTEX mutex)
-{
- if (mutex)
- {
- DeleteNonRecursiveMutex(mutex) ;
- free(mutex) ;
- }
-}
-
-long PyThread_get_thread_ident(void);
-
-/*
- * Initialization of the C package, should not be needed.
- */
-static void
-PyThread__init_thread(void)
-{
-}
-
-/*
- * Thread support.
- */
-
-typedef struct {
- void (*func)(void*);
- void *arg;
- long id;
- HANDLE done;
-} callobj;
-
-static int
-bootstrap(void *call)
-{
- callobj *obj = (callobj*)call;
- /* copy callobj since other thread might free it before we're done */
- void (*func)(void*) = obj->func;
- void *arg = obj->arg;
-
- obj->id = PyThread_get_thread_ident();
- ReleaseSemaphore(obj->done, 1, NULL);
- func(arg);
- return 0;
-}
-
-long
-PyThread_start_new_thread(void (*func)(void *), void *arg)
-{
- Py_uintptr_t rv;
- callobj obj;
-
- dprintf(("%ld: PyThread_start_new_thread called\n",
- PyThread_get_thread_ident()));
- if (!initialized)
- PyThread_init_thread();
-
- obj.id = -1; /* guilty until proved innocent */
- obj.func = func;
- obj.arg = arg;
- obj.done = CreateSemaphore(NULL, 0, 1, NULL);
- if (obj.done == NULL)
- return -1;
-
- rv = _beginthread(bootstrap, _pythread_stacksize, &obj);
- if (rv == (Py_uintptr_t)-1) {
- /* I've seen errno == EAGAIN here, which means "there are
- * too many threads".
- */
- dprintf(("%ld: PyThread_start_new_thread failed: %p errno %d\n",
- PyThread_get_thread_ident(), rv, errno));
- obj.id = -1;
- }
- else {
- dprintf(("%ld: PyThread_start_new_thread succeeded: %p\n",
- PyThread_get_thread_ident(), rv));
- /* wait for thread to initialize, so we can get its id */
- WaitForSingleObject(obj.done, INFINITE);
- assert(obj.id != -1);
- }
- CloseHandle((HANDLE)obj.done);
- return obj.id;
-}
-
-/*
- * Return the thread Id instead of an handle. The Id is said to uniquely identify the
- * thread in the system
- */
-long
-PyThread_get_thread_ident(void)
-{
- if (!initialized)
- PyThread_init_thread();
-
- return GetCurrentThreadId();
-}
-
-static void
-do_PyThread_exit_thread(int no_cleanup)
-{
- dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
- if (!initialized)
- if (no_cleanup)
- _exit(0);
- else
- exit(0);
- _endthread();
-}
-
-void
-PyThread_exit_thread(void)
-{
- do_PyThread_exit_thread(0);
-}
-
-void
-PyThread__exit_thread(void)
-{
- do_PyThread_exit_thread(1);
-}
-
-#ifndef NO_EXIT_PROG
-static void
-do_PyThread_exit_prog(int status, int no_cleanup)
-{
- dprintf(("PyThread_exit_prog(%d) called\n", status));
- if (!initialized)
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
-}
-
-void
-PyThread_exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-void
-PyThread__exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-/*
- * Lock support. It has too be implemented as semaphores.
- * I [Dag] tried to implement it with mutex but I could find a way to
- * tell whether a thread already own the lock or not.
- */
-PyThread_type_lock
-PyThread_allocate_lock(void)
-{
- PNRMUTEX aLock;
-
- dprintf(("PyThread_allocate_lock called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- aLock = AllocNonRecursiveMutex() ;
-
- dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
-
- return (PyThread_type_lock) aLock;
-}
-
-void
-PyThread_free_lock(PyThread_type_lock aLock)
-{
- dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
-
- FreeNonRecursiveMutex(aLock) ;
-}
-
-/*
- * Return 1 on success if the lock was acquired
- *
- * and 0 if the lock was not acquired. This means a 0 is returned
- * if the lock has already been acquired by this thread!
- */
-int
-PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
-{
- int success ;
-
- dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),aLock, waitflag));
-
- success = aLock && EnterNonRecursiveMutex((PNRMUTEX) aLock, (waitflag ? INFINITE : 0)) == WAIT_OBJECT_0 ;
-
- dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success));
-
- return success;
-}
-
-void
-PyThread_release_lock(PyThread_type_lock aLock)
-{
- dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
-
- if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock)))
- dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError()));
-}
-
-/* minimum/maximum thread stack sizes supported */
-#define THREAD_MIN_STACKSIZE 0x8000 /* 32kB */
-#define THREAD_MAX_STACKSIZE 0x10000000 /* 256MB */
-
-/* set the thread stack size.
- * Return 0 if size is valid, -1 otherwise.
- */
-static int
-_pythread_nt_set_stacksize(size_t size)
-{
- /* set to default */
- if (size == 0) {
- _pythread_stacksize = 0;
- return 0;
- }
-
- /* valid range? */
- if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
- _pythread_stacksize = size;
- return 0;
- }
-
- return -1;
-}
-
-#define THREAD_SET_STACKSIZE(x) _pythread_nt_set_stacksize(x)
diff --git a/sys/src/cmd/python/Python/thread_os2.h b/sys/src/cmd/python/Python/thread_os2.h
deleted file mode 100644
index 12eeed51c..000000000
--- a/sys/src/cmd/python/Python/thread_os2.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/* This code implemented by cvale@netcom.com */
-
-#define INCL_DOSPROCESS
-#define INCL_DOSSEMAPHORES
-#include "os2.h"
-#include "limits.h"
-
-#include "process.h"
-
-#if defined(PYCC_GCC)
-#include <sys/builtin.h>
-#include <sys/fmutex.h>
-#else
-long PyThread_get_thread_ident(void);
-#endif
-
-/* default thread stack size of 64kB */
-#if !defined(THREAD_STACK_SIZE)
-#define THREAD_STACK_SIZE 0x10000
-#endif
-
-#define OS2_STACKSIZE(x) (x ? x : THREAD_STACK_SIZE)
-
-/*
- * Initialization of the C package, should not be needed.
- */
-static void
-PyThread__init_thread(void)
-{
-}
-
-/*
- * Thread support.
- */
-long
-PyThread_start_new_thread(void (*func)(void *), void *arg)
-{
- int thread_id;
-
- thread_id = _beginthread(func,
- NULL,
- OS2_STACKSIZE(_pythread_stacksize),
- arg);
-
- if (thread_id == -1) {
- dprintf(("_beginthread failed. return %ld\n", errno));
- }
-
- return thread_id;
-}
-
-long
-PyThread_get_thread_ident(void)
-{
-#if !defined(PYCC_GCC)
- PPIB pib;
- PTIB tib;
-#endif
-
- if (!initialized)
- PyThread_init_thread();
-
-#if defined(PYCC_GCC)
- return _gettid();
-#else
- DosGetInfoBlocks(&tib, &pib);
- return tib->tib_ptib2->tib2_ultid;
-#endif
-}
-
-static void
-do_PyThread_exit_thread(int no_cleanup)
-{
- dprintf(("%ld: PyThread_exit_thread called\n",
- PyThread_get_thread_ident()));
- if (!initialized)
- if (no_cleanup)
- _exit(0);
- else
- exit(0);
- _endthread();
-}
-
-void
-PyThread_exit_thread(void)
-{
- do_PyThread_exit_thread(0);
-}
-
-void
-PyThread__exit_thread(void)
-{
- do_PyThread_exit_thread(1);
-}
-
-#ifndef NO_EXIT_PROG
-static void
-do_PyThread_exit_prog(int status, int no_cleanup)
-{
- dprintf(("PyThread_exit_prog(%d) called\n", status));
- if (!initialized)
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
-}
-
-void
-PyThread_exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-void
-PyThread__exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-/*
- * Lock support. This is implemented with an event semaphore and critical
- * sections to make it behave more like a posix mutex than its OS/2
- * counterparts.
- */
-
-typedef struct os2_lock_t {
- int is_set;
- HEV changed;
-} *type_os2_lock;
-
-PyThread_type_lock
-PyThread_allocate_lock(void)
-{
-#if defined(PYCC_GCC)
- _fmutex *sem = malloc(sizeof(_fmutex));
- if (!initialized)
- PyThread_init_thread();
- dprintf(("%ld: PyThread_allocate_lock() -> %lx\n",
- PyThread_get_thread_ident(),
- (long)sem));
- if (_fmutex_create(sem, 0)) {
- free(sem);
- sem = NULL;
- }
- return (PyThread_type_lock)sem;
-#else
- APIRET rc;
- type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));
-
- dprintf(("PyThread_allocate_lock called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- lock->is_set = 0;
-
- DosCreateEventSem(NULL, &lock->changed, 0, 0);
-
- dprintf(("%ld: PyThread_allocate_lock() -> %p\n",
- PyThread_get_thread_ident(),
- lock->changed));
-
- return (PyThread_type_lock)lock;
-#endif
-}
-
-void
-PyThread_free_lock(PyThread_type_lock aLock)
-{
-#if !defined(PYCC_GCC)
- type_os2_lock lock = (type_os2_lock)aLock;
-#endif
-
- dprintf(("%ld: PyThread_free_lock(%p) called\n",
- PyThread_get_thread_ident(),aLock));
-
-#if defined(PYCC_GCC)
- if (aLock) {
- _fmutex_close((_fmutex *)aLock);
- free((_fmutex *)aLock);
- }
-#else
- DosCloseEventSem(lock->changed);
- free(aLock);
-#endif
-}
-
-/*
- * Return 1 on success if the lock was acquired
- *
- * and 0 if the lock was not acquired.
- */
-int
-PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
-{
-#if !defined(PYCC_GCC)
- int done = 0;
- ULONG count;
- PID pid = 0;
- TID tid = 0;
- type_os2_lock lock = (type_os2_lock)aLock;
-#endif
-
- dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n",
- PyThread_get_thread_ident(),
- aLock,
- waitflag));
-
-#if defined(PYCC_GCC)
- /* always successful if the lock doesn't exist */
- if (aLock &&
- _fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT))
- return 0;
-#else
- while (!done) {
- /* if the lock is currently set, we have to wait for
- * the state to change
- */
- if (lock->is_set) {
- if (!waitflag)
- return 0;
- DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT);
- }
-
- /* enter a critical section and try to get the semaphore. If
- * it is still locked, we will try again.
- */
- if (DosEnterCritSec())
- return 0;
-
- if (!lock->is_set) {
- lock->is_set = 1;
- DosResetEventSem(lock->changed, &count);
- done = 1;
- }
-
- DosExitCritSec();
- }
-#endif
-
- return 1;
-}
-
-void
-PyThread_release_lock(PyThread_type_lock aLock)
-{
-#if !defined(PYCC_GCC)
- type_os2_lock lock = (type_os2_lock)aLock;
-#endif
-
- dprintf(("%ld: PyThread_release_lock(%p) called\n",
- PyThread_get_thread_ident(),
- aLock));
-
-#if defined(PYCC_GCC)
- if (aLock)
- _fmutex_release((_fmutex *)aLock);
-#else
- if (!lock->is_set) {
- dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
- PyThread_get_thread_ident(),
- aLock,
- GetLastError()));
- return;
- }
-
- if (DosEnterCritSec()) {
- dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
- PyThread_get_thread_ident(),
- aLock,
- GetLastError()));
- return;
- }
-
- lock->is_set = 0;
- DosPostEventSem(lock->changed);
-
- DosExitCritSec();
-#endif
-}
-
-/* minimum/maximum thread stack sizes supported */
-#define THREAD_MIN_STACKSIZE 0x8000 /* 32kB */
-#define THREAD_MAX_STACKSIZE 0x2000000 /* 32MB */
-
-/* set the thread stack size.
- * Return 0 if size is valid, -1 otherwise.
- */
-static int
-_pythread_os2_set_stacksize(size_t size)
-{
- /* set to default */
- if (size == 0) {
- _pythread_stacksize = 0;
- return 0;
- }
-
- /* valid range? */
- if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
- _pythread_stacksize = size;
- return 0;
- }
-
- return -1;
-}
-
-#define THREAD_SET_STACKSIZE(x) _pythread_os2_set_stacksize(x)
diff --git a/sys/src/cmd/python/Python/thread_plan9.h b/sys/src/cmd/python/Python/thread_plan9.h
deleted file mode 100644
index d0504806e..000000000
--- a/sys/src/cmd/python/Python/thread_plan9.h
+++ /dev/null
@@ -1,135 +0,0 @@
-#define _PLAN9_SOURCE
-#include <u.h>
-#include <lib9.h>
-#include <qlock.h>
-
-/*
- * Initialization.
- */
-static void
-PyThread__init_thread(void)
-{
-}
-
-/*
- * Thread support.
- */
-long
-PyThread_start_new_thread(void (*func)(void *), void *arg)
-{
- dprintf(("PyThread_start_new_thread called\n"));
- if (!initialized)
- PyThread_init_thread();
- switch(rfork(RFPROC|RFMEM)){
- case -1:
- printf("rfork: %r\n");
- return -1;
- case 0:
- _threadarg->fn = func;
- _threadarg->arg = arg;
- longjmp(_threadarg->jb, 1);
- default:
- return 0;
- }
-}
-
-long
-PyThread_get_thread_ident(void)
-{
- if (!initialized)
- PyThread_init_thread();
- return getpid();
-}
-
-void
-PyThread_exit_thread(void)
-{
- if(initialized)
- _exit(0);
- exit(0);
-}
-
-void
-PyThread__exit_thread(void)
-{
- _exit(0);
-}
-
-#ifndef NO_EXIT_PROG
-static
-void do_PyThread_exit_prog(int status, int no_cleanup)
-{
- /*
- * BUG BUG BUG
- */
-
- dprintf(("PyThread_exit_prog(%d) called\n", status));
- if (!initialized)
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
-}
-
-void
-PyThread_exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-void
-PyThread__exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-/*
- * Lock support.
- */
-PyThread_type_lock
-PyThread_allocate_lock(void)
-{
- QLock *lk;
-
- dprintf(("PyThread_allocate_lock called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- lk = malloc(sizeof(*lk));
- memset(lk, 0, sizeof(*lk));
- dprintf(("PyThread_allocate_lock() -> %p\n", lk));
- return lk;
-}
-
-void
-PyThread_free_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_free_lock(%p) called\n", lock));
- free(lock);
-}
-
-int
-PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
-{
- int success;
-
- dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
- if(lock == nil)
- success = 0;
- else if(waitflag){
- qlock(lock);
- success = 1;
- }else
- success = canqlock(lock);
- dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
- return success;
-}
-
-void
-PyThread_release_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_release_lock(%p) called\n", lock));
- qunlock(lock);
-}
-
diff --git a/sys/src/cmd/python/Python/thread_pth.h b/sys/src/cmd/python/Python/thread_pth.h
deleted file mode 100644
index 8c7dbe925..000000000
--- a/sys/src/cmd/python/Python/thread_pth.h
+++ /dev/null
@@ -1,213 +0,0 @@
-
-/* GNU pth threads interface
- http://www.gnu.org/software/pth
- 2000-05-03 Andy Dustman <andy@dustman.net>
-
- Adapted from Posix threads interface
- 12 May 1997 -- david arnold <davida@pobox.com>
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <pth.h>
-
-/* A pth mutex isn't sufficient to model the Python lock type
- * because pth mutexes can be acquired multiple times by the
- * same thread.
- *
- * The pth_lock struct implements a Python lock as a "locked?" bit
- * and a <condition, mutex> pair. In general, if the bit can be acquired
- * instantly, it is, else the pair is used to block the thread until the
- * bit is cleared.
- */
-
-typedef struct {
- char locked; /* 0=unlocked, 1=locked */
- /* a <cond, mutex> pair to handle an acquire of a locked lock */
- pth_cond_t lock_released;
- pth_mutex_t mut;
-} pth_lock;
-
-#define CHECK_STATUS(name) if (status == -1) { printf("%d ", status); perror(name); error = 1; }
-
-pth_attr_t PyThread_attr;
-
-/*
- * Initialization.
- */
-
-static void PyThread__init_thread(void)
-{
- pth_init();
- PyThread_attr = pth_attr_new();
- pth_attr_set(PyThread_attr, PTH_ATTR_STACK_SIZE, 1<<18);
- pth_attr_set(PyThread_attr, PTH_ATTR_JOINABLE, FALSE);
-}
-
-/*
- * Thread support.
- */
-
-
-long PyThread_start_new_thread(void (*func)(void *), void *arg)
-{
- pth_t th;
- dprintf(("PyThread_start_new_thread called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- th = pth_spawn(PyThread_attr,
- (void* (*)(void *))func,
- (void *)arg
- );
-
- return th;
-}
-
-long PyThread_get_thread_ident(void)
-{
- volatile pth_t threadid;
- if (!initialized)
- PyThread_init_thread();
- /* Jump through some hoops for Alpha OSF/1 */
- threadid = pth_self();
- return (long) *(long *) &threadid;
-}
-
-static void do_PyThread_exit_thread(int no_cleanup)
-{
- dprintf(("PyThread_exit_thread called\n"));
- if (!initialized) {
- if (no_cleanup)
- _exit(0);
- else
- exit(0);
- }
-}
-
-void PyThread_exit_thread(void)
-{
- do_PyThread_exit_thread(0);
-}
-
-void PyThread__exit_thread(void)
-{
- do_PyThread_exit_thread(1);
-}
-
-#ifndef NO_EXIT_PROG
-static void do_PyThread_exit_prog(int status, int no_cleanup)
-{
- dprintf(("PyThread_exit_prog(%d) called\n", status));
- if (!initialized)
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
-}
-
-void PyThread_exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-void PyThread__exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-/*
- * Lock support.
- */
-PyThread_type_lock PyThread_allocate_lock(void)
-{
- pth_lock *lock;
- int status, error = 0;
-
- dprintf(("PyThread_allocate_lock called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- lock = (pth_lock *) malloc(sizeof(pth_lock));
- memset((void *)lock, '\0', sizeof(pth_lock));
- if (lock) {
- lock->locked = 0;
- status = pth_mutex_init(&lock->mut);
- CHECK_STATUS("pth_mutex_init");
- status = pth_cond_init(&lock->lock_released);
- CHECK_STATUS("pth_cond_init");
- if (error) {
- free((void *)lock);
- lock = NULL;
- }
- }
- dprintf(("PyThread_allocate_lock() -> %p\n", lock));
- return (PyThread_type_lock) lock;
-}
-
-void PyThread_free_lock(PyThread_type_lock lock)
-{
- pth_lock *thelock = (pth_lock *)lock;
-
- dprintf(("PyThread_free_lock(%p) called\n", lock));
-
- free((void *)thelock);
-}
-
-int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
-{
- int success;
- pth_lock *thelock = (pth_lock *)lock;
- int status, error = 0;
-
- dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
-
- status = pth_mutex_acquire(&thelock->mut, !waitflag, NULL);
- CHECK_STATUS("pth_mutex_acquire[1]");
- success = thelock->locked == 0;
- if (success) thelock->locked = 1;
- status = pth_mutex_release( &thelock->mut );
- CHECK_STATUS("pth_mutex_release[1]");
-
- if ( !success && waitflag ) {
- /* continue trying until we get the lock */
-
- /* mut must be locked by me -- part of the condition
- * protocol */
- status = pth_mutex_acquire( &thelock->mut, !waitflag, NULL );
- CHECK_STATUS("pth_mutex_acquire[2]");
- while ( thelock->locked ) {
- status = pth_cond_await(&thelock->lock_released,
- &thelock->mut, NULL);
- CHECK_STATUS("pth_cond_await");
- }
- thelock->locked = 1;
- status = pth_mutex_release( &thelock->mut );
- CHECK_STATUS("pth_mutex_release[2]");
- success = 1;
- }
- if (error) success = 0;
- dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
- return success;
-}
-
-void PyThread_release_lock(PyThread_type_lock lock)
-{
- pth_lock *thelock = (pth_lock *)lock;
- int status, error = 0;
-
- dprintf(("PyThread_release_lock(%p) called\n", lock));
-
- status = pth_mutex_acquire( &thelock->mut, 0, NULL );
- CHECK_STATUS("pth_mutex_acquire[3]");
-
- thelock->locked = 0;
-
- status = pth_mutex_release( &thelock->mut );
- CHECK_STATUS("pth_mutex_release[3]");
-
- /* wake up someone (anyone, if any) waiting on the lock */
- status = pth_cond_notify( &thelock->lock_released, 0 );
- CHECK_STATUS("pth_cond_notify");
-}
diff --git a/sys/src/cmd/python/Python/thread_pthread.h b/sys/src/cmd/python/Python/thread_pthread.h
deleted file mode 100644
index 60d2fb216..000000000
--- a/sys/src/cmd/python/Python/thread_pthread.h
+++ /dev/null
@@ -1,533 +0,0 @@
-
-/* Posix threads interface */
-
-#include <stdlib.h>
-#include <string.h>
-#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
-#define destructor xxdestructor
-#endif
-#include <pthread.h>
-#if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
-#undef destructor
-#endif
-#include <signal.h>
-
-/* The POSIX spec requires that use of pthread_attr_setstacksize
- be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
-#ifdef _POSIX_THREAD_ATTR_STACKSIZE
-#ifndef THREAD_STACK_SIZE
-#define THREAD_STACK_SIZE 0 /* use default stack size */
-#endif
-/* for safety, ensure a viable minimum stacksize */
-#define THREAD_STACK_MIN 0x8000 /* 32kB */
-#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
-#ifdef THREAD_STACK_SIZE
-#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
-#endif
-#endif
-
-/* The POSIX spec says that implementations supporting the sem_*
- family of functions must indicate this by defining
- _POSIX_SEMAPHORES. */
-#ifdef _POSIX_SEMAPHORES
-/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
- we need to add 0 to make it work there as well. */
-#if (_POSIX_SEMAPHORES+0) == -1
-#define HAVE_BROKEN_POSIX_SEMAPHORES
-#else
-#include <semaphore.h>
-#include <errno.h>
-#endif
-#endif
-
-/* Before FreeBSD 5.4, system scope threads was very limited resource
- in default setting. So the process scope is preferred to get
- enough number of threads to work. */
-#ifdef __FreeBSD__
-#include <osreldate.h>
-#if __FreeBSD_version >= 500000 && __FreeBSD_version < 504101
-#undef PTHREAD_SYSTEM_SCHED_SUPPORTED
-#endif
-#endif
-
-#if !defined(pthread_attr_default)
-# define pthread_attr_default ((pthread_attr_t *)NULL)
-#endif
-#if !defined(pthread_mutexattr_default)
-# define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
-#endif
-#if !defined(pthread_condattr_default)
-# define pthread_condattr_default ((pthread_condattr_t *)NULL)
-#endif
-
-
-/* Whether or not to use semaphores directly rather than emulating them with
- * mutexes and condition variables:
- */
-#if defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES)
-# define USE_SEMAPHORES
-#else
-# undef USE_SEMAPHORES
-#endif
-
-
-/* On platforms that don't use standard POSIX threads pthread_sigmask()
- * isn't present. DEC threads uses sigprocmask() instead as do most
- * other UNIX International compliant systems that don't have the full
- * pthread implementation.
- */
-#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
-# define SET_THREAD_SIGMASK pthread_sigmask
-#else
-# define SET_THREAD_SIGMASK sigprocmask
-#endif
-
-
-/* A pthread mutex isn't sufficient to model the Python lock type
- * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
- * following are undefined:
- * -> a thread tries to lock a mutex it already has locked
- * -> a thread tries to unlock a mutex locked by a different thread
- * pthread mutexes are designed for serializing threads over short pieces
- * of code anyway, so wouldn't be an appropriate implementation of
- * Python's locks regardless.
- *
- * The pthread_lock struct implements a Python lock as a "locked?" bit
- * and a <condition, mutex> pair. In general, if the bit can be acquired
- * instantly, it is, else the pair is used to block the thread until the
- * bit is cleared. 9 May 1994 tim@ksr.com
- */
-
-typedef struct {
- char locked; /* 0=unlocked, 1=locked */
- /* a <cond, mutex> pair to handle an acquire of a locked lock */
- pthread_cond_t lock_released;
- pthread_mutex_t mut;
-} pthread_lock;
-
-#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
-
-/*
- * Initialization.
- */
-
-#ifdef _HAVE_BSDI
-static
-void _noop(void)
-{
-}
-
-static void
-PyThread__init_thread(void)
-{
- /* DO AN INIT BY STARTING THE THREAD */
- static int dummy = 0;
- pthread_t thread1;
- pthread_create(&thread1, NULL, (void *) _noop, &dummy);
- pthread_join(thread1, NULL);
-}
-
-#else /* !_HAVE_BSDI */
-
-static void
-PyThread__init_thread(void)
-{
-#if defined(_AIX) && defined(__GNUC__)
- pthread_init();
-#endif
-}
-
-#endif /* !_HAVE_BSDI */
-
-/*
- * Thread support.
- */
-
-
-long
-PyThread_start_new_thread(void (*func)(void *), void *arg)
-{
- pthread_t th;
- int status;
-#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
- pthread_attr_t attrs;
-#endif
-#if defined(THREAD_STACK_SIZE)
- size_t tss;
-#endif
-
- dprintf(("PyThread_start_new_thread called\n"));
- if (!initialized)
- PyThread_init_thread();
-
-#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
- if (pthread_attr_init(&attrs) != 0)
- return -1;
-#endif
-#if defined(THREAD_STACK_SIZE)
- tss = (_pythread_stacksize != 0) ? _pythread_stacksize
- : THREAD_STACK_SIZE;
- if (tss != 0) {
- if (pthread_attr_setstacksize(&attrs, tss) != 0) {
- pthread_attr_destroy(&attrs);
- return -1;
- }
- }
-#endif
-#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
- pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
-#endif
-
- status = pthread_create(&th,
-#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
- &attrs,
-#else
- (pthread_attr_t*)NULL,
-#endif
- (void* (*)(void *))func,
- (void *)arg
- );
-
-#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
- pthread_attr_destroy(&attrs);
-#endif
- if (status != 0)
- return -1;
-
- pthread_detach(th);
-
-#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
- return (long) th;
-#else
- return (long) *(long *) &th;
-#endif
-}
-
-/* XXX This implementation is considered (to quote Tim Peters) "inherently
- hosed" because:
- - It does not guarantee the promise that a non-zero integer is returned.
- - The cast to long is inherently unsafe.
- - It is not clear that the 'volatile' (for AIX?) and ugly casting in the
- latter return statement (for Alpha OSF/1) are any longer necessary.
-*/
-long
-PyThread_get_thread_ident(void)
-{
- volatile pthread_t threadid;
- if (!initialized)
- PyThread_init_thread();
- /* Jump through some hoops for Alpha OSF/1 */
- threadid = pthread_self();
-#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
- return (long) threadid;
-#else
- return (long) *(long *) &threadid;
-#endif
-}
-
-static void
-do_PyThread_exit_thread(int no_cleanup)
-{
- dprintf(("PyThread_exit_thread called\n"));
- if (!initialized) {
- if (no_cleanup)
- _exit(0);
- else
- exit(0);
- }
-}
-
-void
-PyThread_exit_thread(void)
-{
- do_PyThread_exit_thread(0);
-}
-
-void
-PyThread__exit_thread(void)
-{
- do_PyThread_exit_thread(1);
-}
-
-#ifndef NO_EXIT_PROG
-static void
-do_PyThread_exit_prog(int status, int no_cleanup)
-{
- dprintf(("PyThread_exit_prog(%d) called\n", status));
- if (!initialized)
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
-}
-
-void
-PyThread_exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-void
-PyThread__exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-#ifdef USE_SEMAPHORES
-
-/*
- * Lock support.
- */
-
-PyThread_type_lock
-PyThread_allocate_lock(void)
-{
- sem_t *lock;
- int status, error = 0;
-
- dprintf(("PyThread_allocate_lock called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- lock = (sem_t *)malloc(sizeof(sem_t));
-
- if (lock) {
- status = sem_init(lock,0,1);
- CHECK_STATUS("sem_init");
-
- if (error) {
- free((void *)lock);
- lock = NULL;
- }
- }
-
- dprintf(("PyThread_allocate_lock() -> %p\n", lock));
- return (PyThread_type_lock)lock;
-}
-
-void
-PyThread_free_lock(PyThread_type_lock lock)
-{
- sem_t *thelock = (sem_t *)lock;
- int status, error = 0;
-
- dprintf(("PyThread_free_lock(%p) called\n", lock));
-
- if (!thelock)
- return;
-
- status = sem_destroy(thelock);
- CHECK_STATUS("sem_destroy");
-
- free((void *)thelock);
-}
-
-/*
- * As of February 2002, Cygwin thread implementations mistakenly report error
- * codes in the return value of the sem_ calls (like the pthread_ functions).
- * Correct implementations return -1 and put the code in errno. This supports
- * either.
- */
-static int
-fix_status(int status)
-{
- return (status == -1) ? errno : status;
-}
-
-int
-PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
-{
- int success;
- sem_t *thelock = (sem_t *)lock;
- int status, error = 0;
-
- dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
-
- do {
- if (waitflag)
- status = fix_status(sem_wait(thelock));
- else
- status = fix_status(sem_trywait(thelock));
- } while (status == EINTR); /* Retry if interrupted by a signal */
-
- if (waitflag) {
- CHECK_STATUS("sem_wait");
- } else if (status != EAGAIN) {
- CHECK_STATUS("sem_trywait");
- }
-
- success = (status == 0) ? 1 : 0;
-
- dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
- return success;
-}
-
-void
-PyThread_release_lock(PyThread_type_lock lock)
-{
- sem_t *thelock = (sem_t *)lock;
- int status, error = 0;
-
- dprintf(("PyThread_release_lock(%p) called\n", lock));
-
- status = sem_post(thelock);
- CHECK_STATUS("sem_post");
-}
-
-#else /* USE_SEMAPHORES */
-
-/*
- * Lock support.
- */
-PyThread_type_lock
-PyThread_allocate_lock(void)
-{
- pthread_lock *lock;
- int status, error = 0;
-
- dprintf(("PyThread_allocate_lock called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- lock = (pthread_lock *) malloc(sizeof(pthread_lock));
- if (lock) {
- memset((void *)lock, '\0', sizeof(pthread_lock));
- lock->locked = 0;
-
- status = pthread_mutex_init(&lock->mut,
- pthread_mutexattr_default);
- CHECK_STATUS("pthread_mutex_init");
-
- status = pthread_cond_init(&lock->lock_released,
- pthread_condattr_default);
- CHECK_STATUS("pthread_cond_init");
-
- if (error) {
- free((void *)lock);
- lock = 0;
- }
- }
-
- dprintf(("PyThread_allocate_lock() -> %p\n", lock));
- return (PyThread_type_lock) lock;
-}
-
-void
-PyThread_free_lock(PyThread_type_lock lock)
-{
- pthread_lock *thelock = (pthread_lock *)lock;
- int status, error = 0;
-
- dprintf(("PyThread_free_lock(%p) called\n", lock));
-
- status = pthread_mutex_destroy( &thelock->mut );
- CHECK_STATUS("pthread_mutex_destroy");
-
- status = pthread_cond_destroy( &thelock->lock_released );
- CHECK_STATUS("pthread_cond_destroy");
-
- free((void *)thelock);
-}
-
-int
-PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
-{
- int success;
- pthread_lock *thelock = (pthread_lock *)lock;
- int status, error = 0;
-
- dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
-
- status = pthread_mutex_lock( &thelock->mut );
- CHECK_STATUS("pthread_mutex_lock[1]");
- success = thelock->locked == 0;
-
- if ( !success && waitflag ) {
- /* continue trying until we get the lock */
-
- /* mut must be locked by me -- part of the condition
- * protocol */
- while ( thelock->locked ) {
- status = pthread_cond_wait(&thelock->lock_released,
- &thelock->mut);
- CHECK_STATUS("pthread_cond_wait");
- }
- success = 1;
- }
- if (success) thelock->locked = 1;
- status = pthread_mutex_unlock( &thelock->mut );
- CHECK_STATUS("pthread_mutex_unlock[1]");
-
- if (error) success = 0;
- dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
- return success;
-}
-
-void
-PyThread_release_lock(PyThread_type_lock lock)
-{
- pthread_lock *thelock = (pthread_lock *)lock;
- int status, error = 0;
-
- dprintf(("PyThread_release_lock(%p) called\n", lock));
-
- status = pthread_mutex_lock( &thelock->mut );
- CHECK_STATUS("pthread_mutex_lock[3]");
-
- thelock->locked = 0;
-
- status = pthread_mutex_unlock( &thelock->mut );
- CHECK_STATUS("pthread_mutex_unlock[3]");
-
- /* wake up someone (anyone, if any) waiting on the lock */
- status = pthread_cond_signal( &thelock->lock_released );
- CHECK_STATUS("pthread_cond_signal");
-}
-
-#endif /* USE_SEMAPHORES */
-
-/* set the thread stack size.
- * Return 0 if size is valid, -1 if size is invalid,
- * -2 if setting stack size is not supported.
- */
-static int
-_pythread_pthread_set_stacksize(size_t size)
-{
-#if defined(THREAD_STACK_SIZE)
- pthread_attr_t attrs;
- size_t tss_min;
- int rc = 0;
-#endif
-
- /* set to default */
- if (size == 0) {
- _pythread_stacksize = 0;
- return 0;
- }
-
-#if defined(THREAD_STACK_SIZE)
-#if defined(PTHREAD_STACK_MIN)
- tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
- : THREAD_STACK_MIN;
-#else
- tss_min = THREAD_STACK_MIN;
-#endif
- if (size >= tss_min) {
- /* validate stack size by setting thread attribute */
- if (pthread_attr_init(&attrs) == 0) {
- rc = pthread_attr_setstacksize(&attrs, size);
- pthread_attr_destroy(&attrs);
- if (rc == 0) {
- _pythread_stacksize = size;
- return 0;
- }
- }
- }
- return -1;
-#else
- return -2;
-#endif
-}
-
-#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
diff --git a/sys/src/cmd/python/Python/thread_sgi.h b/sys/src/cmd/python/Python/thread_sgi.h
deleted file mode 100644
index 234665848..000000000
--- a/sys/src/cmd/python/Python/thread_sgi.h
+++ /dev/null
@@ -1,375 +0,0 @@
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/prctl.h>
-#include <ulocks.h>
-#include <errno.h>
-
-#define HDR_SIZE 2680 /* sizeof(ushdr_t) */
-#define MAXPROC 100 /* max # of threads that can be started */
-
-static usptr_t *shared_arena;
-static ulock_t count_lock; /* protection for some variables */
-static ulock_t wait_lock; /* lock used to wait for other threads */
-static int waiting_for_threads; /* protected by count_lock */
-static int nthreads; /* protected by count_lock */
-static int exit_status;
-#ifndef NO_EXIT_PROG
-static int do_exit; /* indicates that the program is to exit */
-#endif
-static int exiting; /* we're already exiting (for maybe_exit) */
-static pid_t my_pid; /* PID of main thread */
-static struct pidlist {
- pid_t parent;
- pid_t child;
-} pidlist[MAXPROC]; /* PIDs of other threads; protected by count_lock */
-static int maxpidindex; /* # of PIDs in pidlist */
-
-#ifndef NO_EXIT_PROG
-/*
- * This routine is called as a signal handler when another thread
- * exits. When that happens, we must see whether we have to exit as
- * well (because of an PyThread_exit_prog()) or whether we should continue on.
- */
-static void exit_sig(void)
-{
- d2printf(("exit_sig called\n"));
- if (exiting && getpid() == my_pid) {
- d2printf(("already exiting\n"));
- return;
- }
- if (do_exit) {
- d2printf(("exiting in exit_sig\n"));
-#ifdef Py_DEBUG
- if ((thread_debug & 8) == 0)
- thread_debug &= ~1; /* don't produce debug messages */
-#endif
- PyThread_exit_thread();
- }
-}
-
-/*
- * This routine is called when a process calls exit(). If that wasn't
- * done from the library, we do as if an PyThread_exit_prog() was intended.
- */
-static void maybe_exit(void)
-{
- dprintf(("maybe_exit called\n"));
- if (exiting) {
- dprintf(("already exiting\n"));
- return;
- }
- PyThread_exit_prog(0);
-}
-#endif /* NO_EXIT_PROG */
-
-/*
- * Initialization.
- */
-static void PyThread__init_thread(void)
-{
-#ifndef NO_EXIT_PROG
- struct sigaction s;
-#endif /* NO_EXIT_PROG */
-#ifdef USE_DL
- long addr, size;
-#endif /* USE_DL */
-
-
-#ifdef USE_DL
- if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
- perror("usconfig - CONF_INITSIZE (check)");
- if (usconfig(CONF_INITSIZE, size) < 0)
- perror("usconfig - CONF_INITSIZE (reset)");
- addr = (long) dl_getrange(size + HDR_SIZE);
- dprintf(("trying to use addr %p-%p for shared arena\n", addr, addr+size));
- errno = 0;
- if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0)
- perror("usconfig - CONF_ATTACHADDR (set)");
-#endif /* USE_DL */
- if (usconfig(CONF_INITUSERS, 16) < 0)
- perror("usconfig - CONF_INITUSERS");
- my_pid = getpid(); /* so that we know which is the main thread */
-#ifndef NO_EXIT_PROG
- atexit(maybe_exit);
- s.sa_handler = exit_sig;
- sigemptyset(&s.sa_mask);
- /*sigaddset(&s.sa_mask, SIGUSR1);*/
- s.sa_flags = 0;
- sigaction(SIGUSR1, &s, 0);
- if (prctl(PR_SETEXITSIG, SIGUSR1) < 0)
- perror("prctl - PR_SETEXITSIG");
-#endif /* NO_EXIT_PROG */
- if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0)
- perror("usconfig - CONF_ARENATYPE");
- usconfig(CONF_LOCKTYPE, US_DEBUG); /* XXX */
-#ifdef Py_DEBUG
- if (thread_debug & 4)
- usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);
- else if (thread_debug & 2)
- usconfig(CONF_LOCKTYPE, US_DEBUG);
-#endif /* Py_DEBUG */
- if ((shared_arena = usinit(tmpnam(0))) == 0)
- perror("usinit");
-#ifdef USE_DL
- if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */
- perror("usconfig - CONF_ATTACHADDR (reset)");
-#endif /* USE_DL */
- if ((count_lock = usnewlock(shared_arena)) == NULL)
- perror("usnewlock (count_lock)");
- (void) usinitlock(count_lock);
- if ((wait_lock = usnewlock(shared_arena)) == NULL)
- perror("usnewlock (wait_lock)");
- dprintf(("arena start: %p, arena size: %ld\n", shared_arena, (long) usconfig(CONF_GETSIZE, shared_arena)));
-}
-
-/*
- * Thread support.
- */
-
-static void clean_threads(void)
-{
- int i, j;
- pid_t mypid, pid;
-
- /* clean up any exited threads */
- mypid = getpid();
- i = 0;
- while (i < maxpidindex) {
- if (pidlist[i].parent == mypid && (pid = pidlist[i].child) > 0) {
- pid = waitpid(pid, 0, WNOHANG);
- if (pid > 0) {
- /* a thread has exited */
- pidlist[i] = pidlist[--maxpidindex];
- /* remove references to children of dead proc */
- for (j = 0; j < maxpidindex; j++)
- if (pidlist[j].parent == pid)
- pidlist[j].child = -1;
- continue; /* don't increment i */
- }
- }
- i++;
- }
- /* clean up the list */
- i = 0;
- while (i < maxpidindex) {
- if (pidlist[i].child == -1) {
- pidlist[i] = pidlist[--maxpidindex];
- continue; /* don't increment i */
- }
- i++;
- }
-}
-
-long PyThread_start_new_thread(void (*func)(void *), void *arg)
-{
-#ifdef USE_DL
- long addr, size;
- static int local_initialized = 0;
-#endif /* USE_DL */
- int success = 0; /* init not needed when SOLARIS_THREADS and */
- /* C_THREADS implemented properly */
-
- dprintf(("PyThread_start_new_thread called\n"));
- if (!initialized)
- PyThread_init_thread();
- switch (ussetlock(count_lock)) {
- case 0: return 0;
- case -1: perror("ussetlock (count_lock)");
- }
- if (maxpidindex >= MAXPROC)
- success = -1;
- else {
-#ifdef USE_DL
- if (!local_initialized) {
- if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
- perror("usconfig - CONF_INITSIZE (check)");
- if (usconfig(CONF_INITSIZE, size) < 0)
- perror("usconfig - CONF_INITSIZE (reset)");
- addr = (long) dl_getrange(size + HDR_SIZE);
- dprintf(("trying to use addr %p-%p for sproc\n",
- addr, addr+size));
- errno = 0;
- if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 &&
- errno != 0)
- perror("usconfig - CONF_ATTACHADDR (set)");
- }
-#endif /* USE_DL */
- clean_threads();
- if ((success = sproc(func, PR_SALL, arg)) < 0)
- perror("sproc");
-#ifdef USE_DL
- if (!local_initialized) {
- if (usconfig(CONF_ATTACHADDR, addr) < 0)
- /* reset address */
- perror("usconfig - CONF_ATTACHADDR (reset)");
- local_initialized = 1;
- }
-#endif /* USE_DL */
- if (success >= 0) {
- nthreads++;
- pidlist[maxpidindex].parent = getpid();
- pidlist[maxpidindex++].child = success;
- dprintf(("pidlist[%d] = %d\n",
- maxpidindex-1, success));
- }
- }
- if (usunsetlock(count_lock) < 0)
- perror("usunsetlock (count_lock)");
- return success;
-}
-
-long PyThread_get_thread_ident(void)
-{
- return getpid();
-}
-
-static void do_PyThread_exit_thread(int no_cleanup)
-{
- dprintf(("PyThread_exit_thread called\n"));
- if (!initialized)
- if (no_cleanup)
- _exit(0);
- else
- exit(0);
- if (ussetlock(count_lock) < 0)
- perror("ussetlock (count_lock)");
- nthreads--;
- if (getpid() == my_pid) {
- /* main thread; wait for other threads to exit */
- exiting = 1;
-#ifndef NO_EXIT_PROG
- if (do_exit) {
- int i;
-
- /* notify other threads */
- clean_threads();
- if (nthreads >= 0) {
- dprintf(("kill other threads\n"));
- for (i = 0; i < maxpidindex; i++)
- if (pidlist[i].child > 0)
- (void) kill(pidlist[i].child,
- SIGKILL);
- _exit(exit_status);
- }
- }
-#endif /* NO_EXIT_PROG */
- waiting_for_threads = 1;
- if (ussetlock(wait_lock) < 0)
- perror("ussetlock (wait_lock)");
- for (;;) {
- if (nthreads < 0) {
- dprintf(("really exit (%d)\n", exit_status));
- if (no_cleanup)
- _exit(exit_status);
- else
- exit(exit_status);
- }
- if (usunsetlock(count_lock) < 0)
- perror("usunsetlock (count_lock)");
- dprintf(("waiting for other threads (%d)\n", nthreads));
- if (ussetlock(wait_lock) < 0)
- perror("ussetlock (wait_lock)");
- if (ussetlock(count_lock) < 0)
- perror("ussetlock (count_lock)");
- }
- }
- /* not the main thread */
- if (waiting_for_threads) {
- dprintf(("main thread is waiting\n"));
- if (usunsetlock(wait_lock) < 0)
- perror("usunsetlock (wait_lock)");
- }
-#ifndef NO_EXIT_PROG
- else if (do_exit)
- (void) kill(my_pid, SIGUSR1);
-#endif /* NO_EXIT_PROG */
- if (usunsetlock(count_lock) < 0)
- perror("usunsetlock (count_lock)");
- _exit(0);
-}
-
-void PyThread_exit_thread(void)
-{
- do_PyThread_exit_thread(0);
-}
-
-void PyThread__exit_thread(void)
-{
- do_PyThread_exit_thread(1);
-}
-
-#ifndef NO_EXIT_PROG
-static void do_PyThread_exit_prog(int status, int no_cleanup)
-{
- dprintf(("PyThread_exit_prog(%d) called\n", status));
- if (!initialized)
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
- do_exit = 1;
- exit_status = status;
- do_PyThread_exit_thread(no_cleanup);
-}
-
-void PyThread_exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-void PyThread__exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-/*
- * Lock support.
- */
-PyThread_type_lock PyThread_allocate_lock(void)
-{
- ulock_t lock;
-
- dprintf(("PyThread_allocate_lock called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- if ((lock = usnewlock(shared_arena)) == NULL)
- perror("usnewlock");
- (void) usinitlock(lock);
- dprintf(("PyThread_allocate_lock() -> %p\n", lock));
- return (PyThread_type_lock) lock;
-}
-
-void PyThread_free_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_free_lock(%p) called\n", lock));
- usfreelock((ulock_t) lock, shared_arena);
-}
-
-int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
-{
- int success;
-
- dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
- errno = 0; /* clear it just in case */
- if (waitflag)
- success = ussetlock((ulock_t) lock);
- else
- success = uscsetlock((ulock_t) lock, 1); /* Try it once */
- if (success < 0)
- perror(waitflag ? "ussetlock" : "uscsetlock");
- dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
- return success;
-}
-
-void PyThread_release_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_release_lock(%p) called\n", lock));
- if (usunsetlock((ulock_t) lock) < 0)
- perror("usunsetlock");
-}
diff --git a/sys/src/cmd/python/Python/thread_solaris.h b/sys/src/cmd/python/Python/thread_solaris.h
deleted file mode 100644
index ff3e6f359..000000000
--- a/sys/src/cmd/python/Python/thread_solaris.h
+++ /dev/null
@@ -1,174 +0,0 @@
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include </usr/include/thread.h>
-#undef _POSIX_THREADS
-
-
-/*
- * Initialization.
- */
-static void PyThread__init_thread(void)
-{
-}
-
-/*
- * Thread support.
- */
-struct func_arg {
- void (*func)(void *);
- void *arg;
-};
-
-static void *
-new_func(void *funcarg)
-{
- void (*func)(void *);
- void *arg;
-
- func = ((struct func_arg *) funcarg)->func;
- arg = ((struct func_arg *) funcarg)->arg;
- free(funcarg);
- (*func)(arg);
- return 0;
-}
-
-
-long
-PyThread_start_new_thread(void (*func)(void *), void *arg)
-{
- thread_t tid;
- struct func_arg *funcarg;
-
- dprintf(("PyThread_start_new_thread called\n"));
- if (!initialized)
- PyThread_init_thread();
- funcarg = (struct func_arg *) malloc(sizeof(struct func_arg));
- funcarg->func = func;
- funcarg->arg = arg;
- if (thr_create(0, 0, new_func, funcarg,
- THR_DETACHED | THR_NEW_LWP, &tid)) {
- perror("thr_create");
- free((void *) funcarg);
- return -1;
- }
- return tid;
-}
-
-long
-PyThread_get_thread_ident(void)
-{
- if (!initialized)
- PyThread_init_thread();
- return thr_self();
-}
-
-static void
-do_PyThread_exit_thread(int no_cleanup)
-{
- dprintf(("PyThread_exit_thread called\n"));
- if (!initialized)
- if (no_cleanup)
- _exit(0);
- else
- exit(0);
- thr_exit(0);
-}
-
-void
-PyThread_exit_thread(void)
-{
- do_PyThread_exit_thread(0);
-}
-
-void
-PyThread__exit_thread(void)
-{
- do_PyThread_exit_thread(1);
-}
-
-#ifndef NO_EXIT_PROG
-static void
-do_PyThread_exit_prog(int status, int no_cleanup)
-{
- dprintf(("PyThread_exit_prog(%d) called\n", status));
- if (!initialized)
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
-}
-
-void
-PyThread_exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-void
-PyThread__exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-/*
- * Lock support.
- */
-PyThread_type_lock
-PyThread_allocate_lock(void)
-{
- mutex_t *lock;
-
- dprintf(("PyThread_allocate_lock called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- lock = (mutex_t *) malloc(sizeof(mutex_t));
- if (mutex_init(lock, USYNC_THREAD, 0)) {
- perror("mutex_init");
- free((void *) lock);
- lock = 0;
- }
- dprintf(("PyThread_allocate_lock() -> %p\n", lock));
- return (PyThread_type_lock) lock;
-}
-
-void
-PyThread_free_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_free_lock(%p) called\n", lock));
- mutex_destroy((mutex_t *) lock);
- free((void *) lock);
-}
-
-int
-PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
-{
- int success;
-
- dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
- if (waitflag)
- success = mutex_lock((mutex_t *) lock);
- else
- success = mutex_trylock((mutex_t *) lock);
- if (success < 0)
- perror(waitflag ? "mutex_lock" : "mutex_trylock");
- else
- success = !success; /* solaris does it the other way round */
- dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
- return success;
-}
-
-void
-PyThread_release_lock(PyThread_type_lock lock)
-{
- dprintf(("PyThread_release_lock(%p) called\n", lock));
- if (mutex_unlock((mutex_t *) lock))
- perror("mutex_unlock");
-}
diff --git a/sys/src/cmd/python/Python/thread_wince.h b/sys/src/cmd/python/Python/thread_wince.h
deleted file mode 100644
index e16f5d141..000000000
--- a/sys/src/cmd/python/Python/thread_wince.h
+++ /dev/null
@@ -1,171 +0,0 @@
-
-/* This code implemented by Mark Hammond (MHammond@skippinet.com.au) */
-
-#include <windows.h>
-#include <limits.h>
-#include <pydebug.h>
-
-long PyThread_get_thread_ident(void);
-
-/*
- * Change all headers to pure ANSI as no one will use K&R style on an
- * NT
- */
-
-/*
- * Initialization of the C package, should not be needed.
- */
-static void PyThread__init_thread(void)
-{
-}
-
-/*
- * Thread support.
- */
-long PyThread_start_new_thread(void (*func)(void *), void *arg)
-{
- long rv;
- int success = -1;
-
- dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident()));
- if (!initialized)
- PyThread_init_thread();
-
- rv = _beginthread(func, 0, arg); /* use default stack size */
-
- if (rv != -1) {
- success = 0;
- dprintf(("%ld: PyThread_start_new_thread succeeded:\n", PyThread_get_thread_ident()));
- }
-
- return success;
-}
-
-/*
- * Return the thread Id instead of an handle. The Id is said to uniquely identify the
- * thread in the system
- */
-long PyThread_get_thread_ident(void)
-{
- if (!initialized)
- PyThread_init_thread();
-
- return GetCurrentThreadId();
-}
-
-static void do_PyThread_exit_thread(int no_cleanup)
-{
- dprintf(("%ld: do_PyThread_exit_thread called\n", PyThread_get_thread_ident()));
- if (!initialized)
- if (no_cleanup)
- exit(0); /* XXX - was _exit()!! */
- else
- exit(0);
- _endthread();
-}
-
-void PyThread_exit_thread(void)
-{
- do_PyThread_exit_thread(0);
-}
-
-void PyThread__exit_thread(void)
-{
- do_PyThread_exit_thread(1);
-}
-
-#ifndef NO_EXIT_PROG
-static void do_PyThread_exit_prog(int status, int no_cleanup)
-{
- dprintf(("PyThread_exit_prog(%d) called\n", status));
- if (!initialized)
- if (no_cleanup)
- _exit(status);
- else
- exit(status);
-}
-
-void PyThread_exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 0);
-}
-
-void PyThread__exit_prog(int status)
-{
- do_PyThread_exit_prog(status, 1);
-}
-#endif /* NO_EXIT_PROG */
-
-/*
- * Lock support. It has to be implemented using Mutexes, as
- * CE doesnt support semaphores. Therefore we use some hacks to
- * simulate the non reentrant requirements of Python locks
- */
-PyThread_type_lock PyThread_allocate_lock(void)
-{
- HANDLE aLock;
-
- dprintf(("PyThread_allocate_lock called\n"));
- if (!initialized)
- PyThread_init_thread();
-
- aLock = CreateEvent(NULL, /* Security attributes */
- 0, /* Manual-Reset */
- 1, /* Is initially signalled */
- NULL); /* Name of event */
-
- dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
-
- return (PyThread_type_lock) aLock;
-}
-
-void PyThread_free_lock(PyThread_type_lock aLock)
-{
- dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
-
- CloseHandle(aLock);
-}
-
-/*
- * Return 1 on success if the lock was acquired
- *
- * and 0 if the lock was not acquired. This means a 0 is returned
- * if the lock has already been acquired by this thread!
- */
-int PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
-{
- int success = 1;
- DWORD waitResult;
-
- dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),aLock, waitflag));
-
-#ifndef DEBUG
- waitResult = WaitForSingleObject(aLock, (waitflag ? INFINITE : 0));
-#else
- /* To aid in debugging, we regularly wake up. This allows us to
- break into the debugger */
- while (TRUE) {
- waitResult = WaitForSingleObject(aLock, waitflag ? 3000 : 0);
- if (waitflag==0 || (waitflag && waitResult == WAIT_OBJECT_0))
- break;
- }
-#endif
-
- if (waitResult != WAIT_OBJECT_0) {
- success = 0; /* We failed */
- }
-
- dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success));
-
- return success;
-}
-
-void PyThread_release_lock(PyThread_type_lock aLock)
-{
- dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
-
- if (!SetEvent(aLock))
- dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError()));
-}
-
-
diff --git a/sys/src/cmd/python/Python/traceback.c b/sys/src/cmd/python/Python/traceback.c
deleted file mode 100644
index 4ddee2c73..000000000
--- a/sys/src/cmd/python/Python/traceback.c
+++ /dev/null
@@ -1,262 +0,0 @@
-
-/* Traceback implementation */
-
-#include "Python.h"
-
-#include "code.h"
-#include "frameobject.h"
-#include "structmember.h"
-#include "osdefs.h"
-#include "traceback.h"
-
-#define OFF(x) offsetof(PyTracebackObject, x)
-
-static struct memberlist tb_memberlist[] = {
- {"tb_next", T_OBJECT, OFF(tb_next)},
- {"tb_frame", T_OBJECT, OFF(tb_frame)},
- {"tb_lasti", T_INT, OFF(tb_lasti)},
- {"tb_lineno", T_INT, OFF(tb_lineno)},
- {NULL} /* Sentinel */
-};
-
-static PyObject *
-tb_getattr(PyTracebackObject *tb, char *name)
-{
- return PyMember_Get((char *)tb, tb_memberlist, name);
-}
-
-static void
-tb_dealloc(PyTracebackObject *tb)
-{
- PyObject_GC_UnTrack(tb);
- Py_TRASHCAN_SAFE_BEGIN(tb)
- Py_XDECREF(tb->tb_next);
- Py_XDECREF(tb->tb_frame);
- PyObject_GC_Del(tb);
- Py_TRASHCAN_SAFE_END(tb)
-}
-
-static int
-tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg)
-{
- Py_VISIT(tb->tb_next);
- Py_VISIT(tb->tb_frame);
- return 0;
-}
-
-static void
-tb_clear(PyTracebackObject *tb)
-{
- Py_CLEAR(tb->tb_next);
- Py_CLEAR(tb->tb_frame);
-}
-
-PyTypeObject PyTraceBack_Type = {
- PyObject_HEAD_INIT(&PyType_Type)
- 0,
- "traceback",
- sizeof(PyTracebackObject),
- 0,
- (destructor)tb_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- (getattrfunc)tb_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
- 0, /* tp_doc */
- (traverseproc)tb_traverse, /* tp_traverse */
- (inquiry)tb_clear, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
-};
-
-static PyTracebackObject *
-newtracebackobject(PyTracebackObject *next, PyFrameObject *frame)
-{
- PyTracebackObject *tb;
- if ((next != NULL && !PyTraceBack_Check(next)) ||
- frame == NULL || !PyFrame_Check(frame)) {
- PyErr_BadInternalCall();
- return NULL;
- }
- tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type);
- if (tb != NULL) {
- Py_XINCREF(next);
- tb->tb_next = next;
- Py_XINCREF(frame);
- tb->tb_frame = frame;
- tb->tb_lasti = frame->f_lasti;
- tb->tb_lineno = PyCode_Addr2Line(frame->f_code,
- frame->f_lasti);
- PyObject_GC_Track(tb);
- }
- return tb;
-}
-
-int
-PyTraceBack_Here(PyFrameObject *frame)
-{
- PyThreadState *tstate = PyThreadState_GET();
- PyTracebackObject *oldtb = (PyTracebackObject *) tstate->curexc_traceback;
- PyTracebackObject *tb = newtracebackobject(oldtb, frame);
- if (tb == NULL)
- return -1;
- tstate->curexc_traceback = (PyObject *)tb;
- Py_XDECREF(oldtb);
- return 0;
-}
-
-static int
-tb_displayline(PyObject *f, char *filename, int lineno, char *name)
-{
- int err = 0;
- FILE *xfp;
- char linebuf[2000];
- int i;
- if (filename == NULL || name == NULL)
- return -1;
- /* This is needed by Emacs' compile command */
-#define FMT " File \"%.500s\", line %d, in %.500s\n"
- xfp = fopen(filename, "r" PY_STDIOTEXTMODE);
- if (xfp == NULL) {
- /* Search tail of filename in sys.path before giving up */
- PyObject *path;
- char *tail = strrchr(filename, SEP);
- if (tail == NULL)
- tail = filename;
- else
- tail++;
- path = PySys_GetObject("path");
- if (path != NULL && PyList_Check(path)) {
- Py_ssize_t _npath = PyList_Size(path);
- int npath = Py_SAFE_DOWNCAST(_npath, Py_ssize_t, int);
- size_t taillen = strlen(tail);
- char namebuf[MAXPATHLEN+1];
- for (i = 0; i < npath; i++) {
- PyObject *v = PyList_GetItem(path, i);
- if (v == NULL) {
- PyErr_Clear();
- break;
- }
- if (PyString_Check(v)) {
- size_t len;
- len = PyString_GET_SIZE(v);
- if (len + 1 + taillen >= MAXPATHLEN)
- continue; /* Too long */
- strcpy(namebuf, PyString_AsString(v));
- if (strlen(namebuf) != len)
- continue; /* v contains '\0' */
- if (len > 0 && namebuf[len-1] != SEP)
- namebuf[len++] = SEP;
- strcpy(namebuf+len, tail);
- xfp = fopen(namebuf, "r" PY_STDIOTEXTMODE);
- if (xfp != NULL) {
- filename = namebuf;
- break;
- }
- }
- }
- }
- }
- PyOS_snprintf(linebuf, sizeof(linebuf), FMT, filename, lineno, name);
- err = PyFile_WriteString(linebuf, f);
- if (xfp == NULL)
- return err;
- else if (err != 0) {
- fclose(xfp);
- return err;
- }
- for (i = 0; i < lineno; i++) {
- char* pLastChar = &linebuf[sizeof(linebuf)-2];
- do {
- *pLastChar = '\0';
- if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, xfp, NULL) == NULL)
- break;
- /* fgets read *something*; if it didn't get as
- far as pLastChar, it must have found a newline
- or hit the end of the file; if pLastChar is \n,
- it obviously found a newline; else we haven't
- yet seen a newline, so must continue */
- } while (*pLastChar != '\0' && *pLastChar != '\n');
- }
- if (i == lineno) {
- char *p = linebuf;
- while (*p == ' ' || *p == '\t' || *p == '\014')
- p++;
- err = PyFile_WriteString(" ", f);
- if (err == 0) {
- err = PyFile_WriteString(p, f);
- if (err == 0 && strchr(p, '\n') == NULL)
- err = PyFile_WriteString("\n", f);
- }
- }
- fclose(xfp);
- return err;
-}
-
-static int
-tb_printinternal(PyTracebackObject *tb, PyObject *f, int limit)
-{
- int err = 0;
- int depth = 0;
- PyTracebackObject *tb1 = tb;
- while (tb1 != NULL) {
- depth++;
- tb1 = tb1->tb_next;
- }
- while (tb != NULL && err == 0) {
- if (depth <= limit) {
- err = tb_displayline(f,
- PyString_AsString(
- tb->tb_frame->f_code->co_filename),
- tb->tb_lineno,
- PyString_AsString(tb->tb_frame->f_code->co_name));
- }
- depth--;
- tb = tb->tb_next;
- if (err == 0)
- err = PyErr_CheckSignals();
- }
- return err;
-}
-
-int
-PyTraceBack_Print(PyObject *v, PyObject *f)
-{
- int err;
- PyObject *limitv;
- int limit = 1000;
- if (v == NULL)
- return 0;
- if (!PyTraceBack_Check(v)) {
- PyErr_BadInternalCall();
- return -1;
- }
- limitv = PySys_GetObject("tracebacklimit");
- if (limitv && PyInt_Check(limitv)) {
- limit = PyInt_AsLong(limitv);
- if (limit <= 0)
- return 0;
- }
- err = PyFile_WriteString("Traceback (most recent call last):\n", f);
- if (!err)
- err = tb_printinternal((PyTracebackObject *)v, f, limit);
- return err;
-}