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-2024, 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/pg_wchar.h" 23 : #include "mb/stringinfo_mb.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 34 8068 : appendStringInfoStringQuoted(StringInfo str, const char *s, int maxlen) 35 : { 36 8068 : char *copy = NULL; 37 : const char *chunk_search_start, 38 : *chunk_copy_start, 39 : *chunk_end; 40 : int slen; 41 : bool ellipsis; 42 : 43 : Assert(str != NULL); 44 : 45 8068 : slen = strlen(s); 46 8068 : if (maxlen >= 0 && maxlen < slen) 47 12 : { 48 12 : int finallen = pg_mbcliplen(s, slen, maxlen); 49 : 50 12 : copy = pnstrdup(s, finallen); 51 12 : chunk_search_start = copy; 52 12 : chunk_copy_start = copy; 53 : 54 12 : ellipsis = true; 55 : } 56 : else 57 : { 58 8056 : chunk_search_start = s; 59 8056 : chunk_copy_start = s; 60 : 61 8056 : ellipsis = false; 62 : } 63 : 64 8068 : appendStringInfoCharMacro(str, '\''); 65 : 66 8130 : while ((chunk_end = strchr(chunk_search_start, '\'')) != NULL) 67 : { 68 : /* copy including the found delimiting ' */ 69 62 : appendBinaryStringInfoNT(str, 70 : chunk_copy_start, 71 62 : chunk_end - chunk_copy_start + 1); 72 : 73 : /* in order to double it, include this ' into the next chunk as well */ 74 62 : chunk_copy_start = chunk_end; 75 62 : chunk_search_start = chunk_end + 1; 76 : } 77 : 78 : /* copy the last chunk and terminate */ 79 8068 : if (ellipsis) 80 12 : appendStringInfo(str, "%s...'", chunk_copy_start); 81 : else 82 8056 : appendStringInfo(str, "%s'", chunk_copy_start); 83 : 84 8068 : if (copy) 85 12 : pfree(copy); 86 8068 : }