*** ./command.c.orig 2009-08-13 12:50:17.736733508 +0200 --- ./command.c 2009-08-13 15:21:36.236437558 +0200 *************** *** 674,679 **** --- 674,753 ---- success = listAllDbs(false); else if (strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0) success = listAllDbs(true); + else if (strcmp(cmd, "lf") == 0 || (strcmp(cmd, "lf-") == 0)) + { + char *func; + Oid foid = InvalidOid; + + func = psql_scan_slash_option(scan_state, + OT_WHOLE_LINE, NULL, true); + if (!query_buf) + { + psql_error("no query buffer\n"); + status = PSQL_CMD_ERROR; + } + else + { + if (!func) + { + psql_error("missing function name"); + status = PSQL_CMD_ERROR; + } + else if (!lookup_function_oid(pset.db, func, &foid)) + { + /* error already reported */ + status = PSQL_CMD_ERROR; + } + else if (!get_create_function_cmd(pset.db, foid, query_buf)) + { + /* error already reported */ + status = PSQL_CMD_ERROR; + } + else + { + char *cursor = query_buf->data; + char *line = cursor; + bool print_line_number = false; + int row_number = 1; + + if (strcmp(cmd, "lf-") == 0) + fputs(query_buf->data, pset.queryFout); + else + { + /* print source code with line numbers */ + while (*cursor != '\0') + { + if (*cursor == '\n') + { + *cursor = '\0'; + if (strncmp(line, "AS $function$", 13) == 0) + { + print_line_number = true; + if (strlen(line) == 13) + { + fprintf(pset.queryFout, "****\t%s\n", line); + line = ++cursor; + continue; + } + } + else if (strcmp(line, "$function$") ==0) + print_line_number = false; + + if (print_line_number) + fprintf(pset.queryFout, "%4d\t%s\n", row_number++, line); + else + fprintf(pset.queryFout, "****\t%s\n", line); + line = ++cursor; + } + else + cursor++; + } + } + if (func) + free(func); + } + } + } /* * large object things *************** *** 1781,1786 **** --- 1855,1870 ---- if (!quiet) printf(_("Border style is %d.\n"), popt->topt.border); } + + /* set border line style */ + else if (strcmp(param, "linestyle") == 0) + { + if (value) + popt->topt.linestyle = atoi(value); + + if (!quiet) + printf(_("Border line style is %d.\n"), popt->topt.linestyle); + } /* set expanded/vertical mode */ else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0) *** ./help.c.orig 2009-08-13 13:31:35.655440156 +0200 --- ./help.c 2009-08-13 15:15:17.652439244 +0200 *************** *** 221,226 **** --- 221,227 ---- fprintf(output, _(" \\dT[S+] [PATTERN] list data types\n")); fprintf(output, _(" \\du [PATTERN] list roles (users)\n")); fprintf(output, _(" \\dv[S+] [PATTERN] list views\n")); + fprintf(output, _(" \\lf[-] [PATTERN] show function's source code\n")); fprintf(output, _(" \\l[+] list all databases\n")); fprintf(output, _(" \\z [PATTERN] same as \\dp\n")); fprintf(output, "\n"); *************** *** 232,238 **** fprintf(output, _(" \\H toggle HTML output mode (currently %s)\n"), ON(pset.popt.topt.format == PRINT_HTML)); fprintf(output, _(" \\pset NAME [VALUE] set table output option\n" ! " (NAME := {format|border|expanded|fieldsep|footer|null|\n" " numericlocale|recordsep|tuples_only|title|tableattr|pager})\n")); fprintf(output, _(" \\t [on|off] show only rows (currently %s)\n"), ON(pset.popt.topt.tuples_only)); --- 233,239 ---- fprintf(output, _(" \\H toggle HTML output mode (currently %s)\n"), ON(pset.popt.topt.format == PRINT_HTML)); fprintf(output, _(" \\pset NAME [VALUE] set table output option\n" ! " (NAME := {format|border|linestyle|expanded|fieldsep|footer|null|\n" " numericlocale|recordsep|tuples_only|title|tableattr|pager})\n")); fprintf(output, _(" \\t [on|off] show only rows (currently %s)\n"), ON(pset.popt.topt.tuples_only)); *** ./print.c.orig 2009-08-13 13:40:34.343439205 +0200 --- ./print.c 2009-08-13 17:15:33.935437539 +0200 *************** *** 45,55 **** static char *thousands_sep; /* Local functions */ ! static int strlen_max_width(unsigned char *str, int *target_width, int encoding); static void IsPagerNeeded(const printTableContent *cont, const int extra_lines, FILE **fout, bool *is_pager); static void * pg_local_malloc(size_t size) { --- 45,114 ---- static char *thousands_sep; /* Local functions */ ! static int strlen_max_width(unsigned char *str, int *target_width, int encoding, ! bool word_wrap_mode, ! bool *wrapped_in_space); static void IsPagerNeeded(const printTableContent *cont, const int extra_lines, FILE **fout, bool *is_pager); + static char *symbols_utf_single[] = { "\xE2\x94\x94", "\xE2\x94\x80", "\xE2\x94\xb4", "\xE2\x94\x98", + "\xE2\x94\x82", "\xE2\x94\x82", "\xE2\x94\x82", "\xE2\x94\x82", + "\xE2\x94\x9c", "\xE2\x94\x80", "\xE2\x94\xbc", "\xE2\x94\xa4", + "\xE2\x94\x8c", "\xE2\x94\x80", "\xE2\x94\xac", "\xE2\x94\x90", + "\xE2\x94\x9c", "\xE2\x94\x80", "\xE2\x94\xbc", "\xE2\x94\xa4", + "\xe2\x94\x8a", "\xE2\x94\x86", ":" }; + + static char *symbols_utf_singl2[] = { "\xE2\x94\x94", "\xE2\x94\x80", "\xE2\x94\x80", "\xE2\x94\x98", + "\xE2\x94\x82", "\xE2\x94\x82", "\xE2\x94\x82", "\xE2\x94\x82", + "\xE2\x94\x9c", "\xE2\x94\x80", "\xE2\x94\xb4", "\xE2\x94\xa4", + "\xE2\x94\x8c", "\xE2\x94\x80", "\xE2\x94\xac", "\xE2\x94\x90", + "\xE2\x94\x9c", "\xE2\x94\x80", "\xE2\x94\xbc", "\xE2\x94\xa4", + "\xe2\x94\x8a", "\xE2\x94\x86", ":" }; + + static char *symbols_utf_double[] = { "\xE2\x95\x9a", "\xE2\x95\x90", "\xE2\x95\xa7", "\xE2\x95\x9d", + "\xE2\x95\x91", "\xE2\x94\x82", "\xE2\x94\x82", "\xE2\x95\x91", + "\xE2\x95\x9f", "\xE2\x94\x80", "\xE2\x94\xbc", "\xE2\x95\xa2", + "\xE2\x95\x94", "\xE2\x95\x90", "\xE2\x95\xa4", "\xE2\x95\x97", + "\xE2\x95\x9f", "\xE2\x94\x80", "\xE2\x94\xbc", "\xE2\x95\xa2", + "\xe2\x94\x8a", "\xE2\x94\x86", ":" }; + + static char *symbols_utf_doubl2[] = { "\xE2\x95\x9a", "\xE2\x95\x90", "\xE2\x95\xa7", "\xE2\x95\x9d", + "\xE2\x95\x91", "\xE2\x94\x82", "\xE2\x94\x82", "\xE2\x95\x91", + "\xE2\x95\xa0", "\xE2\x95\x90", "\xE2\x95\xaa", "\xE2\x95\xa3", + "\xE2\x95\x94", "\xE2\x95\x90", "\xE2\x95\xa4", "\xE2\x95\x97", + "\xE2\x95\x9f", "\xE2\x94\x80", "\xE2\x94\xbc", "\xE2\x95\xa2", + "\xe2\x94\x8a", "\xE2\x94\x86", ":" }; + + static char *symbols_utf_doubl3[] = { "\xE2\x95\x9a", "\xE2\x95\x90", "\xE2\x95\x90", "\xE2\x95\x9d", + "\xE2\x95\x91", "\xE2\x95\x91", "\xE2\x94\x82", "\xE2\x95\x91", + "\xE2\x95\xa0", "\xE2\x95\x90", "\xE2\x95\xa9", "\xE2\x95\xa3", + "\xE2\x95\x94", "\xE2\x95\x90", "\xE2\x95\xa6", "\xE2\x95\x97", + "\xE2\x95\x9f", "\xE2\x94\x80", "\xE2\x94\xbc", "\xE2\x95\xa2", + "\xe2\x94\x8a", "\xE2\x94\x86", ":" }; + + static char *symbols_utf_doubl4[] = { "\xE2\x95\x9a", "\xE2\x95\x90", "\xE2\x95\xa9", "\xE2\x95\x9d", + "\xE2\x95\x91", "\xE2\x95\x91", "\xE2\x95\x91", "\xE2\x95\x91", + "\xE2\x95\xa0", "\xE2\x95\x90", "\xE2\x95\xac", "\xE2\x95\xa3", + "\xE2\x95\x94", "\xE2\x95\x90", "\xE2\x95\xa6", "\xE2\x95\x97", + "\xE2\x95\x9f", "\xE2\x94\x80", "\xE2\x95\xab", "\xE2\x95\xa2", + "\xe2\x95\x91", "\xE2\x95\x91", "\xE2\x95\x91" }; + + + + static char *symbols_asc[] = { "+", "-", "+", "+", + "|", "|" , "|" , "|", + "+", "-", "+", "+", + "+", "-", "+", "+", + "+", "-", "+", "+", + " ", ";", ":"}; + + static char **styles[] = { symbols_asc, symbols_utf_single, symbols_utf_singl2, + symbols_utf_double, symbols_utf_doubl2, symbols_utf_doubl3, + symbols_utf_doubl4 }; + + + static void * pg_local_malloc(size_t size) { *************** *** 360,393 **** /* draw "line" */ static void _print_horizontal_line(const unsigned int ncolumns, const unsigned int *widths, ! unsigned short border, FILE *fout) { unsigned int i, j; ! if (border == 1) ! fputc('-', fout); ! else if (border == 2) ! fputs("+-", fout); for (i = 0; i < ncolumns; i++) { for (j = 0; j < widths[i]; j++) ! fputc('-', fout); if (i < ncolumns - 1) { if (border == 0) fputc(' ', fout); else ! fputs("-+-", fout); } } ! if (border == 2) ! fputs("-+", fout); else if (border == 1) ! fputc('-', fout); fputc('\n', fout); } --- 419,470 ---- /* draw "line" */ static void _print_horizontal_line(const unsigned int ncolumns, const unsigned int *widths, ! unsigned short border, FILE *fout, ! char valign, unsigned short linestyle) { unsigned int i, j; + char **bsymbols = NULL; /* border line symbols */ ! switch (valign) ! { ! case 'b': ! bsymbols = &styles[linestyle][0]; ! break; ! case 'm': ! bsymbols = &styles[linestyle][8]; ! break; ! case 't': ! bsymbols = &styles[linestyle][12]; ! break; ! case 'r': ! bsymbols = &styles[linestyle][16]; ! break; ! } ! ! if (border == 1 || border == 4) ! fputs(bsymbols[1], fout); ! else if (border == 2 || border == 3) ! fprintf(fout, "%s%s", bsymbols[0], bsymbols[1]); for (i = 0; i < ncolumns; i++) { for (j = 0; j < widths[i]; j++) ! fputs(bsymbols[1], fout); if (i < ncolumns - 1) { if (border == 0) fputc(' ', fout); else ! fprintf(fout, "%s%s%s", bsymbols[1], bsymbols[2], bsymbols[1]); } } ! if (border == 2 || border == 3) ! fprintf(fout, "%s%s", bsymbols[1], bsymbols[3]); else if (border == 1) ! fputs(bsymbols[1], fout); fputc('\n', fout); } *************** *** 403,408 **** --- 480,486 ---- bool opt_numeric_locale = cont->opt->numericLocale; int encoding = cont->opt->encoding; unsigned short opt_border = cont->opt->border; + unsigned short opt_linestyle = cont->opt->linestyle; unsigned int col_count = 0, cell_count = 0; *************** *** 431,442 **** int *bytes_output; /* Bytes output for column value */ int output_columns = 0; /* Width of interactive console */ bool is_pager = false; if (cancel_pressed) return; ! if (opt_border > 2) ! opt_border = 2; if (cont->ncolumns > 0) { --- 509,526 ---- int *bytes_output; /* Bytes output for column value */ int output_columns = 0; /* Width of interactive console */ bool is_pager = false; + char **bsymbols; if (cancel_pressed) return; ! if (opt_border > 4) ! opt_border = 4; ! ! if (opt_linestyle > 6) ! opt_linestyle = 6; ! ! bsymbols = &styles[opt_linestyle][4]; if (cont->ncolumns > 0) { *************** *** 708,715 **** int more_col_wrapping; int curr_nl_line; ! if (opt_border == 2) ! _print_horizontal_line(col_count, width_wrap, opt_border, fout); for (i = 0; i < col_count; i++) pg_wcsformat((unsigned char *) cont->headers[i], --- 792,800 ---- int more_col_wrapping; int curr_nl_line; ! if (opt_border == 2 || opt_border == 3) ! _print_horizontal_line(col_count, width_wrap, opt_border, fout, ! 't', opt_linestyle); for (i = 0; i < col_count; i++) pg_wcsformat((unsigned char *) cont->headers[i], *************** *** 721,729 **** memset(header_done, false, col_count * sizeof(bool)); while (more_col_wrapping) { ! if (opt_border == 2) ! fprintf(fout, "|%c", curr_nl_line ? '+' : ' '); ! else if (opt_border == 1) fputc(curr_nl_line ? '+' : ' ', fout); for (i = 0; i < cont->ncolumns; i++) --- 806,814 ---- memset(header_done, false, col_count * sizeof(bool)); while (more_col_wrapping) { ! if (opt_border == 2 || opt_border == 3) ! fprintf(fout, "%s%c", bsymbols[0], curr_nl_line ? '+' : ' '); ! else if (opt_border == 1 || opt_border == 4) fputc(curr_nl_line ? '+' : ' ', fout); for (i = 0; i < cont->ncolumns; i++) *************** *** 753,771 **** if (opt_border == 0) fputc(curr_nl_line ? '+' : ' ', fout); else ! fprintf(fout, " |%c", curr_nl_line ? '+' : ' '); } } curr_nl_line++; ! if (opt_border == 2) ! fputs(" |", fout); ! else if (opt_border == 1) fputc(' ', fout); fputc('\n', fout); } ! _print_horizontal_line(col_count, width_wrap, opt_border, fout); } } --- 838,857 ---- if (opt_border == 0) fputc(curr_nl_line ? '+' : ' ', fout); else ! fprintf(fout, " %s%c", bsymbols[1], curr_nl_line ? '+' : ' '); } } curr_nl_line++; ! if (opt_border == 2 || opt_border == 3) ! fprintf(fout, " %s", bsymbols[3]); ! else if (opt_border == 1 || opt_border == 4) fputc(' ', fout); fputc('\n', fout); } ! _print_horizontal_line(col_count, width_wrap, opt_border, fout, ! 'm', opt_linestyle); } } *************** *** 776,781 **** --- 862,871 ---- if (cancel_pressed) break; + + if ((opt_border == 3 || opt_border == 4) && i > 0) + _print_horizontal_line(col_count, width_wrap, opt_border, fout, + 'r', opt_linestyle); /* * Format each cell. Format again, if it's a numeric formatting *************** *** 810,818 **** more_lines = false; /* left border */ ! if (opt_border == 2) ! fputs("| ", fout); ! else if (opt_border == 1) fputc(' ', fout); /* for each column */ --- 900,908 ---- more_lines = false; /* left border */ ! if (opt_border == 2 || opt_border == 3) ! fprintf(fout, "%s ", bsymbols[0]); ! else if (opt_border == 1 || opt_border == 4) fputc(' ', fout); /* for each column */ *************** *** 822,828 **** struct lineptr *this_line = &col_lineptrs[j][curr_nl_line[j]]; int bytes_to_output; int chars_to_output = width_wrap[j]; ! bool finalspaces = (opt_border == 2 || j < col_count - 1); if (!this_line->ptr) { --- 912,918 ---- struct lineptr *this_line = &col_lineptrs[j][curr_nl_line[j]]; int bytes_to_output; int chars_to_output = width_wrap[j]; ! bool finalspaces = (opt_border == 2 || opt_border == 3 || j < col_count - 1); if (!this_line->ptr) { *************** *** 832,841 **** } else { /* Get strlen() of the characters up to width_wrap */ bytes_to_output = strlen_max_width(this_line->ptr + bytes_output[j], ! &chars_to_output, encoding); /* * If we exceeded width_wrap, it means the display width --- 922,935 ---- } else { + bool wrapped_in_space = false; + /* Get strlen() of the characters up to width_wrap */ bytes_to_output = strlen_max_width(this_line->ptr + bytes_output[j], ! &chars_to_output, encoding, ! cont->opt->format == PRINT_WRAPPED, ! &wrapped_in_space); /* * If we exceeded width_wrap, it means the display width *************** *** 863,868 **** --- 957,965 ---- } bytes_output[j] += bytes_to_output; + /* skip space on begin of new line */ + if (wrapped_in_space) + bytes_output[j]++; /* Do we have more text to wrap? */ if (*(this_line->ptr + bytes_output[j]) != '\0') *************** *** 884,905 **** fputc(' ', fout); /* Next value is beyond past newlines? */ else if (col_lineptrs[j + 1][curr_nl_line[j + 1]].ptr == NULL) ! fputs(" ", fout); /* In wrapping of value? */ else if (bytes_output[j + 1] != 0) ! fputs(" ; ", fout); /* After first newline value */ else if (curr_nl_line[j + 1] != 0) ! fputs(" : ", fout); else /* Ordinary line */ ! fputs(" | ", fout); } } /* end-of-row border */ ! if (opt_border == 2) ! fputs(" |", fout); fputc('\n', fout); } while (more_lines); --- 981,1002 ---- fputc(' ', fout); /* Next value is beyond past newlines? */ else if (col_lineptrs[j + 1][curr_nl_line[j + 1]].ptr == NULL) ! fprintf(fout, " %s ", styles[opt_linestyle][20]); /* In wrapping of value? */ else if (bytes_output[j + 1] != 0) ! fprintf(fout, " %s ", styles[opt_linestyle][21]); /* After first newline value */ else if (curr_nl_line[j + 1] != 0) ! fprintf(fout, " %s ", styles[opt_linestyle][22]); else /* Ordinary line */ ! fprintf(fout, " %s ", bsymbols[2]); } } /* end-of-row border */ ! if (opt_border == 2 || opt_border == 3) ! fprintf(fout, " %s", bsymbols[3]); fputc('\n', fout); } while (more_lines); *************** *** 907,914 **** if (cont->opt->stop_table) { ! if (opt_border == 2 && !cancel_pressed) ! _print_horizontal_line(col_count, width_wrap, opt_border, fout); /* print footers */ if (cont->footers && !opt_tuples_only && !cancel_pressed) --- 1004,1013 ---- if (cont->opt->stop_table) { ! if ((opt_border == 2 || opt_border == 3) && !cancel_pressed) ! _print_horizontal_line(col_count, width_wrap, opt_border, fout, ! 'b', ! opt_linestyle); /* print footers */ if (cont->footers && !opt_tuples_only && !cancel_pressed) *************** *** 2393,2407 **** * to be the number of display character positions actually filled. */ static int ! strlen_max_width(unsigned char *str, int *target_width, int encoding) { unsigned char *start = str; unsigned char *end = str + strlen((char *) str); int curr_width = 0; while (str < end) { int char_width = PQdsplen((char *) str, encoding); /* * If the display width of the new character causes the string to --- 2492,2516 ---- * to be the number of display character positions actually filled. */ static int ! strlen_max_width(unsigned char *str, int *target_width, int encoding, ! bool word_wrap_mode, ! bool *wrapped_in_space) { unsigned char *start = str; unsigned char *end = str + strlen((char *) str); int curr_width = 0; + int space_pos = 0; + unsigned char *space_ptr = NULL; while (str < end) { int char_width = PQdsplen((char *) str, encoding); + + if (word_wrap_mode && char_width == 1 && *str == ' ') + { + space_pos = curr_width; + space_ptr = str; + } /* * If the display width of the new character causes the string to *************** *** 2417,2423 **** str += PQmblen((char *) str, encoding); } ! *target_width = curr_width; return str - start; } --- 2526,2542 ---- str += PQmblen((char *) str, encoding); } ! if (word_wrap_mode && space_ptr != NULL && str < end) ! { ! *target_width = space_pos; ! *wrapped_in_space = true; ! str = space_ptr; ! } ! else ! { ! *target_width = curr_width; ! *wrapped_in_space = false; ! } return str - start; } *** ./print.h.orig 2009-08-13 15:22:48.555439838 +0200 --- ./print.h 2009-08-13 15:25:31.920439663 +0200 *************** *** 31,36 **** --- 31,40 ---- * output format) */ unsigned short int border; /* Print a border around the table. 0=none, * 1=dividing lines, 2=full */ + unsigned short int linestyle; /* UTF8 border line styles. 0=ASCI, + * 1=single, 2=single2, + * 3=double, 4=double2, + * 5=double3, 6=double4 */ unsigned short int pager; /* use pager for output (if to stdout and * stdout is a tty) 0=off 1=on 2=always */ bool tuples_only; /* don't output headers, row counts, etc. */