diff options
author | Guido van Rossum <guido@python.org> | 1995-01-02 19:04:15 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1995-01-02 19:04:15 (GMT) |
commit | 1ae940a5870df2f706fa884afd533847f6b0b1a8 (patch) | |
tree | ac19577f141b553bd56f998a62478719d5b81cd4 /Python/modsupport.c | |
parent | 824de25fe2edade0ded378b4d602351272f4cf63 (diff) | |
download | cpython-1ae940a5870df2f706fa884afd533847f6b0b1a8.zip cpython-1ae940a5870df2f706fa884afd533847f6b0b1a8.tar.gz cpython-1ae940a5870df2f706fa884afd533847f6b0b1a8.tar.bz2 |
Lots of changes, most minor (fatal() instead of abort(), use of
err_fetch/err_restore and so on). But...
NOTE: import.c has been rewritten and all the DL stuff is now in the
new file importdl.c.
Diffstat (limited to 'Python/modsupport.c')
-rw-r--r-- | Python/modsupport.c | 291 |
1 files changed, 242 insertions, 49 deletions
diff --git a/Python/modsupport.c b/Python/modsupport.c index ae9a838..2952189 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -29,7 +29,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifdef MPW /* MPW pushes 'extended' for float and double types with varargs */ typedef extended va_double; -#else +#else typedef double va_double; #endif @@ -42,7 +42,7 @@ object * initmodule2(name, methods, passthrough) char *name; struct methodlist *methods; - object *passthrough; + object *passthrough; { object *m, *d, *v; struct methodlist *ml; @@ -58,7 +58,7 @@ initmodule2(name, methods, passthrough) fatal("out of mem for method name"); sprintf(namebuf, "%s.%s", name, ml->ml_name); v = newmethodobject(namebuf, ml->ml_meth, - (object *)passthrough, ml->ml_varargs); + (object *)passthrough, ml->ml_varargs); /* XXX The malloc'ed memory in namebuf is never freed */ if (v == NULL || dictinsert(d, ml->ml_name, v) != 0) { fprintf(stderr, "initializing module: %s\n", name); @@ -90,20 +90,33 @@ static int countformat(format, endchar) int count = 0; int level = 0; while (level > 0 || *format != endchar) { - if (*format == '\0') { + switch (*format) { + case '\0': /* Premature end */ err_setstr(SystemError, "unmatched paren in format"); return -1; - } - else if (*format == '(') { + case '(': + case '[': + case '{': if (level == 0) count++; level++; - } - else if (*format == ')') + break; + case ')': + case ']': + case '}': level--; - else if (level == 0 && *format != '#') - count++; + break; + case '#': + case ',': + case ':': + case ' ': + case '\t': + break; + default: + if (level == 0) + count++; + } format++; } return count; @@ -114,8 +127,85 @@ static int countformat(format, endchar) /* After an original idea and first implementation by Steven Miale */ static object *do_mktuple PROTO((char**, va_list *, int, int)); +static object *do_mklist PROTO((char**, va_list *, int, int)); +static object *do_mkdict PROTO((char**, va_list *, int, int)); static object *do_mkvalue PROTO((char**, va_list *)); + +static object * +do_mkdict(p_format, p_va, endchar, n) + char **p_format; + va_list *p_va; + int endchar; + int n; +{ + object *d; + int i; + if (n < 0) + return NULL; + if ((d = newdictobject()) == NULL) + return NULL; + for (i = 0; i < n; i+= 2) { + object *k, *v; + k = do_mkvalue(p_format, p_va); + if (k == NULL) { + DECREF(d); + return NULL; + } + v = do_mkvalue(p_format, p_va); + if (v == NULL) { + DECREF(k); + DECREF(d); + return NULL; + } + if (dict2insert(d, k, v) < 0) { + DECREF(k); + DECREF(v); + DECREF(d); + return NULL; + } + } + if (d != NULL && **p_format != endchar) { + DECREF(d); + d = NULL; + err_setstr(SystemError, "Unmatched paren in format"); + } + else if (endchar) + ++*p_format; + return d; +} + +static object * +do_mklist(p_format, p_va, endchar, n) + char **p_format; + va_list *p_va; + int endchar; + int n; +{ + object *v; + int i; + if (n < 0) + return NULL; + if ((v = newlistobject(n)) == NULL) + return NULL; + for (i = 0; i < n; i++) { + object *w = do_mkvalue(p_format, p_va); + if (w == NULL) { + DECREF(v); + return NULL; + } + setlistitem(v, i, w); + } + if (v != NULL && **p_format != endchar) { + DECREF(v); + v = NULL; + err_setstr(SystemError, "Unmatched paren in format"); + } + else if (endchar) + ++*p_format; + return v; +} + static object * do_mktuple(p_format, p_va, endchar, n) char **p_format; @@ -152,34 +242,41 @@ do_mkvalue(p_format, p_va) char **p_format; va_list *p_va; { - - switch (*(*p_format)++) { - - case '(': - return do_mktuple(p_format, p_va, ')', - countformat(*p_format, ')')); - - case 'b': - case 'h': - case 'i': - return newintobject((long)va_arg(*p_va, int)); - - case 'l': - return newintobject((long)va_arg(*p_va, long)); - - case 'f': - case 'd': - return newfloatobject((double)va_arg(*p_va, va_double)); - - case 'c': + for (;;) { + switch (*(*p_format)++) { + case '(': + return do_mktuple(p_format, p_va, ')', + countformat(*p_format, ')')); + + case '[': + return do_mklist(p_format, p_va, ']', + countformat(*p_format, ']')); + + case '{': + return do_mkdict(p_format, p_va, '}', + countformat(*p_format, '}')); + + case 'b': + case 'h': + case 'i': + return newintobject((long)va_arg(*p_va, int)); + + case 'l': + return newintobject((long)va_arg(*p_va, long)); + + case 'f': + case 'd': + return newfloatobject((double)va_arg(*p_va, double)); + + case 'c': { char p[1]; p[0] = va_arg(*p_va, int); return newsizedstringobject(p, 1); } - - case 's': - case 'z': + + case 's': + case 'z': { object *v; char *str = va_arg(*p_va, char *); @@ -201,33 +298,44 @@ do_mkvalue(p_format, p_va) } return v; } - - case 'S': - case 'O': + + case 'S': + case 'O': { object *v; v = va_arg(*p_va, object *); if (v != NULL) INCREF(v); else if (!err_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. */ + /* 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. */ err_setstr(SystemError, "NULL object passed to mkvalue"); return v; } - - default: - err_setstr(SystemError, "bad format char passed to mkvalue"); - return NULL; - + + case ':': + case ',': + case ' ': + case '\t': + break; + + default: + err_setstr(SystemError, + "bad format char passed to mkvalue"); + return NULL; + + } } } + #ifdef HAVE_STDARG_PROTOTYPES /* VARARGS 2 */ object *mkvalue(char *format, ...) @@ -257,6 +365,14 @@ vmkvalue(format, va) { char *f = format; int n = countformat(f, '\0'); + va_list lva; + +#ifdef VA_LIST_IS_ARRAY + memcpy(lva, va, sizeof(va_list)); +#else + lva = va; +#endif + if (n < 0) return NULL; if (n == 0) { @@ -264,6 +380,83 @@ vmkvalue(format, va) return None; } if (n == 1) - return do_mkvalue(&f, &va); - return do_mktuple(&f, &va, '\0', n); + return do_mkvalue(&f, &lva); + return do_mktuple(&f, &lva, '\0', n); +} + + +#ifdef HAVE_STDARG_PROTOTYPES +object * +PyEval_CallFunction(object *obj, char *format, ...) +#else +object * +PyEval_CallFunction(obj, format, va_alist) + object *obj; + char *format; + va_dcl +#endif +{ + va_list vargs; + object *args; + object *res; + +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + + args = vmkvalue(format, vargs); + va_end(vargs); + + if (args == NULL) + return NULL; + + res = call_object(obj, args); + DECREF(args); + + return res; +} + + +#ifdef HAVE_STDARG_PROTOTYPES +object * +PyEval_CallMethod(object *obj, char *method, char *format, ...) +#else +object * +PyEval_CallMethod(obj, method, format, va_alist) + object *obj; + char *method; + char *format; + va_dcl +#endif +{ + va_list vargs; + object *meth; + object *args; + object *res; + + meth = getattr(obj, method); + if (meth == NULL) + return NULL; + +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + + args = vmkvalue(format, vargs); + va_end(vargs); + + if (args == NULL) { + DECREF(meth); + return NULL; + } + + res = call_object(meth, args); + DECREF(meth); + DECREF(args); + + return res; } |