gambas-source-code/main/gbx/gbx_print.c
Benoît Minisini 4c02c6d338 ******** Merged /branches/64bits r918:1003 into /trunk
[CONFIGURATION]
* NEW: 64 bits port.

[EXAMPLES]
* BUG: Fixed the AnalogWatch example.

[WIKI CGI SCRIPT]
* NEW: Some little cosmetic changes.

[INTERPRETER]
* NEW: The extern function implementation has been redesigned and is now
  based on libffi, so that it works on 64 bits system. Because of a flaw in
  the compiler design, projects that use the Pointer datatype must be
  recompiled to be used on a 64 bits system. This flaw will be fixed in
  Gambas 3.
* OPT: Put some tables into read-only memory. About 1000 bytes are saved
  for each running interpreter, except the first one.
* BUG: Does not crash anymore if a component cannot be loaded.
* NEW: Spanish translation updated.
* NEW: A new interpreter API for returning a pointer.

[COMPILER]
* BUG: Correctly compiles LONG constants inside code.

[GB.DEBUG]
* BUG: Compiles and links the gb.debug components with the thread
  libraries.

[GB.DB.SQLITE3]
* BUG: Getting the primary index of a table without primary index is safe
  now.

[GB.GTK]
* BUG: Modified the GLib priority of watched descriptors, as the main loop 
  could enter in a loop in which user interface events were not managed.
* BUG: Message boxes use application title without crashing now.

[GB.OPENGL]
* BUG: Disable dead code.

[GB.QT.EXT]
* BUG: TextEdit.TextWidth and TextEdit.TextHeight were not declared as
  read-only properties.

[GB.XML.XSLT]
* BUG: XSLT class is now declared as being not creatable.


git-svn-id: svn://localhost/gambas/trunk@1006 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2008-01-17 21:39:26 +00:00

257 lines
4.7 KiB
C

/***************************************************************************
gxb_print.c
Prints values and objects
(c) 2000-2007 Benoit Minisini <gambas@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
#define __GBX_PRINT_C
#include "gb_common.h"
#include "gb_common_buffer.h"
#include "gb_common_case.h"
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include "gbx_exec.h"
#include "gbx_local.h"
#include "gbx_date.h"
#include "gbx_print.h"
static PRINT_FUNCTION _print;
static bool _trace = FALSE;
static void to_string(VALUE *value, char **addr, int *len)
{
static void *jump[16] = {
&&__VOID, &&__BOOLEAN, &&__BYTE, &&__SHORT, &&__INTEGER, &&__LONG, &&__SINGLE, &&__FLOAT, &&__DATE,
&&__STRING, &&__STRING, &&__VARIANT, &&__ARRAY, &&__FUNCTION, &&__CLASS, &&__NULL
};
VALUE conv;
//*more = FALSE;
__CONV:
if (TYPE_is_object(value->type))
goto __OBJECT;
else
goto *jump[value->type];
__NULL:
*addr = "NULL";
*len = 4;
return;
__BOOLEAN:
if (value->_boolean.value)
{
*addr = "TRUE";
*len = 4;
}
else
{
*addr = "FALSE";
*len = 5;
}
return;
__BYTE:
__SHORT:
__INTEGER:
#ifdef OS_OPENBSD
*len = snprintf(COMMON_buffer, COMMON_BUF_MAX, "%d", value->_integer.value);
#else
*len = sprintf(COMMON_buffer, "%d", value->_integer.value);
#endif
*addr = COMMON_buffer;
return;
__LONG:
#ifdef OS_OPENBSD
*len = snprintf(COMMON_buffer, COMMON_BUF_MAX, "%" PRId64, value->_long.value);
#else
*len = sprintf(COMMON_buffer, "%" PRId64, value->_long.value);
#endif
*addr = COMMON_buffer;
return;
__DATE:
LOCAL_format_date(DATE_split(value), LF_STANDARD, NULL, 0, addr, len);
return;
__SINGLE:
__FLOAT:
LOCAL_format_number(value->_float.value, LF_STANDARD, NULL, 0, addr, len, TRUE);
return;
__STRING:
{
int i;
char *d;
const char *s;
uchar c;
s = value->_string.addr + value->_string.start;
d = COMMON_buffer;
*d++ = '"';
for (i = 0; i < value->_string.len; i++)
{
if (i > 128)
{
strcat(d, "...");
*len += 3;
break;
}
c = s[i];
if (c < 32)
{
*d++ = '\\';
if (c == 10)
*d++ = 'n';
else if (c == 13)
*d++ = 'r';
else if (c == 9)
*d++ = 't';
else
#ifdef OS_OPENBSD
d += snprintf(d, &COMMON_buffer[COMMON_BUF_MAX]-d, "x%02X", c);
#else
d += sprintf(d, "x%02X", c);
#endif
}
else if (c == '\"')
{
*d++ = '\\';
*d++ = c;
}
else
{
*d++ = c;
}
}
*d++ = '"';
*addr = COMMON_buffer;
*len = d - COMMON_buffer;
}
return;
__OBJECT:
if (VALUE_is_null(value))
goto __NULL;
//*more = !CLASS_is_native(OBJECT_class(value->_object.object));
*len = sprintf(COMMON_buffer, "(%s %p)", OBJECT_class(value->_object.object)->name, value->_object.object);
*addr = COMMON_buffer;
return;
__VARIANT:
conv = *value;
value = &conv;
VARIANT_undo(value);
goto __CONV;
__VOID:
*addr = "(void)";
*len = 6;
return;
__CLASS:
{
CLASS *class = value->_class.class;
//*more = (!CLASS_is_native(class) && class->load->n_stat > 0);
*len = sprintf(COMMON_buffer, "%s %p", class->name, class);
*addr = COMMON_buffer;
return;
}
__ARRAY:
*len = sprintf(COMMON_buffer, "(ARRAY %p)", value->_array.addr);
*addr = COMMON_buffer;
return;
__FUNCTION:
THROW(E_TYPE, TYPE_get_name(T_STRING), TYPE_get_name(value->type));
}
void PRINT_init(PRINT_FUNCTION func, bool trace)
{
_print = func;
_trace = trace;
}
void PRINT_value(VALUE *value)
{
char *addr;
int len;
/*if (TYPE_is_object(value->type))
{
void *object = value->_object.object;
CLASS *class = OBJECT_class(object);
if (!EXEC_spec(SPEC_PRINT, class, object, 0, TRUE))
return;
}*/
if (_trace)
to_string(value, &addr, &len);
else
VALUE_to_string(value, &addr, &len);
(*_print)(addr, len);
}
void PRINT_string(char *addr, int len)
{
(*_print)(addr, len);
}