Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  info.gi   Sprache: unbekannt

 
#############################################################################
##
##  This file is part of GAP, a system for computational discrete algebra.
##  This file's authors include Steve Linton.
##
##  Copyright of GAP belongs to its developers, whose names are too numerous
##  to list here. Please refer to the COPYRIGHT file for details.
##
##  SPDX-License-Identifier: GPL-2.0-or-later
##
##  This package sets up a GAP level prototype of the new Info messages
##  system, parts of which will eventually have to be moved into
##  the kernel
##
##  Informational messages are controlled by the user setting desired
##  levels of verbosity for InfoClasses. A set of InfoClasses is an
##  InfoSelector, and classes and selectors may be built up with \+
#N  I wanted to use \or, but this isn't at operation
##
##  A message is associated with a selector and a level and is
##  printed when the desired level for any of the classes in the selector
##  equals or exceeds  the level of the message
##
#N  There may be a case for doing this without using method selection at all
#N  as it could then be installed earlier in library loading
#N
##
##  This file is the implementation  part of that package
##


#############################################################################
##
#R  IsInfoClassListRep(<obj>)                       length one positional rep
##
##  An InfoClass is represented as a positional object with the following
##  members:
##
##  INFODATA_NUM            an integer identifying the class
##  INFODATA_CURRENTLEVEL   a positive integer
##  INFODATA_CLASSNAME      a string
##  INFODATA_HANDLER        optional, handler function taking three arguments
##  INFODATA_OUTPUT         optional, output stream

DeclareRepresentation("IsInfoClassListRep", IsAtomicPositionalObjectRep);

# A list of all created InfoClassListReps
INFO_CLASSES := [];

# InfoData is unused, but we keep it for now, to avoid warnings in GAPDoc.
# TODO: remove InfoData
InfoData := rec();

if IsHPCGAP then
    ShareInternalObj(INFO_CLASSES);
fi;

InstallGlobalFunction( "SetDefaultInfoOutput", function( out )
  if IsBound(DefaultInfoOutput) then
    MakeReadWriteGlobal("DefaultInfoOutput");
  fi;
  DefaultInfoOutput := out;
  MakeReadOnlyGlobal("DefaultInfoOutput");
end);


BIND_GLOBAL( "PrintWithoutFormatting", function ( arg )
    CALL_WITH_FORMATTING_STATUS(false, Print, arg);
end );


InstallGlobalFunction( "DefaultInfoHandler", function( infoclass, level, list )
  local out, s;
  out := InfoOutput(infoclass);
  if out = "*Print*" then
    PrintWithoutFormatting("#I  ");
    for s in list do
      PrintWithoutFormatting(s);
    od;
    PrintWithoutFormatting("\n");
  else
    AppendTo(out, "#I  ");
    for s in list do
      AppendTo(out, s);
    od;
    AppendTo(out, "\n");
  fi;
end);


#############################################################################
##
#M  NewInfoClass( <name> )                              make a new Info Class
##
##  This is how Info Classes should be obtained
##

InstallMethod(NewInfoClass, true, [IsString], 0,
        function(name)
    local pos, ic;

    atomic readwrite INFO_CLASSES do
        # if we are rereading and this class already exists then
        # do not make a new class
        if REREADING then
            pos := First(INFO_CLASSES, x -> x![INFODATA_CLASSNAME] = name);
            if pos <> fail then
                return INFO_CLASSES[pos];
            fi;
        fi;

        pos := Length(INFO_CLASSES) + 1;
        # make sure to always allocate a length big enough, even for the optional
        # members, because in HPC-GAP, positional objects cannot be resized
        ic := FixedAtomicList(5);
        ic[INFODATA_CURRENTLEVEL] := 0;
        ic[INFODATA_CLASSNAME] := Immutable(name);
        ic[INFODATA_NUM] := pos;
        ic := Objectify(NewType(InfoClassFamily,IsInfoClassListRep), ic);
        INFO_CLASSES[pos] := ic;
        return ic;
    od;
end);


#############################################################################
##
#F  DeclareInfoClass( <name> )
##
InstallGlobalFunction( DeclareInfoClass, function( name )
    if not ISBOUND_GLOBAL( name ) then
      BIND_GLOBAL( name, NewInfoClass( name ) );
    elif not IsInfoClass( VALUE_GLOBAL( name ) ) then
      Error( "value of `",name,"' is already bound and not an info class" );
    fi;
end );

#############################################################################
##
#F  SetInfoHandler( <class>, <handler> )
##
InstallGlobalFunction( SetInfoHandler, function(class, handler)
    class![INFODATA_HANDLER] := handler;
end);

#############################################################################
##
#F  SetInfoOutput( <class>, <handler> )
##
InstallGlobalFunction( SetInfoOutput, function(class, out)
  class![INFODATA_OUTPUT] := out;
end);

InstallGlobalFunction( UnbindInfoOutput, function(class)
  Unbind(class![INFODATA_OUTPUT]);
end);

InstallGlobalFunction( InfoOutput, function(class)
  if IsBound(class![INFODATA_OUTPUT]) then
    return class![INFODATA_OUTPUT];
  else
    return DefaultInfoOutput;
  fi;
end);

#############################################################################
##
#M  Basic methods for Info Classes: =, < (so that we can make Sets),
##                                  PrintObj
##

InstallMethod(\=,
    "for two info classes",
    IsIdenticalObj, [IsInfoClassListRep, IsInfoClassListRep], 0,
        function(ic1,ic2)
    return ic1![INFODATA_NUM] = ic2![INFODATA_NUM];
end);

InstallMethod(\<,
    "for two info classes",
    IsIdenticalObj, [IsInfoClassListRep, IsInfoClassListRep], 0,
        function(ic1,ic2)
    return ic1![INFODATA_NUM] < ic2![INFODATA_NUM];
end);

InstallMethod(PrintObj,
    "for an info class",
    true, [IsInfoClassListRep], 0,
        function(ic)
    Print(ic![INFODATA_CLASSNAME]);
end);

#############################################################################
##
#M  <info class> + <info class>
#M  <info selector> + <info class>
#M  <info class> + <info selector>
#M  <info selector> + <info selector>
##
##  Used to build up InfoSelectors, these are essentially just taking unions
##

InstallOtherMethod(\+,
    "for two info classes",
    IsIdenticalObj, [IsInfoClass, IsInfoClass], SUM_FLAGS,
        function(ic1,ic2)
    return Set([ic1,ic2]);
end);

InstallOtherMethod(\+,
    "for info class and info selector",
    true, [IsInfoClass, IsInfoSelector], SUM_FLAGS,
        function(ic,is)
    return Union(is,[ic]);
end);

InstallOtherMethod(\+,
    "for info selector and info class",
    true, [IsInfoSelector, IsInfoClass], SUM_FLAGS,
        function(is,ic)
    return Union(is,[ic]);
end);

InstallOtherMethod(\+,
    "for two info selectors",
    IsIdenticalObj, [IsInfoSelector, IsInfoSelector], SUM_FLAGS,
        function(is1,is2)
    return Union(is1,is2);
end);

#############################################################################
##
#M  SetInfoLevel( <class>, <level>)   set desired verbosity level for a class
##

InstallMethod(SetInfoLevel, true,
        [IsInfoClass and IsInfoClassListRep, IsPosInt], 0,
        function(ic,lev)
    ic![INFODATA_CURRENTLEVEL] := lev;
end);

InstallMethod(SetInfoLevel, true,
        [IsInfoClass and IsInfoClassListRep, IsZeroCyc], 0,
        function(ic,lev)
    ic![INFODATA_CURRENTLEVEL] := lev;
end);

#############################################################################
##
#F  SetAllInfoLevels(  <level>)   set desired verbosity level for all classes
##

BIND_GLOBAL( "SetAllInfoLevels", function( level )
    local infoclass;
    atomic readwrite INFO_CLASSES do
        for infoclass in INFO_CLASSES do
            SetInfoLevel(infoclass, level);
        od;
    od;
end );


#############################################################################
##
#M  InfoLevel( <class> )              get desired verbosity level for a class
##

InstallMethod(InfoLevel, true,
        [IsInfoClass and IsInfoClassListRep], 0,
        function(ic)
    return ic![INFODATA_CURRENTLEVEL];
end);

#############################################################################
##
#F  InfoDecision( <selector>, <level>) .  decide whether a message is printed
##
##  The kernel skips this function for the case of an IsInfoClassListRep,
##  where ret will be False.
##

BIND_GLOBAL( "InfoDecision", function(selectors, level)
    local usage, ret;
    usage := "usage : Info(<selectors>, <level>, ...)";
    if not IsInt(level) or level <= 0 then
        if level = 0 then
            Error("level 0 Info messages are not allowed");
        else
            Error(usage);
        fi;
    fi;

    ret := false;

    if IsInfoClass(selectors) then
        ret := InfoLevel(selectors) >= level;
    elif IsInfoSelector(selectors)  then
        # note that we 'or' the classes together
        ret :=  ForAny(selectors, ic -> InfoLevel(ic) >= level);
    else
        Error(usage);
    fi;

    return ret;
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(SHOWN_USED_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
##
##  This info class has a default level of 1.
##  Warnings can be switched off by setting its level to zero.
##
##  The files `lib/oper.g', `lib/oper1.g', `lib/variable.g' contain
##  calls to `INFO_DEBUG' (a plain function delegating to `Print').
##  Here we define the proper info class `InfoDebug',
##  and replace `INFO_DEBUG' by a function that calls `Info'
##  and respects the user defined info level of `InfoDebug'.
##
if not IsBound( InfoDebug ) then
  DeclareInfoClass( "InfoDebug" );
  SetInfoLevel( InfoDebug, 1 );

  MAKE_READ_WRITE_GLOBAL( "INFO_DEBUG" );
  INFO_DEBUG:= function( arg )
    local string, i;

    string:= [];
    for i in [ 2 .. LEN_LIST( arg ) ] do
      APPEND_LIST_INTR( string, arg[i] );
    od;
    Info( InfoDebug, arg[1], string );
  end;
  MAKE_READ_ONLY_GLOBAL( "INFO_DEBUG" );
fi;


#############################################################################
##
#V  InfoMethodSelection
##
if not IsBound(InfoMethodSelection) then
    DeclareInfoClass( "InfoMethodSelection" );
fi;


#############################################################################
##
#V  InfoTiming
##
if not IsBound(InfoTiming) then
    DeclareInfoClass( "InfoTiming" );
fi;

#############################################################################
##
#V  InfoWarning
##
##  This info class has a default level of 1.
##  Warnings can be switched off by setting its level to zero.
##
if not IsBound(InfoWarning) then
    DeclareInfoClass( "InfoWarning" );
    SetInfoLevel( InfoWarning, 1 );
fi;

#############################################################################
##
#V  InfoPerformance
##
##  This info class has a default level of 1. It prints warnings about
##  performance problems when doing things in particularly unsuitable ways.
##  Warnings can be switched off by setting its level to zero
##
DeclareInfoClass( "InfoPerformance" );
SetInfoLevel( InfoPerformance, 1 );

LAST_COMPLETIONBAR_STRING:=fail;
LAST_COMPLETIONBAR_VAL:=0;

InstallGlobalFunction(CompletionBar,function(c,a,s,v)
local out,w,w0,i;
  if InfoLevel(c)>=a then
    if not IsRat(v) then
      out:=OutputTextUser();
      PrintTo(out,"\n");
      return;
    fi;
    w0:=SizeScreen()[1];
    w:=Int(v*(w0-Length(s)-5));
    if s=LAST_COMPLETIONBAR_STRING and w=LAST_COMPLETIONBAR_VAL then
      return; # nothing new to say
    fi;
    LAST_COMPLETIONBAR_STRING:=s;
    LAST_COMPLETIONBAR_VAL:=w;
    out:=OutputTextUser();
    v:=w;
    w:=w0;
    for i in [1..w] do
      PrintTo(out,"\r");
    od;
    PrintTo(out,"\c");
    w:=w-Length(s)-5;
    PrintTo(out,s," ");
    for i in [1..w] do
      if v>0 then
        PrintTo(out,"#");
      else
        PrintTo(out," ");
      fi;
      v:=v-1;
    od;
    PrintTo(out,"|\c");
  fi;
end);


#############################################################################
##
#V  InfoObsolete
##
##  This info class has a default level of 1.
##  Warnings can be disabled entirely by setting its level to 0, and further
##  warnings can be switched on by setting its level to 2.
##
##  Also deal with INFO_OBSOLETE, similar to INFO_DEBUG / InfoDebug earlier in
##  this file.
##
if not IsBound( InfoObsolete ) then
  DeclareInfoClass( "InfoObsolete" );
  SetInfoLevel( InfoObsolete, 1 );

  MAKE_READ_WRITE_GLOBAL( "INFO_OBSOLETE" );
  INFO_OBSOLETE:= function( arg )
    local string, i;

    string:= [];
    for i in [ 2 .. LEN_LIST( arg ) ] do
      APPEND_LIST_INTR( string, arg[i] );
    od;
    Info( InfoObsolete, arg[1], string );
  end;
  MAKE_READ_ONLY_GLOBAL( "INFO_OBSOLETE" );
fi;

[ Dauer der Verarbeitung: 0.36 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge