Lhogho
0.0.027
|
Defines | |
#define | void void __attribute__ ((used,noinline,regparm(0),stdcall)) |
Functions | |
void | init_atoms () |
initializes the Atoms module | |
void | finit_atoms () |
finalizes the Atoms module | |
atom_t | use (atom_t a) |
adds link to atom | |
void | deuse (atom_t a) |
removes link to atom | |
void | dump_atom (atom_t a, int level) |
dumps atom contents | |
void | dump (atom_t a) |
dumps atom contents | |
void | dumpln (atom_t a) |
dumps atom contents | |
void | init_output (outter_t new_outter) |
initializes text output | |
void | init_input (inner_t new_inner, inner_eof_t new_inner_eof) |
initializes text input | |
void | outter (chars_t string, int len) |
prints text | |
int | inner_eof () |
returns eof status | |
char_t | inner () |
Variables | |
inner_t | std_inner |
hook variable for inputting text | |
inner_eof_t | std_inner_eof |
hook variable for inputting text | |
outter_t | std_outter |
hook variable for outputting text | |
int | outter_size = 0 |
counts outted characters | |
FILE * | input_stream = NULL |
current input stream | |
FILE * | output_stream = NULL |
current input stream | |
struct lconv * | locale_info |
locale information |
#define void void __attribute__ ((used,noinline,regparm(0),stdcall)) |
void init_atoms | ( | ) |
Creates a data pool for all atoms and creates one special atom representing the empty list.
{ #ifdef DEBUG_ATOM printf("<ATOM> Atoms initialized\n"); #endif //DEBUG_ATOM #ifdef ADVANCED int i; stats_free = 0; stats_allocs = 0; for( i=MIN_ID; i<MAX_ID; i++ ) { stats[i].max = 0; stats[i].allocs = 0; stats[i].deallocs = 0; } #endif //ADVANCED #ifdef SAFEMODE assert( sizeof(atomrec_t)==16 ); #endif //setlocale( LC_ALL, "" ); locale_info = localeconv(); init_pool( &data_pool, ATOM_SIZE ); init_pool( &data_pool_ex, ATOM_SIZE_EX ); empty_list = (atom_t)take_from_pool( &data_pool ); REF(empty_list) = 1; ID(empty_list) = LIST_ID; CAR(empty_list) = empty_list; CDR(empty_list) = empty_list; FLAGS(empty_list) = 0; }
void finit_atoms | ( | ) |
Returns the empty list back to the data pool.
{ return_to_pool( &data_pool, empty_list ); #ifdef DEBUG_MEMORY_LEAKS dump_pool(); #endif #ifdef DEBUG_ATOM printf("<ATOM> Atoms finalized\n"); #endif //DEBUG_ATOM }
a | atom to use |
Adds a link to an atom by increasing atom's reference count.
{ if( IS_UNBOUND(a) || IS_EMPTY(a) || IS_STOPPED(a) ) return a; //if( a==0x49f3b8) //{ //printf("USE.BUG[%08x] ref %d->%d\n", (int)a, REF(a), REF(a)+1 ); //} #ifdef DEBUG_RUNTIME_ATOMS if( running_compiled_code ) { outter( TEXT("<RUNTIME> use "), -1 ); dump_atom_address( a ); dump_atom( a, 1 ); outter( TEXT("\n"), -1 ); } #endif #ifdef DEBUG_COMPILETIME_ATOMS if( compiling_code ) { outter( TEXT("<COMPILETIME> use "), -1 ); dump_atom_address( a ); dump_atom( a, 1 ); outter( TEXT("\n"), -1 ); } #endif //if( IS_ERROR(a) ) // { // printf("TO BE USEIT hex(a)=%x id=%d REF=%d a=",(int)a,ID(a),REF(a)); dumpln(a); // } #ifdef SAFEMODE assert( a ); assert( ID(a)<MAX_ID ); assert( REF(a)>=0 ); // 2009 was >0 #endif //SAFEMODE //if( IS_INTEGER(a) || IS_FLOAT(a)) //{ //printf("deuse[addr=%x ref=%d]\n",a,REF(a)); //printf("use atom="); dumpln(a); //} REF(a)++; #ifdef DEBUG_ATOM printf("<ATOM> [%08x] ref+1\n",(int)a); #endif //DEBUG_ATOM return a; }
a | atom to unlink |
Decrements the reference count for the atom and if it reaches 0 then frees the atom using one of the functions delete_numeric, delete_list, delete_word, delete_subword, delete_error, delete_var.
{ __asm__ volatile ( ASM_STORE_RESULT:::ASM_CLOBBER_REGISTERS ); typedef void(*deleter_t)(atom_t); static deleter_t deleters[MAX_ID] = { delete_numeric, // INTEGER_ID delete_numeric, // FLOAT_ID delete_list, // LIST_ID delete_word, // WORD_ID delete_subword, // SUBWORD_ID delete_error, // ERROR_ID delete_var, // VAR_ID delete_mem, // MEM_ID }; // array of deleter functions for each atom type //if( a==0x49f3b8) //{ //printf("DEUSE.BUG[%08x] ref %d->%d\n", (int)a, REF(a), REF(a)-1 ); //} //if( IS_INTEGER(a) || IS_FLOAT(a)) // { // //printf("deuse[addr=%x ref=%d]\n",(int)a,REF(a)); // printf("deuse atom="); dumpln(a); // } if( !IS_EMPTY(a) && !IS_UNBOUND(a) && !IS_STOPPED(a)) { //printf("deuse "); dumpln(a); #ifdef DEBUG_RUNTIME_ATOMS if( running_compiled_code ) { outter( TEXT("<RUNTIME> deuse"), -1 ); dump_atom_address( a ); dump_atom( a, 1 ); outter( TEXT("\n"), -1 ); } #endif #ifdef DEBUG_COMPILETIME_ATOMS if( compiling_code ) { outter( TEXT("<COMPILETIME> deuse"), -1 ); dump_atom_address( a ); dump_atom( a, 1 ); outter( TEXT("\n"), -1 ); } #endif //if( IS_ERROR(a) ) //{ //printf("TO BE DEUSE hex(a)=%x id=%d REF=%d a=",(int)a,ID(a),REF(a)); dumpln(a); //} #ifdef SAFEMODE assert( a ); //if(ID(a)>=MAX_ID) {printf("ASSERT[%x]\n",a);} assert( (ID(a)<MAX_ID) ); assert( REF(a)>0 ); #endif // SAFEMODE //printf("GOODY hex(a)=%x id=%d REF=%d\n\n",(int)a,ID(a),REF(a)); if( !--REF(a) ) { #ifdef DEBUG_ATOM printf("<ATOM> [%08x] ref-1\n",(int)a); #endif //DEBUG_ATOM #ifdef ADVANCED stats[ID(a)].deallocs++; stats_free++; #endif //ADVANCED deleter_t deleter = deleters[ID(a)]; deleter(a); } } __asm__ volatile ( ASM_RESTORE_RESULT:::ASM_CLOBBER_REGISTERS ); }
a | atom to dump |
level | level of nesting |
Dumps atom's contents using a call-back outter
function. Texts are automatically indented according to the level
. Typically this function is used to print an atom when the call-back function forwards contents to standard output. The call-back function is set by init_output().
< array of deleter functions for each atom type
{ typedef void(*dumper_t)(atom_t,int); static dumper_t dumpers[MAX_ID] = { dump_integer, // INTEGER_ID dump_float, // FLOAT_ID dump_list, // LIST_ID dump_word, // WORD_ID dump_word, // SUBWORD_ID dump_error, // ERROR_ID dump_var, // VAR_ID dump_mem, // MEM_ID }; #ifdef SAFEMODE assert( a ); //assert( outter ); if( IS_NOT_EMPTY(a) ) assert( ID(a)<MAX_ID ); #endif //SAFEMODE #ifdef DEBUG_REF_COUNT if( IS_EMPTY(a) ) { outter( TEXT("##"), 2 ); } else { int n; char_t buf[64]; n = SPRINTF( buf, DUMP_BUF_SIZE, TEXT(" %d#"), REF(a) ); outter( buf, n ); } #endif dumper_t dumper = dumpers[ID(a)]; dumper(a,level); }
a | atom to dump |
Dumps atom's contents throught the current text output function (e.g. use_stdout).
{ dump_atom( a, 0 ); }
a | atom to dump |
Dumps atom's contents throught the current text output function (e.g. use_stdout) and moves cursor to the next line.
void init_output | ( | outter_t | new_outter | ) |
Initializes the text output system by setting the std_outter function to output text throught it.
{ std_outter = new_outter; }
void init_input | ( | inner_t | new_inner, |
inner_eof_t | new_inner_eof | ||
) |
new_inner | new inner function |
new_inner_eof | new inner_eof function |
Initializes the text input system by setting the std_inner and :std_inner_eof functions to input text throught it.
{ std_inner = new_inner; std_inner_eof = new_inner_eof; }
string | text to print |
len | length of text |
This function prints text to either the hooked output or to a file.
{ if( output_stream==NULL ) { std_outter( string, len ); } else { if( len==-1 ) len = STRLEN( string ); for( ; len>0; len--, string++ ) { int crlf = (DEBAR(*string)==0x0D) && (DEBAR(*(string+1))==0x0A); if( !crlf ) { char_t wc[2]; wc[0] = DEBAR(*string); wc[1] = 0; char* buf =(char*) UTF16_to_UTF8(wc); DEALLOC( buf ); fprintf( output_stream, "%S", wc ); } } } }
Return EOF status of a hooked or file stream.
{ if( input_stream==NULL ) { return std_inner_eof(); } else { return feof(input_stream)?1:0; } }
{ if( input_stream==NULL ) { return std_inner(); } else { char_t ch; //ch = GETCHAR( input_stream ); //while( ch=='\r' ) ch = GETCHAR( input_stream ); // remove ^M from input, keep ^J ch = (char_t)getc( input_stream ); while( ch=='\r' ) ch = (char_t)getc( input_stream ); // remove ^M from input, keep ^J return ch; } }
int outter_size = 0 |
FILE* input_stream = NULL |
FILE* output_stream = NULL |
struct lconv* locale_info |