Age Owner TLA Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * stringinfo_mb.c
4 : * Multibyte encoding-aware additional StringInfo facilities
5 : *
6 : * This is separate from common/stringinfo.c so that frontend users
7 : * of that file need not pull in unnecessary multibyte-encoding support
8 : * code.
9 : *
10 : *
11 : * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
12 : * Portions Copyright (c) 1994, Regents of the University of California
13 : *
14 : *
15 : * IDENTIFICATION
16 : * src/backend/utils/mb/stringinfo_mb.c
17 : *
18 : *-------------------------------------------------------------------------
19 : */
20 : #include "postgres.h"
21 :
22 : #include "mb/stringinfo_mb.h"
23 : #include "mb/pg_wchar.h"
24 :
25 :
26 : /*
27 : * appendStringInfoStringQuoted
28 : *
29 : * Append up to maxlen bytes from s to str, or the whole input string if
30 : * maxlen < 0, adding single quotes around it and doubling all single quotes.
31 : * Add an ellipsis if the copy is incomplete.
32 : */
33 : void
1216 alvherre 34 CBC 4003 : appendStringInfoStringQuoted(StringInfo str, const char *s, int maxlen)
35 : {
36 4003 : char *copy = NULL;
37 : const char *chunk_search_start,
38 : *chunk_copy_start,
39 : *chunk_end;
40 : int slen;
41 : bool ellipsis;
42 :
43 4003 : Assert(str != NULL);
44 :
45 4003 : slen = strlen(s);
1102 tgl 46 4003 : if (maxlen >= 0 && maxlen < slen)
1216 alvherre 47 6 : {
1102 tgl 48 6 : int finallen = pg_mbcliplen(s, slen, maxlen);
49 :
1216 alvherre 50 6 : copy = pnstrdup(s, finallen);
51 6 : chunk_search_start = copy;
52 6 : chunk_copy_start = copy;
53 :
54 6 : ellipsis = true;
55 : }
56 : else
57 : {
58 3997 : chunk_search_start = s;
59 3997 : chunk_copy_start = s;
60 :
61 3997 : ellipsis = false;
62 : }
63 :
64 4003 : appendStringInfoCharMacro(str, '\'');
65 :
66 4034 : while ((chunk_end = strchr(chunk_search_start, '\'')) != NULL)
67 : {
68 : /* copy including the found delimiting ' */
69 31 : appendBinaryStringInfoNT(str,
70 : chunk_copy_start,
71 31 : chunk_end - chunk_copy_start + 1);
72 :
73 : /* in order to double it, include this ' into the next chunk as well */
74 31 : chunk_copy_start = chunk_end;
75 31 : chunk_search_start = chunk_end + 1;
76 : }
77 :
78 : /* copy the last chunk and terminate */
79 4003 : if (ellipsis)
80 6 : appendStringInfo(str, "%s...'", chunk_copy_start);
81 : else
82 3997 : appendStringInfo(str, "%s'", chunk_copy_start);
83 :
84 4003 : if (copy)
85 6 : pfree(copy);
86 4003 : }
|