1/* 2 * This file is part of ltrace. 3 * Copyright (C) 2011,2012,2013,2014 Petr Machata, Red Hat Inc. 4 * Copyright (C) 2010 Joe Damato 5 * Copyright (C) 1997,1998,1999,2001,2002,2003,2004,2007,2008,2009 Juan Cespedes 6 * Copyright (C) 2006 Paul Gilliam, IBM Corporation 7 * Copyright (C) 2006 Ian Wienand 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of the 12 * License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 22 * 02110-1301 USA 23 */ 24 25#include "config.h" 26 27#include <stdio.h> 28#include <stdlib.h> 29#include <stdarg.h> 30#include <string.h> 31#include <time.h> 32#include <sys/time.h> 33#include <unistd.h> 34#include <errno.h> 35#include <assert.h> 36#include <inttypes.h> 37 38#include "output.h" 39#include "demangle.h" 40#include "fetch.h" 41#include "lens_default.h" 42#include "library.h" 43#include "memstream.h" 44#include "options.h" 45#include "param.h" 46#include "proc.h" 47#include "prototype.h" 48#include "summary.h" 49#include "type.h" 50#include "value.h" 51#include "value_dict.h" 52 53static struct process *current_proc = NULL; 54static size_t current_depth = 0; 55static int current_column = 0; 56 57static void 58output_indent(struct process *proc) 59{ 60 int d = options.indent * (proc->callstack_depth - 1); 61 current_column += fprintf(options.output, "%*s", d, ""); 62} 63 64static void 65begin_of_line(struct process *proc, int is_func, int indent) 66{ 67 current_column = 0; 68 if (!proc) { 69 return; 70 } 71 if ((options.output != stderr) && (opt_p || options.follow)) { 72 current_column += fprintf(options.output, "%u ", proc->pid); 73 } else if (options.follow) { 74 current_column += fprintf(options.output, "[pid %u] ", proc->pid); 75 } 76 if (opt_r) { 77 struct timeval tv; 78 static struct timeval old_tv = { 0, 0 }; 79 struct timeval diff; 80 81 gettimeofday(&tv, NULL); 82 83 if (old_tv.tv_sec == 0 && old_tv.tv_usec == 0) { 84 old_tv.tv_sec = tv.tv_sec; 85 old_tv.tv_usec = tv.tv_usec; 86 } 87 diff.tv_sec = tv.tv_sec - old_tv.tv_sec; 88 if (tv.tv_usec >= old_tv.tv_usec) { 89 diff.tv_usec = tv.tv_usec - old_tv.tv_usec; 90 } else { 91 diff.tv_sec--; 92 diff.tv_usec = 1000000 + tv.tv_usec - old_tv.tv_usec; 93 } 94 old_tv.tv_sec = tv.tv_sec; 95 old_tv.tv_usec = tv.tv_usec; 96 current_column += fprintf(options.output, "%3lu.%06d ", 97 (unsigned long)diff.tv_sec, 98 (int)diff.tv_usec); 99 } 100 if (opt_t) { 101 struct timeval tv; 102 gettimeofday(&tv, NULL); 103 if (opt_t > 2) { 104 current_column += fprintf(options.output, "%lu.%06d ", 105 (unsigned long)tv.tv_sec, 106 (int)tv.tv_usec); 107 } else if (opt_t > 1) { 108 struct tm *tmp = localtime(&tv.tv_sec); 109 current_column += 110 fprintf(options.output, "%02d:%02d:%02d.%06d ", 111 tmp->tm_hour, tmp->tm_min, tmp->tm_sec, 112 (int)tv.tv_usec); 113 } else { 114 struct tm *tmp = localtime(&tv.tv_sec); 115 current_column += fprintf(options.output, "%02d:%02d:%02d ", 116 tmp->tm_hour, tmp->tm_min, 117 tmp->tm_sec); 118 } 119 } 120 if (opt_i) { 121 if (is_func) { 122 struct callstack_element *stel 123 = &proc->callstack[proc->callstack_depth - 1]; 124 current_column += fprintf(options.output, "[%p] ", 125 stel->return_addr); 126 } else { 127 current_column += fprintf(options.output, "[%p] ", 128 proc->instruction_pointer); 129 } 130 } 131 if (options.indent > 0 && indent) { 132 output_indent(proc); 133 } 134} 135 136static struct arg_type_info * 137get_unknown_type(void) 138{ 139 static struct arg_type_info *ret = NULL; 140 if (ret != NULL) 141 return ret; 142 143 static struct arg_type_info info; 144 info = *type_get_simple(ARGTYPE_LONG); 145 info.lens = &guess_lens; 146 ret = &info; 147 return ret; 148} 149 150/* The default prototype is: long X(long, long, long, long). */ 151static struct prototype * 152build_default_prototype(void) 153{ 154 static struct prototype *ret = NULL; 155 if (ret != NULL) 156 return ret; 157 158 static struct prototype proto; 159 prototype_init(&proto); 160 161 struct arg_type_info *unknown_type = get_unknown_type(); 162 assert(unknown_type != NULL); 163 proto.return_info = unknown_type; 164 proto.own_return_info = 0; 165 166 struct param unknown_param; 167 param_init_type(&unknown_param, unknown_type, 0); 168 169 size_t i; 170 for (i = 0; i < 4; ++i) 171 if (prototype_push_param(&proto, &unknown_param) < 0) { 172 report_global_error("build_default_prototype: %s", 173 strerror(errno)); 174 prototype_destroy(&proto); 175 return NULL; 176 } 177 178 ret = &proto; 179 return ret; 180} 181 182static bool 183snip_period(char *buf) 184{ 185 char *period = strrchr(buf, '.'); 186 if (period != NULL && strcmp(period, ".so") != 0) { 187 *period = 0; 188 return true; 189 } else { 190 return false; 191 } 192} 193 194static struct prototype * 195library_get_prototype(struct library *lib, const char *name) 196{ 197 if (lib->protolib == NULL) { 198 size_t sz = strlen(lib->soname); 199 char buf[sz + 1]; 200 memcpy(buf, lib->soname, sz + 1); 201 202 do { 203 if (protolib_cache_maybe_load(&g_protocache, buf, 0, 204 true, &lib->protolib) < 0) 205 return NULL; 206 } while (lib->protolib == NULL 207 && lib->type == LT_LIBTYPE_DSO 208 && snip_period(buf)); 209 210 if (lib->protolib == NULL) 211 lib->protolib = protolib_cache_default(&g_protocache, 212 buf, 0); 213 } 214 if (lib->protolib == NULL) 215 return NULL; 216 217 return protolib_lookup_prototype(lib->protolib, name, 218 lib->type != LT_LIBTYPE_SYSCALL); 219} 220 221struct find_proto_data { 222 const char *name; 223 struct prototype *ret; 224}; 225 226static enum callback_status 227find_proto_cb(struct process *proc, struct library *lib, void *d) 228{ 229 struct find_proto_data *data = d; 230 data->ret = library_get_prototype(lib, data->name); 231 return CBS_STOP_IF(data->ret != NULL); 232} 233 234static struct prototype * 235lookup_symbol_prototype(struct process *proc, struct library_symbol *libsym) 236{ 237 if (libsym->proto != NULL) 238 return libsym->proto; 239 240 struct library *lib = libsym->lib; 241 if (lib != NULL) { 242 struct find_proto_data data = { libsym->name }; 243 data.ret = library_get_prototype(lib, libsym->name); 244 if (data.ret == NULL 245 && libsym->plt_type == LS_TOPLT_EXEC) 246 proc_each_library(proc, NULL, find_proto_cb, &data); 247 if (data.ret != NULL) 248 return data.ret; 249 } 250 251 return build_default_prototype(); 252} 253 254void 255output_line(struct process *proc, const char *fmt, ...) 256{ 257 if (options.summary) 258 return; 259 260 if (current_proc != NULL) { 261 if (current_proc->callstack[current_depth].return_addr) 262 fprintf(options.output, " <unfinished ...>\n"); 263 else 264 fprintf(options.output, " <no return ...>\n"); 265 } 266 current_proc = NULL; 267 if (fmt == NULL) 268 return; 269 270 begin_of_line(proc, 0, 0); 271 272 va_list args; 273 va_start(args, fmt); 274 vfprintf(options.output, fmt, args); 275 fprintf(options.output, "\n"); 276 va_end(args); 277 278 current_column = 0; 279} 280 281static void 282tabto(int col) { 283 if (current_column < col) { 284 fprintf(options.output, "%*s", col - current_column, ""); 285 } 286} 287 288static int 289output_error(FILE *stream) 290{ 291 return fprintf(stream, "?"); 292} 293 294static int 295fetch_simple_param(enum tof type, struct process *proc, 296 struct fetch_context *context, 297 struct value_dict *arguments, 298 struct arg_type_info *info, int own, 299 struct value *valuep) 300{ 301 /* Arrays decay into pointers per C standard. We check for 302 * this here, because here we also capture arrays that come 303 * from parameter packs. */ 304 if (info->type == ARGTYPE_ARRAY) { 305 struct arg_type_info *tmp = malloc(sizeof(*tmp)); 306 if (tmp != NULL) { 307 type_init_pointer(tmp, info, own); 308 tmp->lens = info->lens; 309 info = tmp; 310 own = 1; 311 } 312 } 313 314 struct value value; 315 value_init(&value, proc, NULL, info, own); 316 if (fetch_arg_next(context, type, proc, info, &value) < 0) 317 return -1; 318 319 if (val_dict_push_next(arguments, &value) < 0) { 320 value_destroy(&value); 321 return -1; 322 } 323 324 if (valuep != NULL) 325 *valuep = value; 326 327 return 0; 328} 329 330static void 331fetch_param_stop(struct value_dict *arguments, ssize_t *params_leftp) 332{ 333 if (*params_leftp == -1) 334 *params_leftp = val_dict_count(arguments); 335} 336 337static int 338fetch_param_pack(enum tof type, struct process *proc, 339 struct fetch_context *context, 340 struct value_dict *arguments, struct param *param, 341 ssize_t *params_leftp) 342{ 343 struct param_enum *e = param_pack_init(param, arguments); 344 if (e == NULL) 345 return -1; 346 347 int ret = 0; 348 while (1) { 349 int insert_stop = 0; 350 struct arg_type_info *info = malloc(sizeof(*info)); 351 if (info == NULL 352 || param_pack_next(param, e, info, &insert_stop) < 0) { 353 fail: 354 free(info); 355 ret = -1; 356 break; 357 } 358 359 if (insert_stop) 360 fetch_param_stop(arguments, params_leftp); 361 362 if (info->type == ARGTYPE_VOID) { 363 type_destroy(info); 364 free(info); 365 break; 366 } 367 368 struct value val; 369 if (fetch_simple_param(type, proc, context, arguments, 370 info, 1, &val) < 0) 371 goto fail; 372 373 int stop = 0; 374 switch (param_pack_stop(param, e, &val)) { 375 case PPCB_ERR: 376 goto fail; 377 case PPCB_STOP: 378 stop = 1; 379 case PPCB_CONT: 380 break; 381 } 382 383 if (stop) 384 break; 385 } 386 387 param_pack_done(param, e); 388 return ret; 389} 390 391static int 392fetch_one_param(enum tof type, struct process *proc, 393 struct fetch_context *context, 394 struct value_dict *arguments, struct param *param, 395 ssize_t *params_leftp) 396{ 397 switch (param->flavor) { 398 int rc; 399 case PARAM_FLAVOR_TYPE: 400 return fetch_simple_param(type, proc, context, arguments, 401 param->u.type.type, 0, NULL); 402 403 case PARAM_FLAVOR_PACK: 404 if (fetch_param_pack_start(context, 405 param->u.pack.ppflavor) < 0) 406 return -1; 407 rc = fetch_param_pack(type, proc, context, arguments, 408 param, params_leftp); 409 fetch_param_pack_end(context); 410 return rc; 411 412 case PARAM_FLAVOR_STOP: 413 fetch_param_stop(arguments, params_leftp); 414 return 0; 415 } 416 417 assert(!"Invalid param flavor!"); 418 abort(); 419} 420 421struct fetch_one_param_data 422{ 423 struct process *proc; 424 struct fetch_context *context; 425 struct value_dict *arguments; 426 ssize_t *params_leftp; 427 enum tof tof; 428}; 429 430static enum callback_status 431fetch_one_param_cb(struct prototype *proto, struct param *param, void *data) 432{ 433 struct fetch_one_param_data *cb_data = data; 434 return CBS_STOP_IF(fetch_one_param(cb_data->tof, cb_data->proc, 435 cb_data->context, 436 cb_data->arguments, param, 437 cb_data->params_leftp) < 0); 438} 439 440static int 441fetch_params(enum tof type, struct process *proc, 442 struct fetch_context *context, 443 struct value_dict *arguments, struct prototype *func, 444 ssize_t *params_leftp) 445{ 446 struct fetch_one_param_data cb_data 447 = { proc, context, arguments, params_leftp, type }; 448 if (prototype_each_param(func, NULL, 449 &fetch_one_param_cb, &cb_data) != NULL) 450 return -1; 451 452 /* Implicit stop at the end of parameter list. */ 453 fetch_param_stop(arguments, params_leftp); 454 455 return 0; 456} 457 458struct format_argument_data 459{ 460 struct value *value; 461 struct value_dict *arguments; 462}; 463 464static int 465format_argument_cb(FILE *stream, void *ptr) 466{ 467 struct format_argument_data *data = ptr; 468 int o = format_argument(stream, data->value, data->arguments); 469 if (o < 0) 470 o = output_error(stream); 471 return o; 472} 473 474static int 475output_params(struct value_dict *arguments, size_t start, size_t end, 476 int *need_delimp) 477{ 478 size_t i; 479 for (i = start; i < end; ++i) { 480 struct value *value = val_dict_get_num(arguments, i); 481 if (value == NULL) 482 return -1; 483 484 struct format_argument_data data = { value, arguments }; 485 int o = delim_output(options.output, need_delimp, 486 format_argument_cb, &data); 487 if (o < 0) 488 return -1; 489 current_column += o; 490 } 491 return 0; 492} 493 494void 495output_left(enum tof type, struct process *proc, 496 struct library_symbol *libsym) 497{ 498 assert(! options.summary); 499 500 if (current_proc) { 501 fprintf(options.output, " <unfinished ...>\n"); 502 current_column = 0; 503 } 504 current_proc = proc; 505 current_depth = proc->callstack_depth; 506 begin_of_line(proc, type == LT_TOF_FUNCTION, 1); 507 if (!options.hide_caller && libsym->lib != NULL 508 && libsym->plt_type != LS_TOPLT_NONE) 509 /* We don't terribly mind failing this. */ 510 account_output(¤t_column, 511 fprintf(options.output, "%s->", 512 libsym->lib->soname)); 513 514 const char *name = libsym->name; 515#ifdef USE_DEMANGLE 516 if (options.demangle) 517 name = my_demangle(libsym->name); 518#endif 519 if (account_output(¤t_column, 520 fprintf(options.output, "%s", name)) < 0) 521 return; 522 523 if (libsym->lib != NULL 524 && libsym->lib->type != LT_LIBTYPE_MAIN 525 && libsym->plt_type == LS_TOPLT_NONE 526 && account_output(¤t_column, 527 fprintf(options.output, "@%s", 528 libsym->lib->soname)) < 0) 529 /* We do mind failing this though. */ 530 return; 531 532 account_output(¤t_column, fprintf(options.output, "(")); 533 534 struct prototype *func = lookup_symbol_prototype(proc, libsym); 535 if (func == NULL) { 536 fail: 537 account_output(¤t_column, fprintf(options.output, "???")); 538 return; 539 } 540 541 struct fetch_context *context = fetch_arg_init(type, proc, 542 func->return_info); 543 if (context == NULL) 544 goto fail; 545 546 struct value_dict *arguments = malloc(sizeof(*arguments)); 547 if (arguments == NULL) { 548 fetch_arg_done(context); 549 goto fail; 550 } 551 val_dict_init(arguments); 552 553 ssize_t params_left = -1; 554 int need_delim = 0; 555 if (fetch_params(type, proc, context, arguments, func, ¶ms_left) < 0 556 || output_params(arguments, 0, params_left, &need_delim) < 0) { 557 val_dict_destroy(arguments); 558 fetch_arg_done(context); 559 arguments = NULL; 560 context = NULL; 561 } 562 563 struct callstack_element *stel 564 = &proc->callstack[proc->callstack_depth - 1]; 565 stel->fetch_context = context; 566 stel->arguments = arguments; 567 stel->out.params_left = params_left; 568 stel->out.need_delim = need_delim; 569} 570 571#if defined(HAVE_LIBDW) 572/* Prints information about one frame of a thread. Called by 573 dwfl_getthread_frames in output_right. Returns 1 when done (max 574 number of frames reached). Returns -1 on error. Returns 0 on 575 success (if there are more frames in the thread, call us again). */ 576static int 577frame_callback (Dwfl_Frame *state, void *arg) 578{ 579 Dwarf_Addr pc; 580 bool isactivation; 581 582 int *frames = (int *) arg; 583 584 if (!dwfl_frame_pc(state, &pc, &isactivation)) 585 return -1; 586 587 if (!isactivation) 588 pc--; 589 590 Dwfl *dwfl = dwfl_thread_dwfl(dwfl_frame_thread(state)); 591 Dwfl_Module *mod = dwfl_addrmodule(dwfl, pc); 592 const char *modname = NULL; 593 const char *symname = NULL; 594 GElf_Off off = 0; 595 if (mod != NULL) { 596 GElf_Sym sym; 597 modname = dwfl_module_info(mod, NULL, NULL, NULL, NULL, 598 NULL, NULL, NULL); 599 symname = dwfl_module_addrinfo(mod, pc, &off, &sym, 600 NULL, NULL, NULL); 601 } 602 603 /* This mimics the output produced by libunwind below. */ 604 fprintf(options.output, " > %s(%s+0x%" PRIx64 ") [%" PRIx64 "]\n", 605 modname, symname, off, pc); 606 607 /* See if we can extract the source line too and print it on 608 the next line if we can find it. */ 609 if (mod != NULL) { 610 Dwfl_Line *l = dwfl_module_getsrc(mod, pc); 611 if (l != NULL) { 612 int line, col; 613 line = col = -1; 614 const char *src = dwfl_lineinfo(l, NULL, &line, &col, 615 NULL, NULL); 616 if (src != NULL) { 617 fprintf(options.output, "\t%s", src); 618 if (line > 0) { 619 fprintf(options.output, ":%d", line); 620 if (col > 0) 621 fprintf(options.output, 622 ":%d", col); 623 } 624 fprintf(options.output, "\n"); 625 } 626 627 } 628 } 629 630 /* Max number of frames to print reached? */ 631 if ((*frames)-- == 0) 632 return 1; 633 634 return 0; 635} 636#endif /* defined(HAVE_LIBDW) */ 637 638void 639output_right(enum tof type, struct process *proc, struct library_symbol *libsym, 640 struct timedelta *spent) 641{ 642 assert(! options.summary); 643 644 struct prototype *func = lookup_symbol_prototype(proc, libsym); 645 if (func == NULL) 646 return; 647 648 if (current_proc != NULL 649 && (current_proc != proc 650 || current_depth != proc->callstack_depth)) { 651 fprintf(options.output, " <unfinished ...>\n"); 652 current_proc = NULL; 653 } 654 if (current_proc != proc) { 655 begin_of_line(proc, type == LT_TOF_FUNCTIONR, 1); 656#ifdef USE_DEMANGLE 657 current_column += 658 fprintf(options.output, "<... %s resumed> ", 659 options.demangle ? my_demangle(libsym->name) 660 : libsym->name); 661#else 662 current_column += 663 fprintf(options.output, "<... %s resumed> ", libsym->name); 664#endif 665 } 666 667 struct callstack_element *stel 668 = &proc->callstack[proc->callstack_depth - 1]; 669 670 struct fetch_context *context = stel->fetch_context; 671 672 /* Fetch & enter into dictionary the retval first, so that 673 * other values can use it in expressions. */ 674 struct value retval; 675 bool own_retval = false; 676 if (context != NULL) { 677 value_init(&retval, proc, NULL, func->return_info, 0); 678 own_retval = true; 679 if (fetch_retval(context, type, proc, func->return_info, 680 &retval) < 0) 681 value_set_type(&retval, NULL, 0); 682 else if (stel->arguments != NULL 683 && val_dict_push_named(stel->arguments, &retval, 684 "retval", 0) == 0) 685 own_retval = false; 686 } 687 688 if (stel->arguments != NULL) 689 output_params(stel->arguments, stel->out.params_left, 690 val_dict_count(stel->arguments), 691 &stel->out.need_delim); 692 693 current_column += fprintf(options.output, ") "); 694 tabto(options.align - 1); 695 fprintf(options.output, "= "); 696 697 if (context != NULL && retval.type != NULL) { 698 struct format_argument_data data = { &retval, stel->arguments }; 699 format_argument_cb(options.output, &data); 700 } 701 702 if (own_retval) 703 value_destroy(&retval); 704 705 if (opt_T) { 706 assert(spent != NULL); 707 fprintf(options.output, " <%lu.%06d>", 708 (unsigned long) spent->tm.tv_sec, 709 (int) spent->tm.tv_usec); 710 } 711 712 fprintf(options.output, "\n"); 713 714#if defined(HAVE_LIBUNWIND) 715 if (options.bt_depth > 0 716 && proc->unwind_priv != NULL 717 && proc->unwind_as != NULL) { 718 unw_cursor_t cursor; 719 arch_addr_t ip, function_offset; 720 struct library *lib = NULL; 721 int unwind_depth = options.bt_depth; 722 char fn_name[100]; 723 const char *lib_name; 724 size_t distance; 725 726 /* Verify that we can safely cast arch_addr_t* to 727 * unw_word_t*. */ 728 (void)sizeof(char[1 - 2*(sizeof(unw_word_t) 729 != sizeof(arch_addr_t))]); 730 unw_init_remote(&cursor, proc->unwind_as, proc->unwind_priv); 731 while (unwind_depth) { 732 733 int rc = unw_get_reg(&cursor, UNW_REG_IP, 734 (unw_word_t *) &ip); 735 if (rc < 0) { 736 fprintf(options.output, " > Error: %s\n", 737 unw_strerror(rc)); 738 goto cont; 739 } 740 741 /* We are looking for the library with the base address 742 * closest to the current ip. */ 743 lib_name = "unmapped_area"; 744 distance = (size_t) -1; 745 lib = proc->libraries; 746 while (lib != NULL) { 747 /* N.B.: Assumes sizeof(size_t) == 748 * sizeof(arch_addr_t). 749 * Keyword: double cast. */ 750 if ((ip >= lib->base) && 751 ((size_t)(ip - lib->base) 752 < distance)) { 753 distance = ip - lib->base; 754 lib_name = lib->pathname; 755 } 756 lib = lib->next; 757 } 758 759 rc = unw_get_proc_name(&cursor, fn_name, 760 sizeof(fn_name), 761 (unw_word_t *) &function_offset); 762 if (rc == 0 || rc == -UNW_ENOMEM) 763 fprintf(options.output, " > %s(%s+%p) [%p]\n", 764 lib_name, fn_name, function_offset, ip); 765 else 766 fprintf(options.output, " > %s(??\?) [%p]\n", 767 lib_name, ip); 768 769 cont: 770 if (unw_step(&cursor) <= 0) 771 break; 772 unwind_depth--; 773 } 774 fprintf(options.output, "\n"); 775 } 776#endif /* defined(HAVE_LIBUNWIND) */ 777 778#if defined(HAVE_LIBDW) 779 if (options.bt_depth > 0 && proc->leader->dwfl != NULL) { 780 int frames = options.bt_depth; 781 if (dwfl_getthread_frames(proc->leader->dwfl, proc->pid, 782 frame_callback, &frames) < 0) { 783 // Only print an error if we couldn't show anything. 784 // Otherwise just show there might be more... 785 if (frames == options.bt_depth) 786 fprintf(stderr, 787 "dwfl_getthread_frames tid %d: %s\n", 788 proc->pid, dwfl_errmsg(-1)); 789 else 790 fprintf(options.output, " > [...]\n"); 791 } 792 fprintf(options.output, "\n"); 793 } 794#endif /* defined(HAVE_LIBDW) */ 795 796 current_proc = NULL; 797 current_column = 0; 798} 799 800int 801delim_output(FILE *stream, int *need_delimp, 802 int (*writer)(FILE *stream, void *data), 803 void *data) 804{ 805 int o; 806 807 /* If we don't need a delimiter, then we don't need to go 808 * through a temporary stream. It's all the same whether 809 * WRITER emits anything or not. */ 810 if (!*need_delimp) { 811 o = writer(stream, data); 812 813 } else { 814 struct memstream ms; 815 if (memstream_init(&ms) < 0) 816 return -1; 817 o = writer(ms.stream, data); 818 if (memstream_close(&ms) < 0) 819 o = -1; 820 if (o > 0 && ((*need_delimp 821 && account_output(&o, fprintf(stream, ", ")) < 0) 822 || fwrite(ms.buf, 1, ms.size, stream) != ms.size)) 823 o = -1; 824 825 memstream_destroy(&ms); 826 } 827 828 if (o < 0) 829 return -1; 830 831 *need_delimp = *need_delimp || o > 0; 832 return o; 833} 834 835int 836account_output(int *countp, int c) 837{ 838 if (c > 0) 839 *countp += c; 840 return c; 841} 842 843static void 844do_report(const char *filename, unsigned line_no, const char *severity, 845 const char *fmt, va_list args) 846{ 847 char buf[128]; 848 vsnprintf(buf, sizeof(buf), fmt, args); 849 buf[sizeof(buf) - 1] = 0; 850 if (filename != NULL) 851 output_line(0, "%s:%d: %s: %s", 852 filename, line_no, severity, buf); 853 else 854 output_line(0, "%s: %s", severity, buf); 855} 856 857void 858report_error(const char *filename, unsigned line_no, const char *fmt, ...) 859{ 860 va_list args; 861 va_start(args, fmt); 862 do_report(filename, line_no, "error", fmt, args); 863 va_end(args); 864} 865 866void 867report_warning(const char *filename, unsigned line_no, const char *fmt, ...) 868{ 869 va_list args; 870 va_start(args, fmt); 871 do_report(filename, line_no, "warning", fmt, args); 872 va_end(args); 873} 874 875void 876report_global_error(const char *fmt, ...) 877{ 878 va_list args; 879 va_start(args, fmt); 880 do_report(NULL, 0, "error", fmt, args); 881 va_end(args); 882} 883