gap-4r8p8/0000755000175000017500000000000013157272633011147 5ustar billbillgap-4r8p8/etc/0000755000175000017500000000000013157272633011722 5ustar billbillgap-4r8p8/etc/README.tools0000644000175000017500000000650613146323354013743 0ustar billbill README.tools The files in the tools.tar.gz archive have mainly been provided to assist package authors. They are briefly described below according to the directory hierarchy. More information is contained in the Appendix of the Example package manual and in the gapmacro.tex manual (gapmacrodoc.pdf file in this archive). gap4r5/ doc/ gapmacro.tex TeX macros file for writing documentation (the main GAP manuals and almost a half of the currently redistributed GAP packages are already using GAPDoc format which provides a better functionality, so we keep gapmacro.tex here only for packages which are still using it). gapmacrodoc.pdf gapmacro.tex manual, which is made using the same gapmacro.tex format (so it may be used as an example). gapmacrodoc.tex TeX source for the gapmacrodoc.pdf. manualindex awk script that creates manual.ind for a main or package manual (calls MakeIndex). etc/ classifyfiles.py Python script which we use in the package update mechanism to classify files into text and binary and to exclude some files or directories from distribution. It may be used to check how files in your package will be classified. Also it is possible to use it in your own package wrapping scripts. Usage instructions are at the beginning of classifyfiles.py. patternstextbinary.txt file describing patterns for text and binary files, used by the classifyfiles.py script. patternscolor.txt file describing file exclusion/inclusion patterns, used by the classifyfiles.py script. buildman.pe Perl script that builds a .tex file from a .msk file and a config file (see gapmacrodoc.pdf for usage instructions). convert.pl Perl script that builds an HTML manual from TeX files that follow the gapmacro.tex conventions (see gapmacrodoc.pdf and comments in the script itself for usage instructions). packpack shell script that creates archives in several formats (.zoo, .zip, .tar.gz, .tar.bz2) of a package (i.e. it ``packs up a package''). Usage instructions are at the beginning of packpack. You may modify it to remove some parts; for example, we do not use the ``zoo'' archive format any more, so you do not have to provide it). unzoo.c C source file for the unzoo program (in case you need it to unpack some legacy zoo archive). README.tools this file! Most of the software required to use the above tools comes standard with various UNIX/Linux installations, e.g. you should already have tex, bibtex, makeindex, pdftex, perl, awk, python etc. See the Appendix of the Example package manual and the gapmacro.tex manual (gapmacrodoc.pdf file in this archive) for more details about such external dependencies and further usage instructions. The GAP Group October 2011 gap-4r8p8/etc/gap_indent.vim0000644000175000017500000000553713146314334014552 0ustar billbill" GAP indent file " Language: GAP (https://www.gap-system.org) " Maintainer: Frank Lübeck (Frank.Luebeck@Math.RWTH-Aachen.De) " Comments: " -- started from Matlab indent file in vim 6.0 " -- Many people like a 4 blank indentation, I prefer 2 blanks: this can " be adjusted by setting `GAPIndentShift' to 4, 2 (default) or whatever " you like " TODO: nice handling of `continuation' lines " Only load this indent file when no other was loaded. if exists("b:did_indent") finish endif let b:did_indent = 1 " Some preliminary setting setlocal nolisp " Make sure lisp indenting doesn't supersede us setlocal autoindent setlocal indentexpr=GetGAPIndent(v:lnum) setlocal indentkeys=o,O=end,=fi,=else,=elif,=od,=\) let GAPIndentShift = 2 " Only define the function once. if exists("*GetGAPIndent") finish endif " this function computes for line lnum of the current buffer the number of " blanks for the indentation function! GetGAPIndent(lnum) " Give up if this line is explicitly joined. if getline(a:lnum - 1) =~ '\\$' return -1 endif " Search backwards for the first non-empty line. let plnum = a:lnum - 1 while plnum > 0 && getline(plnum) =~ '^\s*$' let plnum = plnum - 1 endwhile if plnum == 0 " This is the first non-empty line, use zero indent. return 0 endif let curind = indent(plnum) " If the current line is a stop-block statement... if getline(v:lnum) =~ '^\s*\(end\|else\|elif\|fi\|od\|until\)\>' " See if this line does not follow the line right after an openblock if getline(plnum) =~ '^\s*\(for\|if\|then\|else\|elif\|while\|repeat\)\>' " See if the user has already dedented elseif indent(v:lnum) > curind - g:GAPIndentShift " If not, recommend one dedent let curind = curind - g:GAPIndentShift else " Otherwise, trust the user return -1 endif " If the previous line opened a block elseif (getline(plnum) =~ '^\s*\(for\|if\|then\|else\|elif\|while\|repeat\)\>' || getline(plnum) =~ '\ *(') " See if the user has already indented, or if block is also finished " im plnum if (indent(v:lnum) < curind + g:GAPIndentShift && getline(plnum) !~ '\<\(end\|fi\|od\)\>') "If not, recommend indent let curind = curind + g:GAPIndentShift else " Otherwise, trust the user return -1 endif " Handle assignments over several lines elseif (getline(plnum) =~ '^\s*[a-zA-Z0-9]*\s*:=[^;]*$') let curind = match(getline(plnum), ':=') + 3 " Handle continuing function calls over several lines elseif (getline(plnum) =~ '^\s*[a-zA-Z0-9]*\s*([^;]*$') let curind = indent(plnum) + 2*GAPIndentShift; endif " If we got to here, it means that the user takes the standard version, " so we return it return curind endfunction " vim:sw=2 gap-4r8p8/etc/debugvim.txt0000644000175000017500000000251313146314334014257 0ustar billbillShort introduction into debugging in GAP by Thomas Breuer and Max Neunhöffer (see library file lib/debug.g) Debug( [,]); # opens an editor to insert debugging code # the debugged function is stored under a number A "debugged" function gets a number and can later be accessed either as itself or via this number. Debug(); # opens an editor to edit debugging code UnDebug(); # restores the function to its old form ShowDebug(); # show currently debugged functions SetDebugCount(,); # Set counter of counting break point Keys in editor: F12 : this help F2 : Set break point before current line F3 : Set watch point before current line F4 : Set counting break point before current line F5 : Set Print statement before current line Put any other debugging code into the function. Note that the function object itself will be changed "in place"! This means that all places where this function is installed for example as a method will be changed simultanously. BEWARE of debugging functions that have been created within the scope of another function possibly with access to the surrounding local variables (see "Orbish" and friends)! ***Debugging of such functions does not work and might ruin them!*** gap-4r8p8/etc/buildman.pe0000755000175000017500000010636413146323354014053 0ustar billbill#!/usr/bin/perl @msfiles = (); @gdfiles = (); $DIR = "."; $LIB="."; $check=0; if ( @ARGV && $ARGV[0] =~ /-f/ ) { open( COF, "$ARGV[1]" ); while ( $line = ) { chomp $line; if ( $line =~ /DIR/ ) { @words = split /=/, $line; $DIR = $words[1]; $DIR =~ s/[; "]//g; print "DIR set to $DIR\n"; } elsif ( $line =~ /LIB/ ) { @words = split /=/, $line; $LIB = $words[1]; $LIB =~ s/[; "]//g; print "LIB set to $LIB\n"; } elsif ( $line =~ /msfiles/ ) { @words = split /=/, $line; $files = $words[1]; while ( !( $line =~ /;/ ) ) { $line = ; $files .= $line; } $files =~ s/[\(\);\n" ]//g; @msfiles = split /,/, $files; } elsif ( $line =~ /gdfiles/ ) { @words = split /=/, $line; $files = $words[1]; while ( !( $line =~ /;/ ) ) { $line = ; $files .= $line; } $files =~ s/[\(\);\n" ]//g; @gdfiles = split /,/, $files; } elsif ( $line =~ /check/ ) { # the manual builder should produce a file `notfound'. $check = 1; } elsif ( $line =~ /=/ ) { # assignment of {{variable}} replacements @varass = split /=/, $line; $defaults{$varass[0]} = $varass[1]; } } } sub coll_and_fam { # cope with `DeclareCategoryFamily' and `DeclareCategoryCollection' if ($line =~ "DeclareCategoryFamily") { @lipa = split /\"/, $line; $line = $lipa[1].":= NewCategory(\"".$lipa[1]."Family\");"; } if ($line =~ "DeclareCategoryCollection") { @lipa = split /\"/, $line; if ($lipa[1] =~ "Collection") { $lipa[1] =~ s/Collection//g; $line = $lipa[1] . "CollColl := NewCategory(\"" . $lipa[1] . "CollColl\",IsObject);"; } else { $line = $lipa[1] . "Collection := NewCategory(\"" . $lipa[1] . "Collection\",IsObject);"; } } } sub read_table { foreach $file ( @gdfiles ) { $currread = ($file =~ /\.(g|tbd|tmd)/ ) ? $file : "$file.gd"; open( GDF, "$LIB/$currread") ? do {print "reading $LIB/$currread\n"; $readon=1;} : do {print "$LIB/$currread not found.\n"; $readon=0;}; while ( ($readon) && ($line = ) ) { if ( $line =~ /^#[CAPOFVR]/ ) { # We look for lines of form: # # ( ) . . # # . . . . . . . # where is a letter in "CAPOFVR". $nfun = 0; #no. of functions in the block @code = (); #CAPOFVR codes of the functions @fdec = (); #things of form: ( ) #or: @ldes = (); #things of form: #with dots and superfluous spaces stripped out #... which we don't currently use. while ( $line =~ /^#([CAPOFVR])/ ) { $code[++$nfun] = $1; # The following piece of code is for long declarations that use several lines. # It is assumed that such a long declaration contains "(" on the first line # and ")" on some line below. $des = $line; if ( $line =~ /\(/ ) { while ( !( $line =~ /\)/ ) ) { ($line = ) =~ s/^#[CAPOFVR]\s*/ /; if ($line =~ /^##\s*$/) { $des =~ m/^#([A-Z])\s*([^\(]*)/; #Is it better to die or print an error message? #... I opted for print error message + try to #recover, because people don't read error #messages ... right or wrong? - GG #die "Closing bracket missing for ". # "$1 definition of $2\n". # "near line $. of $LIB/$currread\n"; print STDERR "Closing bracket missing for ", "$1 definition of $2\n", "near line $. of $LIB/$currread\n", "... attempting to recover by ", "inserting needed closing ", "bracket.\n"; $line .= ") "; } $des =~ s/[%]*$/%/; $des .= $line; } } ( $des =~ /#[A-Z]\s*(\w+(\s*\([^\)]*\))?)(.*)/ ) || die "syntax error near line $. of $LIB/$currread\n"; ($fdec[$nfun] = $1) =~ s/\s*\(/\(/; ($ldes[$nfun] = $3) =~ s/[.]//g; $ldes[$nfun] =~ s/^\s+//; $ldes[$nfun] =~ s/\s+/ /g; #print STDERR "fdec: $fdec[$nfun], ldes: $ldes[$nfun]\n"; $line = ; } $code[0] = $nfun; $fdec[0] = $nfun; $ldes[0] = $nfun; @words = split /\(/, $fdec[1]; $key = $words[0]; $key .= "@"; $key .= $file; if ( ( %{ $tab{$key} } ) ) { print "DUPLICATE DEFINITION OF $key\n"; } @args = (); $args[0] = $nfun; for ($k=1; $k <= $nfun; ++$k ) { @argsk = (); $argsk[0] = 0; if ( $fdec[$k] =~ /\(/ ) { @aa = split /\(/, $fdec[$k]; $w = $aa[1]; @aa = split /\)/, $w; $w = $aa[0]; if (!$w) { $w= " ";} @aa = split /,/, $w; $noa = 0; foreach $a ( @aa ) { ++$noa; $argsk[$noa] = $a; } } $argsk[0] = $noa; $args[$k] = [ @argsk ]; } $expl = ""; while ( ($line = ) =~ /^#/ ) { if ( !( $line =~ /^#T/ ) ) { $line =~ s/^[#]*//g; # remove two leading spaces # Hmmm! ... This doesn't require any spaces!! $line =~ s/^ //; $line =~ s/^ //; $expl .= $line; } } @impl = (); $impl[0] = $nfun; @ipmt = (); $ipmt[0] = $nfun; $ww0 = ""; for ($k=1; $k <= $nfun; ++$k) { $ww1 = $ww0; if ( $fdec[$k] =~ /\(/ ) { @ww = split /\(/, $fdec[$k]; $ww0 = $ww[0]; } else { $ww0 = $fdec[$k]; } # If the 'new' declaration is not the same as the old one, then we look for a # new implementation line (otherwise we do not). if ( !( $ww0 =~ /^$ww1$/ ) ) { coll_and_fam(); while ( !( $line =~ /$ww0/ ) ) { eof( GDF ) && die "$ww0 is declared but there ". "is no implementation line\n... ", "near line $. of $LIB/$currread\n"; $line = ; coll_and_fam(); } $defn = $line; while ( !( $line =~ /;/ ) ) { $line = ; $defn .= $line; } } @implk = (); $implk[0] = 0; $j = 0; @words = split /,/, $defn; foreach $w ( @words ) { if ( !( $w =~ /\(/ ) ) { ++$implk[0]; ++$j; $implkj = ""; @wds = split / and /, $w; foreach $v ( @wds ) { $v =~ s/\)|\[|\]|;| |\n//g; if ( $implkj =~ /\w/ ) { $implkj .= ", ".$v; } else { $implkj .= $v; } } $implk[$j] = $implkj; } } $impl[$k] = [ @implk ]; @words = split /\(/, $defn; $w = $words[0]; if ( $w =~ /:=/ ) { @wds = split /:=/, $w; $v = $wds[1]; } else { $v = $words[0]; } $ipmt[$k] = $v; } # Some default filling in of tester and setter (if such objects are found # later on, they will be inserted). @test = (); @sett = (); # $ntes = 0; $nset = 0; $test[0]=0; $sett[0]=0; $tab{$key}{test} = [ @test ]; $tab{$key}{sett} = [ @sett ]; $tab{$key}{expl} = $expl; $tab{$key}{code} = [ @code ]; $tab{$key}{args} = [ @args ]; $tab{$key}{fdec} = [ @fdec ]; $tab{$key}{ldes} = [ @ldes ]; $tab{$key}{impl} = [ @impl ]; $tab{$key}{ipmt} = [ @ipmt ]; $tab{$key}{file} = $currread; } # The arrays sett and test are bags of setters and testers respectively. This # means that they can appear in any order, it cannot be assumed that they # correspond to the order in which the fdecs appear (for instance). # setter and tester are now declared automatically # if ( $line =~ /Set/ ) { # ++$nset; # ++$sett[0]; # @words = split /:=/, $line; # $w = $words[0]; # $w =~ s/ //g; # $sett[$nset] = $w; # $tab{$key}{sett} = [ @sett ]; # } elsif ( $line =~ /Has/ ) { # ++$ntes; # ++$test[0]; # @words = split /:=/, $line; # $w = $words[0]; # $w =~ s/ //g; # $test[$ntes] = $w; # $tab{$key}{test} = [ @test ]; # } if ( $line =~ /#[0-9]/ ) { @chars = split //, $line; $hnum = $chars[1]; for ($k=2; ($c=$chars[$k]) =~ /[0-9]/; ++$k) { $hnum .= $c; } $htxt = ""; while ( ($line = ) =~ /^#/ ) { if ( $line =~ /##/ ) { $line =~ s/#//g; # remove 1 or two leading spaces $line =~ s/^ //g; $line =~ s/^ //g; $htxt .= $line; } } $clef = "_h".$file; $tab{$clef}{$hnum} = $htxt; } } if ( open( GIF, "$LIB/$file.gi" ) ) { print "reading $LIB/$file.gi\n"; $currread="$file.gi"; $key = ""; $gide=""; $first = 1; while ( $line = ) { if ( $line =~ /#[CAPOFVRM]/ ) { if ( $first == 1 ) { $first = 0; if ( $tab{$key} ) { $tab{$key}{gide} = $gide; $tab{$key}{meth} = [ @meth ]; } @words = split /\(/, $line; $key = $words[0]; $key =~ s/#[CAPOFVRM]| //g; $gide = ""; @mlines = (); $nom = 0; $insm = 0; @meth = (0); } if ( $line =~ /#M/ ) { ++$nom; $mlines[0] = $nom; $mlines[$nom] = $line; } } elsif ( $first == 0 ) { $first =1; } # The next lines of code handle the #M declarations that must go into the # manual from the .gi file. We assume: # # * there are as many #M declarations in the header as Install(Other)Method # lines, # * if a method is installed by InstallOtherMethod, and it contains # comments in the body ( #+ lines ), then the corresponding declaration # goes into the manual. # # In all comment lines in the body of an InstallOtherMethod, the string # NUMBER will be replaced by the number (integer) that reflects the position # of this declaration in the list of all declarations. if ( $line =~ /Install(Other|)Method/ ) { ++$insm; $argres = ""; if ( $insm <= $nom ) { $foundres = 0; $hascom = 0; $end = 0; $occurass = 0; while ( $end == 0 ) { if ( $line =~ /:=/ ) { $occurass = 1; } if ( $line =~ /^(#\+)/ ) { $hascom = 1; $line =~ s/^(#\+)/ /; @words = split ' ', $line; foreach $w ( @words ) { if ( !($w=~/\n/) ) {$gide .= ($w." ");} } $gide .= "\n"; } elsif ( $foundres == 0 && $line =~ /\[/ ) { $argres = $line; while ( !( $line =~ /\]/ ) ) { $line = ; $argres .= $line; } $met = $argres; $met =~ s/\\\[//g; if ( $met =~ /\[/ ) { @words = split /\[|\]/, $met; $met = $words[1]; $met =~ s/,|\n/ /g; $meth[0] = $insm; $meth[$insm] = $met; $foundres = 1; } } if ( ( $line =~ /\);/ && $occurass == 0 ) || $line =~ /end.*\);/ ) { $end = 1; } else { $line = ; } } if ( $hascom == 1 ) { if ( $tab{$key} ) { @code = @{ $tab{$key}{code} }; @fdec = @{ $tab{$key}{fdec} }; @args = @{ $tab{$key}{args} }; @ldes = @{ $tab{$key}{ldes} }; @impl = @{ $tab{$key}{impl} }; } else { @code = (); @fdec = (); @args = (); @ldes = (); @impl = (); $code[0] = 0; $tab{$key}{expl} = ""; } $nfun = $code[0]; ++$nfun; $gide =~ s/NUMBER/$nfun/g; $code[0] = $nfun; $code[$nfun] = "M"; $tab{$key}{code} = [ @code ]; @words = split /\)/, $mlines[$insm]; $w = $words[0]; $w .= "\)"; $w =~ s/#M| //g; $fdec[$nfun] = $w; $fdec[0] = $nfun; $tab{$key}{fdec} = [ @fdec ]; @argsk = (); $argsk[0] = 0; @aa = split // ) { ++$noa; $a =~ s/>| |,|\)//g; $argsk[$noa] = $a; } } $argsk[0] = $noa; $args[0] = $nfun; $args[$nfun] = [ @argsk ]; $tab{$key}{args} = [ @args ]; $w = $words[1]; $w =~ s/\.| |\n//g; $ldes[0] = $nfun; $ldes[$nfun] = $w; $tab{$key}{ldes} = [ @ldes ]; $argres =~ s/\].*/\]/; @implk = (); $implk[0] = 0; $j = 0; @words = split /,/, $argres; foreach $w ( @words ) { ++$implk[0]; ++$j; $implkj = ""; @wds = split / and /, $w; foreach $v ( @wds ) { $v =~ s/\)|\[|\]|;| |\n//g; if ( $implkj =~ /\w/ ) { $implkj .= ", ".$v; } else { $implkj .= $v; } } $implk[$j] = $implkj; } $impl[$nfun] = [ @implk ]; $impl[0] = $nfun; $tab{$key}{impl} = [ @impl ]; } } else { $meth[0] = $insm; $foundres = 0; while ( $foundres == 0 ) { while ( !( $line =~ /\[/ ) ) { $line = ; } $met = " ".$line; while ( !( $line =~ /\]/ ) ) { $line = ; $met .= $line; } $met =~ s/\\\[//g; if ( $met =~ /\[/ ) { @words = split /\[|\]/, $met; $met = $words[1]; $met =~ s/, |\n//g; $meth[$insm] = $met; $foundres = 1; } else { $line = ; } } } } if ( $line =~ /^(#\+)/ ) { $line =~ s/^(#\+)/ /; @words = split ' ', $line; foreach $w ( @words ) { if ( !($w=~/\n/) ) {$gide .= ($w." ");} } $gide .= "\n"; } } if ( $tab{$key} ) { $tab{$key}{gide} = $gide; $tab{$key}{meth} = [ @meth ]; } } if ( open( GFI, "$file.g" ) ) { $key = ""; $gdes=""; while ( $line = ) { if ( $tab{$key} ) { $tab{$key}{gdes} = $gdes; } if ( $line =~ /#[CAPOFVR]/ ) { @words = split /\(/, $line; $key = $words[0]; $key =~ s/#[CAPOFVR]| //g; $gdes = ""; } if ( $line =~ /^(#\+)/ ) { $line =~ s/^(#\+)/ /; @words = split ' ', $line; foreach $w ( @words ) { if ( !($w=~/\n/) ) {$gdes .= ($w." ");} } $gdes .= "\n"; } } if ( $tab{$key} ) { $tab{$key}{gdes} = $gdes; } } close GDF; } %tab; } sub make_tex { print "Reading files...\n"; %tab = {}; %tab = read_table(); foreach $msfile (@msfiles) { open( MSK, "<$msfile.msk" ) || die "Cannot open manual skeleton file $msfile.msk"; # if the `tex' file does already exist, make it writable chmod 0644, "$DIR/$msfile.tex"; open( TEX, ">$DIR/$msfile.tex" ) || die "Cannot open TeX output file $DIR/$msfile.tex."; print "Composing the TeX file $msfile.tex\n"; print TEX "% This file was created automatically from $msfile.msk.\n", "% DO NOT EDIT!\n"; SCANMSK: while ( $line = ) { # treat the {{...}} replacements while ( $line =~ /{{([^}]*)}}/ ) { $key = $1; if ( $key =~ /date/ ) { $replace=`date +"%d %B %Y"`; } elsif ( $key =~ /year/ ) { $replace=`date +"%Y"`; } elsif ( $defaults{$key} ) { $replace=$defaults{$key}; } else { die "$key has no replacement value"; } $line =~ s/{{$key}}/$replace/; } # Now deal with the `Declaration' mechanism. # The following is the most we ever need to match: # \Declaration{}[]{