From 741ffeecf8e33ef03ba521ba0edbae6ad7f73d3d Mon Sep 17 00:00:00 2001 From: Chris Jefferson Date: Sun, 31 Mar 2019 21:09:23 +0100 Subject: [PATCH] Add ShowUsedInfoClasses --- doc/ref/debug.xml | 31 ++++++++++++++++++++++++++++++ lib/info.gi | 37 ++++++++++++++++++++++++++++++++++++ src/gapstate.h | 3 +++ src/info.c | 41 ++++++++++++++++++++++++++++++++++++++++ tst/testinstall/info.tst | 26 +++++++++++++++++++++++++ 5 files changed, 138 insertions(+) diff --git a/doc/ref/debug.xml b/doc/ref/debug.xml index 24f05ece48..d9b963bf1e 100644 --- a/doc/ref/debug.xml +++ b/doc/ref/debug.xml @@ -106,6 +106,8 @@ algorithms for the computation of a subgroup lattice. Note that not all info classes defined in the ⪆ library are currently documented. Many ⪆ packages define additional info classes, which are typically documented in the corresponding package documentation. +The function will show all info classes which +⪆ considers while executing code.

The amount of information to be displayed by each info class can be separately specified by the user. This is done by selecting a non-negative integer @@ -158,6 +160,35 @@ returns the info level of infoclass.

+ + + + +Called with argument true, this makes ⪆ print the info class and level of + any executed statement. Calling with the argument false stops this + printing. + +Each level of each info class is only printed once. The history of printed +info classes and levels is reset whenever true is passed. +

+ + ShowUsedInfoClasses(true); +gap> Intersection(Group((1,3,2,4,5,6)), Group((1,2,3,4,5,6))); +#I Would print info with SetInfoLevel(InfoOptions,1) +#I Would print info with SetInfoLevel(InfoBckt,1) +#I Would print info with SetInfoLevel(InfoBckt,3) +#I Would print info with SetInfoLevel(InfoBckt,5) +Group(()) +gap> Intersection(Group((1,3,2,4,5,6)), Group((1,2,3,4,5,6))); +Group(()) +gap> ShowUsedInfoClasses(false); +]]> + + + +

+ diff --git a/lib/info.gi b/lib/info.gi index d7349d6270..e75ba60767 100644 --- a/lib/info.gi +++ b/lib/info.gi @@ -315,6 +315,43 @@ BIND_GLOBAL( "InfoDecision", function(selectors, level) end ); +############################################################################# +## +## The following functions are used by ShowUsedInfoClasses +## +## SHOWN_USED_INFO_CLASSES contains the InfoClasses which have been printed +## out by ShowUsedInfoClasses. +## RESET_SHOW_USED_INFO_CLASSES and SHOW_USED_INFO_CLASSES are called from +## the kernel. + +SHOWN_USED_INFO_CLASSES := []; + +if IsHPCGAP then + ShareInternalObj(INFO_CLASSES); +fi; + + +BIND_GLOBAL("RESET_SHOW_USED_INFO_CLASSES", function() + atomic readwrite SHOWN_USED_INFO_CLASSES do + SHOWN_USED_INFO_CLASSES := []; + od; +end); + +BIND_GLOBAL("SHOW_USED_INFO_CLASSES", function(selectors, level) + local selector; + # Handle selectors possibly being a list + selectors := Flat([selectors]); + atomic readwrite SHOWN_USED_INFO_CLASSES do + for selector in selectors do + if not [selector, level] in SHOWN_USED_INFO_CLASSES then + Add(SHOWN_USED_INFO_CLASSES, [selector, level]); + Print("#I Would print info with SetInfoLevel(", + selector, ",", level, ")\n"); + fi; + od; + od; +end); + ############################################################################# ## #V InfoDebug diff --git a/src/gapstate.h b/src/gapstate.h index 3b42ec6b82..0aa469b384 100644 --- a/src/gapstate.h +++ b/src/gapstate.h @@ -104,6 +104,9 @@ typedef struct GAPState { Int PrintObjIndex; Int PrintObjDepth; + /* From info.c */ + Int ShowUsedInfoClassesActive; + UInt1 StateSlots[STATE_SLOTS_SIZE]; /* Allocation */ diff --git a/src/info.c b/src/info.c index 4b56b36db9..01f739572c 100644 --- a/src/info.c +++ b/src/info.c @@ -15,6 +15,8 @@ #include "bool.h" #include "calls.h" +#include "error.h" +#include "gapstate.h" #include "gvars.h" #include "modules.h" #include "plist.h" @@ -34,6 +36,24 @@ enum { static Obj InfoDecision; static Obj IsInfoClassListRep; static Obj DefaultInfoHandler; +static Obj ResetShowUsedInfoClassesHandler; +static Obj ShowUsedInfoClassesHandler; + + +Obj FuncShowUsedInfoClasses(Obj self, Obj choice) +{ + RequireTrueOrFalse("ShowUsedInfoClasses", choice); + + if (choice == True) { + STATE(ShowUsedInfoClassesActive) = 1; + CALL_0ARGS(ResetShowUsedInfoClassesHandler); + } + else { + STATE(ShowUsedInfoClassesActive) = 0; + } + + return 0; +} void InfoDoPrint(Obj cls, Obj lvl, Obj args) { @@ -53,6 +73,9 @@ void InfoDoPrint(Obj cls, Obj lvl, Obj args) Obj InfoCheckLevel(Obj selectors, Obj level) { + if (STATE(ShowUsedInfoClassesActive)) { + CALL_2ARGS(ShowUsedInfoClassesHandler, selectors, level); + } // Fast-path the most common failing case. // The fast-path only deals with the case where all arguments are of the // correct type, and were False is returned. @@ -77,6 +100,14 @@ Obj InfoCheckLevel(Obj selectors, Obj level) *F * * * * * * * * * * * * * initialize module * * * * * * * * * * * * * * * */ +/**************************************************************************** +** +*V GVarFuncs . . . . . . . . . . . . . . . . . . list of functions to export +*/ +static StructGVarFunc GVarFuncs[] = { + GVAR_FUNC(ShowUsedInfoClasses, 1, "choice"), { 0, 0, 0, 0, 0 } +}; + /**************************************************************************** ** @@ -84,10 +115,17 @@ Obj InfoCheckLevel(Obj selectors, Obj level) */ static Int InitKernel(StructInitInfo * module) { + /* init filters and functions */ + InitHdlrFuncsFromTable(GVarFuncs); + /* The work of handling Info messages is delegated to the GAP level */ ImportFuncFromLibrary("InfoDecision", &InfoDecision); ImportFuncFromLibrary("DefaultInfoHandler", &DefaultInfoHandler); ImportFuncFromLibrary("IsInfoClassListRep", &IsInfoClassListRep); + ImportFuncFromLibrary("RESET_SHOW_USED_INFO_CLASSES", + &ResetShowUsedInfoClassesHandler); + ImportFuncFromLibrary("SHOW_USED_INFO_CLASSES", + &ShowUsedInfoClassesHandler); /* return success */ return 0; @@ -100,6 +138,9 @@ static Int InitKernel(StructInitInfo * module) */ static Int InitLibrary(StructInitInfo * module) { + + InitGVarFuncsFromTable(GVarFuncs); + ExportAsConstantGVar(INFODATA_CURRENTLEVEL); ExportAsConstantGVar(INFODATA_CLASSNAME); ExportAsConstantGVar(INFODATA_HANDLER); diff --git a/tst/testinstall/info.tst b/tst/testinstall/info.tst index d62f65acf7..d8e99b1da9 100644 --- a/tst/testinstall/info.tst +++ b/tst/testinstall/info.tst @@ -53,6 +53,32 @@ gap> Info(InfoTest1 + InfoTest2, 0); Error, level 0 Info messages are not allowed gap> Info(InfoTest1 + InfoTest2, "apple"); Error, usage : Info(, , ...) +gap> ShowUsedInfoClasses(true); +gap> Info(InfoTest2, 2, "apple"); +#I Would print info with SetInfoLevel(InfoTest2,2) +#I Would print info with SetInfoLevel(InfoGlobal,3) +#I apple +gap> Info(InfoTest1 + InfoTest2, 2, "apple"); +#I Would print info with SetInfoLevel(InfoTest1,2) +#I apple +gap> Info(InfoTest1 + InfoTest2, 2, "apple"); +#I apple +gap> Info(InfoTest1 + InfoTest2, 3, "apple"); +#I Would print info with SetInfoLevel(InfoTest1,3) +#I Would print info with SetInfoLevel(InfoTest2,3) +gap> Info(InfoTest1 + InfoTest2, 3, "apple"); +gap> ShowUsedInfoClasses(true); +gap> Info(InfoTest1 + InfoTest2, 3, "apple"); +#I Would print info with SetInfoLevel(InfoTest1,3) +#I Would print info with SetInfoLevel(InfoTest2,3) +gap> Info(InfoTest1 + InfoTest2, 3, "apple"); +gap> ShowUsedInfoClasses(false); +gap> ShowUsedInfoClasses(fail); +Error, ShowUsedInfoClasses: must be true or false (not the value 'fai\ +l') +gap> ShowUsedInfoClasses("abc"); +Error, ShowUsedInfoClasses: must be true or false (not a list (string\ +)) gap> str := "";; gap> str2 := "";; gap> SetDefaultInfoOutput(OutputTextString(str, false));