void translate_from_uri(const char * input, struct esb_s* out) { const char *cp = input; char tempstr[2]; for (; *cp; ++cp) { char c = *cp; if (c == '%') { int increment = 0; char c2 = cp[1]; /* hexpairtochar deals with c2 being NUL. */ if (c2 == '%') { tempstr[0] = c; tempstr[1] = 0; esb_append(out,tempstr); ++cp; continue; } increment = hexpairtochar(cp+1,&c); tempstr[0] = c; tempstr[1] = 0; esb_append(out,tempstr); cp +=increment; continue; } tempstr[0] = c; tempstr[1] = 0; esb_append(out,tempstr); } }
/* Translate dangerous and some other characters to safe %xx form. */ void translate_to_uri(const char * filename, struct esb_s *out) { char buf[8]; const char *cp = 0; for (cp = filename ; *cp; ++cp) { char v[2]; int c = 0xff & (unsigned char)*cp; if (dwarfdump_ctype_table[c]) { v[0] = c; v[1] = 0; esb_append(out,v); } else { char *b = xchar(c,buf,sizeof(buf)); esb_append(out,b); } } }
int main(void) { struct esb_s data; esb_alloc_size(2); /* small to get all code paths tested. */ esb_constructor(&data); esb_append(&data, "a"); esb_appendn(&data, "bc", 1); esb_append(&data, "d"); esb_append(&data, "e"); check("test 1", &data, "abde"); esb_destructor(&data); esb_constructor(&data); esb_append(&data, "abcdefghij" "0123456789"); check("test 2", &data, "abcdefghij" "0123456789"); esb_destructor(&data); esb_constructor(&data); esb_append(&data, "abcdefghij" "0123456789"); esb_append(&data, "abcdefghij" "0123456789"); esb_append(&data, "abcdefghij" "0123456789"); esb_append(&data, "abcdefghij" "0123456789"); check("test 3", &data, "abcdefghij" "0123456789" "abcdefghij" "0123456789" "abcdefghij" "0123456789" "abcdefghij" "0123456789"); esb_destructor(&data); return 0; }
static void process_line_table(Dwarf_Debug dbg, const char *sec_name, Dwarf_Line *linebuf, Dwarf_Signed linecount, Dwarf_Bool is_logicals_table, Dwarf_Bool is_actuals_table) { char *padding = 0; Dwarf_Signed i = 0; Dwarf_Addr pc = 0; Dwarf_Unsigned lineno = 0; Dwarf_Unsigned logicalno = 0; Dwarf_Unsigned column = 0; Dwarf_Unsigned call_context = 0; string subprog_name = 0; string subprog_filename = 0; Dwarf_Unsigned subprog_line = 0; Dwarf_Error err = 0; Dwarf_Bool newstatement = 0; Dwarf_Bool lineendsequence = 0; Dwarf_Bool new_basic_block = 0; int sres = 0; int ares = 0; int lires = 0; int cores = 0; Dwarf_Addr elf_max_address = 0; Dwarf_Bool SkipRecord = FALSE; current_section_id = DEBUG_LINE; struct esb_s lastsrc; /* line_flag is TRUE */ esb_constructor(&lastsrc); get_address_size_and_max(dbg,0,&elf_max_address,&err); /* Padding for a nice layout */ padding = line_print_pc ? " " : ""; if (do_print_dwarf) { /* Check if print of <pc> address is needed. */ printf("\n"); if (is_logicals_table) { printf("Logicals Table:\n"); printf("%sNS new statement, PE prologue end, " "EB epilogue begin\n",padding); printf("%sDI=val discriminator value\n", padding); printf("%sCC=val context, SB=val subprogram\n", padding); } else if (is_actuals_table) { printf("Actuals Table:\n"); printf("%sBB new basic block, ET end of text sequence\n" "%sIS=val ISA number\n",padding,padding); } else { /* Standard DWARF line table. */ printf("%sNS new statement, BB new basic block, " "ET end of text sequence\n",padding); printf("%sPE prologue end, EB epilogue begin\n",padding); printf("%sIS=val ISA number, DI=val discriminator value\n", padding); } if (is_logicals_table || is_actuals_table) { printf("[ row] "); } if (line_print_pc) { printf("<pc> "); } if (is_logicals_table) { printf("[lno,col] NS PE EB DI= CC= SB= uri: \"filepath\"\n"); } else if (is_actuals_table) { printf("[logical] BB ET IS=\n"); } else { printf("[row,col] NS BB ET PE EB IS= DI= uri: \"filepath\"\n"); } } for (i = 0; i < linecount; i++) { Dwarf_Line line = linebuf[i]; string filename = 0; int nsres = 0; Dwarf_Bool found_line_error = FALSE; Dwarf_Bool has_is_addr_set = FALSE; char *where = NULL; if (check_decl_file && checking_this_compiler()) { /* A line record with addr=0 was detected */ if (SkipRecord) { /* Skip records that do not have ís_addr_set' */ ares = dwarf_line_is_addr_set(line, &has_is_addr_set, &err); if (ares == DW_DLV_OK && has_is_addr_set) { SkipRecord = FALSE; } else { /* Keep ignoring records until we have one with 'is_addr_set' */ continue; } } } if (check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); } filename = "<unknown>"; if (!is_actuals_table) { sres = dwarf_linesrc(line, &filename, &err); if (sres == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_linesrc()"; record_line_error(where,err); found_line_error = TRUE; } } pc = 0; ares = dwarf_lineaddr(line, &pc, &err); if (ares == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_lineaddr()"; record_line_error(where,err); found_line_error = TRUE; pc = 0; } if (ares == DW_DLV_NO_ENTRY) { pc = 0; } if (is_actuals_table) { lires = dwarf_linelogical(line, &logicalno, &err); if (lires == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_linelogical()"; record_line_error(where,err); found_line_error = TRUE; } if (lires == DW_DLV_NO_ENTRY) { logicalno = -1LL; } column = 0; } else { lires = dwarf_lineno(line, &lineno, &err); if (lires == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_lineno()"; record_line_error(where,err); found_line_error = TRUE; } if (lires == DW_DLV_NO_ENTRY) { lineno = -1LL; } cores = dwarf_lineoff_b(line, &column, &err); if (cores == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_lineoff()"; record_line_error(where,err); found_line_error = TRUE; } if (cores == DW_DLV_NO_ENTRY) { /* Zero was always the correct default, meaning the left edge. DWARF2/3/4 spec sec 6.2.2 */ column = 0; } } /* Process any possible error condition, though we won't be at the first such error. */ if (check_decl_file && checking_this_compiler()) { DWARF_CHECK_COUNT(decl_file_result,1); if (found_line_error) { DWARF_CHECK_ERROR2(decl_file_result,where,dwarf_errmsg(err)); } else if (do_check_dwarf) { /* Check the address lies with a valid [lowPC:highPC] in the .text section*/ if (IsValidInBucketGroup(pRangesInfo,pc)) { /* Valid values; do nothing */ } else { /* At this point may be we are dealing with a linkonce symbol. The problem we have here is we have consumed the deug_info section and we are dealing just with the records from the .debug_line, so no PU_name is available and no high_pc. Traverse the linkonce table if try to match the pc value with one of those ranges. */ if (check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); } if (FindAddressInBucketGroup(pLinkonceInfo,pc)){ /* Valid values; do nothing */ } else { /* The SN Systems Linker generates line records with addr=0, when dealing with linkonce symbols and no stripping */ if (pc) { char addr_tmp[100]; if (check_lines && checking_this_compiler()) { snprintf(addr_tmp,sizeof(addr_tmp), "%s: Address" " 0x%" DW_PR_XZEROS DW_PR_DUx " outside a valid .text range", sec_name,pc); DWARF_CHECK_ERROR(lines_result, addr_tmp); } } else { SkipRecord = TRUE; } } } /* Check the last record for the .debug_line, the one created by DW_LNE_end_sequence, is the same as the high_pc address for the last known user program unit (PU) */ if ((i + 1 == linecount) && seen_PU_high_address && !is_logicals_table) { /* Ignore those PU that have been stripped by the linker; their low_pc values are set to -1 (snc linker only) */ /* It is perfectly sensible for a compiler to leave a few bytes of NOP or other stuff after the last instruction in a subprogram, for cache-alignment or other purposes, so a mismatch here is not necessarily an error. */ if (check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); if ((pc != PU_high_address) && (PU_base_address != elf_max_address)) { char addr_tmp[100]; snprintf(addr_tmp,sizeof(addr_tmp), "%s: Address" " 0x%" DW_PR_XZEROS DW_PR_DUx " may be incorrect" " as DW_LNE_end_sequence address", sec_name,pc); DWARF_CHECK_ERROR(lines_result, addr_tmp); } } } } } /* Display the error information */ if (found_line_error || record_dwarf_error) { if (check_verbose_mode && PRINTING_UNIQUE) { /* Print the record number for better error description */ printf("Record = %" DW_PR_DUu " Addr = 0x%" DW_PR_XZEROS DW_PR_DUx " [%4" DW_PR_DUu ",%2" DW_PR_DUu "] '%s'\n", i, pc,lineno,column,filename); /* The compilation unit was already printed */ if (!check_decl_file) { PRINT_CU_INFO(); } } record_dwarf_error = FALSE; /* Due to a fatal error, skip current record */ if (found_line_error) { continue; } } if (do_print_dwarf) { if (is_logicals_table || is_actuals_table) { printf("[%4" DW_PR_DUu "] ", i + 1); } /* Check if print of <pc> address is needed. */ if (line_print_pc) { printf("0x%" DW_PR_XZEROS DW_PR_DUx " ", pc); } if (is_actuals_table) { printf("[%7" DW_PR_DUu "]", logicalno); } else { printf("[%4" DW_PR_DUu ",%2" DW_PR_DUu "]", lineno, column); } } if (!is_actuals_table) { nsres = dwarf_linebeginstatement(line, &newstatement, &err); if (nsres == DW_DLV_OK) { if (newstatement && do_print_dwarf) { printf(" %s","NS"); } } else if (nsres == DW_DLV_ERROR) { print_error(dbg, "linebeginstatment failed", nsres, err); } } if (!is_logicals_table) { nsres = dwarf_lineblock(line, &new_basic_block, &err); if (nsres == DW_DLV_OK) { if (new_basic_block && do_print_dwarf) { printf(" %s","BB"); } } else if (nsres == DW_DLV_ERROR) { print_error(dbg, "lineblock failed", nsres, err); } nsres = dwarf_lineendsequence(line, &lineendsequence, &err); if (nsres == DW_DLV_OK) { if (lineendsequence && do_print_dwarf) { printf(" %s", "ET"); } } else if (nsres == DW_DLV_ERROR) { print_error(dbg, "lineendsequence failed", nsres, err); } } if (do_print_dwarf) { Dwarf_Bool prologue_end = 0; Dwarf_Bool epilogue_begin = 0; Dwarf_Unsigned isa = 0; Dwarf_Unsigned discriminator = 0; int disres = dwarf_prologue_end_etc(line, &prologue_end,&epilogue_begin, &isa,&discriminator,&err); if (disres == DW_DLV_ERROR) { print_error(dbg, "dwarf_prologue_end_etc() failed", disres, err); } if (prologue_end && !is_actuals_table) { printf(" PE"); } if (epilogue_begin && !is_actuals_table) { printf(" EB"); } if (isa && !is_logicals_table) { printf(" IS=0x%" DW_PR_DUx, isa); } if (discriminator && !is_actuals_table) { printf(" DI=0x%" DW_PR_DUx, discriminator); } if (is_logicals_table) { call_context = 0; disres = dwarf_linecontext(line, &call_context, &err); if (disres == DW_DLV_ERROR) { print_error(dbg, "dwarf_linecontext() failed", disres, err); } if (call_context) { printf(" CC=%" DW_PR_DUu, call_context); } subprog_name = 0; disres = dwarf_line_subprog(line, &subprog_name, &subprog_filename, &subprog_line, &err); if (disres == DW_DLV_ERROR) { print_error(dbg, "dwarf_line_subprog() failed", disres, err); } if (subprog_name && strlen(subprog_name)) { /* We do not print an empty name. Clutters things up. */ printf(" SB=\"%s\"", subprog_name); } } } if (!is_actuals_table) { if (i > 0 && verbose < 3 && strcmp(filename,esb_get_string(&lastsrc)) == 0) { /* Do not print name. */ } else { struct esb_s urs; esb_constructor(&urs); esb_append(&urs, " uri: \""); translate_to_uri(filename,&urs); esb_append(&urs,"\""); if (do_print_dwarf) { printf("%s",esb_get_string(&urs)); } esb_destructor(&urs); esb_empty_string(&lastsrc); esb_append(&lastsrc,filename); } if (sres == DW_DLV_OK) { dwarf_dealloc(dbg, filename, DW_DLA_STRING); } } if (do_print_dwarf) { printf("\n"); } } esb_destructor(&lastsrc); }
/* Here we test the interfaces into Dwarf_Line_Context. */ static void print_line_context_record(Dwarf_Debug dbg, Dwarf_Line_Context line_context) { int vres = 0; Dwarf_Unsigned lsecoff = 0; Dwarf_Unsigned version = 0; Dwarf_Signed count = 0; Dwarf_Signed i = 0; const char *name = 0; struct esb_s bufr; Dwarf_Small table_count = 0; esb_constructor(&bufr); printf("Line Context data\n"); vres = dwarf_srclines_table_offset(line_context,&lsecoff,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } printf(" Line Section Offset 0x%" DW_PR_XZEROS DW_PR_DUx "\n", lsecoff); vres = dwarf_srclines_version(line_context,&version, &table_count, &err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } printf(" version number 0x%" DW_PR_DUx " %" DW_PR_DUu "\n", version,version); printf(" number of line tables %d.\n", table_count); vres = dwarf_srclines_comp_dir(line_context,&name,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } if (name) { printf(" Compilation directory: %s\n",name); } else { printf(" Compilation directory: <unknown no DW_AT_comp_dir>\n"); } vres = dwarf_srclines_include_dir_count(line_context,&count,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } printf(" include directory count 0x%" DW_PR_DUx " %" DW_PR_DSd "\n", (Dwarf_Unsigned)count,count); for(i = 1; i <= count; ++i) { vres = dwarf_srclines_include_dir_data(line_context,i, &name,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } printf(" [%2" DW_PR_DSd "] \"%s\"\n",i,name); } vres = dwarf_srclines_files_count(line_context,&count,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } printf( " files count 0x%" DW_PR_DUx " %" DW_PR_DUu "\n", count,count); for(i = 1; i <= count; ++i) { Dwarf_Unsigned dirindex = 0; Dwarf_Unsigned modtime = 0; Dwarf_Unsigned flength = 0; vres = dwarf_srclines_files_data(line_context,i, &name,&dirindex, &modtime,&flength,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } esb_empty_string(&bufr); if (name) { esb_empty_string(&bufr); esb_append(&bufr,"\""); esb_append(&bufr,name); esb_append(&bufr,"\""); } else { esb_append(&bufr,"<ERROR:NULL name in files list>"); } printf(" [%2" DW_PR_DSd "] %-24s ,", i,esb_get_string(&bufr)); printf(" directory index %2" DW_PR_DUu ,modtime); printf(", file length %2" DW_PR_DUu ,flength); if (modtime) { time_t tt3 = (time_t)modtime; /* ctime supplies newline */ printf( "file mod time 0x%x %s", (unsigned)tt3, ctime(&tt3)); } else { printf(" file mod time 0\n"); } } esb_destructor(&bufr); vres = dwarf_srclines_subprog_count(line_context,&count,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } if (count == 0) { return; } printf(" subprograms count (experimental) 0x%" DW_PR_DUx " %" DW_PR_DUu "\n", count,count); for(i = 1; i <= count; ++i) { Dwarf_Unsigned decl_file = 0; Dwarf_Unsigned decl_line = 0; vres = dwarf_srclines_subprog_data(line_context,i, &name,&decl_file, &decl_line,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } printf(" [%2" DW_PR_DSd "] \"%s\"" ", fileindex %2" DW_PR_DUu ", lineindex %2" DW_PR_DUu "\n", i,name,decl_file,decl_line); } }
/* Unified pubnames style output. The error checking here against maxoff may be useless (in that libdwarf may return an error if the offset is bad and we will not get called here). But we leave it in nonetheless as it looks sensible. In at least one gigantic executable such offsets turned out wrong. */ void print_pubname_style_entry(Dwarf_Debug dbg, char *line_title, char *name, Dwarf_Unsigned die_off, Dwarf_Unsigned cu_off, Dwarf_Unsigned global_cu_offset, Dwarf_Unsigned maxoff) { Dwarf_Die die = NULL; Dwarf_Off die_CU_off = 0; int dres = 0; int ddres = 0; int cudres = 0; char tmp_buf[100]; /* get die at die_off */ dres = dwarf_offdie(dbg, die_off, &die, &err); if (dres != DW_DLV_OK) { struct esb_s details; esb_constructor(&details); esb_append(&details,line_title); esb_append(&details," dwarf_offdie : " "die offset does not reference valid DIE. "); snprintf(tmp_buf,sizeof(tmp_buf),"0x%" DW_PR_DUx, die_off); esb_append(&details,tmp_buf); esb_append(&details,"."); print_error(dbg, esb_get_string(&details), dres, err); esb_destructor(&details); } /* get offset of die from its cu-header */ ddres = dwarf_die_CU_offset(die, &die_CU_off, &err); if (ddres != DW_DLV_OK) { struct esb_s details; esb_constructor(&details); esb_append(&details,line_title); esb_append(&details," cannot get CU die offset"); print_error(dbg, esb_get_string(&details), dres, err); esb_destructor(&details); die_CU_off = 0; } /* Get die at offset cu_off to check its existence. */ { Dwarf_Die cu_die = NULL; cudres = dwarf_offdie(dbg, cu_off, &cu_die, &err); if (cudres != DW_DLV_OK) { struct esb_s details; esb_constructor(&details); esb_append(&details,line_title); esb_append(&details," dwarf_offdie: " "cu die offset does not reference valid CU DIE. "); snprintf(tmp_buf,sizeof(tmp_buf),"0x%" DW_PR_DUx, cu_off); esb_append(&details,tmp_buf); esb_append(&details,"."); print_error(dbg, esb_get_string(&details), dres, err); esb_destructor(&details); } else { /* It exists, all is well. */ dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); } } /* Display offsets */ if (display_offsets) { /* Print 'name'at the end for better layout */ printf("%s die-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx ", cu-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx "," " die-in-cu 0x%" DW_PR_XZEROS DW_PR_DUx ", cu-header-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx , line_title, die_off, cu_off, (Dwarf_Unsigned) die_CU_off, /* Following is absolute offset of the ** beginning of the cu */ (Dwarf_Signed) (die_off - die_CU_off)); } if ((die_off - die_CU_off) != global_cu_offset) { printf(" error: real cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx, global_cu_offset); exit(1); } /* Display offsets */ if (display_offsets && verbose) { printf(" cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx , global_cu_offset); } /* Print 'name'at the end for better layout */ printf(" '%s'\n",name); dwarf_dealloc(dbg, die, DW_DLA_DIE); check_info_offset_sanity(line_title, "die offset", name, die_off, maxoff); check_info_offset_sanity(line_title, "die cu offset", name, die_CU_off, maxoff); check_info_offset_sanity(line_title, "cu offset", name, (die_off - die_CU_off), maxoff); }
int main() { { struct esb_s d; esb_constructor(&d); esb_append(&d,"a"); validate_esb(1,&d,1,2,"a"); esb_append(&d,"b"); validate_esb(2,&d,2,3,"ab"); esb_append(&d,"c"); validate_esb(3,&d,3,4,"abc"); esb_empty_string(&d); validate_esb(4,&d,0,4,""); esb_destructor(&d); } { struct esb_s d; esb_constructor(&d); esb_append(&d,"aa"); validate_esb(6,&d,2,3,"aa"); esb_append(&d,"bbb"); validate_esb(7,&d,5,6,"aabbb"); esb_append(&d,"c"); validate_esb(8,&d,6,7,"aabbbc"); esb_empty_string(&d); validate_esb(9,&d,0,7,""); esb_destructor(&d); } { struct esb_s d; static char oddarray[7] = {'a','b',0,'c','c','d',0}; esb_constructor(&d); /* This provokes a msg on stderr. Bad input. */ esb_appendn(&d,oddarray,6); validate_esb(10,&d,2,3,"ab"); esb_appendn(&d,"cc",1); validate_esb(11,&d,3,4,"abc"); esb_empty_string(&d); validate_esb(12,&d,0,4,""); esb_destructor(&d); } { struct esb_s d; esb_constructor(&d); esb_force_allocation(&d,7); trialprint(&d); validate_esb(13,&d,6,7,"aaaa i"); } { struct esb_s d; esb_constructor(&d); esb_force_allocation(&d,50); trialprint(&d); validate_esb(14,&d,19,50,"aaaa insert me bbbb"); } if (failcount) { printf("FAIL esb test\n"); exit(1); } printf("PASS esb test\n"); exit(0); }
int main() { #ifdef _WIN32 /* Open the null device used during formatting printing */ if (!esb_open_null_device()) { fprintf(stderr, "esb: Unable to open null device.\n"); exit(1); } #endif /* _WIN32 */ { /* First lets establish standard sprintf on cases of interest. */ struct esb_s d5; char bufs[4]; char bufl[60]; esb_int i = -33; esb_unsigned u = 0; /* After static alloc we add len, ie, 11 */ esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %d bbb",(int)i); validate_esb(201,&d5,11,15,"aaa -33 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %6d bbb",(int)i); validate_esb(202,&d5,14,18,"aaa -33 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %6d bbb",6); validate_esb(203,&d5,14,18,"aaa 6 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %06d bbb",6); validate_esb(204,&d5,14,18,"aaa 000006 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %06u bbb",6); validate_esb(205,&d5,14,18,"aaa 000006 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %6u bbb",6); validate_esb(206,&d5,14,18,"aaa 6 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %u bbb",12); validate_esb(207,&d5,10,14,"aaa 12 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %06x bbb",12); validate_esb(208,&d5,14,18,"aaa 00000c bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %6x bbb",12); validate_esb(209,&d5,14,18,"aaa c bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %+d bbb",12); validate_esb(210,&d5,11,15,"aaa +12 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %+6d bbb",12); validate_esb(211,&d5,14,18,"aaa +12 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %6d bbb",(int)i); validate_esb(212,&d5,14,18,"aaa -33 bbb",__LINE__); esb_destructor(&d5); } { struct esb_s d; esb_constructor(&d); esb_append(&d,"a"); validate_esb(1,&d,1,2,"a",__LINE__); esb_append(&d,"b"); validate_esb(2,&d,2,3,"ab",__LINE__); esb_append(&d,"c"); validate_esb(3,&d,3,4,"abc",__LINE__); esb_empty_string(&d); validate_esb(4,&d,0,4,"",__LINE__); esb_destructor(&d); } { struct esb_s d; esb_constructor(&d); esb_append(&d,"aa"); validate_esb(6,&d,2,3,"aa",__LINE__); esb_append(&d,"bbb"); validate_esb(7,&d,5,6,"aabbb",__LINE__); esb_append(&d,"c"); validate_esb(8,&d,6,7,"aabbbc",__LINE__); esb_empty_string(&d); validate_esb(9,&d,0,7,"",__LINE__); esb_destructor(&d); } { struct esb_s d; static char oddarray[7] = {'a','b',0,'c','c','d',0}; esb_constructor(&d); /* This used to provoke a msg on stderr. Bad input. Now inserts particular string instead. */ esb_appendn(&d,oddarray,6); validate_esb(10,&d,23,24,"ESBERR_appendn bad call",__LINE__); /* The next one just keeps the previous ESBERR* and adds a 'c' */ esb_appendn(&d,"cc",1); validate_esb(11,&d,24,25,"ESBERR_appendn bad callc",__LINE__); esb_empty_string(&d); validate_esb(12,&d,0,25,"",__LINE__); esb_destructor(&d); } { struct esb_s d; esb_constructor(&d); esb_force_allocation(&d,7); esb_append(&d,"aaaa i"); validate_esb(13,&d,6,7,"aaaa i",__LINE__); esb_destructor(&d); } { struct esb_s d5; const char * s = "insert me %d"; esb_constructor(&d5); esb_force_allocation(&d5,50); esb_append(&d5,"aaa "); esb_append_printf(&d5,s,1); esb_append(&d5,"zzz"); validate_esb(14,&d5,18,50,"aaa insert me 1zzz",__LINE__); esb_destructor(&d5); } { struct esb_s d; struct esb_s e; esb_constructor(&d); esb_constructor(&e); char* result = NULL; esb_append(&d,"abcde fghij klmno pqrst"); validate_esb(15,&d,23,24,"abcde fghij klmno pqrst",__LINE__); result = esb_get_copy(&d); esb_append(&e,result); validate_esb(16,&e,23,24,"abcde fghij klmno pqrst",__LINE__); esb_destructor(&d); esb_destructor(&e); } { struct esb_s d5; char bufs[4]; char bufl[60]; const char * s = "insert me %d"; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append(&d5,"aaa "); esb_append_printf(&d5,s,1); esb_append(&d5,"zzz"); validate_esb(17,&d5,18,19,"aaa insert me 1zzz",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufl,sizeof(bufl)); esb_append(&d5,"aaa "); esb_append_printf(&d5,s,1); esb_append(&d5,"zzz"); validate_esb(18,&d5,18,60,"aaa insert me 1zzz",__LINE__); esb_destructor(&d5); } { struct esb_s d5; char bufs[4]; char bufl[60]; const char * s = "insert me"; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_s(&d5,"aaa %s bbb",s); validate_esb(19,&d5,17,18,"aaa insert me bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_s(&d5,"aaa %12s bbb",s); validate_esb(20,&d5,20,21,"aaa insert me bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_s(&d5,"aaa %-12s bbb",s); validate_esb(21,&d5,20,21,"aaa insert me bbb",__LINE__); esb_destructor(&d5); } { struct esb_s d5; char bufs[4]; char bufl[60]; esb_int i = -33; esb_unsigned u = 0; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %d bbb",i); validate_esb(18,&d5,11,12,"aaa -33 bbb",__LINE__); esb_destructor(&d5); i = -2; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %4d bbb",i); validate_esb(19,&d5,12,13,"aaa -2 bbb",__LINE__); esb_destructor(&d5); i = -2; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %4d bbb",i); validate_esb(20,&d5,12,13,"aaa -2 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %6d bbb",i); validate_esb(21,&d5,14,15,"aaa -2 bbb",__LINE__); esb_destructor(&d5); i = -2; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %04d bbb",i); validate_esb(22,&d5,12,13,"aaa -002 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %06d bbb",i); validate_esb(23,&d5,14,15,"aaa -00002 bbb",__LINE__); esb_destructor(&d5); i = -200011; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %04d bbb",i); validate_esb(24,&d5,15,16,"aaa -200011 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %06d bbb",i); validate_esb(25,&d5,15,16,"aaa -200011 bbb",__LINE__); esb_destructor(&d5); u = 0x80000000; u = 0x8000000000000000; i = u; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %4d bbb",i); validate_esb(26,&d5,28,29,"aaa -9223372036854775808 bbb",__LINE__); esb_destructor(&d5); i = 987665432; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %4d bbb",i); validate_esb(27,&d5,17,18,"aaa 987665432 bbb",__LINE__); esb_destructor(&d5); } { struct esb_s d5; char bufs[4]; char bufl[60]; esb_unsigned u = 0; u = 37; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %u bbb",u); validate_esb(28,&d5,10,11,"aaa 37 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %4u bbb",u); validate_esb(29,&d5,12,13,"aaa 37 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %4u bbb",u); validate_esb(30,&d5,12,13,"aaa 37 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %6u bbb",u); validate_esb(31,&d5,14,15,"aaa 37 bbb",__LINE__); esb_destructor(&d5); } { struct esb_s d5; char bufs[4]; char bufl[60]; esb_int i = -33; esb_unsigned u = 0; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %+d bbb",i); validate_esb(18,&d5,11,12,"aaa -33 bbb",__LINE__); esb_destructor(&d5); i = 33; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %+d bbb",i); validate_esb(18,&d5,11,12,"aaa +33 bbb",__LINE__); esb_destructor(&d5); i = -2; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %+4d bbb",i); validate_esb(19,&d5,12,13,"aaa -2 bbb",__LINE__); esb_destructor(&d5); } #ifdef _WIN32 /* Close the null device used during formatting printing */ esb_close_null_device(); #endif /* _WIN32 */ if (failcount) { printf("FAIL esb test\n"); exit(1); } printf("PASS esb test\n"); exit(0); }