MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
string.c
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 
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 
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 
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 
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 
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 
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 
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 
178 void dynstr_free(DYNAMIC_STRING *str)
179 {
180  my_free(str->str);
181  str->str= NULL;
182 }