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>
24 #include "my_readline.h"
26 static bool init_line_buffer(LINE_BUFFER
*buffer
,File file
,ulong 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
;
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
))
45 if (!(line_buff
=(LINE_BUFFER
*)
46 my_malloc(sizeof(*line_buff
),MYF(MY_WME
| MY_ZEROFILL
))))
48 if (init_line_buffer(line_buff
,fileno(file
),IO_SIZE
,max_size
))
50 my_free(line_buff
,MYF(0));
57 char *batch_readline(LINE_BUFFER
*line_buff
)
62 if (!(pos
=intern_read_line(line_buff
, &out_length
)))
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
;
73 void batch_readline_end(LINE_BUFFER
*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
)
86 if (!(line_buff
=(LINE_BUFFER
*)
87 my_malloc(sizeof(*line_buff
),MYF(MY_WME
| MY_ZEROFILL
))))
89 if (init_line_buffer_from_string(line_buff
,str
))
91 my_free(line_buff
,MYF(0));
98 /*****************************************************************************
99 Functions to handle buffered readings of lines from a stream
100 ******************************************************************************/
103 init_line_buffer(LINE_BUFFER
*buffer
,File file
,ulong size
,ulong max_buffer
)
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
))))
111 buffer
->end_of_line
=buffer
->end
=buffer
->buffer
;
112 buffer
->buffer
[0]=0; /* For easy start test */
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
))))
129 buffer
->end
= buffer
->buffer
+ old_length
;
132 memcpy(buffer
->end
, str
, length
);
133 buffer
->end
[length
]= '\n';
134 buffer
->end
[length
+1]= 0;
135 buffer
->end
+= length
+1;
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
)
151 uint bufbytes
= (uint
) (buffer
->end
- buffer
->start_of_line
);
154 return 0; /* Everything read */
156 /* See if we need to grow the buffer. */
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
))
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.
172 buffer
->bufread
*= 2;
173 if (!(buffer
->buffer
= (char*) my_realloc(buffer
->buffer
,
175 MYF(MY_WME
| MY_FAE
))))
177 buffer
->error
= my_errno
;
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
;
199 DBUG_PRINT("fill_buff", ("Got %lu bytes", (ulong
) read_count
));
204 /* Kludge to pretend every nonempty file ends with a newline. */
205 if (bufbytes
&& buffer
->end
[-1] != '\n')
211 buffer
->end_of_line
=(buffer
->start_of_line
=buffer
->buffer
)+bufbytes
;
212 buffer
->end
+=read_count
;
213 *buffer
->end
=0; /* Sentinel */
218 char *intern_read_line(LINE_BUFFER
*buffer
, ulong
*out_length
)
222 DBUG_ENTER("intern_read_line");
224 buffer
->start_of_line
=buffer
->end_of_line
;
227 pos
=buffer
->end_of_line
;
228 while (*pos
!= '\n' && *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
238 if (!(length
= fill_buffer(buffer
)))
243 else if (length
== (size_t) -1)
247 pos
--; /* break line here */
248 buffer
->truncated
= 1;
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
);