1 /* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15
16 /*
17 Code for handling strings with can grow dynamicly.
18 Copyright Monty Program KB.
19 By monty.
20 */
21
22 #include "mysys_priv.h"
23 #include <m_string.h>
24
init_dynamic_string(DYNAMIC_STRING * str,const char * init_str,size_t init_alloc,size_t alloc_increment)25 my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
26 size_t init_alloc, size_t alloc_increment)
27 {
28 size_t length;
29 DBUG_ENTER("init_dynamic_string");
30
31 if (!alloc_increment)
32 alloc_increment=128;
33 length=1;
34 if (init_str && (length= strlen(init_str)+1) < init_alloc)
35 init_alloc=((length+alloc_increment-1)/alloc_increment)*alloc_increment;
36 if (!init_alloc)
37 init_alloc=alloc_increment;
38
39 if (!(str->str=(char*) my_malloc(init_alloc,MYF(MY_WME))))
40 DBUG_RETURN(TRUE);
41 str->length=length-1;
42 if (init_str)
43 memcpy(str->str,init_str,length);
44 str->max_length=init_alloc;
45 str->alloc_increment=alloc_increment;
46 DBUG_RETURN(FALSE);
47 }
48
49
dynstr_set(DYNAMIC_STRING * str,const char * init_str)50 my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str)
51 {
52 uint length=0;
53 DBUG_ENTER("dynstr_set");
54
55 if (init_str && (length= (uint) strlen(init_str)+1) > str->max_length)
56 {
57 str->max_length=((length+str->alloc_increment-1)/str->alloc_increment)*
58 str->alloc_increment;
59 if (!str->max_length)
60 str->max_length=str->alloc_increment;
61 if (!(str->str=(char*) my_realloc(str->str,str->max_length,MYF(MY_WME))))
62 DBUG_RETURN(TRUE);
63 }
64 if (init_str)
65 {
66 str->length=length-1;
67 memcpy(str->str,init_str,length);
68 }
69 else
70 str->length=0;
71 DBUG_RETURN(FALSE);
72 }
73
74
dynstr_realloc(DYNAMIC_STRING * str,size_t additional_size)75 my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size)
76 {
77 DBUG_ENTER("dynstr_realloc");
78
79 if (!additional_size) DBUG_RETURN(FALSE);
80 if (str->length + additional_size > str->max_length)
81 {
82 str->max_length=((str->length + additional_size+str->alloc_increment-1)/
83 str->alloc_increment)*str->alloc_increment;
84 if (!(str->str=(char*) my_realloc(str->str,str->max_length,MYF(MY_WME))))
85 DBUG_RETURN(TRUE);
86 }
87 DBUG_RETURN(FALSE);
88 }
89
90
dynstr_append(DYNAMIC_STRING * str,const char * append)91 my_bool dynstr_append(DYNAMIC_STRING *str, const char *append)
92 {
93 return dynstr_append_mem(str,append,(uint) strlen(append));
94 }
95
96
dynstr_append_mem(DYNAMIC_STRING * str,const char * append,size_t length)97 my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
98 size_t length)
99 {
100 char *new_ptr;
101 if (str->length+length >= str->max_length)
102 {
103 size_t new_length=(str->length+length+str->alloc_increment)/
104 str->alloc_increment;
105 new_length*=str->alloc_increment;
106 if (!(new_ptr=(char*) my_realloc(str->str,new_length,MYF(MY_WME))))
107 return TRUE;
108 str->str=new_ptr;
109 str->max_length=new_length;
110 }
111 memcpy(str->str + str->length,append,length);
112 str->length+=length;
113 str->str[str->length]=0; /* Safety for C programs */
114 return FALSE;
115 }
116
117
dynstr_trunc(DYNAMIC_STRING * str,size_t n)118 my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n)
119 {
120 str->length-=n;
121 str->str[str->length]= '\0';
122 return FALSE;
123 }
124
125 /*
126 Concatenates any number of strings, escapes any OS quote in the result then
127 surround the whole affair in another set of quotes which is finally appended
128 to specified DYNAMIC_STRING. This function is especially useful when
129 building strings to be executed with the system() function.
130
131 @param str Dynamic String which will have addtional strings appended.
132 @param append String to be appended.
133 @param ... Optional. Additional string(s) to be appended.
134
135 @note The final argument in the list must be NullS even if no additional
136 options are passed.
137
138 @return True = Success.
139 */
140
dynstr_append_os_quoted(DYNAMIC_STRING * str,const char * append,...)141 my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...)
142 {
143 #ifdef __WIN__
144 const char *quote_str= "\"";
145 const uint quote_len= 1;
146 #else
147 const char *quote_str= "\'";
148 const uint quote_len= 1;
149 #endif /* __WIN__ */
150 my_bool ret= TRUE;
151 va_list dirty_text;
152
153 ret&= dynstr_append_mem(str, quote_str, quote_len); /* Leading quote */
154 va_start(dirty_text, append);
155 while (append != NullS)
156 {
157 const char *cur_pos= append;
158 const char *next_pos= cur_pos;
159
160 /* Search for quote in each string and replace with escaped quote */
161 while(*(next_pos= strcend(cur_pos, quote_str[0])) != '\0')
162 {
163 ret&= dynstr_append_mem(str, cur_pos, (uint) (next_pos - cur_pos));
164 ret&= dynstr_append_mem(str ,"\\", 1);
165 ret&= dynstr_append_mem(str, quote_str, quote_len);
166 cur_pos= next_pos + 1;
167 }
168 ret&= dynstr_append_mem(str, cur_pos, (uint) (next_pos - cur_pos));
169 append= va_arg(dirty_text, char *);
170 }
171 va_end(dirty_text);
172 ret&= dynstr_append_mem(str, quote_str, quote_len); /* Trailing quote */
173
174 return ret;
175 }
176
177
dynstr_free(DYNAMIC_STRING * str)178 void dynstr_free(DYNAMIC_STRING *str)
179 {
180 my_free(str->str);
181 str->str= NULL;
182 }
183