comparison libfdproto/messages.c @ 1096:97a257c80de0

Implemented remaining flavour of message dump function
author Sebastien Decugis <sdecugis@freediameter.net>
date Mon, 06 May 2013 18:25:50 +0800
parents 647c7e7015af
children f38d77f9cfd3 6ce5c99a40af
comparison
equal deleted inserted replaced
1095:647c7e7015af 1096:97a257c80de0
1015 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " }"), return NULL); 1015 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " }"), return NULL);
1016 } 1016 }
1017 1017
1018 return *buf; 1018 return *buf;
1019 } 1019 }
1020
1020 /* one-line dump with all the contents of the message */ 1021 /* one-line dump with all the contents of the message */
1021 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_full, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) 1022 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_full, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse )
1022 { 1023 {
1023 return msg_dump_process(FD_DUMP_STD_PARAMS, msg_format_full, avp_format_full, obj, dict, force_parsing, recurse); 1024 return msg_dump_process(FD_DUMP_STD_PARAMS, msg_format_full, avp_format_full, obj, dict, force_parsing, recurse);
1024 } 1025 }
1025 1026
1026 #warning "todo" 1027
1028
1029 /*
1030 * One-line dumper for compact but complete traces
1031 */
1032 static DECLARE_FD_DUMP_PROTOTYPE( msg_format_summary, struct msg * msg )
1033 {
1034 if (!CHECK_MSG(msg)) {
1035 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{message}(@%p): INVALID", msg), return NULL);
1036 return *buf;
1037 }
1038
1039 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "{message}(@%p): ", msg), return NULL);
1040 if (!msg->msg_model) {
1041 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(no model)"), return NULL);
1042 } else {
1043 enum dict_object_type dicttype;
1044 struct dict_cmd_data dictdata;
1045 if (fd_dict_gettype(msg->msg_model, &dicttype) || (dicttype != DICT_COMMAND) || (fd_dict_getval(msg->msg_model, &dictdata))) {
1046 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(model error)"), return NULL);
1047 } else {
1048 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'", dictdata.cmd_name), return NULL);
1049 }
1050 }
1051 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%u/%u f:" DUMP_CMDFL_str " src:'%s' len:%d",
1052 msg->msg_public.msg_appl, msg->msg_public.msg_code, DUMP_CMDFL_val(msg->msg_public.msg_flags), msg->msg_src_id?:"(nil)", msg->msg_public.msg_length), return NULL);
1053
1054 return *buf;
1055 }
1056
1057 static DECLARE_FD_DUMP_PROTOTYPE( avp_format_summary, struct avp * avp, int level, int first, int last )
1058 {
1059 char * name;
1060 struct dict_avp_data dictdata;
1061 struct dict_avp_data *dictinfo = NULL;
1062 struct dict_vendor_data vendordata;
1063 struct dict_vendor_data *vendorinfo = NULL;
1064
1065 if (level) {
1066 if (first) {
1067 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " {"), return NULL);
1068 } else {
1069 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "+"), return NULL);
1070 }
1071 }
1072
1073 if (!CHECK_AVP(avp)) {
1074 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "INVALID"), return NULL);
1075 goto end;
1076 }
1077
1078 if (!level) {
1079 /* We have been called to explicitely dump this AVP, so we parse its name if available */
1080 if (!avp->avp_model) {
1081 name = "(no model)";
1082 } else {
1083 enum dict_object_type dicttype;
1084 if (fd_dict_gettype(avp->avp_model, &dicttype) || (dicttype != DICT_AVP) || (fd_dict_getval(avp->avp_model, &dictdata))) {
1085 name = "(model error)";
1086 } else {
1087 name = dictdata.avp_name;
1088 dictinfo = &dictdata;
1089 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) {
1090 struct dictionary * dict;
1091 struct dict_object * vendor;
1092 if ((!fd_dict_getdict(avp->avp_model, &dict))
1093 && (!fd_dict_search(dict, DICT_VENDOR, VENDOR_OF_AVP, avp->avp_model, &vendor, ENOENT))
1094 && (!fd_dict_getval(vendor, &vendordata))) {
1095 vendorinfo = &vendordata;
1096 }
1097 }
1098 }
1099 }
1100
1101 if (dictinfo) {
1102 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "'%s'(%u)", name, avp->avp_public.avp_code), return NULL);
1103 } else {
1104 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "%u%s", avp->avp_public.avp_code, name), return NULL);
1105 }
1106
1107 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) {
1108 if (vendorinfo) {
1109 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " V='%s'(%u)", vendorinfo->vendor_name, avp->avp_public.avp_vendor), return NULL);
1110 } else {
1111 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " V=%u", avp->avp_public.avp_vendor), return NULL);
1112 }
1113 }
1114
1115 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, " L=%d F=" DUMP_AVPFL_str " V=", avp->avp_public.avp_len, DUMP_AVPFL_val(avp->avp_public.avp_flags)), return NULL);
1116
1117 if ((!dictinfo) || (dictinfo->avp_basetype != AVP_TYPE_GROUPED)) {
1118 if (avp->avp_public.avp_value) {
1119 CHECK_MALLOC_DO( fd_dict_dump_avp_value(FD_DUMP_STD_PARAMS, avp->avp_public.avp_value, avp->avp_model, 0, 0), return NULL);
1120 } else if (avp->avp_rawdata) {
1121 CHECK_MALLOC_DO( fd_dump_extend_hexdump(FD_DUMP_STD_PARAMS, avp->avp_rawdata, avp->avp_rawlen, 0, 0), return NULL);
1122 } else {
1123 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "(not set)"), return NULL);
1124 }
1125 }
1126 } else {
1127 /* For embedded AVPs, we only display (vendor,) code & length */
1128 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) {
1129 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "V=%u,", avp->avp_public.avp_vendor), return NULL);
1130 }
1131 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "C=%u,L=%d", avp->avp_public.avp_code, avp->avp_public.avp_len), return NULL);
1132 }
1133
1134 end:
1135 if ((level) && (last)) {
1136 CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "}"), return NULL);
1137 }
1138
1139 return *buf;
1140 }
1027 1141
1028 /* This one only prints a short display, does not go into the complete tree */ 1142 /* This one only prints a short display, does not go into the complete tree */
1029 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_summary, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse ) 1143 DECLARE_FD_DUMP_PROTOTYPE( fd_msg_dump_summary, msg_or_avp *obj, struct dictionary *dict, int force_parsing, int recurse )
1030 { 1144 {
1031 return NULL; 1145 return msg_dump_process(FD_DUMP_STD_PARAMS, msg_format_summary, avp_format_summary, obj, dict, force_parsing, recurse);
1032 } 1146 }
1033 1147
1034 #ifndef OLD_CODE_TO_BE_REPLACED 1148 #ifndef OLD_CODE_TO_BE_REPLACED
1035 void fd_msg_dump_walk ( int level, msg_or_avp *obj ) 1149 void fd_msg_dump_walk ( int level, msg_or_avp *obj )
1036 { 1150 {
1038 } 1152 }
1039 void fd_msg_dump_one ( int level, msg_or_avp * obj ) 1153 void fd_msg_dump_one ( int level, msg_or_avp * obj )
1040 { 1154 {
1041 LOG_D("fd_msg_dump_one %d, %p is deprecated", level, obj); 1155 LOG_D("fd_msg_dump_one %d, %p is deprecated", level, obj);
1042 } 1156 }
1043 #else /* OLD_CODE_TO_BE_REPLACED */ 1157 #endif
1044
1045
1046 /* indent inside an object */
1047 #define INOBJHDR "%*s "
1048 #define INOBJHDRVAL indent<0 ? 1 : indent, indent<0 ? "-" : "|"
1049
1050 /* Write some debug data in a buffer */
1051
1052 /* Dump a msg_t object */
1053 static int obj_dump_msg (struct msg * msg, int indent, char **outstr, size_t *offset, size_t *outlen )
1054 {
1055 int ret = 0;
1056
1057 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%*sMSG: %p|", INOBJHDRVAL, msg) );
1058
1059 if (!CHECK_MSG(msg)) {
1060 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "INVALID!", INOBJHDRVAL) );
1061 return 0;
1062 }
1063
1064 if (!msg->msg_model) {
1065
1066 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(no model)|", INOBJHDRVAL) );
1067
1068 } else {
1069
1070 enum dict_object_type dicttype;
1071 struct dict_cmd_data dictdata;
1072 ret = fd_dict_gettype(msg->msg_model, &dicttype);
1073 if (ret || (dicttype != DICT_COMMAND)) {
1074 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(invalid model: %d %d)|", INOBJHDRVAL, ret, dicttype) );
1075 goto public;
1076 }
1077 ret = fd_dict_getval(msg->msg_model, &dictdata);
1078 if (ret != 0) {
1079 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(error getting model data: %s)|", INOBJHDRVAL, strerror(ret)) );
1080 goto public;
1081 }
1082 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "model : v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %u \"%s\"|", INOBJHDRVAL,
1083 DUMP_CMDFL_val(dictdata.cmd_flag_val), DUMP_CMDFL_val(dictdata.cmd_flag_mask), dictdata.cmd_code, dictdata.cmd_name) );
1084 }
1085 public:
1086 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "public: V:%d L:%d fl:" DUMP_CMDFL_str " CC:%u A:%d hi:%x ei:%x|", INOBJHDRVAL,
1087 msg->msg_public.msg_version,
1088 msg->msg_public.msg_length,
1089 DUMP_CMDFL_val(msg->msg_public.msg_flags),
1090 msg->msg_public.msg_code,
1091 msg->msg_public.msg_appl,
1092 msg->msg_public.msg_hbhid,
1093 msg->msg_public.msg_eteid
1094 ) );
1095 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "intern: rwb:%p rt:%d cb:%p,%p(%p) qry:%p asso:%d sess:%p src:%s(%zd)|",
1096 INOBJHDRVAL, msg->msg_rawbuffer, msg->msg_routable, msg->msg_cb.anscb, msg->msg_cb.expirecb, msg->msg_cb.data, msg->msg_query, msg->msg_associated, msg->msg_sess, msg->msg_src_id?:"(nil)", msg->msg_src_id_len) );
1097 return 0;
1098 }
1099
1100 /* Dump an avp object */
1101 static int obj_dump_avp ( struct avp * avp, int indent, char **outstr, size_t *offset, size_t *outlen )
1102 {
1103 int ret = 0;
1104
1105 if (!CHECK_AVP(avp)) {
1106 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "INVALID!", INOBJHDRVAL) );
1107 return 0;
1108 }
1109
1110 if (!avp->avp_model) {
1111
1112 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(no model resolved)|", INOBJHDRVAL) );
1113
1114 } else {
1115
1116 enum dict_object_type dicttype;
1117 struct dict_avp_data dictdata;
1118 ret = fd_dict_gettype(avp->avp_model, &dicttype);
1119 if (ret || (dicttype != DICT_AVP)) {
1120 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(invalid model: %d %d)|", INOBJHDRVAL, ret, dicttype) );
1121 goto public;
1122 }
1123 ret = fd_dict_getval(avp->avp_model, &dictdata);
1124 if (ret != 0) {
1125 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(error getting model data: %s)|", INOBJHDRVAL, strerror(ret)) );
1126 goto public;
1127 }
1128 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "model : v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %u \"%s\"|", INOBJHDRVAL,
1129 DUMP_AVPFL_val(dictdata.avp_flag_val),
1130 DUMP_AVPFL_val(dictdata.avp_flag_mask),
1131 type_base_name[dictdata.avp_basetype],
1132 dictdata.avp_code,
1133 dictdata.avp_name ) );
1134 }
1135 public:
1136 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "public: C:%u fl:" DUMP_AVPFL_str " L:%d V:%u data:@%p|", INOBJHDRVAL,
1137 avp->avp_public.avp_code,
1138 DUMP_AVPFL_val(avp->avp_public.avp_flags),
1139 avp->avp_public.avp_len,
1140 avp->avp_public.avp_vendor,
1141 avp->avp_public.avp_value
1142 ) );
1143 /* Dump the value if set */
1144 if (avp->avp_public.avp_value) {
1145 if (!avp->avp_model) {
1146 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "(data set but no model: ERROR)|", INOBJHDRVAL) );
1147 } else {
1148 CHECK_FCT( fd_dict_dump_avp_value(avp->avp_public.avp_value, avp->avp_model, indent, outstr, offset, outlen, 1) );
1149 }
1150 }
1151
1152 CHECK_FCT( dump_add_str(outstr, offset, outlen, INOBJHDR "intern: src:%p mf:%d raw:%p(%d)|", INOBJHDRVAL, avp->avp_source, avp->avp_mustfreeos, avp->avp_rawdata, avp->avp_rawlen) );
1153 return 0;
1154 }
1155
1156 /* Dump a single object content into out string, realloc if needed */
1157 static int msg_dump_intern ( int level, msg_or_avp * obj, int indent, char **outstr, size_t *offset, size_t *outlen )
1158 {
1159 /* Log only if we are at least at level */
1160 if ( ! TRACE_BOOL(level) )
1161 return 0;
1162
1163 /* Check the object */
1164 if (!VALIDATE_OBJ(obj)) {
1165 CHECK_FCT( dump_add_str(outstr, offset, outlen, ">>> invalid object (%p)!.", obj) );
1166 return 0;
1167 }
1168
1169 /* Dump the object */
1170 switch (_C(obj)->type) {
1171 case MSG_AVP:
1172 CHECK_FCT( obj_dump_avp ( _A(obj), indent, outstr, offset, outlen ));
1173 break;
1174
1175 case MSG_MSG:
1176 CHECK_FCT( obj_dump_msg ( _M(obj), indent, outstr, offset, outlen ) );
1177 break;
1178
1179 default:
1180 ASSERT(0);
1181 }
1182 return 0;
1183 }
1184
1185 /* Dump a message to a specified file stream */
1186 void fd_msg_dump_fstr ( struct msg * msg, FILE * fstr )
1187 {
1188 msg_or_avp * ref = msg;
1189 int indent = 2;
1190 char *outstr;
1191 size_t offset, outlen;
1192 CHECK_FCT_DO( dump_init_str(&outstr, &offset, &outlen), { fd_log_debug_fstr(fstr, "Error initializing string for dumping %p", msg); return; } );
1193 do {
1194 CHECK_FCT_DO( msg_dump_intern ( NONE, ref, indent, &outstr, &offset, &outlen ),
1195 fd_log_debug_fstr(fstr, "Error while dumping %p", ref) );
1196
1197 /* Now find the next object */
1198 CHECK_FCT_DO( fd_msg_browse ( ref, MSG_BRW_WALK, &ref, &indent ), break );
1199
1200 /* dump next object */
1201 } while (ref);
1202
1203 /* now really output this in one shot, so it is not interrupted */
1204 fd_log_debug_fstr(fstr, "%s", outstr);
1205
1206 free(outstr);
1207 }
1208 void fd_msg_dump_fstr_one ( struct msg * msg, FILE * fstr ) /* just the header */
1209 {
1210 char *outstr;
1211 size_t offset, outlen;
1212 CHECK_FCT_DO( dump_init_str(&outstr, &offset, &outlen), { fd_log_debug_fstr(fstr, "Error initializing string for dumping %p", msg); return; } );
1213 CHECK_FCT_DO( msg_dump_intern ( NONE, msg, 2, &outstr, &offset, &outlen ),
1214 fd_log_debug_fstr(fstr, "Error while dumping %p", msg) );
1215 /* now really output this in one shot, so it is not interrupted */
1216 fd_log_debug_fstr(fstr, "%s", outstr);
1217
1218 free(outstr);
1219 }
1220
1221 /* Completely dump a msg_t object */
1222 static int full_obj_dump_msg (struct msg * msg, struct dictionary *dict, char **outstr, size_t *offset, size_t *outlen)
1223 {
1224 int ret = 0;
1225 int success = 0;
1226 struct dict_cmd_data dictdata;
1227 char buf[20];
1228
1229 if (!CHECK_MSG(msg)) {
1230 CHECK_FCT( dump_add_str(outstr, offset, outlen, "INVALID MESSAGE") );
1231 return 0;
1232 }
1233
1234 if (!msg->msg_model) {
1235 fd_msg_parse_dict(msg, dict, NULL);
1236 }
1237 if (!msg->msg_model) {
1238 CHECK_FCT( dump_add_str(outstr, offset, outlen, "(no model) ") );
1239 } else {
1240 enum dict_object_type dicttype;
1241 ret = fd_dict_gettype(msg->msg_model, &dicttype);
1242 if (ret || (dicttype != DICT_COMMAND)) {
1243 CHECK_FCT( dump_add_str(outstr, offset, outlen, "(invalid model: %d %d) ", ret, dicttype) );
1244 } else {
1245 ret = fd_dict_getval(msg->msg_model, &dictdata);
1246 if (ret != 0) {
1247 CHECK_FCT( dump_add_str(outstr, offset, outlen, "(error getting model data: %s) ", strerror(ret)) );
1248 } else {
1249 success = 1;
1250 }
1251 }
1252 }
1253
1254 if (msg->msg_public.msg_appl) {
1255 snprintf(buf, sizeof(buf), "%u/", msg->msg_public.msg_appl);
1256 } else {
1257 buf[0] = '\0';
1258 }
1259 CHECK_FCT( dump_add_str(outstr, offset, outlen, "%s(%s%u)[" DUMP_CMDFL_str "], Length=%u, Hop-By-Hop-Id=0x%08x, End-to-End=0x%08x",
1260 success ? dictdata.cmd_name : "unknown", buf, msg->msg_public.msg_code, DUMP_CMDFL_val(msg->msg_public.msg_flags),
1261 msg->msg_public.msg_length, msg->msg_public.msg_hbhid, msg->msg_public.msg_eteid));
1262
1263 return 0;
1264 }
1265
1266 /* Dump an avp object completely */
1267 static int full_obj_dump_avp ( struct avp * avp, char **outstr, size_t *offset, size_t *outlen, int first )
1268 {
1269 int success = 0;
1270 struct dict_avp_data dictdata;
1271 char buf[20];
1272
1273 CHECK_FCT( dump_add_str(outstr, offset, outlen, first ? ((*outstr)[*offset-1] == '=' ? "{ " : ", { ") : ", ") );
1274
1275 if (!CHECK_AVP(avp)) {
1276 CHECK_FCT( dump_add_str(outstr, offset, outlen, "INVALID AVP") );
1277 return 0;
1278 }
1279
1280 if (avp->avp_model) {
1281 enum dict_object_type dicttype;
1282 int ret;
1283 ret = fd_dict_gettype(avp->avp_model, &dicttype);
1284 if (ret || (dicttype != DICT_AVP)) {
1285 CHECK_FCT( dump_add_str(outstr, offset, outlen, "(invalid model: %d %d) ", ret, dicttype) );
1286 } else {
1287 ret = fd_dict_getval(avp->avp_model, &dictdata);
1288 if (ret != 0) {
1289 CHECK_FCT( dump_add_str(outstr, offset, outlen, "(error getting model data: %s) ", strerror(ret)) );
1290 } else {
1291 success = 1;
1292 }
1293 }
1294 }
1295
1296 if (avp->avp_public.avp_vendor) {
1297 snprintf(buf, sizeof(buf), "%u/", avp->avp_public.avp_vendor);
1298 } else {
1299 buf[0] = '\0';
1300 }
1301 /* \todo add full vendorname? */
1302 CHECK_FCT(dump_add_str(outstr, offset, outlen, "%s(%s%u)[" DUMP_AVPFL_str "]=", success ? dictdata.avp_name : "unknown", buf, avp->avp_public.avp_code, DUMP_AVPFL_val(avp->avp_public.avp_flags)));
1303
1304 /* Dump the value if set */
1305 if (avp->avp_public.avp_value) {
1306 if (!avp->avp_model) {
1307 CHECK_FCT( dump_add_str(outstr, offset, outlen, "(unknown data type)") );
1308 } else {
1309 CHECK_FCT( fd_dict_dump_avp_value(avp->avp_public.avp_value, avp->avp_model, 1, outstr, offset, outlen, 0) );
1310 }
1311 }
1312
1313 return 0;
1314 }
1315
1316 /* Dump full message */
1317 // TODO: need align with new prototype & behavior
1318 void fd_msg_dump_full_TODO ( int level, struct dictionary *dict, const char *prefix, msg_or_avp *obj )
1319 {
1320 msg_or_avp * ref = obj;
1321 char *outstr;
1322 int indent = 1;
1323 int first = 1;
1324 int previous;
1325 size_t offset, outlen;
1326 CHECK_FCT_DO( dump_init_str(&outstr, &offset, &outlen),
1327 { fd_log_error("Error initializing string for dumping %p", obj); return; } );
1328 CHECK_FCT_DO( dump_add_str(&outstr, &offset, &outlen, "%s: ", prefix),
1329 { fd_log_error("Error while dumping %p", ref); return; });
1330
1331 do {
1332 /* Check the object */
1333 if (!VALIDATE_OBJ(ref)) {
1334 CHECK_FCT_DO( dump_add_str(&outstr, &offset, &outlen, ">>> invalid object (%p)", ref),
1335 { fd_log_error("Error in error handling dumping %p", ref); break; });
1336 }
1337 /* Dump the object */
1338 switch (_C(ref)->type) {
1339 case MSG_AVP:
1340 CHECK_FCT_DO( full_obj_dump_avp ( _A(ref), &outstr, &offset, &outlen, first ),
1341 { fd_log_error("Error in error handling dumping %p", ref); });
1342 break;
1343 case MSG_MSG:
1344 CHECK_FCT_DO( full_obj_dump_msg ( _M(obj), dict, &outstr, &offset, &outlen ),
1345 { fd_log_error("Error in error handling dumping %p", ref); });
1346 break;
1347 default:
1348 ASSERT(0);
1349 }
1350
1351 first = 0;
1352 previous = indent;
1353 /* Now find the next object */
1354 CHECK_FCT_DO( fd_msg_browse ( ref, MSG_BRW_WALK, &ref, &indent ), break );
1355 if (previous < indent) {
1356 first = 1;
1357 } else while (previous-- > indent) {
1358 CHECK_FCT_DO( dump_add_str(&outstr, &offset, &outlen, " }"),
1359 { fd_log_error("Error while dumping %p", ref); return; });
1360 }
1361 /* dump next object */
1362 } while (ref);
1363
1364 fd_log(level, "%s", outstr);
1365 free(outstr);
1366 }
1367
1368 /* Dump a message content -- for debug mostly */
1369 void fd_msg_dump_walk ( int level, msg_or_avp *obj )
1370 {
1371 msg_or_avp * ref = obj;
1372 int indent = 1;
1373 char *outstr;
1374 size_t offset, outlen;
1375 CHECK_FCT_DO( dump_init_str(&outstr, &offset, &outlen),
1376 { fd_log_debug_fstr(fd_g_debug_fstr, "Error initializing string for dumping %p", obj); return; } );
1377
1378 do {
1379 CHECK_FCT_DO( msg_dump_intern ( level, ref, indent, &outstr, &offset, &outlen ),
1380 fd_log_debug_fstr(fd_g_debug_fstr, "Error while dumping %p", ref) );
1381
1382 /* Now find the next object */
1383 CHECK_FCT_DO( fd_msg_browse ( ref, MSG_BRW_WALK, &ref, &indent ), break );
1384
1385 /* dump next object */
1386 } while (ref);
1387
1388 /* now really output this in one shot, so it is not interrupted */
1389 TRACE_DEBUG(level, "------ Dumping object %p (w)-------", obj);
1390 TRACE_DEBUG(level, "%s", outstr);
1391 TRACE_DEBUG(level, "------ /end of object %p -------", obj);
1392
1393 free(outstr);
1394 }
1395
1396 /* Dump a single object content -- for debug mostly */
1397 void fd_msg_dump_one ( int level, msg_or_avp * obj )
1398 {
1399 char *outstr;
1400 size_t offset, outlen;
1401 CHECK_FCT_DO( dump_init_str(&outstr, &offset, &outlen),
1402 { fd_log_debug_fstr(fd_g_debug_fstr, "Error initializing string for dumping %p", obj); return; } );
1403 CHECK_FCT_DO( msg_dump_intern ( level, obj, 1, &outstr, &offset, &outlen ),
1404 fd_log_debug_fstr(fd_g_debug_fstr, "Error while dumping %p", obj) );
1405 TRACE_DEBUG(level, "------ Dumping object %p (s)-------", obj);
1406 TRACE_DEBUG(level, "%s", outstr);
1407 TRACE_DEBUG(level, "------ /end of object %p -------", obj);
1408 free(outstr);
1409 }
1410
1411 #endif /* OLD_CODE_TO_BE_REPLACED */
1412 /***************************************************************************************************************/ 1158 /***************************************************************************************************************/
1413 /* Simple meta-data management */ 1159 /* Simple meta-data management */
1414 1160
1415 /* Retrieve the model of an object */ 1161 /* Retrieve the model of an object */
1416 int fd_msg_model ( msg_or_avp * reference, struct dict_object ** model ) 1162 int fd_msg_model ( msg_or_avp * reference, struct dict_object ** model )
"Welcome to our mercurial repository"