1
by brian
clean slate |
1 |
/* Copyright (C) 2000 MySQL AB
|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
15 |
||
16 |
/* readline for batch mode */
|
|
17 |
||
520.4.43
by mordred
A set of Solaris fixes. |
18 |
#include <drizzled/global.h> |
212.5.13
by Monty Taylor
Moved my_sys/my_pthread/my_nosys and mysys_err to mysys. |
19 |
#include <mysys/my_sys.h> |
212.5.18
by Monty Taylor
Moved m_ctype, m_string and my_bitmap. Removed t_ctype. |
20 |
#include <mystrings/m_string.h> |
1
by brian
clean slate |
21 |
#include "my_readline.h" |
22 |
||
520.4.43
by mordred
A set of Solaris fixes. |
23 |
using namespace std; |
24 |
||
288
by Brian Aker
ulong cleanp in client apps |
25 |
static bool init_line_buffer(LINE_BUFFER *buffer,File file,uint32_t size, |
26 |
uint32_t max_size); |
|
1
by brian
clean slate |
27 |
static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str); |
28 |
static size_t fill_buffer(LINE_BUFFER *buffer); |
|
288
by Brian Aker
ulong cleanp in client apps |
29 |
static char *intern_read_line(LINE_BUFFER *buffer,uint32_t *out_length); |
30 |
||
31 |
||
32 |
LINE_BUFFER *batch_readline_init(uint32_t max_size,FILE *file) |
|
1
by brian
clean slate |
33 |
{
|
34 |
LINE_BUFFER *line_buff; |
|
35 |
if (!(line_buff=(LINE_BUFFER*) |
|
36 |
my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL)))) |
|
37 |
return 0; |
|
38 |
if (init_line_buffer(line_buff,fileno(file),IO_SIZE,max_size)) |
|
39 |
{
|
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
40 |
free(line_buff); |
1
by brian
clean slate |
41 |
return 0; |
42 |
}
|
|
43 |
return line_buff; |
|
44 |
}
|
|
45 |
||
46 |
||
47 |
char *batch_readline(LINE_BUFFER *line_buff) |
|
48 |
{
|
|
49 |
char *pos; |
|
288
by Brian Aker
ulong cleanp in client apps |
50 |
uint32_t out_length; |
1
by brian
clean slate |
51 |
|
52 |
if (!(pos=intern_read_line(line_buff,&out_length))) |
|
53 |
return 0; |
|
54 |
if (out_length && pos[out_length-1] == '\n') |
|
55 |
if (--out_length && pos[out_length-1] == '\r') /* Remove '\n' */ |
|
56 |
out_length--; /* Remove '\r' */ |
|
57 |
line_buff->read_length=out_length; |
|
58 |
pos[out_length]=0; |
|
59 |
return pos; |
|
60 |
}
|
|
61 |
||
62 |
||
63 |
void batch_readline_end(LINE_BUFFER *line_buff) |
|
64 |
{
|
|
65 |
if (line_buff) |
|
66 |
{
|
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
67 |
free(line_buff->buffer); |
68 |
free(line_buff); |
|
1
by brian
clean slate |
69 |
}
|
70 |
}
|
|
71 |
||
72 |
||
73 |
LINE_BUFFER *batch_readline_command(LINE_BUFFER *line_buff, char * str) |
|
74 |
{
|
|
75 |
if (!line_buff) |
|
76 |
if (!(line_buff=(LINE_BUFFER*) |
|
77 |
my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL)))) |
|
78 |
return 0; |
|
79 |
if (init_line_buffer_from_string(line_buff,str)) |
|
80 |
{
|
|
477
by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that. |
81 |
free(line_buff); |
1
by brian
clean slate |
82 |
return 0; |
83 |
}
|
|
84 |
return line_buff; |
|
85 |
}
|
|
86 |
||
87 |
||
88 |
/*****************************************************************************
|
|
89 |
Functions to handle buffered readings of lines from a stream
|
|
90 |
******************************************************************************/
|
|
91 |
||
92 |
static bool |
|
288
by Brian Aker
ulong cleanp in client apps |
93 |
init_line_buffer(LINE_BUFFER *buffer,File file,uint32_t size,uint32_t max_buffer) |
1
by brian
clean slate |
94 |
{
|
95 |
buffer->file=file; |
|
96 |
buffer->bufread=size; |
|
97 |
buffer->max_size=max_buffer; |
|
98 |
if (!(buffer->buffer = (char*) my_malloc(buffer->bufread+1, |
|
99 |
MYF(MY_WME | MY_FAE)))) |
|
100 |
return 1; |
|
101 |
buffer->end_of_line=buffer->end=buffer->buffer; |
|
102 |
buffer->buffer[0]=0; /* For easy start test */ |
|
103 |
return 0; |
|
104 |
}
|
|
105 |
||
106 |
/*
|
|
107 |
init_line_buffer_from_string can be called on the same buffer
|
|
108 |
several times. the resulting buffer will contain a
|
|
109 |
concatenation of all strings separated by spaces
|
|
110 |
*/
|
|
111 |
static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str) |
|
112 |
{
|
|
113 |
uint old_length=(uint)(buffer->end - buffer->buffer); |
|
114 |
uint length= (uint) strlen(str); |
|
115 |
if (!(buffer->buffer= buffer->start_of_line= buffer->end_of_line= |
|
481
by Brian Aker
Remove all of uchar. |
116 |
(char*) my_realloc((unsigned char*) buffer->buffer, old_length+length+2, |
1
by brian
clean slate |
117 |
MYF(MY_FAE|MY_ALLOW_ZERO_PTR)))) |
118 |
return 1; |
|
119 |
buffer->end= buffer->buffer + old_length; |
|
120 |
if (old_length) |
|
121 |
buffer->end[-1]=' '; |
|
122 |
memcpy(buffer->end, str, length); |
|
123 |
buffer->end[length]= '\n'; |
|
124 |
buffer->end[length+1]= 0; |
|
125 |
buffer->end+= length+1; |
|
126 |
buffer->eof=1; |
|
127 |
buffer->max_size=1; |
|
128 |
return 0; |
|
129 |
}
|
|
130 |
||
131 |
||
132 |
/*
|
|
133 |
Fill the buffer retaining the last n bytes at the beginning of the
|
|
134 |
newly filled buffer (for backward context). Returns the number of new
|
|
135 |
bytes read from disk.
|
|
136 |
*/
|
|
137 |
||
138 |
static size_t fill_buffer(LINE_BUFFER *buffer) |
|
139 |
{
|
|
140 |
size_t read_count; |
|
141 |
uint bufbytes= (uint) (buffer->end - buffer->start_of_line); |
|
142 |
||
143 |
if (buffer->eof) |
|
144 |
return 0; /* Everything read */ |
|
145 |
||
146 |
/* See if we need to grow the buffer. */
|
|
147 |
||
148 |
for (;;) |
|
149 |
{
|
|
150 |
uint start_offset=(uint) (buffer->start_of_line - buffer->buffer); |
|
151 |
read_count=(buffer->bufread - bufbytes)/IO_SIZE; |
|
152 |
if ((read_count*=IO_SIZE)) |
|
153 |
break; |
|
154 |
buffer->bufread *= 2; |
|
155 |
if (!(buffer->buffer = (char*) my_realloc(buffer->buffer, |
|
156 |
buffer->bufread+1, |
|
157 |
MYF(MY_WME | MY_FAE)))) |
|
158 |
return (uint) -1; |
|
159 |
buffer->start_of_line=buffer->buffer+start_offset; |
|
160 |
buffer->end=buffer->buffer+bufbytes; |
|
161 |
}
|
|
162 |
||
163 |
/* Shift stuff down. */
|
|
164 |
if (buffer->start_of_line != buffer->buffer) |
|
165 |
{
|
|
212.6.3
by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents: |
166 |
memcpy(buffer->buffer, buffer->start_of_line, (uint) bufbytes); |
1
by brian
clean slate |
167 |
buffer->end=buffer->buffer+bufbytes; |
168 |
}
|
|
169 |
||
170 |
/* Read in new stuff. */
|
|
481
by Brian Aker
Remove all of uchar. |
171 |
if ((read_count= my_read(buffer->file, (unsigned char*) buffer->end, read_count, |
1
by brian
clean slate |
172 |
MYF(MY_WME))) == MY_FILE_ERROR) |
173 |
return (size_t) -1; |
|
174 |
||
175 |
/* Kludge to pretend every nonempty file ends with a newline. */
|
|
176 |
if (!read_count && bufbytes && buffer->end[-1] != '\n') |
|
177 |
{
|
|
178 |
buffer->eof = read_count = 1; |
|
179 |
*buffer->end = '\n'; |
|
180 |
}
|
|
181 |
buffer->end_of_line=(buffer->start_of_line=buffer->buffer)+bufbytes; |
|
182 |
buffer->end+=read_count; |
|
183 |
*buffer->end=0; /* Sentinel */ |
|
184 |
return read_count; |
|
185 |
}
|
|
186 |
||
187 |
||
188 |
||
288
by Brian Aker
ulong cleanp in client apps |
189 |
char *intern_read_line(LINE_BUFFER *buffer,uint32_t *out_length) |
1
by brian
clean slate |
190 |
{
|
191 |
char *pos; |
|
192 |
size_t length; |
|
142.1.2
by Patrick
All DBUG_x removed from client/ |
193 |
|
1
by brian
clean slate |
194 |
|
195 |
buffer->start_of_line=buffer->end_of_line; |
|
196 |
for (;;) |
|
197 |
{
|
|
198 |
pos=buffer->end_of_line; |
|
199 |
while (*pos != '\n' && *pos) |
|
200 |
pos++; |
|
201 |
if (pos == buffer->end) |
|
202 |
{
|
|
203 |
if ((uint) (pos - buffer->start_of_line) < buffer->max_size) |
|
204 |
{
|
|
205 |
if (!(length=fill_buffer(buffer)) || length == (size_t) -1) |
|
142.1.2
by Patrick
All DBUG_x removed from client/ |
206 |
return(0); |
1
by brian
clean slate |
207 |
continue; |
208 |
}
|
|
209 |
pos--; /* break line here */ |
|
210 |
}
|
|
211 |
buffer->end_of_line=pos+1; |
|
288
by Brian Aker
ulong cleanp in client apps |
212 |
*out_length=(uint32_t) (pos + 1 - buffer->eof - buffer->start_of_line); |
142.1.2
by Patrick
All DBUG_x removed from client/ |
213 |
return(buffer->start_of_line); |
1
by brian
clean slate |
214 |
}
|
215 |
}
|