/**************************************************************************
util2 . c
Colin Ramsay ( cram @ itee . uq . edu . au )
6 Dec 00
ADVANCED COSET ENUMERATOR , Version 3 . 001
Copyright 2000
Centre for Discrete Mathematics and Computing ,
Department of Mathematics and
Department of Computer Science & Electrical Engineering ,
The University of Queensland , QLD 4072 .
( http : //staff.itee.uq.edu.au/havas)
These are the utilities for Level 2 of ACE .
**************************************************************************/
#include "al2.h"
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <time.h>
/******************************************************************
void al2_init ( void )
One - off initialisation of the Level 2 stuff , and all lower levels .
Note that there is no need to initialise , for example , intarr [ ] .
******************************************************************/
void al2_init(void )
{
al1_init();
okstart = okcont = okredo = FALSE ;
tabinfo = tabindex = FALSE ;
lresult = -8192 ; /* invalid mode ! */
echo = FALSE ;
skipnl = TRUE ;
currip = currkey[0 ] = currname[0 ] = '\0' ;
currword = NULL;
currsiz = currexp = 0 ;
intcnt = 0 ;
srand((unsigned int )time(NULL)); /* Seed rand() with time */
}
/******************************************************************
char * al2_strdup ( char * s )
strdup ( ) is not ANSI C , so this is our version . Should we regard
an error as fatal , and abort ?
******************************************************************/
char *al2_strdup(char *s)
{
char *t;
if ((t = malloc(strlen(s)+1 )) == NULL)
{ al2_continue("out of memory in al2_strdup()" ); }
return (strcpy(t,s));
}
/******************************************************************
int al2_outlen ( int i )
Returns the print - length of an integer i ( i . e . , ~ $ \ log_ { 10 } i $ ) .
The int i is assumed to satisfy i > = 0 .
******************************************************************/
int al2_outlen(int i)
{
int len = 1 ;
while ((i /= 10 ) != 0 )
{ len++; }
return (len);
}
/**************************************************************************
All Level 2 errors are filtered by one of the following three handlers .
These take the appropriate action , and then jump back to the top - level
main ( ) routine ; ie , the outermost level of Level 2 . We swallow the
remainder of any input line ( possibly losing some commands ) ; so multi - line
commands in error may not be properly tidied - up . The question of what
exactly to do if fip / fop are not stdin / stdout is put in the ` too hard '
basket ; we simply switch them both back to their defaults . Note that ,
although the code for _ continue ( ) & _ restart ( ) is the same , they return to
different points ( & do different things ) in main ( ) .
Warning : The error - handling is fairly basic , since it ' s not our intent to
develop a fully - fledged interactive interface . We simply tidy - up the best
we can and carry on .
**************************************************************************/
/******************************************************************
void al2_continue ( char * msg )
An error has occurred , but it doesn ' t affected the ok . . . flags , or
the table ' s validity .
******************************************************************/
void al2_continue(char *msg)
{
if (fop != stdout)
{
if (fop != NULL)
{ fclose(fop); }
fop = stdout;
}
if (fip != stdin)
{
if (fip != NULL)
{ fclose(fip); }
fip = stdin;
currip = '\0' ;
}
fflush(fop);
fprintf(fop, "** ERROR (continuing with next line)\n" );
fprintf(fop, " %s\n" , msg);
while ( !(currip == '\n' || currip == '\r' || currip == EOF) )
{ al2_nextip(); }
longjmp(env,1 );
}
/******************************************************************
void al2_restart ( char * msg )
Something nasty has happened & we ' ll be disallowing continue / redo .
******************************************************************/
void al2_restart(char *msg)
{
if (fop != stdout)
{
if (fop != NULL)
{ fclose(fop); }
fop = stdout;
}
if (fip != stdin)
{
if (fip != NULL)
{ fclose(fip); }
fip = stdin;
currip = '\0' ;
}
fflush(fop);
fprintf(fop, "** ERROR (restarting with next line)\n" );
fprintf(fop, " %s\n" , msg);
while ( !(currip == '\n' || currip == '\r' || currip == EOF) )
{ al2_nextip(); }
longjmp(env,2 );
}
/******************************************************************
void al2_abort ( char * msg )
No point in being clever here , we ' re going to stop .
******************************************************************/
void al2_abort(char *msg)
{
if (fop != stdout)
{
if (fop != NULL)
{ fclose(fop); }
fop = stdout;
}
if (fip != stdin)
{
if (fip != NULL)
{ fclose(fip); }
fip = stdin;
currip = '\0' ;
}
fflush(fop);
fprintf(fop, "** ERROR (aborting)\n" );
fprintf(fop, " %s\n" , msg);
longjmp(env,3 );
}
/******************************************************************
void al2_aip ( char * name )
Switch to a new input file . We abort via _ restart ( ) if this is not
possible , and that call will reset fip / fop properly .
******************************************************************/
void al2_aip(char *name)
{
/* Close the current input file (unless it is 'stdin'). */
if (fip != stdin && fip != NULL)
{ fclose(fip); }
fip = NULL;
/* Try to open the new input file (unless it is 'stdin'). */
if (strcmp(name, "stdin" ) != 0 )
{
if ((fip = fopen(name, "r" )) == NULL)
{ al2_restart("can't open new input, using 'stdin'" ); }
}
else
{ fip = stdin; }
currip = '\0' ; /* Initialise current i/p char. */
}
/******************************************************************
void al2_aop ( char * name )
Switch to a new output file . We abort via _ restart ( ) if this is
not possible , and that call will reset fip / fop properly . Note
that there is no need to run setvbuf ( ) on stdout , since this was
done in the call to al0_init ( ) .
******************************************************************/
void al2_aop(char *name)
{
/* Close the current output file (unless it is 'stdout'). */
if (fop != stdout && fop != NULL)
{ fclose(fop); }
fop = NULL;
/* Try to open the new output file (unless it is 'stdout'). */
if (strcmp(name, "stdout" ) != 0 )
{
if ((fop = fopen(name, "w" )) == NULL)
{
fop = stdout;
fprintf(fop, "can't open new output, using 'stdout'" );
}
else
{ setvbuf(fop, NULL, _IOLBF, 0 ); } /* line buffered o/p */
}
else
{ fop = stdout; }
}
/******************************************************************
void al2_dump ( Logic allofit )
Dump out the internals of Level 2 of ACE , working through al2 . h
more or less in order .
******************************************************************/
void al2_dump(Logic allofit)
{
int i;
fprintf(fop, " #---- %s: Level 2 Dump ----\n" , ACE_VER);
/* env; - nothing (meaningful) we can do here! */
/* okstart, okcont, okredo; */
fprintf(fop, "okstart=%d okcont=%d okredo=%d\n" ,
okstart, okcont, okredo);
/* tabinfo, tabindex, lresult */
fprintf(fop, "tabinfo=%d tabindex=%d lresult=%d\n" ,
tabinfo, tabindex, lresult);
/* echo, skipnl, currip, currkey, currname; */
fprintf(fop, "echo=%d skipnl=%d currip=%d" , echo, skipnl, currip);
if (isprint(currip))
{ fprintf(fop, "(%c)\n" , currip); }
else
{ fprintf(fop, "\n" ); }
fprintf(fop, "currkey=%s\n" , currkey);
fprintf(fop, "currname=%s\n" , currname);
/* *currword, currsiz, currexp; */
fprintf(fop, "currsize=%d currexp=%d currword=" , currsiz, currexp);
if (currword == NULL)
{ fprintf(fop, "NULL" ); }
else
{
if (allofit)
{
for (i = 0 ; i < currsiz; i++)
{ fprintf(fop, "%d " , currword[i]); }
}
else
{ fprintf(fop, "non-NULL" ); }
}
fprintf(fop, "\n" );
/* intcnt, intarr[32]; */
if (intcnt == 0 )
{ fprintf(fop, "intcnt=0 (empty)\n" ); }
else
{
fprintf(fop, "intcnt=%d intarr[]=" , intcnt);
for (i = 0 ; i < intcnt; i++)
{ fprintf(fop, "%d " , intarr[i]); }
fprintf(fop, "\n" );
}
fprintf(fop, " #---------------------------------\n" );
}
/******************************************************************
void al2_opt ( void )
Pretty - print the date of compilation and all the various options
included in this build .
******************************************************************/
void al2_opt(void )
{
fprintf(fop, "%s executable\n" , ACE_VER);
fprintf(fop, "Level 0 options:\n" );
#ifdef AL0_STAT
fprintf(fop, " statistics package = on\n" );
#else
fprintf(fop, " statistics package = off\n" );
#endif
#ifdef AL0_CC
fprintf(fop, " coinc processing messages = on\n" );
#else
fprintf(fop, " coinc processing messages = off\n" );
#endif
#ifdef AL0_DD
fprintf(fop, " dedn processing messages = on\n" );
#else
fprintf(fop, " dedn processing messages = off\n" );
#endif
fprintf(fop, "Level 1 options:\n" );
#ifdef AL1_BINARY
fprintf(fop, " workspace multipliers = binary\n" );
#else
fprintf(fop, " workspace multipliers = decimal\n" );
#endif
fprintf(fop, "Level 2 options:\n" );
#ifdef AL2_HINFO
fprintf(fop, " host info = on\n" );
#else
fprintf(fop, " host info = off\n" );
#endif
}
/******************************************************************
void al2_help ( void )
******************************************************************/
void al2_help(void )
{
fprintf(fop, " #---- %s: Level 2 Help ----\n" , ACE_VER);
fprintf(fop, "add gen[erators] / sg : <word list> ;\n" );
fprintf(fop, "add rel[ators] / rl : <relation list> ;\n" );
fprintf(fop, "aep : 1..7 ;\n" );
fprintf(fop, "ai / alter i[nput] : [<filename>] ;\n" );
fprintf(fop, "ao / alter o[utput] : [<filename>] ;\n" );
fprintf(fop, "as[is] : [0/1] ;\n" );
fprintf(fop, "beg[in] / end / start ;\n" );
fprintf(fop, "bye / exit / q[uit] ;\n" );
fprintf(fop, "cc / coset coinc[idence] : int ;\n" );
fprintf(fop, "c[factor] / ct[ factor] : [int] ;\n" );
fprintf(fop, "check / redo ;\n" );
fprintf(fop, "com[paction] : [0..100] ;\n" );
fprintf(fop, "cont[inue] ;\n" );
fprintf(fop, "cy[cles] ;\n" );
fprintf(fop, "ded mo[de] / dmod[e] : [0..4] ;\n" );
fprintf(fop, "ded si[ze] / dsiz[e] : [0/1..] ;\n" );
fprintf(fop, "def[ault] ;\n" );
fprintf(fop, "del gen[erators] / ds : <int list> ;\n" );
fprintf(fop, "del rel[ators] / dr : <int list> ;\n" );
fprintf(fop, "d[ump] : [0/1/2[,0/1]] ;\n" );
fprintf(fop, "easy ;\n" );
fprintf(fop, "echo : [0/1] ;\n" );
fprintf(fop, "enum[eration] / group name : <string> ;\n" );
fprintf(fop, "fel[sch] : [0/1] ;\n" );
fprintf(fop, "f[factor] / fi[ll factor] : [0/1..] ;\n" );
fprintf(fop, "gen[erators] / subgroup gen[erators] : <word list> ;\n" );
fprintf(fop, "gr[oup generators]: [<letter list> / int] ;\n" );
fprintf(fop, "group relators / rel[ators] : <relation list> ;\n" );
fprintf(fop, "hard ;\n" );
fprintf(fop, "h[elp] ;\n" );
fprintf(fop, "hlt ;\n" );
fprintf(fop, "ho[le limit] : [-1/0..100] ;\n" );
fprintf(fop, "look[ahead] : [0/1..4] ;\n" );
fprintf(fop, "loop[ limit] : [0/1..] ;\n" );
fprintf(fop, "max[ cosets] : [0/2..] ;\n" );
fprintf(fop, "mend[elsohn] : [0/1] ;\n" );
fprintf(fop, "mess[ages] / mon[itor] : [int] ;\n" );
fprintf(fop, "mo[de] ;\n" );
fprintf(fop, "nc / normal[ closure] : [0/1] ;\n" );
fprintf(fop, "no[ relators in subgroup] : [-1/0/1..] ;\n" );
fprintf(fop, "oo / order[ option] : int ;\n" );
fprintf(fop, "opt[ions] ;\n" );
fprintf(fop, "par[ameters] ; - old option (ignored)\n" );
fprintf(fop, "path[ compression] : [0/1] ;\n" );
fprintf(fop, "pd mo[de] / pmod[e] : [0/1..3] ;\n" );
fprintf(fop, "pd si[ze] / psiz[e] : [0/2/4/8/...] ;\n" );
fprintf(fop, "print det[ails] / sr : [int] ;\n" );
fprintf(fop, "pr[int table] : [[-]int[,int[,int]]] ;\n" );
fprintf(fop, "pure c[t] ;\n" );
fprintf(fop, "pure r[t] ;\n" );
fprintf(fop, "rc / random coinc[idences]: int[,int] ;\n" );
fprintf(fop, "rec[over] / contig[uous] ;\n" );
fprintf(fop, "rep : 1..7[,int] ;\n" );
fprintf(fop, "restart ; - old option (ignored)\n" );
fprintf(fop, "r[factor] / rt[ factor] : [int] ;\n" );
fprintf(fop, "row[ filling] : [0/1] ;\n" );
fprintf(fop, "sc / stabil[ising cosets] : int ;\n" );
fprintf(fop, "sims : 1/3/5/7/9 ;\n" );
fprintf(fop, "st[andard table] ;\n" );
#ifdef AL0_STAT
fprintf(fop, "stat[istics] / stats ;\n" );
#endif
fprintf(fop, "style ;\n" );
fprintf(fop, "subg[roup name] : <string> ;\n" );
fprintf(fop, "sys[tem] : <string> ;\n" );
fprintf(fop, "text : <string> ;\n" );
fprintf(fop, "ti[me limit] : [-1/0/1..] ;\n" );
fprintf(fop, "tw / trace[ word] : int,<word> ;\n" );
fprintf(fop, "wo[rkspace] : [int[k/m/g]] ;\n" );
fprintf(fop, "# ... <newline> - a comment (ignored)\n" );
fprintf(fop, " #---------------------------------\n" );
}
/******************************************************************
void al2_nextip ( void )
Primes currip with the next character from fip , if we ' re not at the
end - of - file . Echoes the character if echo is on .
******************************************************************/
void al2_nextip(void )
{
if (currip != EOF)
{
currip = fgetc(fip);
if (echo && currip != EOF)
{ fputc(currip, fop); }
}
}
/******************************************************************
void al2_skipws ( void )
Skip all whitespace characters .
******************************************************************/
void al2_skipws(void )
{
Logic comment = (currip == '#' );
while ( currip == ' ' || currip == '\t' || comment ||
(skipnl && (currip == '\n' || currip == '\r' )) )
{
al2_nextip();
comment = (currip == '#' ||
(comment && currip != '\n' && currip != '\r' && currip != EOF));
}
}
/******************************************************************
void al2_nextnw ( void )
Skip to the next non - whitespace character .
******************************************************************/
void al2_nextnw(void )
{
al2_nextip();
al2_skipws();
}
Messung V0.5 in Prozent C=94 H=77 G=85
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet am 2026-06-27)
¤
*© Formatika GbR, Deutschland