summaryrefslogtreecommitdiffstats
path: root/Modules/_decimal
diff options
context:
space:
mode:
authorStefan Krah <skrah@bytereef.org>2012-06-06 13:57:18 (GMT)
committerStefan Krah <skrah@bytereef.org>2012-06-06 13:57:18 (GMT)
commita3394bce336372848921690dbac5e504d369f174 (patch)
tree4a2a67e02c205e09c51fb0b4ba6b9f8929b4da52 /Modules/_decimal
parenta01f1adb87c71d9fbd07334f00bd94e106b9ad43 (diff)
downloadcpython-a3394bce336372848921690dbac5e504d369f174.zip
cpython-a3394bce336372848921690dbac5e504d369f174.tar.gz
cpython-a3394bce336372848921690dbac5e504d369f174.tar.bz2
1) Add error analysis comments to mpd_qln10() and _mpd_qln().
2) Simplify the precision adjustment code for values in [0.900, 1.15].
Diffstat (limited to 'Modules/_decimal')
-rw-r--r--Modules/_decimal/libmpdec/mpdecimal.c127
1 files changed, 96 insertions, 31 deletions
diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c
index 66a4f1f..346e5ee 100644
--- a/Modules/_decimal/libmpdec/mpdecimal.c
+++ b/Modules/_decimal/libmpdec/mpdecimal.c
@@ -4212,6 +4212,18 @@ mpd_qfma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c,
*status |= workstatus;
}
+/*
+ * Schedule the optimal precision increase for the Newton iteration.
+ * v := input operand
+ * z_0 := initial approximation
+ * initprec := natural number such that abs(log(v) - z_0) < 10**-initprec
+ * maxprec := target precision
+ *
+ * For convenience the output klist contains the elements in reverse order:
+ * klist := [k_n-1, ..., k_0], where
+ * 1) k_0 <= initprec and
+ * 2) abs(log(v) - result) < 10**(-2*k_n-1 + 1) <= 10**-maxprec.
+ */
static inline int
ln_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2], mpd_ssize_t maxprec,
mpd_ssize_t initprec)
@@ -4231,6 +4243,7 @@ ln_schedule_prec(mpd_ssize_t klist[MPD_MAX_PREC_LOG2], mpd_ssize_t maxprec,
return i-1;
}
+/* The constants have been verified with both decimal.py and mpfr. */
#ifdef CONFIG_64
#if MPD_RDIGITS != 19
#error "mpdecimal.c: MPD_RDIGITS must be 19."
@@ -4285,7 +4298,7 @@ static const mpd_t _mpd_ln10 = {
(mpd_uint_t *)mpd_ln10_data
};
-/* Set 'result' to ln(10), with 'prec' digits, using ROUND_HALF_EVEN. */
+/* Set 'result' to ln(10). ulp error: abs(result - log(10)) < ulp(log(10)) */
void
mpd_qln10(mpd_t *result, mpd_ssize_t prec, uint32_t *status)
{
@@ -4320,7 +4333,7 @@ mpd_qln10(mpd_t *result, mpd_ssize_t prec, uint32_t *status)
mpd_maxcontext(&varcontext);
varcontext.round = MPD_ROUND_TRUNC;
- i = ln_schedule_prec(klist, prec+2, result->digits);
+ i = ln_schedule_prec(klist, prec+2, -result->exp);
for (; i >= 0; i--) {
varcontext.prec = 2*klist[i]+3;
result->flags ^= MPD_NEG;
@@ -4339,7 +4352,18 @@ mpd_qln10(mpd_t *result, mpd_ssize_t prec, uint32_t *status)
mpd_qfinalize(result, &maxcontext, status);
}
-/* Initial approximations for the ln() iteration */
+/*
+ * Initial approximations for the ln() iteration. The values have the
+ * following properties (established with both decimal.py and mpfr):
+ *
+ * Index 0 - 400, logarithms of x in [1.00, 5.00]:
+ * abs(lnapprox[i] * 10**-3 - log((i+100)/100)) < 10**-2
+ * abs(lnapprox[i] * 10**-3 - log((i+1+100)/100)) < 10**-2
+ *
+ * Index 401 - 899, logarithms of x in (0.500, 0.999]:
+ * abs(-lnapprox[i] * 10**-3 - log((i+100)/1000)) < 10**-2
+ * abs(-lnapprox[i] * 10**-3 - log((i+1+100)/1000)) < 10**-2
+ */
static const uint16_t lnapprox[900] = {
/* index 0 - 400: log((i+100)/100) * 1000 */
0, 10, 20, 30, 39, 49, 58, 68, 77, 86, 95, 104, 113, 122, 131, 140, 148, 157,
@@ -4406,7 +4430,10 @@ static const uint16_t lnapprox[900] = {
18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
};
-/* Internal ln() function that does not check for specials, zero or one. */
+/*
+ * Internal ln() function that does not check for specials, zero or one.
+ * Relative error: abs(result - log(a)) < 0.1 * 10**-prec * abs(log(a))
+ */
static void
_mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
uint32_t *status)
@@ -4451,10 +4478,16 @@ _mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
mpd_setdigits(z);
if (x <= 400) {
+ /* Reduce the input operand to 1.00 <= v <= 5.00. Let y = x + 100,
+ * so 100 <= y <= 500. Since y contains the most significant digits
+ * of v, y/100 <= v < (y+1)/100 and abs(z - log(v)) < 10**-2. */
v.exp = -(a_digits - 1);
t = a_exp + a_digits - 1;
}
else {
+ /* Reduce the input operand to 0.500 < v <= 0.999. Let y = x + 100,
+ * so 500 < y <= 999. Since y contains the most significant digits
+ * of v, y/1000 <= v < (y+1)/1000 and abs(z - log(v)) < 10**-2. */
v.exp = -a_digits;
t = a_exp + a_digits;
mpd_set_negative(z);
@@ -4465,37 +4498,46 @@ _mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
varcontext.round = MPD_ROUND_TRUNC;
maxprec = ctx->prec + 2;
- if (x <= 10 || x >= 805) {
- /* v is close to 1: Estimate the magnitude of the logarithm.
- * If v = 1 or ln(v) will underflow, skip the loop. Otherwise,
- * adjust the precision upwards in order to obtain a sufficient
- * number of significant digits.
- *
- * 1) x/(1+x) < ln(1+x) < x, for x > -1, x != 0
+ if (t == 0 && (x <= 15 || x >= 800)) {
+ /* 0.900 <= v <= 1.15: Estimate the magnitude of the logarithm.
+ * If ln(v) will underflow, skip the loop. Otherwise, adjust the
+ * precision upwards in order to obtain a sufficient number of
+ * significant digits.
*
- * 2) (v-1)/v < ln(v) < v-1
+ * Case v > 1:
+ * abs((v-1)/10) < abs((v-1)/v) < abs(ln(v)) < abs(v-1)
+ * Case v < 1:
+ * abs(v-1) < abs(ln(v)) < abs((v-1)/v) < abs((v-1)*10)
*/
- mpd_t *lower = &tmp;
- mpd_t *upper = &vtmp;
int cmp = _mpd_cmp(&v, &one);
- varcontext.round = MPD_ROUND_CEILING;
- varcontext.prec = maxprec;
- mpd_qsub(upper, &v, &one, &varcontext, &varcontext.status);
- varcontext.round = MPD_ROUND_FLOOR;
- mpd_qdiv(lower, upper, &v, &varcontext, &varcontext.status);
- varcontext.round = MPD_ROUND_TRUNC;
+ /* Upper bound (assume v > 1): abs(v-1), unrounded */
+ _mpd_qsub(&tmp, &v, &one, &maxcontext, &maxcontext.status);
+ if (maxcontext.status & MPD_Errors) {
+ mpd_seterror(result, MPD_Malloc_error, status);
+ goto finish;
+ }
if (cmp < 0) {
- _mpd_ptrswap(&upper, &lower);
+ /* v < 1: abs((v-1)*10) */
+ tmp.exp += 1;
}
- if (mpd_adjexp(upper) < mpd_etiny(ctx)) {
- _settriple(z, (cmp<0), 1, mpd_etiny(ctx)-1);
- goto postloop;
+ if (mpd_adjexp(&tmp) < mpd_etiny(ctx)) {
+ /* The upper bound is less than etiny: Underflow to zero */
+ _settriple(result, (cmp<0), 1, mpd_etiny(ctx)-1);
+ goto finish;
}
- /* XXX optimization: t == 0 && mpd_adjexp(lower) < 0 */
- if (mpd_adjexp(lower) < 0) {
- maxprec = maxprec - mpd_adjexp(lower);
+ /* Lower bound: abs((v-1)/10) or abs(v-1) */
+ tmp.exp -= 1;
+ if (mpd_adjexp(&tmp) < 0) {
+ /* Absolute error of the loop: abs(z - log(v)) < 10**-p. If
+ * p = ctx->prec+2-adjexp(lower), then the relative error of
+ * the result is (using 10**adjexp(x) <= abs(x)):
+ *
+ * abs(z - log(v)) / abs(log(v)) < 10**-p / abs(log(v))
+ * <= 10**(-ctx->prec-2)
+ */
+ maxprec = maxprec - mpd_adjexp(&tmp);
}
}
@@ -4523,14 +4565,37 @@ _mpd_qln(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
}
}
-postloop:
- mpd_qln10(&v, maxprec+2, status);
+ /*
+ * Case t == 0:
+ * t * log(10) == 0, the result does not change and the analysis
+ * above applies. If v < 0.900 or v > 1.15, the relative error is
+ * less than 10**(-ctx.prec-1).
+ * Case t != 0:
+ * z := approx(log(v))
+ * y := approx(log(10))
+ * p := maxprec = ctx->prec + 2
+ * Absolute errors:
+ * 1) abs(z - log(v)) < 10**-p
+ * 2) abs(y - log(10)) < 10**-p
+ * The multiplication is exact, so:
+ * 3) abs(t*y - t*log(10)) < t*10**-p
+ * The sum is exact, so:
+ * 4) abs((z + t*y) - (log(v) + t*log(10))) < (abs(t) + 1) * 10**-p
+ * Bounds for log(v) and log(10):
+ * 5) -7/10 < log(v) < 17/10
+ * 6) 23/10 < log(10) < 24/10
+ * Using 4), 5), 6) and t != 0, the relative error is:
+ *
+ * 7) relerr < ((abs(t) + 1)*10**-p) / abs(log(v) + t*log(10))
+ * < 0.5 * 10**(-p + 1) = 0.5 * 10**(-ctx->prec-1)
+ */
+ mpd_qln10(&v, maxprec+1, status);
mpd_qmul_ssize(&tmp, &v, t, &maxcontext, status);
- varcontext.prec = maxprec+2;
- mpd_qadd(result, &tmp, z, &varcontext, status);
+ mpd_qadd(result, &tmp, z, &maxcontext, status);
finish:
+ *status |= (MPD_Inexact|MPD_Rounded);
mpd_del(&v);
mpd_del(&vtmp);
mpd_del(&tmp);
ass='ctx'> extern int getilongarg PROTO((object *args, int nargs, int i, long *p_a));
diff --git a/Include/listobject.h b/Include/listobject.h
index 519776a..f18877f 100644
--- a/Include/listobject.h
+++ b/Include/listobject.h
@@ -53,6 +53,8 @@ extern object *getlistitem PROTO((object *, int));
extern int setlistitem PROTO((object *, int, object *));
extern int inslistitem PROTO((object *, int, object *));
extern int addlistitem PROTO((object *, object *));
+extern object *getlistslice PROTO((object *, int, int));
+extern int setlistslice PROTO((object *, int, int, object *));
extern int sortlist PROTO((object *));
/* Macro, trading safety for speed */
diff --git a/Include/modsupport.h b/Include/modsupport.h
index bb809c7..5c1bdf5 100644
--- a/Include/modsupport.h
+++ b/Include/modsupport.h
@@ -40,29 +40,8 @@ extern int vgetargs PROTO((object *, char *, va_list));
extern object *mkvalue PROTO((char *, ...));
extern object *vmkvalue PROTO((char *, va_list));
+/* The following are obsolete -- use getargs directly! */
#define getnoarg(v) getargs(v, "")
#define getintarg(v, a) getargs(v, "i", a)
-#define getintintarg(v, a, b) getargs(v, "(ii)", a, b)
-#define getintintintarg(v, a, b, c) getargs(v, "(iii)", a, b, c)
#define getlongarg(v, a) getargs(v, "l", a)
-#define getlonglongarg(v, a, b) getargs(v, "(ll)", a, b)
-#define getlonglongobjectarg(v, a, b, c) getargs(v, "(llO)", a, b, c)
-#define getStrarg(v, a) getargs(v, "S", a)
#define getstrarg(v, a) getargs(v, "s", a)
-#define getstrstrarg(v, a, b) getargs(v, "(ss)", a, b)
-#define getStrStrarg(v, a, b) getargs(v, "(SS)", a, b)
-#define getstrstrintarg(v, a, b, c) getargs(v, "(ssi)", a, b, c)
-#define getStrintarg(v, a, b) getargs(v, "(Si)", a, b)
-#define getstrintarg(v, a, b) getargs(v, "(si)", a, b)
-#define getintstrarg(v, a, b) getargs(v, "(is)", a, b)
-#define getpointarg(v, a) getargs(v, "(ii)", a, (a)+1)
-#define get3pointarg(v, a) getargs(v, "((ii)(ii)(ii))", \
- a, a+1, a+2, a+3, a+4, a+5)
-#define getrectarg(v, a) getargs(v, "((ii)(ii))", a, a+1, a+2, a+3)
-#define getrectintarg(v, a) getargs(v, "(((ii)(ii))i)", a, a+1, a+2, a+3, a+4)
-#define getpointintarg(v, a) getargs(v, "((ii)i)", a, a+1, a+2)
-#define getpointstrarg(v, a, b) getargs(v, "((ii)s)", a, a+1, b)
-#define getrectpointarg(v, a) getargs(v, "(((ii)(ii))(ii))", \
- a, a+1, a+2, a+3, a+4, a+5)
-#define getdoublearg(v, a) getargs(v, "d", a)
-#define get2doublearg(v, a, b) getargs(v, "(dd)", a, b)
diff --git a/Include/pythonrun.h b/Include/pythonrun.h
index 6c6117b..c3c3aca 100644
--- a/Include/pythonrun.h
+++ b/Include/pythonrun.h
@@ -28,6 +28,7 @@ void initall PROTO((void));
int run PROTO((FILE *, char *));
+int run_command PROTO((char *));
int run_script PROTO((FILE *, char *));
int run_tty_1 PROTO((FILE *, char *));
int run_tty_loop PROTO((FILE *, char *));
diff --git a/Modules/almodule.c b/Modules/almodule.c
index d986d34..26bf38f 100644
--- a/Modules/almodule.c
+++ b/Modules/almodule.c
@@ -568,7 +568,7 @@ al_openport (self, args)
}
size = gettuplesize(args);
if (size == 2) {
- if (!getstrstrarg (args, &name, &dir))
+ if (!getargs (args, "(ss)", &name, &dir))
return NULL;
}
else if (size == 3) {
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index e5bf46a..b5a2cfa 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -209,7 +209,7 @@ d_setitem(ap, i, v)
}
/* Description of types */
-struct arraydescr descriptors[] = {
+static struct arraydescr descriptors[] = {
{'c', sizeof(char), c_getitem, c_setitem},
{'b', sizeof(char), b_getitem, b_setitem},
{'h', sizeof(short), h_getitem, h_setitem},
diff --git a/Modules/cdmodule.c b/Modules/cdmodule.c
index 27cf35c..b5d0def 100644
--- a/Modules/cdmodule.c
+++ b/Modules/cdmodule.c
@@ -725,12 +725,12 @@ CD_addcallback(self, args)
object *args;
{
int type;
- object *funcobject, *funcargobject;
+ object *func, *funcarg;
CheckParser(self);
/* XXX - more work here */
- if (!getargs(args, "(iOO)", &type, &funcobject, &funcargobject))
+ if (!getargs(args, "(iOO)", &type, &func, &funcarg))
return NULL;
if (type < 0 || type >= NCALLBACKS) {
@@ -744,11 +744,11 @@ CD_addcallback(self, args)
CDsetcallback(self->ob_cdparser, (CDDATATYPES) type, CD_callback, (void *) self);
#endif
XDECREF(self->ob_cdcallbacks[type].ob_cdcallback);
- INCREF(funcobject);
- self->ob_cdcallbacks[type].ob_cdcallback = funcobject;
+ INCREF(func);
+ self->ob_cdcallbacks[type].ob_cdcallback = func;
XDECREF(self->ob_cdcallbacks[type].ob_cdcallbackarg);
- INCREF(funcargobject);
- self->ob_cdcallbacks[type].ob_cdcallbackarg = funcargobject;
+ INCREF(funcarg);
+ self->ob_cdcallbacks[type].ob_cdcallbackarg = funcarg;
INCREF(None);
return None;
diff --git a/Modules/cgensupport.c b/Modules/cgensupport.c
index 5dcac86..87fcfab 100644
--- a/Modules/cgensupport.c
+++ b/Modules/cgensupport.c
@@ -28,17 +28,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "cgensupport.h"
-/* Functions to construct return values */
-
-object *
-mknewcharobject(c)
- int c;
-{
- char ch[1];
- ch[0] = c;
- return newsizedstringobject(ch, 1);
-}
-
/* Functions to extract arguments.
These needs to know the total number of arguments supplied,
since the argument list is a tuple only of there is more than
diff --git a/Modules/cgensupport.h b/Modules/cgensupport.h
index 5c2cbd4..43818bc 100644
--- a/Modules/cgensupport.h
+++ b/Modules/cgensupport.h
@@ -29,8 +29,7 @@ typedef char *string;
#define mknewlongobject(x) newintobject(x)
#define mknewshortobject(x) newintobject((long)x)
#define mknewfloatobject(x) newfloatobject(x)
-
-extern object *mknewcharobject PROTO((int c));
+#define mknewcharobject(c) mkvalue("c", c)
extern int getiobjectarg PROTO((object *args, int nargs, int i, object **p_a));
extern int getilongarg PROTO((object *args, int nargs, int i, long *p_a));
diff --git a/Modules/flmodule.c b/Modules/flmodule.c
index 3d424d1..0cc08da 100644
--- a/Modules/flmodule.c
+++ b/Modules/flmodule.c
@@ -528,7 +528,7 @@ call_forms_INiINstr (func, obj, args)
char *b;
int a;
- if (!getintstrarg(args, &a, &b)) return NULL;
+ if (!getargs(args, "(is)", &a, &b)) return NULL;
(*func) (obj, a, b);
@@ -546,7 +546,7 @@ call_forms_INiINi (func, obj, args)
{
int par1, par2;
- if (!getintintarg(args, &par1, &par2)) return NULL;
+ if (!getargs(args, "(ii)", &par1, &par2)) return NULL;
(*func) (obj, par1, par2);
@@ -1048,7 +1048,7 @@ get_default(g, args)
c = fl_get_default (g->ob_generic);
- return ((object *) mknewcharobject (c)); /* in cgensupport.c */
+ return mkvalue("c", c);
}
static struct methodlist default_methods[] = {
@@ -1479,7 +1479,7 @@ form_call_INiINi(func, f, args)
{
int a, b;
- if (!getintintarg(args, &a, &b)) return NULL;
+ if (!getargs(args, "(ii)", &a, &b)) return NULL;
(*func)(f, a, b);
@@ -2144,7 +2144,7 @@ forms_set_graphics_mode(dummy, args)
{
int rgbmode, doublebuf;
- if (!getintintarg(args, &rgbmode, &doublebuf))
+ if (!getargs(args, "(ii)", &rgbmode, &doublebuf))
return NULL;
fl_set_graphics_mode(rgbmode,doublebuf);
INCREF(None);
@@ -2441,7 +2441,7 @@ forms_show_input(f, args)
char *str;
char *a, *b;
- if (!getstrstrarg(args, &a, &b)) return NULL;
+ if (!getargs(args, "(ss)", &a, &b)) return NULL;
BGN_SAVE
str = fl_show_input(a, b);
diff --git a/Modules/fmmodule.c b/Modules/fmmodule.c
index 8d54d97..aa49be3 100644
--- a/Modules/fmmodule.c
+++ b/Modules/fmmodule.c
@@ -68,7 +68,7 @@ fh_scalefont(self, args)
object *args;
{
double size;
- if (!getdoublearg(args, &size))
+ if (!getargs(args, "d", &size))
return NULL;
return newfhobject(fmscalefont(self->fh_fh, size));
}
diff --git a/Modules/imgfile.c b/Modules/imgfile.c
index a6db026..93f5ef3 100644
--- a/Modules/imgfile.c
+++ b/Modules/imgfile.c
@@ -162,9 +162,9 @@ imgfile_read(self, args)
return rv;
}
-IMAGE *glob_image;
-long *glob_datap;
-int glob_width, glob_z;
+static IMAGE *glob_image;
+static long *glob_datap;
+static int glob_width, glob_z;
static
xs_get(buf, y)
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index 979155e..8b1bccf 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -33,6 +33,9 @@ extern int errno;
#include "modsupport.h"
+#define getdoublearg(v, a) getargs(v, "d", a)
+#define get2doublearg(v, a, b) getargs(v, "(dd)", a, b)
+
#include <math.h>
#ifdef i860
diff --git a/Modules/nismodule.c b/Modules/nismodule.c
index eb97dee..9234127 100644
--- a/Modules/nismodule.c
+++ b/Modules/nismodule.c
@@ -87,7 +87,7 @@ nis_match (self, args)
int err;
object *res;
- if (!getstrstrarg(args, &key, &map))
+ if (!getargs(args, "(ss)", &key, &map))
return NULL;
if ((err = yp_get_default_domain(&domain)) != 0)
return nis_error(err);
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 2e800de..88861c6 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -166,7 +166,7 @@ posix_2str(args, func)
{
char *path1, *path2;
int res;
- if (!getstrstrarg(args, &path1, &path2))
+ if (!getargs(args, "(ss)", &path1, &path2))
return NULL;
BGN_SAVE
res = (*func)(path1, path2);
@@ -185,7 +185,7 @@ posix_strint(args, func)
char *path;
int i;
int res;
- if (!getstrintarg(args, &path, &i))
+ if (!getargs(args, "(si)", &path, &i))
return NULL;
BGN_SAVE
res = (*func)(path, i);
@@ -691,7 +691,7 @@ posix_kill(self, args)
object *args;
{
int pid, sig;
- if (!getintintarg(args, &pid, &sig))
+ if (!getargs(args, "(ii)", &pid, &sig))
return NULL;
if (kill(pid, sig) == -1)
return posix_error();
@@ -891,7 +891,7 @@ posix_tcsetpgrp(self, args)
/* Functions acting on file descriptors */
-object *
+static object *
posix_open(self, args)
object *self;
object *args;
@@ -913,7 +913,7 @@ posix_open(self, args)
return newintobject((long)fd);
}
-object *
+static object *
posix_close(self, args)
object *self;
object *args;
@@ -930,7 +930,7 @@ posix_close(self, args)
return None;
}
-object *
+static object *
posix_dup(self, args)
object *self;
object *args;
@@ -946,7 +946,7 @@ posix_dup(self, args)
return newintobject((long)fd);
}
-object *
+static object *
posix_dup2(self, args)
object *self;
object *args;
@@ -963,7 +963,7 @@ posix_dup2(self, args)
return None;
}
-object *
+static object *
posix_lseek(self, args)
object *self;
object *args;
@@ -988,7 +988,7 @@ posix_lseek(self, args)
return newintobject(res);
}
-object *
+static object *
posix_read(self, args)
object *self;
object *args;
@@ -1011,7 +1011,7 @@ posix_read(self, args)
return buffer;
}
-object *
+static object *
posix_write(self, args)
object *self;
object *args;
@@ -1028,7 +1028,7 @@ posix_write(self, args)
return newintobject((long)size);
}
-object *
+static object *
posix_fstat(self, args)
object *self;
object *args;
@@ -1079,7 +1079,7 @@ posix_fdopen(self, args)
}
#ifndef MSDOS
-object *
+static object *
posix_pipe(self, args)
object *self;
object *args;
diff --git a/Modules/rotormodule.c b/Modules/rotormodule.c
index 4e9afd8..71bac90 100644
--- a/Modules/rotormodule.c
+++ b/Modules/rotormodule.c
@@ -763,8 +763,10 @@ static typeobject Rotortype = {
};
-object *rotor_rotor(self, args)
-object *args;
+static object *
+rotor_rotor(self, args)
+ object *self;
+ object *args;
{
char *string;
rotorobject *r;
diff --git a/Modules/sgimodule.c b/Modules/sgimodule.c
index b373384..418609d 100644
--- a/Modules/sgimodule.c
+++ b/Modules/sgimodule.c
@@ -57,4 +57,4 @@ initsgi()
initmodule("sgi", sgi_methods);
}
-int dummy; /* $%#@!& dl wants at least a byte of bss */
+static int dummy; /* $%#@!& dl wants at least a byte of bss */
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 160c292..dfdf97b 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -744,9 +744,9 @@ sock_send(s, args)
char *buf;
int len, n, flags;
flags = 0;
- if (!getargs(args, "(s#)", &buf, &len)) {
+ if (!getargs(args, "s#", &buf, &len)) {
err_clear();
- if (!getargs(args, "s#", &buf, &len, &flags))
+ if (!getargs(args, "(s#i)", &buf, &len, &flags))
return NULL;
}
BGN_SAVE
diff --git a/Modules/stdwinmodule.c b/Modules/stdwinmodule.c
index 02f7bcb..6e666a6 100644
--- a/Modules/stdwinmodule.c
+++ b/Modules/stdwinmodule.c
@@ -91,6 +91,15 @@ static type_lock StdwinLock; /* Lock held when interpreter not locked */
#endif
+#define getpointarg(v, a) getargs(v, "(ii)", a, (a)+1)
+#define get3pointarg(v, a) getargs(v, "((ii)(ii)(ii))", \
+ a, a+1, a+2, a+3, a+4, a+5)
+#define getrectarg(v, a) getargs(v, "((ii)(ii))", a, a+1, a+2, a+3)
+#define getrectintarg(v, a) getargs(v, "(((ii)(ii))i)", a, a+1, a+2, a+3, a+4)
+#define getpointintarg(v, a) getargs(v, "((ii)i)", a, a+1, a+2)
+#define getrectpointarg(v, a) getargs(v, "(((ii)(ii))(ii))", \
+ a, a+1, a+2, a+3, a+4, a+5)
+
static object *StdwinError; /* Exception stdwin.error */
/* Window and menu object types declared here because of forward references */
@@ -1236,7 +1245,7 @@ menu_setitem(self, args)
{
int index;
char *text;
- if (!getintstrarg(args, &index, &text))
+ if (!getargs(args, "(is)", &index, &text))
return NULL;
wmenusetitem(self->m_menu, index, text);
INCREF(None);
@@ -1250,7 +1259,7 @@ menu_enable(self, args)
{
int index;
int flag;
- if (!getintintarg(args, &index, &flag))
+ if (!getargs(args, "(ii)", &index, &flag))
return NULL;
wmenuenable(self->m_menu, index, flag);
INCREF(None);
@@ -1264,7 +1273,7 @@ menu_check(self, args)
{
int index;
int flag;
- if (!getintintarg(args, &index, &flag))
+ if (!getargs(args, "(ii)", &index, &flag))
return NULL;
wmenucheck(self->m_menu, index, flag);
INCREF(None);
@@ -1705,7 +1714,7 @@ window_settitle(wp, args)
object *args;
{
object *title;
- if (!getStrarg(args, &title))
+ if (!getargs(args, "S", &title))
return NULL;
DECREF(wp->w_title);
INCREF(title);
@@ -1930,7 +1939,7 @@ stdwin_open(sw, args)
int tag;
object *title;
windowobject *wp;
- if (!getStrarg(args, &title))
+ if (!getargs(args, "S", &title))
return NULL;
for (tag = 0; tag < MAXNWIN; tag++) {
if (windowlist[tag] == NULL)
@@ -2180,7 +2189,7 @@ stdwin_askfile(self, args)
char *prompt, *dflt;
int new, ret;
char buf[256];
- if (!getstrstrintarg(args, &prompt, &dflt, &new))
+ if (!getargs(args, "(ssi)", &prompt, &dflt, &new))
return NULL;
strncpy(buf, dflt, sizeof buf);
buf[sizeof buf - 1] = '\0';
@@ -2201,7 +2210,7 @@ stdwin_askync(self, args)
{
char *prompt;
int new, ret;
- if (!getstrintarg(args, &prompt, &new))
+ if (!getargs(args, "(si)", &prompt, &new))
return NULL;
BGN_STDWIN
ret = waskync(prompt, new);
@@ -2221,7 +2230,7 @@ stdwin_askstr(self, args)
char *prompt, *dflt;
int ret;
char buf[256];
- if (!getstrstrarg(args, &prompt, &dflt))
+ if (!getargs(args, "(ss)", &prompt, &dflt))
return NULL;
strncpy(buf, dflt, sizeof buf);
buf[sizeof buf - 1] = '\0';
diff --git a/Modules/sunaudiodev.c b/Modules/sunaudiodev.c
index b4470dd..4e63123 100644
--- a/Modules/sunaudiodev.c
+++ b/Modules/sunaudiodev.c
@@ -28,6 +28,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "modsupport.h"
#include "structmember.h"
+#include <stropts.h>
#include <sys/ioctl.h>
#include <sun/audioio.h>
@@ -255,6 +256,38 @@ sad_drain(self, args)
return None;
}
+static object *
+sad_flush(self, args)
+ sadobject *self;
+ object *args;
+{
+
+ if ( !getargs(args, "") )
+ return 0;
+ if ( ioctl(self->x_fd, I_FLUSH, FLUSHW) < 0 ) {
+ err_errno(SunAudioError);
+ return NULL;
+ }
+ INCREF(None);
+ return None;
+}
+
+static object *
+sad_close(self, args)
+ sadobject *self;
+ object *args;
+{
+
+ if ( !getargs(args, "") )
+ return 0;
+ if ( self->x_fd >= 0 ) {
+ close(self->x_fd);
+ self->x_fd = -1;
+ }
+ INCREF(None);
+ return None;
+}
+
static struct methodlist sad_methods[] = {
{ "read", sad_read },
{ "write", sad_write },
@@ -264,6 +297,8 @@ static struct methodlist sad_methods[] = {
{ "getinfo", sad_getinfo },
{ "setinfo", sad_setinfo },
{ "drain", sad_drain },
+ { "flush", sad_flush },
+ { "close", sad_close },
{NULL, NULL} /* sentinel */
};
diff --git a/Modules/threadmodule.c b/Modules/threadmodule.c
index 7a5f29d..f22aa8c 100644
--- a/Modules/threadmodule.c
+++ b/Modules/threadmodule.c
@@ -33,7 +33,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
int threads_started = 0;
-object *ThreadError;
+static object *ThreadError;
/* Lock objects */
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index b8b22e3..3df0885 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -78,6 +78,26 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <errno.h>
#endif
+#ifdef SYSV
+/* Access timezone stuff */
+#ifdef OLDTZ /* ANSI prepends underscore to these */
+#define _timezone timezone /* seconds to be added to GMT */
+#define _altzone 0 /* _timezone if daylight saving time */
+#define _daylight 0 /* if zero, _altzone is not available*/
+#define _tzname tzname /* Name of timezone and altzone */
+#endif
+#ifdef NOALTTZ /* if system doesn't support alt tz */
+#undef _daylight
+#undef _altzone
+#define _daylight 0
+#define _altzone 0
+#endif
+#endif /* SYSV */
+
+/* Forward declarations */
+static void floatsleep PROTO((double));
+static long millitimer PROTO((void));
+
/* Time methods */
static object *
@@ -199,7 +219,6 @@ time_millitimer(self, args)
object *args;
{
long msecs;
- extern long millitimer();
if (!getnoarg(args))
return NULL;
msecs = millitimer();
@@ -225,7 +244,7 @@ time_times(self, args)
err_errno(IOError);
return NULL;
}
- return mkvalue("dddd",
+ return mkvalue("(dddd)",
(double)t.tms_utime / HZ,
(double)t.tms_stime / HZ,
(double)t.tms_cutime / HZ,
@@ -235,6 +254,71 @@ time_times(self, args)
#endif
+static object *
+time_convert(when, function)
+ time_t when;
+ struct tm * (*function) PROTO((time_t *));
+{
+ struct tm *p = function(&when);
+ return mkvalue("(iiiiiiiii)",
+ p->tm_year + 1900,
+ p->tm_mon + 1, /* Want January == 1 */
+ p->tm_mday,
+ p->tm_hour,
+ p->tm_min,
+ p->tm_sec,
+ (p->tm_wday + 6) % 7, /* Want Monday == 0 */
+ p->tm_yday,
+ p->tm_isdst);
+}
+
+static object *
+time_gmtime(self, args)
+ object *self;
+ object *args;
+{
+ double when;
+ if (!getargs(args, "d", &when))
+ return NULL;
+ return time_convert((time_t)when, gmtime);
+}
+
+static object *
+time_localtime(self, args)
+ object *self;
+ object *args;
+{
+ double when;
+ if (!getargs(args, "d", &when))
+ return NULL;
+ return time_convert((time_t)when, localtime);
+}
+
+/* Some very old systems may not have mktime(). Comment it out then! */
+
+static object *
+time_mktime(self, args)
+ object *self;
+ object *args;
+{
+ struct tm buf;
+ if (!getargs(args, "(iiiiiiiii)",
+ &buf.tm_year,
+ &buf.tm_mon,
+ &buf.tm_mday,
+ &buf.tm_hour,
+ &buf.tm_min,
+ &buf.tm_sec,
+ &buf.tm_wday,
+ &buf.tm_yday,
+ &buf.tm_isdst))
+ return NULL;
+ if (buf.tm_year >= 1900)
+ buf.tm_year -= 1900;
+ buf.tm_mon--;
+ return newintobject((long)mktime(&buf));
+}
+
static struct methodlist time_methods[] = {
#ifdef DO_MILLI
{"millisleep", time_millisleep},
@@ -245,6 +329,9 @@ static struct methodlist time_methods[] = {
#endif
{"sleep", time_sleep},
{"time", time_time},
+ {"gmtime", time_gmtime},
+ {"localtime", time_localtime},
+ {"mktime", time_mktime},
{NULL, NULL} /* sentinel */
};
@@ -252,7 +339,40 @@ static struct methodlist time_methods[] = {
void
inittime()
{
- initmodule("time", time_methods);
+ object *m, *d;
+ m = initmodule("time", time_methods);
+ d = getmoduledict(m);
+#ifdef SYSV
+ tzset();
+ dictinsert(d, "timezone", newintobject((long)_timezone));
+ dictinsert(d, "altzone", newintobject((long)_altzone));
+ dictinsert(d, "daylight", newintobject((long)_daylight));
+ dictinsert(d, "tzname", mkvalue("(zz)", _tzname[0], _tzname[1]));
+#else /* !SYSV */
+ {
+#define YEAR ((time_t)((365 * 24 + 6) * 3600))
+ time_t t;
+ struct tm *p;
+ long winterzone, summerzone;
+ char wintername[10], summername[10];
+ t = (time((time_t *)0) / YEAR) * YEAR;
+ p = localtime(&t);
+ winterzone = -p->tm_gmtoff;
+ strncpy(wintername, p->tm_zone ? p->tm_zone : " ", 9);
+ wintername[9] = '\0';
+ t += YEAR/2;
+ p = localtime(&t);
+ summerzone = -p->tm_gmtoff;
+ strncpy(summername, p->tm_zone ? p->tm_zone : " ", 9);
+ summername[9] = '\0';
+ dictinsert(d, "timezone", newintobject(winterzone));
+ dictinsert(d, "altzone", newintobject(summerzone));
+ dictinsert(d, "daylight",
+ newintobject((long)(winterzone != summerzone)));
+ dictinsert(d, "tzname",
+ mkvalue("(zz)", wintername, summername));
+ }
+#endif /* !SYSV */
}
@@ -274,6 +394,7 @@ sleep(secs)
}
#endif
+static void
floatsleep(secs)
double secs;
{
@@ -286,7 +407,7 @@ floatsleep(secs)
}
}
-long
+static long
millitimer()
{
return MacTicks * 50 / 3; /* MacTicks * 1000 / 60 */
@@ -299,7 +420,7 @@ millitimer()
#ifdef BSD_TIME
-long
+static long
millitimer()
{
struct timeval t;
@@ -309,6 +430,7 @@ millitimer()
return t.tv_sec*1000 + t.tv_usec/1000;
}
+static void
floatsleep(secs)
double secs;
{
@@ -325,6 +447,7 @@ floatsleep(secs)
#else /* !BSD_TIME */
+static void
floatsleep(secs)
double secs;
{
@@ -342,13 +465,14 @@ floatsleep(secs)
#define CLOCKS_PER_SEC 55 /* 54.945 msec per tick (18.2 HZ clock) */
#endif
+static void
floatsleep(secs)
double secs;
{
delay(long(secs/1000.0));
}
-long
+static long
millitimer()
{
clock_t ticks;
diff --git a/Objects/accessobject.c b/Objects/accessobject.c
index 1275eba..c9b7ce3 100644
--- a/Objects/accessobject.c
+++ b/Objects/accessobject.c
@@ -24,6 +24,13 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Access object implementation */
+/* XXX TO DO LIST
+ - need a "super user" mechanism for debugger etc.
+ - __init__ and __del__ (and all other similar methods)
+ should be usable even when private, not ignored
+ - "from foo import bar" should check access of bar
+*/
+
#include "allobjects.h"
#include "structmember.h"
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index faf7e86..15263d3 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -328,7 +328,7 @@ file_read(f, args)
< 0: strip trailing '\n', raise EOFError if EOF reached immediately
*/
-object *
+static object *
getline(f, n)
fileobject *f;
int n;
diff --git a/Objects/floatobject.c b/Objects/floatobject.c