# HG changeset patch # User Sebastien Decugis # Date 1291882464 -32400 # Node ID a5682d003ed9a8d8fa9482330d6e0e90868c4d83 # Parent fc4f5815f0aab1ce85ba02a18c6dca01e870b7d1 Finally got the proxy aka shadow class to work diff -r fc4f5815f0aa -r a5682d003ed9 doc/dbg_interactive.py.sample --- a/doc/dbg_interactive.py.sample Tue Dec 07 17:24:53 2010 +0900 +++ b/doc/dbg_interactive.py.sample Thu Dec 09 17:14:24 2010 +0900 @@ -29,8 +29,8 @@ # Print messages to freeDiameter's debug facility -fd_log_debug("3 + 4 = %d\n", 7) -# Hum... Currently I get "3 + 4 = 0" output... need some fix... +fd_log_debug("3 + 4 = %d\n" % (7)) +# See SWIG documentation about varargs functions for more information # SWIG deals with structures as follow: @@ -41,6 +41,12 @@ # foo_a_set(s, 2) --> s->a = 2 # foo_a_get(s) --> returns s->a value # delete_foo(s) --> free(s) +# +# In addition, thanks to proxy (aka shadow) class, we can also do: +# s = foo() +# s.a = 2 +# s.a +# del s # Display the local Diameter Identity: @@ -62,6 +68,7 @@ mypicflag = peer_info_config_pic_flags_get(myconfig) peer_info_config_pic_flags_pro4_set(mypicflag, 1) # 1 for TCP fd_peer_add(mypeer, "python", None, None) +delete_peer_info(mypeer) # Lists @@ -77,17 +84,100 @@ # Dictionary gdict = fd_config_cnf_dict_get(cvar.fd_g_config) + id = new_int_ptr() int_ptr_assign(id, 3) -res = new_dict_object_ptr() -err = fd_dict_search ( gdict, DICT_APPLICATION, APPLICATION_BY_ID, id, res, -1 ) -obj = dict_object_ptr_value(res) +pobj = new_dict_object_pptr() +fd_dict_search ( gdict, DICT_APPLICATION, APPLICATION_BY_ID, id, pobj, -1 ) +delete_int_ptr(id) +obj = dict_object_pptr_value(pobj) +delete_dict_object_pptr(pobj) t = new_dict_object_type_ptr() -err = fd_dict_gettype(obj, t) +fd_dict_gettype(obj, t) dict_object_type_ptr_dump(t) -v = new_dict_application_data() -err = fd_dict_getval(obj, v) -dict_application_data_application_name_get(v) +delete_dict_object_type_ptr(t) +objdata = new_dict_application_data() +fd_dict_getval(obj, objdata) +dict_application_data_application_name_get(objdata) +delete_dict_application_data(objdata) + +vd = new_dict_vendor_data() +dict_vendor_data_vendor_id_set(vd, 123) +dict_vendor_data_vendor_name_set(vd, "my test vendor") +pobj = new_dict_object_pptr() +fd_dict_new ( gdict, DICT_VENDOR, vd, None, pobj) +delete_dict_vendor_data(vd) +obj = dict_object_pptr_value(pobj) +delete_dict_object_pptr(pobj) +fd_dict_dump_object(obj) + + +# Sessions +pmyhdl = new_session_handler_pptr() +fd_sess_handler_create_internal(pmyhdl, None) +### Have to work on this one, a cleanup handler is actually required. +### How to define the handler in python ? +myhdl = session_handler_pptr_value(pmyhdl) +delete_session_handler_pptr(pmyhdl) + +psess = new_session_pptr() +fd_sess_new (psess, fd_config_cnf_diamid_get(cvar.fd_g_config), "dbg_interactive", 0) +sess = session_pptr_value(psess) +fd_sess_dump(0, sess) +fd_sess_destroy(psess) +delete_session_pptr(psess) +# Routing data +prtd = new_rt_data_pptr() +fd_rtd_init(prtd) +fd_rtd_candidate_add(rt_data_pptr_value(prtd), "p1.testbed.aaa", "testbed.aaa") +fd_rtd_candidate_add(rt_data_pptr_value(prtd), "p2.testbed.aaa", "testbed.aaa") +fd_rtd_candidate_add(rt_data_pptr_value(prtd), "p3.testbed.aaa", "testbed.aaa") +fd_rtd_candidate_del(rt_data_pptr_value(prtd), "p2.testbed.aaa", 0) +pcands = new_fd_list_pptr() +fd_rtd_candidate_extract(rt_data_pptr_value(prtd), pcands, 0) +li = fd_list_pptr_value(pcands) +li = fd_list_next_get(li) +c = fd_list_to_rtd_candidate(li) +rtd_candidate_diamid_get(c) +li = fd_list_next_get(li) +c = fd_list_to_rtd_candidate(li) +rtd_candidate_diamid_get(c) + +# Messages +gdict = fd_config_cnf_dict_get(cvar.fd_g_config) +pobj = new_dict_object_pptr() +fd_dict_search ( gdict, DICT_COMMAND, CMD_BY_NAME, char_to_void("Capabilities-Exchange-Request"), pobj, -1 ) +cerdict = dict_object_pptr_value(pobj) +fd_dict_search ( gdict, DICT_AVP, AVP_BY_NAME, char_to_void("Origin-Host"), pobj, -1 ) +ohdict = dict_object_pptr_value(pobj) +delete_dict_object_pptr(pobj) + +pmsg = new_msg_pptr() +fd_msg_new(cerdict, MSGFL_ALLOC_ETEID, pmsg) +msg = msg_pptr_value(pmsg); +pavp = new_avp_pptr() +fd_msg_avp_new(ohdict, 0, pavp) +avp = avp_pptr_value(pavp); +fd_msg_avp_add(msg, MSG_BRW_FIRST_CHILD, avp) +fd_msg_dump_walk(0, msg) + +pahdr = new_avp_hdr_pptr() +fd_msg_avp_hdr(avp, pahdr) +ahdr = avp_hdr_pptr_value(pahdr) +delete_avp_hdr_pptr(pahdr) +avp_hdr_avp_code_get(ahdr) +os = new_avp_value_os() +avp_value_os_fromstr(os, fd_config_cnf_diamid_get(cvar.fd_g_config)) +val = new_avp_value() +avp_value_os_set(val, os) +delete_avp_value_os(os) +fd_msg_avp_setvalue(avp, val) +delete_avp_value(val) + +r,buf = fd_msg_bufferize_py(msg) +fd_msg_free(msg) +delete_avp_pptr(pavp) + diff -r fc4f5815f0aa -r a5682d003ed9 extensions/dbg_interactive/CMakeLists.txt --- a/extensions/dbg_interactive/CMakeLists.txt Tue Dec 07 17:24:53 2010 +0900 +++ b/extensions/dbg_interactive/CMakeLists.txt Thu Dec 09 17:14:24 2010 +0900 @@ -10,19 +10,47 @@ # Wrapper to fD in python FIND_PACKAGE(SWIG REQUIRED) INCLUDE(${SWIG_USE_FILE}) -SET(CMAKE_SWIG_FLAGS "") +SET(CMAKE_SWIG_FLAGS -castmode -threads) # Add the dependencies for re-swig-ing the file -SET(SWIG_MODULE_diwrap_EXTRA_DEPS +SET(SWIG_MODULE_fDpy_EXTRA_DEPS ${CMAKE_BINARY_DIR}/include/freeDiameter/freeDiameter-host.h ${CMAKE_SOURCE_DIR}/include/freeDiameter/libfreeDiameter.h ${CMAKE_SOURCE_DIR}/include/freeDiameter/freeDiameter.h) +SET_SOURCE_FILES_PROPERTIES(dbg_interactive.i PROPERTIES SWIG_MODULE_NAME fDpy) -# We create the module even if we don't use it, so that intermediate values are defined (OK, this is stupid...) -SWIG_ADD_MODULE(diwrap python diwrap.i) +# The following code is inspired from SWIG_ADD_MODULE, but we do only what we need +SWIG_MODULE_INITIALIZE(fDpy python) +SWIG_ADD_SOURCE_TO_MODULE(fDpy swig_generated_sources "dbg_interactive.i") + +# In order to avoid shipping the python file that contains the shadow class definitions, +# we transform this file in a C-style string and compile it within our software. +# We use for this purpose xxd tool provided with vim package. +FIND_PROGRAM(XXD_EXECUTABLE xxd) +# To avoid the dependency, simply compile it if not provided +if (NOT XXD_EXECUTABLE) + SET_SOURCE_FILES_PROPERTIES(helper/xxd.c PROPERTIES COMPILE_DEFINITIONS UNIX) + ADD_EXECUTABLE(xxd helper/xxd.c) + SET(XXD_EXECUTABLE xxd) +endif (NOT XXD_EXECUTABLE) +# And now the magic command +ADD_CUSTOM_COMMAND( + OUTPUT "fDpy-inc.c" + COMMAND "${XXD_EXECUTABLE}" + ARGS "-i" + "fDpy.py" + "fDpy-inc.c" + MAIN_DEPENDENCY "${swig_extra_generated_files}" + COMMENT "Converting swig proxy class to C string") + +# Ensure that the generated source files are removed +GET_DIRECTORY_PROPERTY(swig_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES) +SET_DIRECTORY_PROPERTIES(PROPERTIES + ADDITIONAL_MAKE_CLEAN_FILES "${swig_extra_clean_files};${swig_generated_sources};fDpy-inc.c") + ##### # Extension that embeds the python interpreter -FD_ADD_EXTENSION(dbg_interactive dbg_interactive.c ${swig_generated_sources} ${swig_other_sources}) +FD_ADD_EXTENSION(dbg_interactive dbg_interactive.c ${swig_generated_sources} fDpy-inc.c) TARGET_LINK_LIBRARIES(dbg_interactive ${PYTHON_LIBRARIES}) diff -r fc4f5815f0aa -r a5682d003ed9 extensions/dbg_interactive/dbg_interactive.c --- a/extensions/dbg_interactive/dbg_interactive.c Tue Dec 07 17:24:53 2010 +0900 +++ b/extensions/dbg_interactive/dbg_interactive.c Thu Dec 09 17:14:24 2010 +0900 @@ -37,7 +37,17 @@ #include /* wrapper generated by SWIG */ -extern void init_diwrap(void); +#if PY_VERSION_HEX >= 0x03000000 + extern void PyInit__fDpy(void); + #define WRAPPER_INIT PyInit__fDpy() +#else /* PY_VERSION_HEX */ + extern void init_fDpy(void); + #define WRAPPER_INIT init_fDpy() +#endif /* PY_VERSION_HEX */ + +/* The string created in the shadow proxy C string file */ +extern unsigned char fDpy_py[]; +extern unsigned int fDpy_py_len; /* Run an interactive interpreter in a separate thread */ static pthread_t pyinterp = (pthread_t)NULL; @@ -62,18 +72,34 @@ /* Register the callbacks to the daemon */ static int di_main(char * conffile) { + char * shadow_hlp = NULL; + int mustfree = 0; TRACE_ENTRY("%p", conffile); Py_Initialize(); -#if PY_VERSION_HEX >= 0x03000000 - PyInit__diwrap(); -#else /* PY_VERSION_HEX */ - init_diwrap(); -#endif /* PY_VERSION_HEX */ + WRAPPER_INIT; - /* In future version, it might be better to use the diwrap.py file generated by SWIG here to get the proxy classes definitions */ - PyRun_SimpleString("from _diwrap import *\n"); + /* Small hack to avoid duplicating the string, we replace the last char by a \0. + It works if the python file is terminated with several \n */ + if ( (fDpy_py[fDpy_py_len - 2] == '\n') + && (fDpy_py[fDpy_py_len - 1] == '\n')) { + fDpy_py[fDpy_py_len - 1] = '\0'; + shadow_hlp = (char *)&fDpy_py[0]; + } else { + CHECK_MALLOC(shadow_hlp = malloc(fDpy_py_len + 1)); + memcpy(shadow_hlp, fDpy_py, fDpy_py_len); + shadow_hlp[fDpy_py_len] = '\0'; + mustfree=1; + } + + PyRun_SimpleString("__file__ = \"\"\n"); + PyRun_SimpleString(shadow_hlp); + + if (mustfree) + free(shadow_hlp); + + if (TRACE_BOOL(INFO)) { PyRun_SimpleString("print \"[dbg_interactive] \",FD_PROJECT_NAME,FD_PROJECT_VERSION_MAJOR,FD_PROJECT_VERSION_MINOR,FD_PROJECT_VERSION_REV\n"); } diff -r fc4f5815f0aa -r a5682d003ed9 extensions/dbg_interactive/dbg_interactive.i --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extensions/dbg_interactive/dbg_interactive.i Thu Dec 09 17:14:24 2010 +0900 @@ -0,0 +1,192 @@ +/* This interface file is processed by SWIG to create a python wrapper interface to freeDiameter framework. */ +%module fDpy +%begin %{ +/********************************************************************************************************* +* Software License Agreement (BSD License) * +* Author: Sebastien Decugis * +* * +* Copyright (c) 2010, WIDE Project and NICT * +* All rights reserved. * +* * +* Redistribution and use of this software in source and binary forms, with or without modification, are * +* permitted provided that the following conditions are met: * +* * +* * Redistributions of source code must retain the above * +* copyright notice, this list of conditions and the * +* following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the * +* following disclaimer in the documentation and/or other * +* materials provided with the distribution. * +* * +* * Neither the name of the WIDE Project or NICT nor the * +* names of its contributors may be used to endorse or * +* promote products derived from this software without * +* specific prior written permission of WIDE Project and * +* NICT. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * +* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * +* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +*********************************************************************************************************/ +%} + +%{ +/* This text is included in the generated wrapper verbatim */ +#define SWIG +#include +%} + + +/* Include standard types & functions used in freeDiameter headers */ +%include +%include +%include +%include +%include + +/* Some functions are not available through the wrapper */ +%ignore fd_lib_init; +%ignore fd_lib_fini; + +/* Inline functions seems to give problems to SWIG -- just remove the inline definition */ +%define __inline__ +%enddef + +/* Make some global-variables read-only (mainly to avoid warnings) */ +%immutable fd_g_config; +%immutable peer_state_str; + +/* Overwrite a few functions prototypes for usability: default parameters values, OUTPUT typemaps, ... */ +extern void fd_list_init ( struct fd_list * list, void * obj = NULL ); + + +/* +extern int fd_dict_new ( struct dictionary * dict, enum dict_object_type type, void * data, struct dict_object * parent, struct dict_object ** OUTPUT ); +extern int fd_dict_search ( struct dictionary * dict, enum dict_object_type type, int criteria, void * what, struct dict_object ** OUTPUT, int retval ); +extern int fd_dict_get_error_cmd(struct dictionary * dict, struct dict_object ** OUTPUT); +extern int fd_dict_getval ( struct dict_object * object, void * INOUT); +//extern int fd_dict_gettype ( struct dict_object * object, enum dict_object_type * OUTPUT); +extern int fd_dict_getdict ( struct dict_object * object, struct dictionary ** OUTPUT); +*/ + +/* Retrieve the compile-time definitions of freeDiameter */ +%include "freeDiameter/freeDiameter-host.h" +%include "freeDiameter/libfreeDiameter.h" +%include "freeDiameter/freeDiameter.h" + + +/* Some pointer types that are useful */ +%pointer_functions(int, int_ptr); +%pointer_functions(uint8_t *, uint8_t_pptr); +%pointer_cast(char *, void *, char_to_void); + +%pointer_functions(struct fd_list *, fd_list_pptr); + +%pointer_functions(enum dict_object_type, dict_object_type_ptr); +%pointer_functions(struct dict_object *, dict_object_pptr); + +%pointer_functions(struct session *, session_pptr); +%pointer_functions(struct session_handler *, session_handler_pptr); +%pointer_functions(session_state *, session_state_pptr); + +%pointer_functions(struct rt_data *, rt_data_pptr); +%pointer_cast(struct fd_list *, struct rtd_candidate *, fd_list_to_rtd_candidate); + +%pointer_functions(struct msg *, msg_pptr); +%pointer_functions(struct msg_hdr *, msg_hdr_pptr); +%pointer_functions(struct avp *, avp_pptr); +%pointer_functions(struct avp_hdr *, avp_hdr_pptr); + + +/* Extend some structures for usability/debug in python */ +%extend fd_list { + fd_list(void * o = NULL) { + struct fd_list * li; + li = (struct fd_list *) malloc(sizeof(struct fd_list)); + if (!li) { + fd_log_debug("Out of memory!\n"); + PyErr_SetString(PyExc_MemoryError,"Not enough memory"); + return NULL; + } + fd_list_init(li, o); + return li; + } + ~fd_list() { + fd_list_unlink($self); + free($self); + } + void dump() { + fd_log_debug("list: %p\n", $self); + fd_log_debug(" - next: %p\n", $self->next); + fd_log_debug(" - prev: %p\n", $self->prev); + fd_log_debug(" - head: %p\n", $self->head); + fd_log_debug(" - o : %p\n", $self->o); + } +}; + +%inline %{ +void dict_object_type_ptr_dump(enum dict_object_type * t) { + #define CASE_STR(x) case x: fd_log_debug(#x "\n"); break; + switch (*t) { + CASE_STR(DICT_VENDOR) + CASE_STR(DICT_APPLICATION) + CASE_STR(DICT_TYPE) + CASE_STR(DICT_ENUMVAL) + CASE_STR(DICT_AVP) + CASE_STR(DICT_COMMAND) + CASE_STR(DICT_RULE) + default: + fd_log_debug("Invalid value (%d)", *t); + PyErr_SetString(PyExc_IndexError,"Invalid dictionary type object"); + } +} +%} + +%extend avp_value_os { + void fromstr(char * string) { + if ($self->data) free($self->data); + $self->data = (uint8_t *)strdup(string); + if (!$self->data) { + fd_log_debug("Out of memory!\n"); + PyErr_SetString(PyExc_MemoryError,"Not enough memory"); + $self->len = 0; + return; + } + $self->len = strlen(string); + } + %newobject as_str; + char * tostr() { + char * r; + if ($self->len == 0) + return NULL; + r = malloc($self->len + 1); + if (r) { + strncpy(r, (char *)$self->data, $self->len + 1); + } else { + fd_log_debug("Out of memory!\n"); + PyErr_SetString(PyExc_MemoryError,"Not enough memory"); + } + return r; + } +}; + +%extend avp_value { + void os_set(void * os) { + memcpy(&$self->os, os, sizeof($self->os)); + } +}; + +%cstring_output_allocate_size(char ** swig_buffer, size_t * swig_len, free(*$1)) +%inline %{ +int fd_msg_bufferize_py ( struct msg * msg, char ** swig_buffer, size_t * swig_len ) { + return fd_msg_bufferize(msg, (void *)swig_buffer, swig_len); +} +%}; + diff -r fc4f5815f0aa -r a5682d003ed9 extensions/dbg_interactive/diwrap.i --- a/extensions/dbg_interactive/diwrap.i Tue Dec 07 17:24:53 2010 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +0,0 @@ -/* This interface file is processed by SWIG to create a python wrapper interface to freeDiameter framework. */ -%module diwrap -%begin %{ -/********************************************************************************************************* -* Software License Agreement (BSD License) * -* Author: Sebastien Decugis * -* * -* Copyright (c) 2010, WIDE Project and NICT * -* All rights reserved. * -* * -* Redistribution and use of this software in source and binary forms, with or without modification, are * -* permitted provided that the following conditions are met: * -* * -* * Redistributions of source code must retain the above * -* copyright notice, this list of conditions and the * -* following disclaimer. * -* * -* * Redistributions in binary form must reproduce the above * -* copyright notice, this list of conditions and the * -* following disclaimer in the documentation and/or other * -* materials provided with the distribution. * -* * -* * Neither the name of the WIDE Project or NICT nor the * -* names of its contributors may be used to endorse or * -* promote products derived from this software without * -* specific prior written permission of WIDE Project and * -* NICT. * -* * -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * -* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * -* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * -*********************************************************************************************************/ -%} - - -%init %{ -/* TODO: How to load the proxy classes here? */ -%} - -%{ -/* Define types etc. */ -#define SWIG -#include -%} - - -/* Include standard types & functions used in freeDiameter headers */ -%include -%include -%include - -/* Some functions are not available through the wrapper */ -%ignore fd_lib_init; -%ignore fd_lib_fini; - -/* Inline functions seems to give problems to SWIG -- just remove the inline definition */ -%define __inline__ -%enddef - -/* Make some global-variables read-only (mainly to avoid warnings) */ -%immutable fd_g_config; -%immutable peer_state_str; - -/* Overwrite a few functions prototypes for usability: default parameters values, OUTPUT typemaps, ... */ -extern void fd_list_init ( struct fd_list * list, void * obj = NULL ); - - -/* -extern int fd_dict_new ( struct dictionary * dict, enum dict_object_type type, void * data, struct dict_object * parent, struct dict_object ** OUTPUT ); -extern int fd_dict_search ( struct dictionary * dict, enum dict_object_type type, int criteria, void * what, struct dict_object ** OUTPUT, int retval ); -extern int fd_dict_get_error_cmd(struct dictionary * dict, struct dict_object ** OUTPUT); -extern int fd_dict_getval ( struct dict_object * object, void * INOUT); -//extern int fd_dict_gettype ( struct dict_object * object, enum dict_object_type * OUTPUT); -extern int fd_dict_getdict ( struct dict_object * object, struct dictionary ** OUTPUT); -*/ - - -/* Retrieve the compile-time definitions of freeDiameter */ -%include "freeDiameter/freeDiameter-host.h" -%include "freeDiameter/libfreeDiameter.h" -%include "freeDiameter/freeDiameter.h" - - -/* Some pointer types that are useful */ -%pointer_class(int, int_ptr); -%pointer_class(enum dict_object_type, dict_object_type_ptr); -%pointer_functions(struct dict_object *, dict_object_ptr); -%pointer_functions(struct session *, session_ptr); - - - - -/* Extend some structures for usability/debug in python */ -%extend fd_list { - fd_list(void * o = NULL) { - struct fd_list * li; - li = (struct fd_list *) malloc(sizeof(struct fd_list)); - if (!li) { - fd_log_debug("Out of memory!\n"); - return NULL; - } - fd_list_init(li, o); - return li; - } - ~fd_list() { - fd_list_unlink($self); - free($self); - } - void dump() { - fd_log_debug("list: %p\n", $self); - fd_log_debug(" - next: %p\n", $self->next); - fd_log_debug(" - prev: %p\n", $self->prev); - fd_log_debug(" - head: %p\n", $self->head); - fd_log_debug(" - o : %p\n", $self->o); - } -}; - -%extend dict_object_type_ptr { - void dump() { - %#define CASE_STR(x) case x: fd_log_debug(#x "\n"); break; - switch (*$self) { - CASE_STR(DICT_VENDOR) - CASE_STR(DICT_APPLICATION) - CASE_STR(DICT_TYPE) - CASE_STR(DICT_ENUMVAL) - CASE_STR(DICT_AVP) - CASE_STR(DICT_COMMAND) - CASE_STR(DICT_RULE) - default: fd_log_debug("Invalid value (%d)", *$self); break; - } - } -} - -%inline %{ -void session_ptr_showsid(struct session * s) { - char * sid; - int ret = fd_sess_getsid ( s, &sid ); - if (ret != 0) { - fd_log_debug("Error %d\n", ret); - /* throw an exception in SWIG? */ - return; - } - fd_log_debug("%s\n", sid); -} -%} diff -r fc4f5815f0aa -r a5682d003ed9 extensions/dbg_interactive/helper/xxd.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extensions/dbg_interactive/helper/xxd.c Thu Dec 09 17:14:24 2010 +0900 @@ -0,0 +1,787 @@ +/* fD note: This source file comes from the VIM source package. All credits go to the original authors */ + +/* xxd: my hexdump facility. jw + * + * 2.10.90 changed to word output + * 3.03.93 new indent style, dumb bug inserted and fixed. + * -c option, mls + * 26.04.94 better option parser, -ps, -l, -s added. + * 1.07.94 -r badly needs - as input file. Per default autoskip over + * consecutive lines of zeroes, as unix od does. + * -a shows them too. + * -i dump as c-style #include "file.h" + * 1.11.95 if "xxd -i" knows the filename, an 'unsigned char filename_bits[]' + * array is written in correct c-syntax. + * -s improved, now defaults to absolute seek, relative requires a '+'. + * -r improved, now -r -s -0x... is supported. + * change/suppress leading '\0' bytes. + * -l n improved: stops exactly after n bytes. + * -r improved, better handling of partial lines with trailing garbage. + * -r improved, now -r -p works again! + * -r improved, less flushing, much faster now! (that was silly) + * 3.04.96 Per repeated request of a single person: autoskip defaults to off. + * 15.05.96 -v added. They want to know the version. + * -a fixed, to show last line inf file ends in all zeros. + * -u added: Print upper case hex-letters, as preferred by unix bc. + * -h added to usage message. Usage message extended. + * Now using outfile if specified even in normal mode, aehem. + * No longer mixing of ints and longs. May help doze people. + * Added binify ioctl for same reason. (Enough Doze stress for 1996!) + * 16.05.96 -p improved, removed occasional superfluous linefeed. + * 20.05.96 -l 0 fixed. tried to read anyway. + * 21.05.96 -i fixed. now honours -u, and prepends __ to numeric filenames. + * compile -DWIN32 for NT or W95. George V. Reilly, * -v improved :-) + * support --gnuish-longhorn-options + * 25.05.96 MAC support added: CodeWarrior already uses ``outline'' in Types.h + * which is included by MacHeaders (Axel Kielhorn). Renamed to + * xxdline(). + * 7.06.96 -i printed 'int' instead of 'char'. *blush* + * added Bram's OS2 ifdefs... + * 18.07.96 gcc -Wall @ SunOS4 is now slient. + * Added osver for MSDOS/DJGPP/WIN32. + * 29.08.96 Added size_t to strncmp() for Amiga. + * 24.03.97 Windows NT support (Phil Hanna). Clean exit for Amiga WB (Bram) + * 02.04.97 Added -E option, to have EBCDIC translation instead of ASCII + * (azc10@yahoo.com) + * 22.05.97 added -g (group octets) option (jcook@namerica.kla.com). + * 23.09.98 nasty -p -r misfeature fixed: slightly wrong output, when -c was + * missing or wrong. + * 26.09.98 Fixed: 'xxd -i infile outfile' did not truncate outfile. + * 27.10.98 Fixed: -g option parser required blank. + * option -b added: 01000101 binary output in normal format. + * 16.05.00 Added VAXC changes by Stephen P. Wall + * 16.05.00 Improved MMS file and merge for VMS by Zoltan Arpadffy + * + * (c) 1990-1998 by Juergen Weigert (jnweiger@informatik.uni-erlangen.de) + * + * Small changes made afterwards by Bram Moolenaar et al. + * + * Distribute freely and credit me, + * make money and share with me, + * lose money and don't ask me. + */ + +/* Visual Studio 2005 has 'deprecated' many of the standard CRT functions */ +#if _MSC_VER >= 1400 +# define _CRT_SECURE_NO_DEPRECATE +# define _CRT_NONSTDC_NO_DEPRECATE +#endif +#if !defined(CYGWIN) && (defined(CYGWIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__)) +# define CYGWIN +#endif + +#include +#ifdef VAXC +# include +#else +# include +#endif +#ifdef __TSC__ +# define MSDOS +#endif +#if !defined(OS2) && defined(__EMX__) +# define OS2 +#endif +#if defined(MSDOS) || defined(WIN32) || defined(OS2) || defined(__BORLANDC__) \ + || defined(CYGWIN) +# include /* for setmode() */ +#else +# ifdef UNIX +# include +# endif +#endif +#include +#include /* for strncmp() */ +#include /* for isalnum() */ +#if __MWERKS__ && !defined(BEBOX) +# include /* for fdopen() on MAC */ +#endif + +#if defined(__BORLANDC__) && __BORLANDC__ <= 0x0410 && !defined(fileno) +/* Missing define and prototype grabbed from the BC 4.0 */ +# define fileno(f) ((f)->fd) +FILE _FAR *_Cdecl _FARFUNC fdopen(int __handle, char _FAR *__type); +#endif + + +/* This corrects the problem of missing prototypes for certain functions + * in some GNU installations (e.g. SunOS 4.1.x). + * Darren Hiebert (sparc-sun-sunos4.1.3_U1/2.7.2.2) + */ +#if defined(__GNUC__) && defined(__STDC__) +# ifndef __USE_FIXED_PROTOTYPES__ +# define __USE_FIXED_PROTOTYPES__ +# endif +#endif + +#ifndef __USE_FIXED_PROTOTYPES__ +/* + * This is historic and works only if the compiler really has no prototypes: + * + * Include prototypes for Sun OS 4.x, when using an ANSI compiler. + * FILE is defined on OS 4.x, not on 5.x (Solaris). + * if __SVR4 is defined (some Solaris versions), don't include this. + */ +#if defined(sun) && defined(FILE) && !defined(__SVR4) && defined(__STDC__) +# define __P(a) a +/* excerpt from my sun_stdlib.h */ +extern int fprintf __P((FILE *, char *, ...)); +extern int fputs __P((char *, FILE *)); +extern int _flsbuf __P((unsigned char, FILE *)); +extern int _filbuf __P((FILE *)); +extern int fflush __P((FILE *)); +extern int fclose __P((FILE *)); +extern int fseek __P((FILE *, long, int)); +extern int rewind __P((FILE *)); + +extern void perror __P((char *)); +# endif +#endif + +extern long int strtol(); +extern long int ftell(); + +char version[] = "xxd V1.10 27oct98 by Juergen Weigert"; +#ifdef WIN32 +char osver[] = " (Win32)"; +#else +# ifdef DJGPP +char osver[] = " (dos 32 bit)"; +# else +# ifdef MSDOS +char osver[] = " (dos 16 bit)"; +# else +char osver[] = ""; +# endif +# endif +#endif + +#if defined(MSDOS) || defined(WIN32) || defined(OS2) +# define BIN_READ(yes) ((yes) ? "rb" : "rt") +# define BIN_WRITE(yes) ((yes) ? "wb" : "wt") +# define BIN_CREAT(yes) ((yes) ? (O_CREAT|O_BINARY) : O_CREAT) +# define BIN_ASSIGN(fp, yes) setmode(fileno(fp), (yes) ? O_BINARY : O_TEXT) +# define PATH_SEP '\\' +#elif defined(CYGWIN) +# define BIN_READ(yes) ((yes) ? "rb" : "rt") +# define BIN_WRITE(yes) ((yes) ? "wb" : "w") +# define BIN_CREAT(yes) ((yes) ? (O_CREAT|O_BINARY) : O_CREAT) +# define BIN_ASSIGN(fp, yes) ((yes) ? (void) setmode(fileno(fp), O_BINARY) : (void) (fp)) +# define PATH_SEP '/' +#else +# ifdef VMS +# define BIN_READ(dummy) "r" +# define BIN_WRITE(dummy) "w" +# define BIN_CREAT(dummy) O_CREAT +# define BIN_ASSIGN(fp, dummy) fp +# define PATH_SEP ']' +# define FILE_SEP '.' +# else +# define BIN_READ(dummy) "r" +# define BIN_WRITE(dummy) "w" +# define BIN_CREAT(dummy) O_CREAT +# define BIN_ASSIGN(fp, dummy) fp +# define PATH_SEP '/' +# endif +#endif + +/* open has only to arguments on the Mac */ +#if __MWERKS__ +# define OPEN(name, mode, umask) open(name, mode) +#else +# define OPEN(name, mode, umask) open(name, mode, umask) +#endif + +#ifdef AMIGA +# define STRNCMP(s1, s2, l) strncmp(s1, s2, (size_t)l) +#else +# define STRNCMP(s1, s2, l) strncmp(s1, s2, l) +#endif + +#ifndef __P +# if defined(__STDC__) || defined(MSDOS) || defined(WIN32) || defined(OS2) \ + || defined(__BORLANDC__) +# define __P(a) a +# else +# define __P(a) () +# endif +#endif + +/* Let's collect some prototypes */ +/* CodeWarrior is really picky about missing prototypes */ +static void exit_with_usage __P((char *)); +static int huntype __P((FILE *, FILE *, FILE *, char *, int, int, long)); +static void xxdline __P((FILE *, char *, int)); + +#define TRY_SEEK /* attempt to use lseek, or skip forward by reading */ +#define COLS 256 /* change here, if you ever need more columns */ +#define LLEN (11 + (9*COLS-1)/1 + COLS + 2) + +char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa; + +/* the different hextypes known by this program: */ +#define HEX_NORMAL 0 +#define HEX_POSTSCRIPT 1 +#define HEX_CINCLUDE 2 +#define HEX_BITS 3 /* not hex a dump, but bits: 01111001 */ + +static void +exit_with_usage(pname) +char *pname; +{ + fprintf(stderr, "Usage:\n %s [options] [infile [outfile]]\n", pname); + fprintf(stderr, " or\n %s -r [-s [-]offset] [-c cols] [-ps] [infile [outfile]]\n", pname); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -a toggle autoskip: A single '*' replaces nul-lines. Default off.\n"); + fprintf(stderr, " -b binary digit dump (incompatible with -ps,-i,-r). Default hex.\n"); + fprintf(stderr, " -c cols format octets per line. Default 16 (-i: 12, -ps: 30).\n"); + fprintf(stderr, " -E show characters in EBCDIC. Default ASCII.\n"); + fprintf(stderr, " -g number of octets per group in normal output. Default 2.\n"); + fprintf(stderr, " -h print this summary.\n"); + fprintf(stderr, " -i output in C include file style.\n"); + fprintf(stderr, " -l len stop after octets.\n"); + fprintf(stderr, " -ps output in postscript plain hexdump style.\n"); + fprintf(stderr, " -r reverse operation: convert (or patch) hexdump into binary.\n"); + fprintf(stderr, " -r -s off revert with added to file positions found in hexdump.\n"); + fprintf(stderr, " -s %sseek start at bytes abs. %sinfile offset.\n", +#ifdef TRY_SEEK + "[+][-]", "(or +: rel.) "); +#else + "", ""); +#endif + fprintf(stderr, " -u use upper case hex letters.\n"); + fprintf(stderr, " -v show version: \"%s%s\".\n", version, osver); + exit(1); +} + +/* + * Max. cols binary characters are decoded from the input stream per line. + * Two adjacent garbage characters after evaluated data delimit valid data. + * Everything up to the next newline is discarded. + * + * The name is historic and came from 'undo type opt h'. + */ +static int +huntype(fpi, fpo, fperr, pname, cols, hextype, base_off) +FILE *fpi, *fpo, *fperr; +char *pname; +int cols, hextype; +long base_off; +{ + int c, ign_garb = 1, n1 = -1, n2 = 0, n3, p = cols; + long have_off = 0, want_off = 0; + + rewind(fpi); + + while ((c = getc(fpi)) != EOF) + { + if (c == '\r') /* Doze style input file? */ + continue; + + /* Allow multiple spaces. This doesn't work when there is normal text + * after the hex codes in the last line that looks like hex, thus only + * use it for PostScript format. */ + if (hextype == HEX_POSTSCRIPT && (c == ' ' || c == '\n' || c == '\t')) + continue; + + n3 = n2; + n2 = n1; + + if (c >= '0' && c <= '9') + n1 = c - '0'; + else if (c >= 'a' && c <= 'f') + n1 = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + n1 = c - 'A' + 10; + else + { + n1 = -1; + if (ign_garb) + continue; + } + + ign_garb = 0; + + if (p >= cols) + { + if (!hextype) + { + if (n1 < 0) + { + p = 0; + continue; + } + want_off = (want_off << 4) | n1; + continue; + } + else + p = 0; + } + + if (base_off + want_off != have_off) + { + fflush(fpo); +#ifdef TRY_SEEK + c = fseek(fpo, base_off + want_off - have_off, 1); + if (c >= 0) + have_off = base_off + want_off; +#endif + if (base_off + want_off < have_off) + { + fprintf(fperr, "%s: sorry, cannot seek backwards.\n", pname); + return 5; + } + for (; have_off < base_off + want_off; have_off++) + putc(0, fpo); + } + + if (n2 >= 0 && n1 >= 0) + { + putc((n2 << 4) | n1, fpo); + have_off++; + want_off++; + n1 = -1; + if ((++p >= cols) && !hextype) + { + /* skip rest of line as garbage */ + want_off = 0; + while ((c = getc(fpi)) != '\n' && c != EOF) + ; + ign_garb = 1; + } + } + else if (n1 < 0 && n2 < 0 && n3 < 0) + { + /* already stumbled into garbage, skip line, wait and see */ + if (!hextype) + want_off = 0; + while ((c = getc(fpi)) != '\n' && c != EOF) + ; + ign_garb = 1; + } + } + fflush(fpo); +#ifdef TRY_SEEK + fseek(fpo, 0L, 2); +#endif + fclose(fpo); + fclose(fpi); + return 0; +} + +/* + * Print line l. If nz is false, xxdline regards the line a line of + * zeroes. If there are three or more consecutive lines of zeroes, + * they are replaced by a single '*' character. + * + * If the output ends with more than two lines of zeroes, you + * should call xxdline again with l being the last line and nz + * negative. This ensures that the last line is shown even when + * it is all zeroes. + * + * If nz is always positive, lines are never suppressed. + */ +static void +xxdline(fp, l, nz) +FILE *fp; +char *l; +int nz; +{ + static char z[LLEN+1]; + static int zero_seen = 0; + + if (!nz && zero_seen == 1) + strcpy(z, l); + + if (nz || !zero_seen++) + { + if (nz) + { + if (nz < 0) + zero_seen--; + if (zero_seen == 2) + fputs(z, fp); + if (zero_seen > 2) + fputs("*\n", fp); + } + if (nz >= 0 || zero_seen > 0) + fputs(l, fp); + if (nz) + zero_seen = 0; + } +} + +/* This is an EBCDIC to ASCII conversion table */ +/* from a proposed BTL standard April 16, 1979 */ +static unsigned char etoa64[] = +{ + 0040,0240,0241,0242,0243,0244,0245,0246, + 0247,0250,0325,0056,0074,0050,0053,0174, + 0046,0251,0252,0253,0254,0255,0256,0257, + 0260,0261,0041,0044,0052,0051,0073,0176, + 0055,0057,0262,0263,0264,0265,0266,0267, + 0270,0271,0313,0054,0045,0137,0076,0077, + 0272,0273,0274,0275,0276,0277,0300,0301, + 0302,0140,0072,0043,0100,0047,0075,0042, + 0303,0141,0142,0143,0144,0145,0146,0147, + 0150,0151,0304,0305,0306,0307,0310,0311, + 0312,0152,0153,0154,0155,0156,0157,0160, + 0161,0162,0136,0314,0315,0316,0317,0320, + 0321,0345,0163,0164,0165,0166,0167,0170, + 0171,0172,0322,0323,0324,0133,0326,0327, + 0330,0331,0332,0333,0334,0335,0336,0337, + 0340,0341,0342,0343,0344,0135,0346,0347, + 0173,0101,0102,0103,0104,0105,0106,0107, + 0110,0111,0350,0351,0352,0353,0354,0355, + 0175,0112,0113,0114,0115,0116,0117,0120, + 0121,0122,0356,0357,0360,0361,0362,0363, + 0134,0237,0123,0124,0125,0126,0127,0130, + 0131,0132,0364,0365,0366,0367,0370,0371, + 0060,0061,0062,0063,0064,0065,0066,0067, + 0070,0071,0372,0373,0374,0375,0376,0377 +}; + +int +main(argc, argv) +int argc; +char *argv[]; +{ + FILE *fp, *fpo; + int c, e, p = 0, relseek = 1, negseek = 0, revert = 0; + int cols = 0, nonzero = 0, autoskip = 0, hextype = HEX_NORMAL; + int ebcdic = 0; + int octspergrp = -1; /* number of octets grouped in output */ + int grplen; /* total chars per octet group */ + long length = -1, n = 0, seekoff = 0; + char l[LLEN+1]; + char *pname, *pp; + +#ifdef AMIGA + /* This program doesn't work when started from the Workbench */ + if (argc == 0) + exit(1); +#endif + + pname = argv[0]; + for (pp = pname; *pp; ) + if (*pp++ == PATH_SEP) + pname = pp; +#ifdef FILE_SEP + for (pp = pname; *pp; pp++) + if (*pp == FILE_SEP) + { + *pp = '\0'; + break; + } +#endif + + while (argc >= 2) + { + pp = argv[1] + (!STRNCMP(argv[1], "--", 2) && argv[1][2]); + if (!STRNCMP(pp, "-a", 2)) autoskip = 1 - autoskip; + else if (!STRNCMP(pp, "-b", 2)) hextype = HEX_BITS; + else if (!STRNCMP(pp, "-u", 2)) hexx = hexxa + 16; + else if (!STRNCMP(pp, "-p", 2)) hextype = HEX_POSTSCRIPT; + else if (!STRNCMP(pp, "-i", 2)) hextype = HEX_CINCLUDE; + else if (!STRNCMP(pp, "-r", 2)) revert++; + else if (!STRNCMP(pp, "-E", 2)) ebcdic++; + else if (!STRNCMP(pp, "-v", 2)) + { + fprintf(stderr, "%s%s\n", version, osver); + exit(0); + } + else if (!STRNCMP(pp, "-c", 2)) + { + if (pp[2] && STRNCMP("ols", pp + 2, 3)) + cols = (int)strtol(pp + 2, NULL, 0); + else + { + if (!argv[2]) + exit_with_usage(pname); + cols = (int)strtol(argv[2], NULL, 0); + argv++; + argc--; + } + } + else if (!STRNCMP(pp, "-g", 2)) + { + if (pp[2] && STRNCMP("group", pp + 2, 5)) + octspergrp = (int)strtol(pp + 2, NULL, 0); + else + { + if (!argv[2]) + exit_with_usage(pname); + octspergrp = (int)strtol(argv[2], NULL, 0); + argv++; + argc--; + } + } + else if (!STRNCMP(pp, "-s", 2)) + { + relseek = 0; + negseek = 0; + if (pp[2] && STRNCMP("kip", pp+2, 3) && STRNCMP("eek", pp+2, 3)) + { +#ifdef TRY_SEEK + if (pp[2] == '+') + relseek++; + if (pp[2+relseek] == '-') + negseek++; +#endif + seekoff = strtol(pp + 2+relseek+negseek, (char **)NULL, 0); + } + else + { + if (!argv[2]) + exit_with_usage(pname); +#ifdef TRY_SEEK + if (argv[2][0] == '+') + relseek++; + if (argv[2][relseek] == '-') + negseek++; +#endif + seekoff = strtol(argv[2] + relseek+negseek, (char **)NULL, 0); + argv++; + argc--; + } + } + else if (!STRNCMP(pp, "-l", 2)) + { + if (pp[2] && STRNCMP("en", pp + 2, 2)) + length = strtol(pp + 2, (char **)NULL, 0); + else + { + if (!argv[2]) + exit_with_usage(pname); + length = strtol(argv[2], (char **)NULL, 0); + argv++; + argc--; + } + } + else if (!strcmp(pp, "--")) /* end of options */ + { + argv++; + argc--; + break; + } + else if (pp[0] == '-' && pp[1]) /* unknown option */ + exit_with_usage(pname); + else + break; /* not an option */ + + argv++; /* advance to next argument */ + argc--; + } + + if (!cols) + switch (hextype) + { + case HEX_POSTSCRIPT: cols = 30; break; + case HEX_CINCLUDE: cols = 12; break; + case HEX_BITS: cols = 6; break; + case HEX_NORMAL: + default: cols = 16; break; + } + + if (octspergrp < 0) + switch (hextype) + { + case HEX_BITS: octspergrp = 1; break; + case HEX_NORMAL: octspergrp = 2; break; + case HEX_POSTSCRIPT: + case HEX_CINCLUDE: + default: octspergrp = 0; break; + } + + if (cols < 1 || ((hextype == HEX_NORMAL || hextype == HEX_BITS) + && (cols > COLS))) + { + fprintf(stderr, "%s: invalid number of columns (max. %d).\n", pname, COLS); + exit(1); + } + + if (octspergrp < 1) + octspergrp = cols; + + if (argc > 3) + exit_with_usage(pname); + + if (argc == 1 || (argv[1][0] == '-' && !argv[1][1])) + BIN_ASSIGN(fp = stdin, !revert); + else + { + if ((fp = fopen(argv[1], BIN_READ(!revert))) == NULL) + { + fprintf(stderr,"%s: ", pname); + perror(argv[1]); + return 2; + } + } + + if (argc < 3 || (argv[2][0] == '-' && !argv[2][1])) + BIN_ASSIGN(fpo = stdout, revert); + else + { + int fd; + int mode = revert ? O_WRONLY : (O_TRUNC|O_WRONLY); + + if (((fd = OPEN(argv[2], mode | BIN_CREAT(revert), 0666)) < 0) || + (fpo = fdopen(fd, BIN_WRITE(revert))) == NULL) + { + fprintf(stderr, "%s: ", pname); + perror(argv[2]); + return 3; + } + rewind(fpo); + } + + if (revert) + { + if (hextype && (hextype != HEX_POSTSCRIPT)) + { + fprintf(stderr, "%s: sorry, cannot revert this type of hexdump\n", pname); + return -1; + } + return huntype(fp, fpo, stderr, pname, cols, hextype, + negseek ? -seekoff : seekoff); + } + + if (seekoff || negseek || !relseek) + { +#ifdef TRY_SEEK + if (relseek) + e = fseek(fp, negseek ? -seekoff : seekoff, 1); + else + e = fseek(fp, negseek ? -seekoff : seekoff, negseek ? 2 : 0); + if (e < 0 && negseek) + { + fprintf(stderr, "%s: sorry cannot seek.\n", pname); + return 4; + } + if (e >= 0) + seekoff = ftell(fp); + else +#endif + { + long s = seekoff; + + while (s--) + (void)getc(fp); + } + } + + if (hextype == HEX_CINCLUDE) + { + if (fp != stdin) + { + fprintf(fpo, "unsigned char %s", isdigit((int)argv[1][0]) ? "__" : ""); + for (e = 0; (c = argv[1][e]) != 0; e++) + putc(isalnum(c) ? c : '_', fpo); + fputs("[] = {\n", fpo); + } + + p = 0; + while ((length < 0 || p < length) && (c = getc(fp)) != EOF) + { + fprintf(fpo, (hexx == hexxa) ? "%s0x%02x" : "%s0X%02X", + (p % cols) ? ", " : ",\n "+2*!p, c); + p++; + } + + if (p) + fputs("\n};\n"+3*(fp == stdin), fpo); + + if (fp != stdin) + { + fprintf(fpo, "unsigned int %s", isdigit((int)argv[1][0]) ? "__" : ""); + for (e = 0; (c = argv[1][e]) != 0; e++) + putc(isalnum(c) ? c : '_', fpo); + fprintf(fpo, "_len = %d;\n", p); + } + + fclose(fp); + fclose(fpo); + return 0; + } + + if (hextype == HEX_POSTSCRIPT) + { + p = cols; + while ((length < 0 || n < length) && (e = getc(fp)) != EOF) + { + putchar(hexx[(e >> 4) & 0xf]); + putchar(hexx[(e ) & 0xf]); + n++; + if (!--p) + { + putchar('\n'); + p = cols; + } + } + if (p < cols) + putchar('\n'); + fclose(fp); + fclose(fpo); + return 0; + } + + /* hextype: HEX_NORMAL or HEX_BITS */ + + if (hextype == HEX_NORMAL) + grplen = octspergrp + octspergrp + 1; /* chars per octet group */ + else /* hextype == HEX_BITS */ + grplen = 8 * octspergrp + 1; + + while ((length < 0 || n < length) && (e = getc(fp)) != EOF) + { + if (p == 0) + { + sprintf(l, "%07lx: ", n + seekoff); + for (c = 9; c < LLEN; l[c++] = ' '); + } + if (hextype == HEX_NORMAL) + { + l[c = (9 + (grplen * p) / octspergrp)] = hexx[(e >> 4) & 0xf]; + l[++c] = hexx[ e & 0xf]; + } + else /* hextype == HEX_BITS */ + { + int i; + + c = (9 + (grplen * p) / octspergrp) - 1; + for (i = 7; i >= 0; i--) + l[++c] = (e & (1 << i)) ? '1' : '0'; + } + if (ebcdic) + e = (e < 64) ? '.' : etoa64[e-64]; + /* When changing this update definition of LLEN above. */ + l[11 + (grplen * cols - 1)/octspergrp + p] = +#ifdef __MVS__ + (e >= 64) +#else + (e > 31 && e < 127) +#endif + ? e : '.'; + if (e) + nonzero++; + n++; + if (++p == cols) + { + l[c = (11 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0'; + xxdline(fpo, l, autoskip ? nonzero : 1); + nonzero = 0; + p = 0; + } + } + if (p) + { + l[c = (11 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0'; + xxdline(fpo, l, 1); + } + else if (autoskip) + xxdline(fpo, l, -1); /* last chance to flush out suppressed lines */ + + fclose(fp); + fclose(fpo); + return 0; +}