/*
// File : identify.c
// Syntax : varargs string identify( mixed a, string indent )
// Purpose : identify the variable 'a' as a string.
// 92-12-12 : Pallando wrote this function, based on ones he wrote
// for Ephemeral Dales and other muds.
// 93-03-03 : Pallando@TMI-2 added floats
// 93-03-28 : Pallando changed implode(explode()) to replace_string()
// Pallando@Nightmare added replacement of \\ and \"
// 93-08-19 : Pallando added check for recursive arrays and mappings
// Pallando added check for too deep recursion
// 93-09-09 : Pallando@CWLIB added indent option
// Pallando included config.h (for __tmi__) and origin.h
*/
#include <driver/origin.h>
#include <config.h>
#define MAX_RECURSION 20
#ifdef __tmi__
#define QUERY_NAME query( "name" )
#else
#define QUERY_NAME query_name()
#endif /* __tmi__ */
static mapping found;
static string *position;
static int recursion;
varargs string identify( mixed a, string indent )
{
int i, s;
string ind, rec, ret;
mapping map;
if( origin() != ORIGIN_LOCAL )
{
found = ([ ]);
position = allocate( MAX_RECURSION + 1 );
recursion = 0;
position[recursion] = "X";
}
ind = "";
if( stringp( indent ) )
for( i = 0 ; i < recursion ; i++ )
ind += indent;
if( undefinedp( a ) )
return ind + "UNDEFINED";
if( nullp( a ) )
return ind + "0";
if( intp( a ) )
return ind + a;
if( floatp( a ) )
return ind + a;
if( objectp( a ) )
{
if( stringp( ret = (string)a-> QUERY_NAME ) )
ret += " ";
else
ret = "";
return ind + "OBJ(" + ret + file_name( a ) + ")";
}
if( stringp( a ) )
{
a = replace_string( a, "\"", "\\\"" );
a = "\"" + a + "\"";
a = replace_string( a, "\\", "\\\\" );
a = replace_string( a, "\\\"", "\"" );
a = replace_string( a, "\n", "\\n" );
a = replace_string( a, "\t", "\\t" );
return ind + a;
}
if( functionp( a ) )
return ind + "(: " + identify( a[0] ) + ", " + identify( a[1] ) + " :)";
if( recursion == MAX_RECURSION )
return ind + "TOO_DEEP_RECURSION";
if( pointerp( a ) )
{
#if 0
found[a] = implode( position[0..recursion], "" );
if( !( s = sizeof( a ) ) ) return ind + "({ })";
recursion++;
ret = "";
for( i = 0 ; i < s ; i++ )
{
position[recursion] = "[" + i + "]";
if( !( rec = found[a[i]] ) )
rec = identify( a[i], indent );
ret += ( i ? ( indent ? ",\n" : ", " ) : "" ) + rec;
}
recursion--;
if( !indent ) return "({ " + ret + " })";
return ind + "({\n" + ret + "\n" + ind + "})";
#else
ret = "({ ";
s = sizeof( a );
for( i = 0 ; i < s ; i++ )
{
if( i ) ret += ", ";
ret += identify( a[i] );
}
return ret + ( s ? " " : "" ) + "})";
#endif
}
if( mapp( a ) )
{
found[a] = implode( position[0..recursion], "" );
map = (mapping)(a);
a = keys( map );
if( !( s = sizeof( a ) ) ) return ind + "([ ])";
recursion++;
ret = "";
for( i = 0 ; i < s ; i++ )
{
ret += ( i ? ( indent ? ",\n" : ", " ) : "" );
position[recursion] = ".KEY(" + i + ").";
if( !( rec = found[a[i]] ) )
rec = identify( a[i] );
ret += ind + ( indent ? indent : "" ) + rec + " : ";
position[recursion] = "[" + rec + "]";
if( !( rec = found[map[a[i]]] ) )
{
if( indent && (
( mapp( map[a[i]] ) && sizeof( keys( map[a[i]] ) ) ) ||
( pointerp( map[a[i]] ) && sizeof( map[a[i]] ) ) ) )
rec = "\n" + identify( map[a[i]], indent );
else
rec = identify( map[a[i]] );
}
ret += rec;
}
recursion--;
if( !indent ) return "([ " + ret + " ])";
return ind + "([\n" + ret + "\n" + ind + "])";
}
return ind + "UNKNOWN";
}