| 542 | } |
| 543 | |
| 544 | void _cfg_dump_context(const char *file, int line, int colstart, int colend, |
| 545 | int run_once) |
| 546 | { |
| 547 | static int called_before; |
| 548 | struct cfg_context *con; |
| 549 | int i, iter = 1, len; |
| 550 | char *p, *end, *wsbuf, *wb, *hiline; |
| 551 | |
| 552 | if (!file) |
| 553 | return; |
| 554 | |
| 555 | for (con = __ccon; con; con = con->next) |
| 556 | if (!strcmp(con->path, file)) |
| 557 | break; |
| 558 | |
| 559 | if (!con || !con->lines[0] || (run_once && called_before)) |
| 560 | return; |
| 561 | |
| 562 | called_before = 1; |
| 563 | |
| 564 | /* 2 lines above */ |
| 565 | if (line >= 3) { |
| 566 | startline = line - 2; |
| 567 | iter += 2; |
| 568 | } else { |
| 569 | startline = 1; |
| 570 | iter += line - 1; |
| 571 | } |
| 572 | |
| 573 | for (i = startline - 1; iter > 0; i++, iter--) |
| 574 | LM_GEN1(L_CRIT, "%s", con->lines[i]); |
| 575 | |
| 576 | /* error indicator line */ |
| 577 | len = strlen(con->lines[i-1]); |
| 578 | wsbuf = malloc(len + 1); |
| 579 | if (!wsbuf) { |
| 580 | LM_ERR("oom\n"); |
| 581 | return; |
| 582 | } |
| 583 | |
| 584 | wb = wsbuf; |
| 585 | for (p = con->lines[i-1], end = p + len; p < end && is_ws(*p); p++) |
| 586 | *wb++ = *p; |
| 587 | *wb = '\0'; |
| 588 | |
| 589 | if (colend < colstart) { |
| 590 | hiline = NULL; |
| 591 | } else { |
| 592 | hiline = malloc(colend - colstart); |
| 593 | if (!hiline) { |
| 594 | LM_ERR("oom\n"); |
| 595 | free(wsbuf); |
| 596 | return; |
| 597 | } |
| 598 | memset(hiline, '~', colend - colstart); |
| 599 | } |
| 600 | |
| 601 | LM_GEN1(L_CRIT, "%s^%.*s\n", wsbuf, |