- minor code cleanup

- updated CHANGES.txt
- nalt.i: forgot to release reference for callback result (in py_import_enum_cb())
This commit is contained in:
elias.bachaalany 2010-03-05 11:35:28 +00:00
parent 57d37a638a
commit 8e78513e91
13 changed files with 359 additions and 372 deletions

View File

@ -1,6 +1,14 @@
Please see http://code.google.com/p/idapython/source/list for a Please see http://code.google.com/p/idapython/source/list for a
detailed list of changes. detailed list of changes.
Changes from version 1.2.0 to 1.3.0
------------------------------------
- IDA Pro 5.6 support
- Added Appcall mechanism
- Added procregs to idautils.py (r254)
- Lots of cleanups and fixes
Changes from version 1.1.0 to 1.2.0 Changes from version 1.1.0 to 1.2.0
------------------------------------ ------------------------------------

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
#------------------------------------------------------------ # -----------------------------------------------------------------------
# IDAPython - Python plugin for Interactive Disassembler Pro # IDAPython - Python plugin for Interactive Disassembler Pro
# #
# Copyright (c) 2004-2009 Gergely Erdelyi <dyce@d-dome.net> # Copyright (c) 2004-2009 Gergely Erdelyi <dyce@d-dome.net>
@ -8,9 +8,9 @@
# #
# For detailed copyright information see the file COPYING in # For detailed copyright information see the file COPYING in
# the root of the distribution archive. # the root of the distribution archive.
#------------------------------------------------------------ # -----------------------------------------------------------------------
# init.py - Essential init routines # init.py - Essential init routines
#------------------------------------------------------------ # -----------------------------------------------------------------------
import os import os
import sys import sys
import time import time
@ -21,7 +21,7 @@ import _idaapi
# __EA64__ is set if IDA is running in 64-bit mode # __EA64__ is set if IDA is running in 64-bit mode
__EA64__ = _idaapi.BADADDR == 0xFFFFFFFFFFFFFFFFL __EA64__ = _idaapi.BADADDR == 0xFFFFFFFFFFFFFFFFL
# -----------------------------------------------------------------------
def addscriptpath(script): def addscriptpath(script):
""" """
Add the path part of the scriptfile to the system path to Add the path part of the scriptfile to the system path to
@ -45,7 +45,7 @@ def addscriptpath(script):
if not script in scriptbox.list: if not script in scriptbox.list:
scriptbox.list.insert(0, script) scriptbox.list.insert(0, script)
# ------------------------------------------------------------
def runscript(script): def runscript(script):
""" """
Run the specified script after adding its directory path to Run the specified script after adding its directory path to
@ -80,28 +80,24 @@ def runscript(script):
if not module in basemodules: if not module in basemodules:
del(sys.modules[module]) del(sys.modules[module])
# -----------------------------------------------------------------------
def print_banner(): def print_banner():
version1 = "Python interpreter version %d.%d.%d %s (serial %d)" % sys.version_info banner = [
version2 = "Copyright (c) 1990-2009 Python Software Foundation - http://www.python.org/" "Python interpreter version %d.%d.%d %s (serial %d)" % sys.version_info,
if __EA64__: "Copyright (c) 1990-2009 Python Software Foundation - http://www.python.org/",
version3 = "IDAPython 64-bit" "",
else: "IDAPython" + (" 64-bit" if __EA64__ else "") + " version %d.%d.%d %s (serial %d)" % IDAPYTHON_VERSION,
version3 = "IDAPython" "Copyright (c) 2004-2009 Gergely Erdelyi - http://d-dome.net/idapython/"
version3 += " version %d.%d.%d %s (serial %d)" % IDAPYTHON_VERSION ]
version4 = "Copyright (c) 2004-2009 Gergely Erdelyi - http://d-dome.net/idapython/" sepline = '-' * max([len(s) for s in banner])
linelen = max(len(version1), len(version2), len(version3), len(version4))
print '-' * linelen print sepline
print version1 print "\n".join(banner)
print version2 print sepline
print
print version3
print version4
print '-' * linelen
#----------------------------------------------------------- # -----------------------------------------------------------------------
# Take over the standard text outputs # Take over the standard text outputs
#----------------------------------------------------------- # -----------------------------------------------------------------------
class MyStdOut: class MyStdOut:
""" """
Dummy file-like class that receives stout and stderr Dummy file-like class that receives stout and stderr
@ -109,6 +105,7 @@ class MyStdOut:
def write(self, text): def write(self, text):
# Swap out the unprintable characters # Swap out the unprintable characters
text = text.decode('ascii', 'replace').encode('ascii', 'replace') text = text.decode('ascii', 'replace').encode('ascii', 'replace')
# Print to IDA message window
_idaapi.msg(text.replace("%", "%%")) _idaapi.msg(text.replace("%", "%%"))
def flush(self): def flush(self):
@ -121,22 +118,22 @@ class MyStdOut:
sys.stdout = sys.stderr = MyStdOut() sys.stdout = sys.stderr = MyStdOut()
# Assign a default sys.argv # Assign a default sys.argv
sys.argv = [ "" ] sys.argv = [""]
# Have to make sure Python finds our modules # Have to make sure Python finds our modules
sys.path.append(_idaapi.idadir("python")) sys.path.append(_idaapi.idadir("python"))
#----------------------------------------------------------- # -----------------------------------------------------------------------
# Import all the required modules # Import all the required modules
#----------------------------------------------------------- # -----------------------------------------------------------------------
from idaapi import Choose, get_user_idadir, cvar, Choose2, Appcall from idaapi import Choose, get_user_idadir, cvar, Choose2, Appcall
from idc import * from idc import *
from idautils import * from idautils import *
import idaapi import idaapi
#----------------------------------------------------------- # -----------------------------------------------------------------------
# Build up the ScriptBox tool # Build up the ScriptBox tool
#----------------------------------------------------------- # -----------------------------------------------------------------------
class ScriptBox(Choose): class ScriptBox(Choose):
def __init__(self, list=None): def __init__(self, list=None):
if list: if list:
@ -161,7 +158,7 @@ class ScriptBox(Choose):
scriptbox = ScriptBox() scriptbox = ScriptBox()
#------------------------------------------------------------- # -----------------------------------------------------------------------
# Watchdog to catch runaway scripts after a specified timeout # Watchdog to catch runaway scripts after a specified timeout
# #
# Usage: # Usage:
@ -170,7 +167,7 @@ scriptbox = ScriptBox()
# #
# Note: The watchdog only works for code running inside # Note: The watchdog only works for code running inside
# functions, not in global/module namespace. # functions, not in global/module namespace.
#------------------------------------------------------------- # -----------------------------------------------------------------------
class WatchDog(): class WatchDog():
""" """
Python tracer-based watchdog class Python tracer-based watchdog class
@ -217,11 +214,14 @@ class WatchDog():
watchdog = WatchDog(10) watchdog = WatchDog(10)
# -----------------------------------------------------------------------
# Load the users personal init file # Load the users personal init file
userrc = get_user_idadir() + os.sep + "idapythonrc.py" userrc = get_user_idadir() + os.sep + "idapythonrc.py"
# -----------------------------------------------------------------------
if os.path.exists(userrc): if os.path.exists(userrc):
runscript(userrc) runscript(userrc)
# Remove the user script from the history # Remove the user script from the history
del scriptbox.list[0] del scriptbox.list[0]

View File

@ -41,4 +41,10 @@
%ignore areacb_t::move_areas; %ignore areacb_t::move_areas;
%ignore areacb_t::for_all_areas; %ignore areacb_t::for_all_areas;
%ignore areaset_t::count;
%ignore areaset_t::lower_bound;
%ignore areaset_t::upper_bound;
%ignore areaset_t::move_chunk;
%ignore areaset_t::check_move_args;
%include "area.hpp" %include "area.hpp"

View File

@ -258,5 +258,7 @@ int idaapi DBG_Callback(void *ud, int notification_code, va_list va)
PyErr_Print(); PyErr_Print();
} }
} }
return 0;
} }
%} %}

View File

@ -50,7 +50,7 @@ int idaapi py_enumerate_files_cb(const char *file, void *ud)
{ {
PyObject *py_file = PyString_FromString(file); PyObject *py_file = PyString_FromString(file);
PyObject *py_ret = PyObject_CallFunctionObjArgs((PyObject *)ud, py_file, NULL); PyObject *py_ret = PyObject_CallFunctionObjArgs((PyObject *)ud, py_file, NULL);
int r = (py_ret == 0 || !PyNumber_Check(py_ret)) ? 1 /* stop enumeration on failure */ : PyInt_AsLong(py_ret); int r = (py_ret == NULL || !PyNumber_Check(py_ret)) ? 1 /* stop enumeration on failure */ : PyInt_AsLong(py_ret);
Py_XDECREF(py_file); Py_XDECREF(py_file);
Py_XDECREF(py_ret); Py_XDECREF(py_ret);
return r; return r;
@ -98,7 +98,7 @@ public:
// class from and to IDC. The value of this variable must be set to two // class from and to IDC. The value of this variable must be set to two
int __idc_cvt_id__; int __idc_cvt_id__;
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
loader_input_t(PyObject *pycobject = NULL): li(NULL), own(OWN_NONE), __idc_cvt_id__(2) loader_input_t(PyObject *pycobject = NULL): li(NULL), own(OWN_NONE), __idc_cvt_id__(PY_ICID_OPAQUE)
{ {
if (pycobject != NULL && PyCObject_Check(pycobject)) if (pycobject != NULL && PyCObject_Check(pycobject))
_from_cobject(pycobject); _from_cobject(pycobject);
@ -114,8 +114,9 @@ public:
close_linput(li); close_linput(li);
else if (own == OWN_FROM_FP) else if (own == OWN_FROM_FP)
unmake_linput(li); unmake_linput(li);
own = OWN_NONE;
li = NULL; li = NULL;
own = OWN_NONE;
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------

View File

@ -42,7 +42,7 @@ public:
fp = NULL; fp = NULL;
own = true; own = true;
fn.qclear(); fn.qclear();
__idc_cvt_id__ = 2; // Opaque object __idc_cvt_id__ = PY_ICID_OPAQUE;
if (pycobject != NULL && PyCObject_Check(pycobject)) if (pycobject != NULL && PyCObject_Check(pycobject))
_from_cobject(pycobject); _from_cobject(pycobject);
} }
@ -61,6 +61,7 @@ public:
if (own) if (own)
qfclose(fp); qfclose(fp);
fp = NULL; fp = NULL;
own = true;
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------

View File

@ -1,31 +1,19 @@
%{ %{
//<code(py_graph)> //<code(py_graph)>
#define GR_HAVE_USER_HINT 0x00000001
#define GR_HAVE_CLICKED 0x00000002
#define GR_HAVE_DBL_CLICKED 0x00000004
#define GR_HAVE_GOTFOCUS 0x00000008
#define GR_HAVE_LOSTFOCUS 0x00000010
#define GR_HAVE_CHANGED_CURRENT 0x00000020
#define GR_HAVE_CLOSE 0x00000040
#define GR_HAVE_COMMAND 0x00000080
#define S_ON_COMMAND "OnCommand"
#define S_ON_REFRESH "OnRefresh"
#define S_ON_HINT "OnHint"
#define S_ON_GETTEXT "OnGetText"
#define S_ON_CLOSE "OnClose"
#define S_ON_CLICK "OnClick"
#define S_ON_DBL_CLICK "OnDblClick"
#define S_ON_ACTIVATE "OnActivate"
#define S_ON_DEACTIVATE "OnDeactivate"
#define S_ON_SELECT "OnSelect"
#define S_M_EDGES "_edges"
#define S_M_NODES "_nodes"
#define S_M_THIS "_this"
#define S_M_TITLE "_title"
class py_graph_t class py_graph_t
{ {
private: private:
enum
{
GR_HAVE_USER_HINT = 0x00000001,
GR_HAVE_CLICKED = 0x00000002,
GR_HAVE_DBL_CLICKED = 0x00000004,
GR_HAVE_GOTFOCUS = 0x00000008,
GR_HAVE_LOSTFOCUS = 0x00000010,
GR_HAVE_CHANGED_CURRENT = 0x00000020,
GR_HAVE_CLOSE = 0x00000040,
GR_HAVE_COMMAND = 0x00000080
};
struct nodetext_cache_t struct nodetext_cache_t
{ {
qstring text; qstring text;
@ -126,7 +114,7 @@ private:
void on_command(Py_ssize_t id) void on_command(Py_ssize_t id)
{ {
// Check return value to OnRefresh() call // Check return value to OnRefresh() call
PyObject *ret = PyObject_CallMethod(self, S_ON_COMMAND, "n", id); PyObject *ret = PyObject_CallMethod(self, (char *)S_ON_COMMAND, "n", id);
Py_XDECREF(ret); Py_XDECREF(ret);
} }
@ -139,7 +127,7 @@ private:
return; return;
// Check return value to OnRefresh() call // Check return value to OnRefresh() call
PyObject *ret = PyObject_CallMethod(self, S_ON_REFRESH, NULL); PyObject *ret = PyObject_CallMethod(self, (char *)S_ON_REFRESH, NULL);
if (ret == NULL || !PyBool_Check(ret) || ret != Py_True) if (ret == NULL || !PyBool_Check(ret) || ret != Py_True)
{ {
Py_XDECREF(ret); Py_XDECREF(ret);
@ -224,7 +212,7 @@ private:
} }
// Not cached, call Python // Not cached, call Python
PyObject *result = PyObject_CallMethod(self, S_ON_GETTEXT, "l", node); PyObject *result = PyObject_CallMethod(self, (char *)S_ON_GETTEXT, "i", node);
if (result == NULL) if (result == NULL)
return false; return false;
@ -274,7 +262,7 @@ private:
if (mousenode == -1) if (mousenode == -1)
return 0; return 0;
PyObject *result = PyObject_CallMethod(self, S_ON_HINT, "l", mousenode); PyObject *result = PyObject_CallMethod(self, (char *)S_ON_HINT, "i", mousenode);
bool ok = result != NULL && PyString_Check(result); bool ok = result != NULL && PyString_Check(result);
if (!ok) if (!ok)
{ {
@ -293,7 +281,7 @@ private:
{ {
if (cb_flags & GR_HAVE_CLOSE) if (cb_flags & GR_HAVE_CLOSE)
{ {
PyObject *result = PyObject_CallMethod(self, S_ON_CLOSE, NULL); PyObject *result = PyObject_CallMethod(self, (char *)S_ON_CLOSE, NULL);
Py_XDECREF(result); Py_XDECREF(result);
} }
unbind(); unbind();
@ -322,7 +310,7 @@ private:
if (item2->n == -1) if (item2->n == -1)
return 1; return 1;
PyObject *result = PyObject_CallMethod(self, S_ON_CLICK, "l", item2->n); PyObject *result = PyObject_CallMethod(self, (char *)S_ON_CLICK, "i", item2->n);
if (result == NULL || !PyBool_Check(result) || result != Py_True) if (result == NULL || !PyBool_Check(result) || result != Py_True)
{ {
Py_XDECREF(result); Py_XDECREF(result);
@ -343,7 +331,7 @@ private:
//selection_item_t *s = va_arg(va, selection_item_t *); //selection_item_t *s = va_arg(va, selection_item_t *);
if (item == NULL || !item->is_node) if (item == NULL || !item->is_node)
return 1; return 1;
PyObject *result = PyObject_CallMethod(self, S_ON_DBL_CLICK, "l", item->node); PyObject *result = PyObject_CallMethod(self, (char *)S_ON_DBL_CLICK, "i", item->node);
if (result == NULL || !PyBool_Check(result) || result != Py_True) if (result == NULL || !PyBool_Check(result) || result != Py_True)
{ {
Py_XDECREF(result); Py_XDECREF(result);
@ -356,14 +344,14 @@ private:
// a graph viewer got focus // a graph viewer got focus
void on_gotfocus(graph_viewer_t * /*gv*/) void on_gotfocus(graph_viewer_t * /*gv*/)
{ {
PyObject *result = PyObject_CallMethod(self, S_ON_ACTIVATE, NULL); PyObject *result = PyObject_CallMethod(self, (char *)S_ON_ACTIVATE, NULL);
Py_XDECREF(result); Py_XDECREF(result);
} }
// a graph viewer lost focus // a graph viewer lost focus
void on_lostfocus(graph_viewer_t *gv) void on_lostfocus(graph_viewer_t *gv)
{ {
PyObject *result = PyObject_CallMethod(self, S_ON_DEACTIVATE, NULL); PyObject *result = PyObject_CallMethod(self, (char *)S_ON_DEACTIVATE, NULL);
Py_XDECREF(result); Py_XDECREF(result);
} }
@ -378,8 +366,8 @@ private:
//msg("%x: current node becomes %d\n", v, curnode); //msg("%x: current node becomes %d\n", v, curnode);
if (curnode < 0) if (curnode < 0)
return 0; return 0;
PyObject *result = PyObject_CallMethod(self, S_ON_SELECT, "l", curnode); PyObject *result = PyObject_CallMethod(self, (char *)S_ON_SELECT, "i", curnode);
bool allow = (result != NULL && PyBool_Check(result) && result == Py_True); bool allow = (result != NULL && PyObject_IsTrue(result));
Py_XDECREF(result); Py_XDECREF(result);
return allow ? 0 : 1; return allow ? 0 : 1;
} }
@ -747,29 +735,6 @@ void pyg_select_node(PyObject *self, int nid)
{ {
py_graph_t::SelectNode(self, nid); py_graph_t::SelectNode(self, nid);
} }
#undef GR_HAVE_USER_HINT
#undef GR_HAVE_CLICKED
#undef GR_HAVE_DBL_CLICKED
#undef GR_HAVE_GOTFOCUS
#undef GR_HAVE_LOSTFOCUS
#undef GR_HAVE_CHANGED_CURRENT
#undef GR_HAVE_CLOSE
#undef GR_HAVE_COMMAND
#undef S_ON_COMMAND
#undef S_ON_REFRESH
#undef S_ON_HINT
#undef S_ON_GETTEXT
#undef S_ON_CLOSE
#undef S_ON_CLICK
#undef S_ON_DBL_CLICK
#undef S_ON_ACTIVATE
#undef S_ON_DEACTIVATE
#undef S_ON_SELECT
#undef S_M_EDGES
#undef S_M_NODES
#undef S_M_THIS
#undef S_M_TITLE
//</code(py_graph)> //</code(py_graph)>
%} %}

View File

@ -30,7 +30,7 @@ PyObject *meminfo_vec_t_to_py(meminfo_vec_t &areas)
const memory_info_t &mi = *it; const memory_info_t &mi = *it;
// startEA endEA name sclass sbase bitness perm // startEA endEA name sclass sbase bitness perm
PyList_SetItem(py_list, i, PyList_SetItem(py_list, i,
Py_BuildValue("(KKssKii)", Py_BuildValue("("PY_FMT64 PY_FMT64 "ss" PY_FMT64 "II)",
pyul_t(mi.startEA), pyul_t(mi.startEA),
pyul_t(mi.endEA), pyul_t(mi.endEA),
mi.name.c_str(), mi.name.c_str(),
@ -110,7 +110,7 @@ PyObject *dbg_get_thread_sreg_base(PyObject *py_tid, PyObject *py_sreg_value)
int sreg_value = PyInt_AsLong(py_sreg_value); int sreg_value = PyInt_AsLong(py_sreg_value);
if (dbg->thread_get_sreg_base(tid, sreg_value, &answer) != 1) if (dbg->thread_get_sreg_base(tid, sreg_value, &answer) != 1)
Py_RETURN_NONE; Py_RETURN_NONE;
return Py_BuildValue("K", pyul_t(answer)); return Py_BuildValue(PY_FMT64, pyul_t(answer));
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -185,7 +185,7 @@ PyObject *py_appcall(
msg("obj[%d]->%s\n", int(i), s.c_str()); msg("obj[%d]->%s\n", int(i), s.c_str());
} }
// Convert it // Convert it
if (pyvar_to_idcvar(py_item, &idc_args[i], &sn) <= 0) if (pyvar_to_idcvar(py_item, &idc_args[i], &sn) < CIP_OK)
{ {
ok = false; ok = false;
break; break;

View File

@ -7,6 +7,7 @@
%ignore IDPOPT_NUM; %ignore IDPOPT_NUM;
%ignore IDPOPT_BIT; %ignore IDPOPT_BIT;
%ignore IDPOPT_FLT; %ignore IDPOPT_FLT;
%ignore IDPOPT_I64;
%ignore IDPOPT_OK; %ignore IDPOPT_OK;
%ignore IDPOPT_BADKEY; %ignore IDPOPT_BADKEY;
%ignore IDPOPT_BADTYPE; %ignore IDPOPT_BADTYPE;
@ -277,6 +278,7 @@ int idaapi IDB_Callback(void *ud, int notification_code, va_list va)
PyErr_Print(); PyErr_Print();
} }
} }
return 0;
} }
// Assemble an instruction into the database (display a warning if an error is found) // Assemble an instruction into the database (display a warning if an error is found)

View File

@ -79,6 +79,7 @@
%ignore save_text_line; %ignore save_text_line;
%ignore print_all_structs; %ignore print_all_structs;
%ignore print_all_enums; %ignore print_all_enums;
%ignore enum_processor_modules;
%ignore database_id0; %ignore database_id0;
%ignore is_database_ext; %ignore is_database_ext;
%ignore ida_database_memory; %ignore ida_database_memory;

View File

@ -33,6 +33,7 @@ static int idaapi py_import_enum_cb(
Py_DECREF(py_ea); Py_DECREF(py_ea);
Py_DECREF(py_name); Py_DECREF(py_name);
Py_DECREF(py_ord); Py_DECREF(py_ord);
Py_XDECREF(py_result);
return r; return r;
} }
//</code(py_nalt)> //</code(py_nalt)>

View File

@ -81,6 +81,8 @@
%ignore netnode::altadjust; %ignore netnode::altadjust;
%ignore netnode::operator nodeidx_t;
// Renaming one version of hashset() otherwise SWIG will not be able to activate the other one // Renaming one version of hashset() otherwise SWIG will not be able to activate the other one
%rename (hashset_idx) netnode::hashset(const char *idx, nodeidx_t value, char tag=htag); %rename (hashset_idx) netnode::hashset(const char *idx, nodeidx_t value, char tag=htag);

View File

@ -152,7 +152,7 @@
static bool convert_pyobj_to_idc_exc(PyObject *py_obj, idc_value_t *idc_obj) static bool convert_pyobj_to_idc_exc(PyObject *py_obj, idc_value_t *idc_obj)
{ {
int sn = 0; int sn = 0;
if (pyvar_to_idcvar(py_obj, idc_obj, &sn) <= 0) if (pyvar_to_idcvar(py_obj, idc_obj, &sn) < CIP_OK)
{ {
PyErr_SetString(PyExc_ValueError, "Could not convert Python object to IDC object!"); PyErr_SetString(PyExc_ValueError, "Could not convert Python object to IDC object!");
return false; return false;
@ -401,36 +401,34 @@ int idc_parse_types(const char *input, int flags)
if ((flags & 1) != 0) if ((flags & 1) != 0)
hti |= HTI_FIL; hti |= HTI_FIL;
return parse_types2(input, (flags & 2) == 0 ? msg : NULL, hti); return parse_decls(idati, input, (flags & 2) == 0 ? msg : NULL, hti);
} }
char *idc_get_type(ea_t ea, char *buf, size_t bufsize) char *idc_get_type(ea_t ea, char *buf, size_t bufsize)
{ {
type_t type[MAXSTR]; qtype type, fnames;
p_list fnames[MAXSTR];
if (get_ti(ea, type, sizeof(type), fnames, sizeof(fnames))) if (get_tinfo(ea, &type, &fnames))
{ {
int code = print_type_to_one_line(buf, bufsize, idati, type, int code = print_type_to_one_line(buf, bufsize, idati, type.c_str(),
NULL, NULL, fnames); NULL, NULL, fnames.c_str());
if (code == T_NORMAL) if (code == T_NORMAL)
return buf; return buf;
} \ }
return NULL; return NULL;
} }
char *idc_guess_type(ea_t ea, char *buf, size_t bufsize) char *idc_guess_type(ea_t ea, char *buf, size_t bufsize)
{ {
type_t type[MAXSTR]; qtype type, fnames;
p_list fnames[MAXSTR];
if (guess_type(ea, type, sizeof(type), fnames, sizeof(fnames))) if (guess_tinfo(ea, &type, &fnames))
{ {
int code = print_type_to_one_line(buf, bufsize, idati, type, int code = print_type_to_one_line(buf, bufsize, idati, type.c_str(),
NULL, NULL, fnames); NULL, NULL, fnames.c_str());
if (code == T_NORMAL) if (code == T_NORMAL)
return buf; return buf;
} \ }
return NULL; return NULL;
} }