mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / client / readline.cc
blob7765a62766ffca5675083e348b8dab5c53d78044
1 /*
2 Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 /* readline for batch mode */
20 #include <my_global.h>
21 #include <my_sys.h>
22 #include <m_string.h>
23 #include <my_dir.h>
24 #include "my_readline.h"
26 static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,
27 ulong max_size);
28 static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str);
29 static size_t fill_buffer(LINE_BUFFER *buffer);
30 static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length);
33 LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
35 LINE_BUFFER *line_buff;
36 MY_STAT input_file_stat;
38 #ifndef __WIN__
39 if (my_fstat(fileno(file), &input_file_stat, MYF(MY_WME)) ||
40 MY_S_ISDIR(input_file_stat.st_mode) ||
41 MY_S_ISBLK(input_file_stat.st_mode))
42 return 0;
43 #endif
45 if (!(line_buff=(LINE_BUFFER*)
46 my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL))))
47 return 0;
48 if (init_line_buffer(line_buff,fileno(file),IO_SIZE,max_size))
50 my_free(line_buff,MYF(0));
51 return 0;
53 return line_buff;
57 char *batch_readline(LINE_BUFFER *line_buff)
59 char *pos;
60 ulong out_length= 0;
62 if (!(pos=intern_read_line(line_buff, &out_length)))
63 return 0;
64 if (out_length && pos[out_length-1] == '\n')
65 if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */
66 out_length--; /* Remove '\r' */
67 line_buff->read_length=out_length;
68 pos[out_length]=0;
69 return pos;
73 void batch_readline_end(LINE_BUFFER *line_buff)
75 if (line_buff)
77 my_free(line_buff->buffer,MYF(MY_ALLOW_ZERO_PTR));
78 my_free(line_buff,MYF(0));
83 LINE_BUFFER *batch_readline_command(LINE_BUFFER *line_buff, char * str)
85 if (!line_buff)
86 if (!(line_buff=(LINE_BUFFER*)
87 my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL))))
88 return 0;
89 if (init_line_buffer_from_string(line_buff,str))
91 my_free(line_buff,MYF(0));
92 return 0;
94 return line_buff;
98 /*****************************************************************************
99 Functions to handle buffered readings of lines from a stream
100 ******************************************************************************/
102 static bool
103 init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,ulong max_buffer)
105 buffer->file=file;
106 buffer->bufread=size;
107 buffer->max_size=max_buffer;
108 if (!(buffer->buffer = (char*) my_malloc(buffer->bufread+1,
109 MYF(MY_WME | MY_FAE))))
110 return 1;
111 buffer->end_of_line=buffer->end=buffer->buffer;
112 buffer->buffer[0]=0; /* For easy start test */
113 return 0;
117 init_line_buffer_from_string can be called on the same buffer
118 several times. the resulting buffer will contain a
119 concatenation of all strings separated by spaces
121 static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str)
123 uint old_length=(uint)(buffer->end - buffer->buffer);
124 uint length= (uint) strlen(str);
125 if (!(buffer->buffer= buffer->start_of_line= buffer->end_of_line=
126 (char*) my_realloc((uchar*) buffer->buffer, old_length+length+2,
127 MYF(MY_FAE|MY_ALLOW_ZERO_PTR))))
128 return 1;
129 buffer->end= buffer->buffer + old_length;
130 if (old_length)
131 buffer->end[-1]=' ';
132 memcpy(buffer->end, str, length);
133 buffer->end[length]= '\n';
134 buffer->end[length+1]= 0;
135 buffer->end+= length+1;
136 buffer->eof=1;
137 buffer->max_size=1;
138 return 0;
143 Fill the buffer retaining the last n bytes at the beginning of the
144 newly filled buffer (for backward context). Returns the number of new
145 bytes read from disk.
148 static size_t fill_buffer(LINE_BUFFER *buffer)
150 size_t read_count;
151 uint bufbytes= (uint) (buffer->end - buffer->start_of_line);
153 if (buffer->eof)
154 return 0; /* Everything read */
156 /* See if we need to grow the buffer. */
158 for (;;)
160 uint start_offset=(uint) (buffer->start_of_line - buffer->buffer);
161 read_count=(buffer->bufread - bufbytes)/IO_SIZE;
162 if ((read_count*=IO_SIZE))
163 break;
164 if (buffer->bufread * 2 > buffer->max_size)
167 So we must grow the buffer but we cannot due to the max_size limit.
168 Return 0 w/o setting buffer->eof to signal this condition.
170 return 0;
172 buffer->bufread *= 2;
173 if (!(buffer->buffer = (char*) my_realloc(buffer->buffer,
174 buffer->bufread+1,
175 MYF(MY_WME | MY_FAE))))
177 buffer->error= my_errno;
178 return (size_t) -1;
180 buffer->start_of_line=buffer->buffer+start_offset;
181 buffer->end=buffer->buffer+bufbytes;
184 /* Shift stuff down. */
185 if (buffer->start_of_line != buffer->buffer)
187 bmove(buffer->buffer,buffer->start_of_line,(uint) bufbytes);
188 buffer->end=buffer->buffer+bufbytes;
191 /* Read in new stuff. */
192 if ((read_count= my_read(buffer->file, (uchar*) buffer->end, read_count,
193 MYF(MY_WME))) == MY_FILE_ERROR)
195 buffer->error= my_errno;
196 return (size_t) -1;
199 DBUG_PRINT("fill_buff", ("Got %lu bytes", (ulong) read_count));
201 if (!read_count)
203 buffer->eof = 1;
204 /* Kludge to pretend every nonempty file ends with a newline. */
205 if (bufbytes && buffer->end[-1] != '\n')
207 read_count = 1;
208 *buffer->end = '\n';
211 buffer->end_of_line=(buffer->start_of_line=buffer->buffer)+bufbytes;
212 buffer->end+=read_count;
213 *buffer->end=0; /* Sentinel */
214 return read_count;
218 char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length)
220 char *pos;
221 size_t length;
222 DBUG_ENTER("intern_read_line");
224 buffer->start_of_line=buffer->end_of_line;
225 for (;;)
227 pos=buffer->end_of_line;
228 while (*pos != '\n' && *pos)
229 pos++;
230 if (pos == buffer->end)
233 fill_buffer() can return NULL on EOF (in which case we abort),
234 on error, or when the internal buffer has hit the size limit.
235 In the latter case return what we have read so far and signal
236 string truncation.
238 if (!(length= fill_buffer(buffer)))
240 if (buffer->eof)
241 DBUG_RETURN(0);
243 else if (length == (size_t) -1)
244 DBUG_RETURN(NULL);
245 else
246 continue;
247 pos--; /* break line here */
248 buffer->truncated= 1;
250 else
251 buffer->truncated= 0;
252 buffer->end_of_line=pos+1;
253 *out_length=(ulong) (pos + 1 - buffer->eof - buffer->start_of_line);
254 DBUG_RETURN(buffer->start_of_line);