/* de.c SYMMETRICA */
#include "def.h"
#include "macro.h"

#include <sys/types.h>
#ifdef unix
#undef MSDOS
#include <sys/times.h>
#endif /* unix */
#ifdef MSDOS
#include <time.h>   /* for the routine clock */
#endif

#ifdef unix
#include <sys/param.h>
#endif /* unix */

OP cons_zwei;   /* global INTEGER variable 2 */
OP cons_eins;   /* global INTEGER variable 1 */
OP cons_negeins;/* global INTEGER variable -1 */
OP cons_null;   /* global INTEGER variable 0 */
FILE *texout;   /* global variable for texoutput */
OP *speicher;   /* global variable for callocobject/SYMfreeall */
INT speicherposition;
INT no_banner = FALSE; /* AK 281293 */
INT no_mem_check=TRUE; /* AK 100893 */
INT english_tableau=FALSE; /* AK 290995 */

INT doffset=0L;  /* global for debugprint AK 160393 */
#define MEMOFFSET 0

#ifdef MEMCHECK 
/* d.h. test ob alles wieder freigegeben wird */
static INT mem_counter=0L; /* AK 090893 */
static INT mem_malloc=0L;
static INT mem_calloc=0L;

#define MEMTRACENUMBER 100
static char *mem_trace_pointer[MEMTRACENUMBER];


#endif /* MEMCHECK */
#define MEMDEBUG 
/* d.h. alles allocieren wird ausgegeben */
#undef MEMDEBUG 

char *  SYM_malloc_debug(a) int a;
{ char *b; b =  SYM_malloc(a); printf("SYM_malloc_debug:%ld\n",b); 
fflush(stdout);return b;}
char *  SYM_calloc_debug(a,c) int a,c;
{ char *b; b =  SYM_calloc(a,c); printf("SYM_calloc_debug:%ld\n",b); 
fflush(stdout);return b;}
int SYM_free_debug(a) char *a;
{int b; printf("SYM_free_debug:%ld\n",a); fflush(stdout);b=SYM_free(a);return b; }

#define PADDING 4
int SYM_free(a) char *a;
{
       if (sym_timelimit > 0L)
                check_time();

#ifdef MEMCHECK
	{
	int i;
	for (i=0;i<MEMTRACENUMBER;i++)
		{
		if (mem_trace_pointer[i]==a)
			{
			printf("freeing traced %d \n",a);
			mem_trace_pointer[i]=NULL;
			}
		}
	}

if (no_mem_check == TRUE)
	{
	mem_counter--;
	a-=PADDING;
	if (a[0]=='m')
		mem_malloc--;
	else if (a[0]=='c')
		mem_calloc--;
	else if (a[0]=='f')
		error("SYM_free:freeing free memory");
	else {
		error("SYM_free:unknown memory type");
		}
	a[0]='f';
#ifdef MEMDEBUG
	printf("SYM_free:%ld\n",a+1);
#endif /* MEMDEBUG */
	}
#endif /* MEMCHECK */
	free(a);
	return 0;
}
#ifdef MEMCHECK
char * SYM_calloc_trace(k,l) int k,l;
	{
	char *erg = SYM_calloc(k,l);
	int i;
	for (i=0;i<MEMTRACENUMBER;i++)
		{
		if (mem_trace_pointer[i]==NULL)
			{
			printf("calloc traced %d \n",erg);
			mem_trace_pointer[i]=erg;
			return erg;
			}
		}
	error("no trace space left in malloc");
	}

char * SYM_malloc_trace(k) int k;
	{
	char *erg = SYM_malloc(k);
	int i;
	for (i=0;i<MEMTRACENUMBER;i++)
		{
		if (mem_trace_pointer[i]==NULL)
			{
			printf("malloc traced %d \n",erg);
			mem_trace_pointer[i]=erg;
			return erg;
			}
		}
	error("no trace space left in malloc");
	}

#endif /* MEMCHECK */

char * SYM_malloc(a) int a;
{
	char *erg;
	INT err;
	if (sym_timelimit > 0L)
                check_time();

sca:
	
#ifdef MEMCHECK
	erg =  (char *)malloc(a+MEMOFFSET+PADDING);
#endif /* MEMCHECK */
#ifndef MEMCHECK
	erg =  (char *)malloc(a+MEMOFFSET);
#endif /* MEMCHECK */

#ifdef MEMCHECK
if (no_mem_check == TRUE)
	{
#ifdef MEMDEBUG
	printf("SYM_malloc:%ld,length:%d\n",erg+PADDING,a);
#endif /* MEMDEBUG */
	mem_counter++; 
	mem_malloc++; 
	}
#endif /* MEMCHECK */
if (erg == NULL)
		{
		err=error("SYM_malloc: no memory");
		if (err==ERROR_RETRY) goto sca;
		if (err==ERROR_EXPLAIN) {
			fprintf(stderr,"I wanted %ld Byte of Memory", a); }
		}
#ifdef MEMCHECK
if (no_mem_check == TRUE)
	{
	erg[0]='m';
	erg+=PADDING;
	}
#endif /* MEMCHECK */
	return erg;
}
char * SYM_calloc(a,b) int a,b;
{
	char *erg;
	INT err;
       if (sym_timelimit > 0L)
                check_time();

	if ( a < 0 )
		{
		err = error("SYM_calloc: negative number of entires");
		if (err==ERROR_EXPLAIN) {
			fprintf(stderr,"I wanted %ld pieces", a); }
		return NULL;
		}
sca:
#ifndef MEMCHECK
	erg= (char *)calloc(a,b+MEMOFFSET);
#endif /* MEMCHECK */
#ifdef MEMCHECK
	erg= (char *)calloc(a,b+MEMOFFSET+PADDING);
#endif /* MEMCHECK */
#ifdef MEMCHECK
if (no_mem_check == TRUE)
	{
#ifdef MEMDEBUG
	printf("SYM_calloc:%ld,length:%d\n",erg+PADDING,a*b);
#endif /* MEMDEBUG */
	mem_counter++; 
	mem_calloc++; 
	}
#endif /* MEMCHECK */
	if (erg == NULL)
		{
		err=error("SYM_calloc: no memory");
		if (err==ERROR_RETRY) goto sca;
		if (err==ERROR_EXPLAIN) {
			fprintf(stderr,"I wanted %ld Byte of Memory",
			a*b); }
		}
#ifdef MEMCHECK
if (no_mem_check == TRUE)
	{
	erg[0]='c';
	erg = erg+PADDING;
	}
#endif /* MEMCHECK */
	return erg;
}

char * SYM_realloc(a,b) char *a; int b;
{
	char *erg;
	char p;
	INT i,err,k= -1;
       if (sym_timelimit > 0L)
                check_time();
sca:
#ifdef MEMCHECK
	if (no_mem_check == TRUE)
		{
		a-=PADDING;
		p=a[0];
		if ( (p != 'c') && (p != 'm'))
			{
			error("unknown memory in realloc");
			}
		}
	for (i=0;i<MEMTRACENUMBER;i++)
		{
		if (mem_trace_pointer[i]==a) 
			{
			k = i;
			printf("realloc traced %d ",a);
			break;
			}
		}
#endif /* MEMCHECK */
#ifdef MEMCHECK
	erg= (char *)realloc(a,b+MEMOFFSET+PADDING);
#endif /* MEMCHECK */
#ifndef MEMCHECK
	erg= (char *)realloc(a,b+MEMOFFSET);
#endif /* MEMCHECK */
	if (erg == NULL)
		{
		err=error("SYM_realloc: no memory");
		if (err == ERROR_RETRY) goto sca;
		}
#ifdef MEMCHECK
	if (k != -1) printf(" becomes %d\n",erg);
	if (no_mem_check == TRUE)
		{
#ifdef MEMDEBUG
		printf("SYM_realloc:%ld\n",erg+1);
#endif /* MEMDEBUG */
		erg[0]=p;
		erg+=PADDING;
		}
#endif /* MEMCHECK */
	return erg;
}



INT anfang() 
/* AK 070890 V1.1 */ /* AK 210891 V1.3 */
{
	INT l;
	if (not no_banner)
		{
		printeingabe("SYMMETRICA VERSION 1.99 - ANFANG");
		printeingabe(TITELTEXT);
		}
#ifdef MEMCHECK
	callocobject_anfang();
	mem_counter=0L;
	mem_malloc=0L;
	mem_calloc=0L;
	for (l=0;l<MEMTRACENUMBER;l++)
		{
		mem_trace_pointer[l]=NULL;
		}
	
#endif /* MEMCHECK */
#ifdef unix
#ifndef linux
	mallopt(M_MXFAST,0);
	mallopt(M_GRAIN,1);
#endif /* linux */
#endif /* unix */
	time(&l);
	srand((unsigned long)l*l);
	memcheck("anfang");
	fflush(stdout); fflush(stderr);
	speicher=(OP *)SYM_malloc(SPEICHERSIZE * sizeof(OP));
	if (speicher == NULL)
		error("anfang:no mem");
	speicherposition = -1L;
	texmath_yn=0L; /* not in math mode */
#ifdef LONGINTTRUE
	start_longint();
#endif /* LONGINTTRUE */
	check_time_co = NULL; /* co routine called in check time,
				may be set by other programms */
	cons_zwei=callocobject(); m_i_i(2L,cons_zwei);
	cons_eins=callocobject(); m_i_i(1L,cons_eins);
	cons_negeins=callocobject(); m_i_i(-1L,cons_negeins);
	cons_null=callocobject(); m_i_i(0L,cons_null);
	texout = stdout;
#ifdef NUMBERTRUE	/* 291091: TPMcD */
/*	The third parameter is NULL or the name of a file with cyclotomic data	*/
	setup_numbers(STD_BASIS,TRUE, NULL);
	/*
	setup_numbers(STD_BASIS,TRUE,"CYCLOS.DAT");
	*/
#endif /* NUMBERTRUE */
#ifdef BRUCHTRUE
	bruch_anfang(); /* AK 100893 */
#endif /* BRUCHTRUE */
#ifdef VECTORTRUE
	vec_anfang(); /* AK 100893 */
#endif /* VECTORTRUE */
#ifdef TABLEAUXTRUE
	tab_anfang(); /* AK 100893 */
#endif /* TABLEAUXTRUE */
#ifdef PERMTRUE
	perm_anfang(); /* AK 100893 */
#endif /* PERMTRUE */
#ifdef LISTTRUE
	list_anfang(); /* AK 100893 */
#endif /* LISTTRUE */
#ifdef POLYTRUE
	monom_anfang(); /* AK 100893 */
#endif /* POLYTRUE */
	return(OK);
}

INT ende() 
/* AK 070890 V1.1 */ /* AK 210891 V1.3 */
{
	INT i;
	INT erg = OK;
	char t[100];
#ifdef NUMBERTRUE	/* 29.10.91: TPMcD */
	release_numbers();
#endif /* NUMBERTRUE */
#ifdef LONGINTTRUE
	longint_release();
#endif /* LONGINTTRUE */
#ifdef POLYTRUE
	monom_release();
#endif /* POLYTRUE */
#ifdef BRUCHTRUE
	bruch_ende(); /* AK 100893 */
#endif /* BRUCHTRUE */
#ifdef TABLEAUXTRUE
	tab_ende(); /* AK 100893 */
#endif /* TABLEAUXTRUE */
#ifdef VECTORTRUE
	vec_ende(); /* AK 100893 */
#endif /* VECTORTRUE */
#ifdef POLYTRUE
	monom_ende(); /* AK 100893 */
#endif /* POLYTRUE */
#ifdef SCHURTRUE
	schur_ende();
#endif /* SCHURTRUE */
#ifdef PARTTRUE
	part_ende();
#endif /* PARTTRUE */
#ifdef LISTTRUE
	list_ende(); /* AK 100893 */
#endif /* LISTTRUE */
#ifdef PERMTRUE
	perm_ende(); /* AK 100893 */
#endif /* PERMTRUE */
#ifdef FFTRUE
	ff_ende();
#endif /* FFTRUE */
#ifdef NUMBERTRUE	/* AK 310893 */
	nb_ende();
#endif /* NUMBERTRUE */
#ifdef LONGINTTRUE
	longint_ende();
#endif /* LONGINTTRUE */
	if  (  /* AK 190194 */
		(S_O_K(cons_null) != INTEGER) ||
		(S_O_K(cons_zwei) != INTEGER) ||
		(S_O_K(cons_eins) != INTEGER) ||
		(S_O_K(cons_negeins) != INTEGER) ||
		(S_I_I(cons_null) != (INT) 0) ||
		(S_I_I(cons_zwei) != (INT) 2) ||
		(S_I_I(cons_eins) != (INT) 1) ||
		(S_I_I(cons_negeins) != (INT) -1) 
	    )
	erg += error("ende: wrong constant values e.g. cons_null");
	erg += SYMfreeall(cons_null);
	erg += SYMfreeall(cons_zwei);
	erg += SYMfreeall(cons_eins);
	erg += SYMfreeall(cons_negeins);

	for (i=speicherposition;i>=0L;i--) /* AK 161091 */
		{
		SYM_free(speicher[i]); /* AK 161091 */
		}
	SYM_free(speicher); /* AK 161091 */
#ifdef  MEMCHECK
	callocobject_ende();
	if (mem_counter != 0L)
		{
		fprintf(stderr,"mem_counter=%ld\n",mem_counter);
		fprintf(stderr,"mem_malloc=%ld\n",mem_malloc);
		fprintf(stderr,"mem_calloc=%ld\n",mem_calloc);
		error("ende: not all memory was freed");
		}
	for (i=0;i<MEMTRACENUMBER;i++)
		{
		if (mem_trace_pointer[i] != NULL)
			printf("traced memory %d left\n",mem_trace_pointer[i]);
		}
	
#endif /* MEMCHECK */
	memcheck("ende");
	if (not no_banner)
		{
		printeingabe("SYMMETRICA VERSION 1.99 - ENDE");
		sprintf(t,"last changed: %s",TITELTEXT); /* AK 181194 */
		printeingabe(t);
		}
	fflush(stdout);
	fflush(stderr);
	return erg;
}

INT runtime(l) long *l;
/* AK 270689 V1.0 */ /* AK 070890 V1.1 */ /* AK 210891 V1.3 */
{
#ifdef MSDOS
	*l = (long) clock();
#endif /* MSDOS */
#ifdef unix
	struct tms buffer;
	times(&buffer);
	*l = (long) buffer.tms_utime;
#endif /* unix */
	return OK;
}

INT get_time(a) OP a;
/* AK 160890 V1.1 */ /* AK 210891 V1.3 */
{
	long l;
	runtime(&l); 
	return m_i_i((INT)l,a);
}


INT print_time()
/* AK 160890 V1.1 */ /* AK 210891 V1.3 */
{
	long l;
	runtime(&l); 
	printf("zeit:%ld\n",l);return OK;
}


INT fusedmemory(fn,stelle) FILE *fn; char *stelle;
/* AK 270689 V1.0 */ /* AK 010290 V1.1 */ /* AK 130691 V1.2 */
/* AK 210891 V1.3 */
{
#ifdef unix
#ifndef linux
	struct mallinfo mallinfo();
	struct mallinfo ergebnis;
	free(calloc(1,1));
	ergebnis = mallinfo(/* 0 */);
	fprintf(fn,"%s: ",stelle);
	fprintf(fn,"%d ",ergebnis.uordblks);
	fprintf(fn,"%d\n",ergebnis.usmblks);
	return(OK);
#endif /* linux */
#endif /* unix */
#ifdef TURBOC
	fprintf(fn,"%s: ",stelle);
	fprintf(fn,"%ul\n",coreleft());
	return(OK);
#endif /* TURBOC */
	return(OK);
}

INT mem_small()
/* anzahl small memory zurueck */
/* AK 270689 V1.0 */ /* AK 070890 V1.1 */ /* AK 210891 V1.3 */
{
#ifdef unix
#ifndef linux
	struct mallinfo mallinfo();
	struct mallinfo ergebnis;
	ergebnis = mallinfo(/* 0 */);
	return(ergebnis.usmblks);
#endif /*linux */
#endif /* unix */
	return(0);
}


INT memcheck(stelle) char *stelle;
/* informationen ueber memory 31/10/86 */
/* AK 270689 V1.0 */ /* AK 010290 V1.1 */ /* AK 210891 V1.3 */
{
#ifdef unix
#ifndef linux
	struct mallinfo mallinfo();
	struct mallinfo ergebnis;

	if (no_mem_check == TRUE) return OK;
	SYM_free(SYM_calloc(1,1));
	ergebnis = mallinfo(/* 0 */);
	printf("memory information  %s\n",stelle);
	printf("total space     %d\n",ergebnis.arena);
	printf("block number    %d\n",ergebnis.ordblks);
	printf("small blocks    %d\n",ergebnis.smblks);
	printf("used blocks     %d\n",ergebnis.uordblks);
	printf("free blocks     %d\n",ergebnis.fordblks);
	printf("used sm. blocks %d\n",ergebnis.usmblks);
	printf("free sm. blocks %d\n",ergebnis.fsmblks);
	return(OK);
#endif /*linux */
#endif /* unix */
	return(OK);
}

INT sym_background = 0L;
INT sym_timelimit = 0L;
INT fatal_error(fehlertext) char *fehlertext;
/* AK 270295 */
{
	fprintf(stderr,"fatal error in function %s\n",fehlertext);
	exit(11);
}
// NT 2005/01/05:
// Disabled and redefined in ../Symmetrica-module/Symmetrica.mcc
INT DISABLED_error(fehlertext) char *fehlertext;
/* if answer == a ==> abort
   if answer == e ==> explain
   if answer == g ==> go on
   if answer == r ==> retry
   if answer == s ==> go on supress error texts
   if answer == f ==> go on forever
   else               exit */
/* AK 270689 V1.0 */ /* AK 070890 V1.1 */
/* AK 070291 V1.2 explanation of possible input */
/* AK 210891 V1.3 */
{
	char antwort[2];
	static int forever=0;
	if (forever==2) return ERROR;
	fflush(stdout);
	fflush(stderr);
	fprintf(stderr,
"\nenter a to abort with core dump, g to go, f to supress\n");
	fprintf(stderr, 
"s to supress further error text, r to retry,  e to explain, else stop\n");
	fprintf(stderr,"ERROR: %s?: ",fehlertext);


	fflush(stderr);

	if (sym_background) {
		fprintf(stderr,"\nerror occured in background mode finishing SYMMETRICA\n");
		exit(ERROR_BACKGROUND);
		}

	if (forever==1) return ERROR;
        
	antwort[0]='X';
	scanf("%s",antwort);
	if (antwort[0] == 'a') abort();
	if (antwort[0] == 'f') {forever = 1; return ERROR;}
	if (antwort[0] == 's') {forever = 2; return ERROR;}
	if (antwort[0] == 'g') return ERROR;
	if (antwort[0] == 'r') return ERROR_RETRY;
	if (antwort[0] == 'e') return ERROR_EXPLAIN;
	exit(1); /* AK 121192 */
}


INT no_memory()
/* AK 090792 */
{
	return error("no memory left");
}

INT debugprint(a) OP a;
/* AK 260788 */ /* AK 030789 V1.0 */ /* AK 130690 V1.1 */ /* AK 210891 V1.3 */
{
	OBJECTKIND kind;
	INT i,j,k;
	char *text;
	for (i=0L;i<doffset;i++) fprintf(stderr," ");
	if (a==NULL) { 
		fprintf(stderr,"NULL\n"); 
		return(OK); 
	}
	kind = s_o_k(a);
	switch ((int)kind)
	/* abschluss immer mit newline */
	{
	case 0: 
		fprintf(stderr,"kind:0=empty\n");
		break;
	case 1: 
		fprintf(stderr,"kind:1=integer value:");
		fprintf(stderr,"%ld\n",s_i_i(a));
		return(OK);
#ifdef VECTORTRUE
        case 26: case 19: case 15:
	case 2: 
		if (kind == 2) text="vector";
		if (kind == 15) text="integervector";
		if (kind == 19) text="word";
		if (kind == 26) text="comp";
		fprintf(stderr,"kind:%d=%s length:\n",(int)kind, text);
		doffset += 2L;
		debugprint(s_v_l(a));
		doffset -= 2L;
		for (i=0L;i<s_v_li(a);i++)
		{
		for (k=0L;k<doffset;k++) fprintf(stderr," ");
		fprintf(stderr,"%s %ld-komponente:\n",text,i);
		doffset += 2L;
		debugprint(s_v_i(a,i));
		doffset -= 2L;
		}
		return(OK);
#endif /* VECTORTRUE */
#ifdef PARTTRUE
	case 3: 
	case 12: 
		{
		if (kind == 12) text="augpartition";
		if (kind == 3) text="partition";
		fprintf(stderr,"kind:%d=%s kind:%d\n",(int)kind,text,
					(int)s_pa_k(a));
		for (k=0L;k<doffset;k++) fprintf(stderr," ");
		fprintf(stderr,"%s self:\n",text);
		doffset += 2L;
		debugprint(s_pa_s(a));
		doffset -= 2L;
		return(OK);
		}
#endif /* PARTTRUE */
#ifdef BRUCHTRUE
	case 4: 
		{
		fprintf(stderr,"kind:4=bruch oben:\n");
		doffset += 2L;
		debugprint(s_b_o(a));
		doffset -= 2L;
		for (k=0L;k<doffset;k++) fprintf(stderr," ");
		fprintf(stderr,"bruch unten:\n");
		doffset += 2L;
		debugprint(s_b_u(a));
		doffset -= 2L;
		return(OK);
		}
#endif /* BRUCHTRUE */
#ifdef PERMTRUE
	case 6: 
		{
		fprintf(stderr,"kind:6=permutation kind:%d\n",(int)s_p_k(a));
		for (k=0L;k<doffset;k++) fprintf(stderr," ");
		fprintf(stderr,"permutation self:\n");
		doffset += 2L;
		debugprint(s_p_s(a));
		doffset -= 2L;
		return(OK);
		}
#endif /* PERMTRUE */
#ifdef SKEWPARTTRUE
	case 7: 
		{
		fprintf(stderr,"kind:7=skewpartition gross:\n");
		doffset += 2L;
		debugprint(s_spa_g(a));
		doffset -= 2L;
		for (k=0L;k<doffset;k++) fprintf(stderr," ");
		fprintf(stderr,"skewpartition klein:\n");
		doffset += 2L;
		debugprint(s_spa_k(a));
		doffset -= 2L;
		return(OK);
		}
#endif /* SKEWPARTTRUE */
#ifdef TABLEAUXTRUE
	case 8: 
		{
		fprintf(stderr,"kind:8=tableaux self:\n");
		doffset += 2L;
		debugprint(s_t_s(a));
		doffset -= 2L;
		for (k=0L;k<doffset;k++) fprintf(stderr," ");
		fprintf(stderr,"tableaux umriss:\n");
		doffset += 2L;
		debugprint(s_t_u(a));
		doffset -= 2L;
		return(OK);
		}
#endif /* TABLEAUXTRUE */
#ifdef LISTTRUE
	case 13: case 10: case 29: case 28: case 33: case 32:case 14:
	case 20: case 9: case 42:
		{
		if (kind == 9)	text="polynom";
		if (kind == 20)	text="list";
		if (kind == 14)	text="schubert";
		if (kind == 10) text="schur";
		if (kind == 13) text="homsym";
		if (kind == 28) text="powsym";
		if (kind == 29) text="monomial";
		if (kind == 32) text="groupalgebra";
		if (kind == 33) text="elmsym";
		if (kind == 42) text="monopoly";
		fprintf(stderr,"kind:%d=%s self:\n",(int)kind,text);
		doffset += 2L;
		debugprint(s_l_s(a));
		doffset -= 2L;
		for (k=0L;k<doffset;k++) fprintf(stderr," ");
		fprintf(stderr,"%s next:\n",text);
		doffset += 2L;
		debugprint(s_l_n(a));
		doffset -= 2L;
		return(OK);
		}
#endif /* LISTTRUE */
#ifdef MATRIXTRUE
	case 27: case 11:
		{
		if (kind==11) text = "matrix";
		if (kind==27) text = "kranztypus";

		fprintf(stderr,"kind:%d=%s height:\n",(int)kind,text);
		doffset += 2L;
		debugprint(s_m_h(a));
		doffset -= 2L;
		for (k=0L;k<doffset;k++) fprintf(stderr," ");
		fprintf(stderr,"%s length:\n",text);
		doffset += 2L;
		debugprint(s_m_l(a));
		doffset -= 2L;
		for (k=0L;k<doffset;k++) fprintf(stderr," ");
		for (i=0L;i<s_m_hi(a);i++)
		for (j=0L;j<s_m_li(a);j++)
		{
		for (k=0L;k<doffset;k++) fprintf(stderr," ");
		fprintf(stderr,"%s %ld %ld-komponente:\n",text,i,j);
		doffset += 2L;
		debugprint(s_m_ij(a,i,j));
		doffset -= 2L;
		}
		return(OK);
		}
#endif /* MATRIXTRUE */
#ifdef MONOMTRUE
	case 21:
		{
		fprintf(stderr,"kind:21=monom koeff:\n");
		doffset += 2L;
		debugprint(s_mo_k(a));
		doffset -= 2L;
		for (k=0L;k<doffset;k++) fprintf(stderr," ");
		fprintf(stderr,"monom self:\n");
		doffset += 2L;
		debugprint(s_mo_s(a));
		doffset -= 2L;
		return(OK);
		}
#endif /* MONOMTRUE */
#ifdef LONGINTTRUE
	case 22: return(debugprint_longint(a));
#endif /* LONGINTTRUE */
#ifdef NUMBERTRUE
	case 41: case 43:
		{
		if (kind == 41) text = "cyclotomic";
		if (kind == 43) text = "squareradical";

		fprintf(stderr,"kind:%d=%s self:\n",(int)kind,text);
		doffset += 2L;
		debugprint(s_n_s(a));
		doffset -= 2L;
		return(OK);
		}
#endif /*NUMBERTRUE*/
#ifdef FFTRUE
	case 35: return debugprint_ff(a);
#endif /* FFTRUE */
#ifdef REIHETRUE
	case 36: return debugprint_reihe(a);
#endif /* REIHETRUE */
	default: 
		fprintf(stderr,"kind:%d unknown\n",s_o_k(a));
		break;
	}
	return OK;
}

int SYM_isdigit(a) char a; /* AK 040194 */
{ return ((a >= '0') && (a <= '9')); }

int SYM_strlen(a) char *a; /* AK 030294 */
{ int i=0; while (*a++) i++; return i; }

int SYM_memcmp(a,b,c) char *a,*b; /* AK 210294 */
{ return memcmp(a,b,c); }

int SYM_abs(a) INT a; /* AK 230695 */
{ return (a>0 ) ? a : -a; }


INT mem_size(a) OP a;
/* AK 150295 */
{
	INT erg = OK;
	if (a == NULL)		
				return 0;
	switch(S_O_K(a))
		{
		case EMPTY:
		case INTEGER:	return sizeof(struct object);
		case MATRIX:
		case KOSTKA:	return mem_size_matrix(a);
		case COMP:
		case WORD:
		case INTEGERVECTOR:
		case VECTOR:	return mem_size_vector(a);
		default:
			erg += WTO("mem_size",a);goto endr_ende;
		}
	return -1;
	ENDR("mem_size");
}
