Kaydet (Commit) fe3f1a25 authored tarafından Guido van Rossum's avatar Guido van Rossum

* Python/{modsupport.c,getargs.c,Makefile.in},

	Include/modsupport.h: moved getargs() to its own file and
	re-implemented it entirely to support optional arguments, multiple
	arguments without surrounding parentheses
	(when called as newgetargs()), and better error messages
üst 6989e54e
......@@ -34,7 +34,7 @@ OBJS= \
ceval.o cgensupport.o compile.o \
errors.o \
frozenmain.o \
getmtime.o graminit.o \
getargs.o getmtime.o graminit.o \
import.o \
marshal.o modsupport.o mystrtoul.o \
pythonmain.o pythonrun.o \
......
This diff is collapsed.
......@@ -25,7 +25,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Module support implementation */
#include "allobjects.h"
#include "modsupport.h"
#include "import.h"
#ifdef MPW /* MPW pushes 'extended' for float and double types with varargs */
......@@ -111,345 +110,6 @@ static int countformat(format, endchar)
}
/* Generic argument list parser */
static int do_arg PROTO((object *arg, char** p_format, va_list *p_va));
static int
do_arg(arg, p_format, p_va)
object *arg;
char** p_format;
va_list *p_va;
{
char *format = *p_format;
if (arg == NULL)
return 0; /* Incomplete tuple or list */
switch (*format++) {
case '(': /* tuple, distributed over C parameters */ {
int i, n;
if (!is_tupleobject(arg))
return 0;
n = gettuplesize(arg);
for (i = 0; i < n; i++) {
if (!do_arg(gettupleitem(arg, i), &format, p_va))
return 0;
}
if (*format++ != ')')
return 0;
break;
}
case ')': /* End of format -- too many arguments */
return 0;
case 'b': /* byte -- very short int */ {
char *p = va_arg(*p_va, char *);
long ival = getintvalue(arg);
if (ival == -1 && err_occurred())
return 0;
else
*p = ival;
break;
}
case 'h': /* short int */ {
short *p = va_arg(*p_va, short *);
long ival = getintvalue(arg);
if (ival == -1 && err_occurred())
return 0;
else
*p = ival;
break;
}
case 'i': /* int */ {
int *p = va_arg(*p_va, int *);
long ival = getintvalue(arg);
if (ival == -1 && err_occurred())
return 0;
else
*p = ival;
break;
}
case 'l': /* long int */ {
long *p = va_arg(*p_va, long *);
long ival = getintvalue(arg);
if (ival == -1 && err_occurred())
return 0;
else
*p = ival;
break;
}
case 'f': /* float */ {
float *p = va_arg(*p_va, float *);
double dval = getfloatvalue(arg);
if (err_occurred())
return 0;
else
*p = dval;
break;
}
case 'd': /* double */ {
double *p = va_arg(*p_va, double *);
double dval = getfloatvalue(arg);
if (err_occurred())
return 0;
else
*p = dval;
break;
}
case 'c': /* char */ {
char *p = va_arg(*p_va, char *);
if (is_stringobject(arg) && getstringsize(arg) == 1)
*p = getstringvalue(arg)[0];
else
return 0;
break;
}
case 's': /* string */ {
char **p = va_arg(*p_va, char **);
if (is_stringobject(arg))
*p = getstringvalue(arg);
else
return 0;
if (*format == '#') {
int *q = va_arg(*p_va, int *);
*q = getstringsize(arg);
format++;
}
else if (strlen(*p) != getstringsize(arg)) {
err_setstr(ValueError, "embedded '\\0' in string arg");
return 0;
}
break;
}
case 'z': /* string, may be NULL (None) */ {
char **p = va_arg(*p_va, char **);
if (arg == None)
*p = 0;
else if (is_stringobject(arg))
*p = getstringvalue(arg);
else
return 0;
if (*format == '#') {
int *q = va_arg(*p_va, int *);
if (arg == None)
*q = 0;
else
*q = getstringsize(arg);
format++;
}
else if (*p != NULL && strlen(*p) != getstringsize(arg)) {
err_setstr(ValueError, "embedded '\\0' in string arg");
return 0;
}
break;
}
case 'S': /* string object */ {
object **p = va_arg(*p_va, object **);
if (is_stringobject(arg))
*p = arg;
else
return 0;
break;
}
case 'O': /* object */ {
typeobject *type;
object **p;
if (*format == '!') {
format++;
type = va_arg(*p_va, typeobject*);
if (arg->ob_type != type)
return 0;
else {
p = va_arg(*p_va, object **);
*p = arg;
}
}
else if (*format == '?') {
inquiry pred = va_arg(*p_va, inquiry);
format++;
if ((*pred)(arg)) {
p = va_arg(*p_va, object **);
*p = arg;
}
}
else if (*format == '&') {
binaryfunc convert = va_arg(*p_va, binaryfunc);
void *addr = va_arg(*p_va, void *);
format++;
if (! (*convert)(arg, addr))
return 0;
}
else {
p = va_arg(*p_va, object **);
*p = arg;
}
break;
}
default:
fprintf(stderr, "bad do_arg format: x%x '%c'\n",
format[-1], format[-1]);
return 0;
}
*p_format = format;
return 1;
}
#ifdef HAVE_STDARG_PROTOTYPES
/* VARARGS2 */
int getargs(object *arg, char *format, ...)
#else
/* VARARGS */
int getargs(va_alist) va_dcl
#endif
{
char *f;
int ok;
va_list va;
#ifdef HAVE_STDARG_PROTOTYPES
va_start(va, format);
#else
object *arg;
char *format;
va_start(va);
arg = va_arg(va, object *);
format = va_arg(va, char *);
#endif
if (*format == '\0' || *format == ';') {
va_end(va);
if (arg != NULL) {
char *str = "no arguments needed";
if (*format == ';')
str = format+1;
err_setstr(TypeError, str);
return 0;
}
return 1;
}
f = format;
ok = do_arg(arg, &f, &va) && (*f == '\0' || *f == ';');
va_end(va);
if (!ok) {
if (!err_occurred()) {
char buf[256];
char *str;
f = strchr(format, ';');
if (f != NULL)
str = f+1;
else {
sprintf(buf, "bad argument list (format '%s')",
format);
str = buf;
}
err_setstr(TypeError, str);
}
}
return ok;
}
#ifdef UNUSED
int
getlongtuplearg(args, a, n)
object *args;
long *a; /* [n] */
int n;
{
int i;
if (!is_tupleobject(args) || gettuplesize(args) != n) {
return err_badarg();
}
for (i = 0; i < n; i++) {
object *v = gettupleitem(args, i);
if (!is_intobject(v)) {
return err_badarg();
}
a[i] = getintvalue(v);
}
return 1;
}
int
getshorttuplearg(args, a, n)
object *args;
short *a; /* [n] */
int n;
{
int i;
if (!is_tupleobject(args) || gettuplesize(args) != n) {
return err_badarg();
}
for (i = 0; i < n; i++) {
object *v = gettupleitem(args, i);
if (!is_intobject(v)) {
return err_badarg();
}
a[i] = getintvalue(v);
}
return 1;
}
int
getlonglistarg(args, a, n)
object *args;
long *a; /* [n] */
int n;
{
int i;
if (!is_listobject(args) || getlistsize(args) != n) {
return err_badarg();
}
for (i = 0; i < n; i++) {
object *v = getlistitem(args, i);
if (!is_intobject(v)) {
return err_badarg();
}
a[i] = getintvalue(v);
}
return 1;
}
int
getshortlistarg(args, a, n)
object *args;
short *a; /* [n] */
int n;
{
int i;
if (!is_listobject(args) || getlistsize(args) != n) {
return err_badarg();
}
for (i = 0; i < n; i++) {
object *v = getlistitem(args, i);
if (!is_intobject(v)) {
return err_badarg();
}
a[i] = getintvalue(v);
}
return 1;
}
#endif /* UNUSED */
/* Generic function to create a value -- the inverse of getargs() */
/* After an original idea and first implementation by Steven Miale */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment