[pypy-svn] r68869 - in pypy/branch/logging2/pypy: rlib rlib/test rpython/lltypesystem translator/c translator/c/src translator/c/test
arigo at codespeak.net
arigo at codespeak.net
Fri Oct 30 17:45:25 CET 2009
Author: arigo
Date: Fri Oct 30 17:45:24 2009
New Revision: 68869
Modified:
pypy/branch/logging2/pypy/rlib/debug.py
pypy/branch/logging2/pypy/rlib/test/test_debug.py
pypy/branch/logging2/pypy/rpython/lltypesystem/lloperation.py
pypy/branch/logging2/pypy/rpython/lltypesystem/opimpl.py
pypy/branch/logging2/pypy/translator/c/funcgen.py
pypy/branch/logging2/pypy/translator/c/src/debug.h
pypy/branch/logging2/pypy/translator/c/test/test_standalone.py
Log:
Move all the code to support variants of logging to debug.h.
Implement a number of variants, documented at the start of debug.h.
Modified: pypy/branch/logging2/pypy/rlib/debug.py
==============================================================================
--- pypy/branch/logging2/pypy/rlib/debug.py (original)
+++ pypy/branch/logging2/pypy/rlib/debug.py Fri Oct 30 17:45:24 2009
@@ -61,35 +61,30 @@
hop.genop(fn.__name__, vlist)
-def debug_level():
- """Returns the current debug level. It is:
- 0: all calls to debug_print/debug_start/debug_stop are ignored
- 1: profiling: debug_start/debug_stop handled, but debug_print ignored
- 2: all handled
- The value returned depend on the runtime presence of the PYPYLOG env var,
- unless debuglevel == 0 in the config.
- """
- return 2
+def have_debug_prints():
+ # returns True if the next calls to debug_print show up,
+ # and False if they would not have any effect.
+ return True
class Entry(ExtRegistryEntry):
- _about_ = debug_level
+ _about_ = have_debug_prints
def compute_result_annotation(self):
from pypy.annotation import model as annmodel
t = self.bookkeeper.annotator.translator
if t.config.translation.log:
- return annmodel.SomeInteger()
+ return annmodel.s_Bool
else:
- return self.bookkeeper.immutablevalue(0)
+ return self.bookkeeper.immutablevalue(False)
def specialize_call(self, hop):
from pypy.rpython.lltypesystem import lltype
t = hop.rtyper.annotator.translator
hop.exception_cannot_occur()
if t.config.translation.log:
- return hop.genop('debug_level', [], resulttype=lltype.Signed)
+ return hop.genop('have_debug_prints', [], resulttype=lltype.Bool)
else:
- return hop.inputconst(lltype.Signed, 0)
+ return hop.inputconst(lltype.Bool, False)
def llinterpcall(RESTYPE, pythonfunction, *args):
Modified: pypy/branch/logging2/pypy/rlib/test/test_debug.py
==============================================================================
--- pypy/branch/logging2/pypy/rlib/test/test_debug.py (original)
+++ pypy/branch/logging2/pypy/rlib/test/test_debug.py Fri Oct 30 17:45:24 2009
@@ -1,7 +1,8 @@
import py
from pypy.rlib.debug import check_annotation, make_sure_not_resized
-from pypy.rlib.debug import debug_print, debug_start, debug_stop, debug_level
+from pypy.rlib.debug import debug_print, debug_start, debug_stop
+from pypy.rlib.debug import have_debug_prints
from pypy.rpython.test.test_llinterp import interpret
def test_check_annotation():
@@ -50,13 +51,13 @@
debug_start("mycat")
debug_print("foo", 2, "bar", x)
debug_stop("mycat")
- return debug_level()
+ return have_debug_prints()
olderr = sys.stderr
try:
sys.stderr = c = StringIO()
res = f(3)
- assert res == 2
+ assert res == True
finally:
sys.stderr = olderr
assert 'mycat' in c.getvalue()
@@ -65,7 +66,7 @@
try:
sys.stderr = c = StringIO()
res = self.interpret(f, [3])
- assert res == 2
+ assert res == True
finally:
sys.stderr = olderr
assert 'mycat' in c.getvalue()
Modified: pypy/branch/logging2/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/logging2/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/branch/logging2/pypy/rpython/lltypesystem/lloperation.py Fri Oct 30 17:45:24 2009
@@ -525,7 +525,7 @@
'debug_print': LLOp(canrun=True),
'debug_start': LLOp(canrun=True),
'debug_stop': LLOp(canrun=True),
- 'debug_level': LLOp(canrun=True),
+ 'have_debug_prints': LLOp(canrun=True),
'debug_pdb': LLOp(),
'debug_assert': LLOp(tryfold=True),
'debug_fatalerror': LLOp(),
Modified: pypy/branch/logging2/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/branch/logging2/pypy/rpython/lltypesystem/opimpl.py (original)
+++ pypy/branch/logging2/pypy/rpython/lltypesystem/opimpl.py Fri Oct 30 17:45:24 2009
@@ -429,8 +429,8 @@
def op_debug_stop(category):
debug.debug_stop(_normalize(category))
-def op_debug_level():
- return debug.debug_level()
+def op_have_debug_prints():
+ return debug.have_debug_prints()
def op_gc_stack_bottom():
pass # marker for trackgcroot.py
Modified: pypy/branch/logging2/pypy/translator/c/funcgen.py
==============================================================================
--- pypy/branch/logging2/pypy/translator/c/funcgen.py (original)
+++ pypy/branch/logging2/pypy/translator/c/funcgen.py Fri Oct 30 17:45:24 2009
@@ -744,8 +744,9 @@
raise Exception("don't know how to debug_print %r" % (T,))
argv.append(self.expr(arg))
argv.insert(0, c_string_constant(' '.join(format) + '\n'))
- return ("if (PYPY_DEBUG_ENABLED) { fprintf(PYPY_DEBUG_FILE, %s); %s}"
- % (', '.join(argv), free_line))
+ return (
+ "if (PYPY_HAVE_DEBUG_PRINTS) { fprintf(PYPY_DEBUG_FILE, %s); %s}"
+ % (', '.join(argv), free_line))
def OP_DEBUG_START(self, op):
arg = op.args[0]
Modified: pypy/branch/logging2/pypy/translator/c/src/debug.h
==============================================================================
--- pypy/branch/logging2/pypy/translator/c/src/debug.h (original)
+++ pypy/branch/logging2/pypy/translator/c/src/debug.h Fri Oct 30 17:45:24 2009
@@ -2,42 +2,41 @@
/*** C header subsection: debug_print & related tools ***/
/* values of the PYPYLOG environment variable:
+ ("top-level" debug_prints means not between debug_start and debug_stop)
- (empty) logging is turned off
- - logging goes to stderr
- filename logging goes to the given file; overwritten at process start
- prof:filename logs only debug_start and debug_stop, not debug_print
+ (empty) logging is turned off, apart from top-level debug_prints
+ that go to stderr
+ fname logging for profiling: includes all debug_start/debug_stop
+ but not any nested debug_print
+ :fname full logging
+ prefix:fname conditional logging
+
+ Conditional logging means that it only includes the debug_start/debug_stop
+ sections whose name match 'prefix'. Other sections are ignored, including
+ all debug_prints that occur while this section is running and all nested
+ subsections.
+
+ Note that 'fname' can be '-' to send the logging data to stderr.
*/
/* macros used by the generated code */
-#define PYPY_DEBUG_ENABLED \
- (pypy_debug_level >= PYDEBUG_FULL && pypy_debug_is_ready_full())
-#define PYPY_DEBUG_FILE \
- pypy_debug_file
-#define PYPY_DEBUG_START(cat) \
- if (pypy_debug_level >= PYDEBUG_PROFILE) pypy_debug_start(cat)
-#define PYPY_DEBUG_STOP(cat) \
- if (pypy_debug_level >= PYDEBUG_PROFILE) pypy_debug_stop(cat)
-#define OP_DEBUG_LEVEL(r) \
- if (pypy_debug_level == PYDEBUG_UNINITIALIZED) pypy_debug_open(); \
- r = pypy_debug_level
+#define PYPY_HAVE_DEBUG_PRINTS (pypy_ignoring_nested_prints ? 0 : \
+ (pypy_debug_ensure_opened(), 1))
+#define PYPY_DEBUG_FILE pypy_debug_file
+#define PYPY_DEBUG_START(cat) pypy_debug_start(cat)
+#define PYPY_DEBUG_STOP(cat) pypy_debug_stop(cat)
+#define OP_HAVE_DEBUG_PRINTS(r) r = !pypy_ignoring_nested_prints
/************************************************************/
-#define PYDEBUG_OFF 0
-#define PYDEBUG_PROFILE 1
-#define PYDEBUG_FULL 2
-#define PYDEBUG_UNINITIALIZED 3
-
/* prototypes (internal use only) */
-void pypy_debug_open(void);
-bool_t pypy_debug_is_ready_full(void);
+void pypy_debug_ensure_opened(void);
void pypy_debug_start(const char *category);
void pypy_debug_stop(const char *category);
-extern int pypy_debug_level;
+extern int pypy_ignoring_nested_prints;
extern FILE *pypy_debug_file;
@@ -45,40 +44,46 @@
#ifndef PYPY_NOT_MAIN_FILE
#include <sys/time.h>
+#include <string.h>
-int pypy_debug_level = PYDEBUG_UNINITIALIZED;
-FILE *pypy_debug_file;
+int pypy_ignoring_nested_prints = 0;
+FILE *pypy_debug_file = NULL;
+static bool_t debug_ready = 0;
+static bool_t debug_profile = 0;
+static char *debug_prefix = NULL;
-void pypy_debug_open(void)
+static void pypy_debug_open(void)
{
char *filename = getenv("PYPYLOG");
- pypy_debug_level = PYDEBUG_FULL;
- pypy_debug_file = NULL;
if (filename && filename[0])
{
- if (filename[0] == 'p' &&
- filename[1] == 'r' &&
- filename[2] == 'o' &&
- filename[3] == 'f' &&
- filename[4] == ':')
+ char *colon = strchr(filename, ':');
+ if (!colon)
{
- pypy_debug_level = PYDEBUG_PROFILE;
- filename += 5;
+ /* PYPYLOG=filename --- profiling version */
+ debug_profile = 1;
}
- if (filename[0] == '-' && filename[1] == 0)
- pypy_debug_file = stderr;
else
+ {
+ /* PYPYLOG=prefix:filename --- conditional logging */
+ int n = colon - filename;
+ debug_prefix = malloc(n + 1);
+ memcpy(debug_prefix, filename, n);
+ debug_prefix[n] = '\0';
+ filename = colon + 1;
+ }
+ if (strcmp(filename, "-") != 0)
pypy_debug_file = fopen(filename, "w");
}
- if (pypy_debug_file == NULL)
- pypy_debug_level = PYDEBUG_OFF;
+ if (!pypy_debug_file)
+ pypy_debug_file = stderr;
+ debug_ready = 1;
}
-bool_t pypy_debug_is_ready_full(void)
+void pypy_debug_ensure_opened(void)
{
- if (pypy_debug_level == PYDEBUG_UNINITIALIZED)
+ if (!debug_ready)
pypy_debug_open();
- return pypy_debug_level == PYDEBUG_FULL;
}
@@ -87,25 +92,58 @@
__asm__ __volatile__("rdtsc" : "=A" (val))
-static void pypy_debug_category(const char *start, const char *category)
+static bool_t startswith(const char *str, const char *substr)
+{
+ while (*substr)
+ if (*str++ != *substr++)
+ return 0;
+ return 1;
+}
+
+static void display_startstop(const char *start, const char *category)
{
long long timestamp;
- if (pypy_debug_level == PYDEBUG_UNINITIALIZED)
- pypy_debug_open();
- if (pypy_debug_level < PYDEBUG_PROFILE)
- return;
READ_TIMESTAMP(timestamp);
fprintf(pypy_debug_file, "{%llx} -%s- %s\n", timestamp, start, category);
}
void pypy_debug_start(const char *category)
{
- pypy_debug_category("start", category);
+ if (debug_profile)
+ {
+ /* profiling version */
+ pypy_debug_ensure_opened();
+ pypy_ignoring_nested_prints++; /* disable nested debug_print */
+ }
+ else
+ {
+ /* non-profiling version */
+ if (pypy_ignoring_nested_prints > 0)
+ {
+ /* already ignoring the parent section */
+ pypy_ignoring_nested_prints++;
+ return;
+ }
+ pypy_debug_ensure_opened();
+ if (!debug_prefix || !startswith(category, debug_prefix))
+ {
+ /* wrong section name, or no PYPYLOG at all, skip it */
+ pypy_ignoring_nested_prints = 1;
+ return;
+ }
+ }
+ display_startstop("start", category);
}
void pypy_debug_stop(const char *category)
{
- pypy_debug_category("stop", category);
+ if (pypy_ignoring_nested_prints > 0)
+ {
+ pypy_ignoring_nested_prints--;
+ if (!debug_profile)
+ return;
+ }
+ display_startstop("stop", category);
}
#endif /* PYPY_NOT_MAIN_FILE */
Modified: pypy/branch/logging2/pypy/translator/c/test/test_standalone.py
==============================================================================
--- pypy/branch/logging2/pypy/translator/c/test/test_standalone.py (original)
+++ pypy/branch/logging2/pypy/translator/c/test/test_standalone.py Fri Oct 30 17:45:24 2009
@@ -2,8 +2,8 @@
import sys, os, re
from pypy.rlib.rarithmetic import r_longlong
-from pypy.rlib.debug import ll_assert
-from pypy.rlib.debug import debug_print, debug_start, debug_stop, debug_level
+from pypy.rlib.debug import ll_assert, have_debug_prints
+from pypy.rlib.debug import debug_print, debug_start, debug_stop
from pypy.translator.translator import TranslationContext
from pypy.translator.backendopt import all
from pypy.translator.c.genc import CStandaloneBuilder, ExternalCompilationInfo
@@ -258,42 +258,104 @@
def test_debug_print_start_stop(self):
def entry_point(argv):
- os.write(1, str(debug_level()) + '\n')
- debug_start("mycat")
- debug_print("foo", 2, "bar", 3)
- debug_stop("mycat")
+ x = "got:"
+ if have_debug_prints(): x += "a"
+ debug_print("toplevel")
+ debug_start ("mycat")
+ if have_debug_prints(): x += "b"
+ debug_print ("foo", 2, "bar", 3)
+ debug_start ("cat2")
+ if have_debug_prints(): x += "c"
+ debug_print ("baz")
+ debug_stop ("cat2")
+ if have_debug_prints(): x += "d"
+ debug_print ("bok")
+ debug_stop ("mycat")
+ os.write(1, x + '.\n')
return 0
t, cbuilder = self.compile(entry_point)
# check with PYPYLOG undefined
out, err = cbuilder.cmdexec("", err=True, env={})
- assert out.strip() == '0'
- assert not err
+ assert out.strip() == 'got:a.'
+ assert 'toplevel' in err
+ assert 'mycat' not in err
+ assert 'foo 2 bar 3' not in err
+ assert 'cat2' not in err
+ assert 'baz' not in err
+ assert 'bok' not in err
# check with PYPYLOG defined to an empty string (same as undefined)
out, err = cbuilder.cmdexec("", err=True, env={'PYPYLOG': ''})
- assert out.strip() == '0'
- assert not err
- # check with PYPYLOG=- (means print to stderr)
- out, err = cbuilder.cmdexec("", err=True, env={'PYPYLOG': '-'})
- assert out.strip() == '2'
+ assert out.strip() == 'got:a.'
+ assert 'toplevel' in err
+ assert 'mycat' not in err
+ assert 'foo 2 bar 3' not in err
+ assert 'cat2' not in err
+ assert 'baz' not in err
+ assert 'bok' not in err
+ # check with PYPYLOG=:- (means print to stderr)
+ out, err = cbuilder.cmdexec("", err=True, env={'PYPYLOG': ':-'})
+ assert out.strip() == 'got:abcd.'
+ assert 'toplevel' in err
assert 'mycat' in err
assert 'foo 2 bar 3' in err
- # check with PYPYLOG=somefilename
+ assert 'cat2' in err
+ assert 'baz' in err
+ assert 'bok' in err
+ # check with PYPYLOG=:somefilename
path = udir.join('test_debug_xxx.log')
+ out, err = cbuilder.cmdexec("", err=True,
+ env={'PYPYLOG': ':%s' % path})
+ assert out.strip() == 'got:abcd.'
+ assert not err
+ assert path.check(file=1)
+ data = path.read()
+ assert 'toplevel' in data
+ assert 'mycat' in data
+ assert 'foo 2 bar 3' in data
+ assert 'cat2' in data
+ assert 'baz' in data
+ assert 'bok' in data
+ # check with PYPYLOG=somefilename
+ path = udir.join('test_debug_xxx_prof.log')
out, err = cbuilder.cmdexec("", err=True, env={'PYPYLOG': str(path)})
- assert out.strip() == '2'
+ assert out.strip() == 'got:a.'
assert not err
assert path.check(file=1)
+ data = path.read()
+ assert 'toplevel' in data
+ assert 'mycat' in data
+ assert 'foo 2 bar 3' not in data
+ assert 'cat2' in data
+ assert 'baz' not in data
+ assert 'bok' not in data
+ # check with PYPYLOG=myc:somefilename (includes mycat but not cat2)
+ path = udir.join('test_debug_xxx_myc.log')
+ out, err = cbuilder.cmdexec("", err=True,
+ env={'PYPYLOG': 'myc:%s' % path})
+ assert out.strip() == 'got:abd.'
+ assert not err
+ assert path.check(file=1)
+ data = path.read()
+ assert 'toplevel' in path.read()
assert 'mycat' in path.read()
assert 'foo 2 bar 3' in path.read()
- # check with PYPYLOG=prof:somefilename (only start/stop events)
- path = udir.join('test_debug_xxx_prof.log')
+ assert 'cat2' not in data
+ assert 'baz' not in data
+ assert 'bok' in data
+ # check with PYPYLOG=cat:somefilename (includes cat2 but not mycat)
+ path = udir.join('test_debug_xxx_cat.log')
out, err = cbuilder.cmdexec("", err=True,
- env={'PYPYLOG': 'prof:%s' % path})
- assert out.strip() == '1'
+ env={'PYPYLOG': 'cat:%s' % path})
+ assert out.strip() == 'got:a.'
assert not err
assert path.check(file=1)
- assert 'mycat' in path.read()
+ data = path.read()
+ assert 'toplevel' in path.read()
+ assert 'mycat' not in path.read()
assert 'foo 2 bar 3' not in path.read()
+ assert 'cat2' not in data # because it is nested
+ assert 'baz' not in data
+ assert 'bok' not in data
#
# finally, check compiling with logging disabled
from pypy.config.pypyoption import get_pypy_config
@@ -302,8 +364,10 @@
self.config = config
t, cbuilder = self.compile(entry_point)
path = udir.join('test_debug_does_not_show_up.log')
- out = cbuilder.cmdexec("", env={'PYPYLOG': str(path)})
- assert out.strip() == '0'
+ out, err = cbuilder.cmdexec("", err=True,
+ env={'PYPYLOG': ':%s' % path})
+ assert out.strip() == 'got:.'
+ assert not err
assert path.check(file=0)
More information about the Pypy-commit
mailing list