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; |
|
656.1.20
by Monty Taylor
Removed my_strdup, my_malloc, my_realloc from client/ |
35 |
if (!(line_buff=(LINE_BUFFER*) malloc(sizeof(*line_buff)))) |
1
by brian
clean slate |
36 |
return 0; |
656.1.20
by Monty Taylor
Removed my_strdup, my_malloc, my_realloc from client/ |
37 |
memset(line_buff, 0, sizeof(*line_buff)); |
1
by brian
clean slate |
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) |
|
656.1.20
by Monty Taylor
Removed my_strdup, my_malloc, my_realloc from client/ |
76 |
{
|
77 |
if (!(line_buff=(LINE_BUFFER*) malloc(sizeof(*line_buff)))) |
|
1
by brian
clean slate |
78 |
return 0; |
656.1.20
by Monty Taylor
Removed my_strdup, my_malloc, my_realloc from client/ |
79 |
memset(line_buff, 0, sizeof(*line_buff)); |
80 |
}
|
|
1
by brian
clean slate |
81 |
if (init_line_buffer_from_string(line_buff,str)) |
82 |
{
|
|
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. |
83 |
free(line_buff); |
1
by brian
clean slate |
84 |
return 0; |
85 |
}
|
|
86 |
return line_buff; |
|
87 |
}
|
|
88 |
||
89 |
||
90 |
/*****************************************************************************
|
|
91 |
Functions to handle buffered readings of lines from a stream
|
|
92 |
******************************************************************************/
|
|
93 |
||
94 |
static bool |
|
288
by Brian Aker
ulong cleanp in client apps |
95 |
init_line_buffer(LINE_BUFFER *buffer,File file,uint32_t size,uint32_t max_buffer) |
1
by brian
clean slate |
96 |
{
|
97 |
buffer->file=file; |
|
98 |
buffer->bufread=size; |
|
99 |
buffer->max_size=max_buffer; |
|
656.1.20
by Monty Taylor
Removed my_strdup, my_malloc, my_realloc from client/ |
100 |
if (!(buffer->buffer = (char*) malloc(buffer->bufread+1))) |
1
by brian
clean slate |
101 |
return 1; |
102 |
buffer->end_of_line=buffer->end=buffer->buffer; |
|
103 |
buffer->buffer[0]=0; /* For easy start test */ |
|
104 |
return 0; |
|
105 |
}
|
|
106 |
||
107 |
/*
|
|
108 |
init_line_buffer_from_string can be called on the same buffer
|
|
109 |
several times. the resulting buffer will contain a
|
|
110 |
concatenation of all strings separated by spaces
|
|
111 |
*/
|
|
112 |
static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str) |
|
113 |
{
|
|
114 |
uint old_length=(uint)(buffer->end - buffer->buffer); |
|
115 |
uint length= (uint) strlen(str); |
|
656.1.50
by Monty Taylor
More malloc return type checking |
116 |
char * tmpptr= (char*)realloc(buffer->buffer, old_length+length+2); |
117 |
if (tmpptr == NULL) |
|
1
by brian
clean slate |
118 |
return 1; |
656.1.50
by Monty Taylor
More malloc return type checking |
119 |
|
120 |
buffer->buffer= buffer->start_of_line= buffer->end_of_line= tmpptr; |
|
1
by brian
clean slate |
121 |
buffer->end= buffer->buffer + old_length; |
122 |
if (old_length) |
|
123 |
buffer->end[-1]=' '; |
|
124 |
memcpy(buffer->end, str, length); |
|
125 |
buffer->end[length]= '\n'; |
|
126 |
buffer->end[length+1]= 0; |
|
127 |
buffer->end+= length+1; |
|
128 |
buffer->eof=1; |
|
129 |
buffer->max_size=1; |
|
130 |
return 0; |
|
131 |
}
|
|
132 |
||
133 |
||
134 |
/*
|
|
135 |
Fill the buffer retaining the last n bytes at the beginning of the
|
|
136 |
newly filled buffer (for backward context). Returns the number of new
|
|
137 |
bytes read from disk.
|
|
138 |
*/
|
|
139 |
||
140 |
static size_t fill_buffer(LINE_BUFFER *buffer) |
|
141 |
{
|
|
142 |
size_t read_count; |
|
143 |
uint bufbytes= (uint) (buffer->end - buffer->start_of_line); |
|
144 |
||
145 |
if (buffer->eof) |
|
146 |
return 0; /* Everything read */ |
|
147 |
||
148 |
/* See if we need to grow the buffer. */
|
|
149 |
||
150 |
for (;;) |
|
151 |
{
|
|
152 |
uint start_offset=(uint) (buffer->start_of_line - buffer->buffer); |
|
153 |
read_count=(buffer->bufread - bufbytes)/IO_SIZE; |
|
154 |
if ((read_count*=IO_SIZE)) |
|
155 |
break; |
|
156 |
buffer->bufread *= 2; |
|
656.1.20
by Monty Taylor
Removed my_strdup, my_malloc, my_realloc from client/ |
157 |
if (!(buffer->buffer = (char*) realloc(buffer->buffer, |
158 |
buffer->bufread+1))) |
|
1
by brian
clean slate |
159 |
return (uint) -1; |
160 |
buffer->start_of_line=buffer->buffer+start_offset; |
|
161 |
buffer->end=buffer->buffer+bufbytes; |
|
162 |
}
|
|
163 |
||
164 |
/* Shift stuff down. */
|
|
165 |
if (buffer->start_of_line != buffer->buffer) |
|
166 |
{
|
|
629.3.2
by Kristian Nielsen
Fix a couple of memcpy() that should be memmove() (caused by wrong |
167 |
memmove(buffer->buffer, buffer->start_of_line, (uint) bufbytes); |
1
by brian
clean slate |
168 |
buffer->end=buffer->buffer+bufbytes; |
169 |
}
|
|
170 |
||
171 |
/* Read in new stuff. */
|
|
481
by Brian Aker
Remove all of uchar. |
172 |
if ((read_count= my_read(buffer->file, (unsigned char*) buffer->end, read_count, |
1
by brian
clean slate |
173 |
MYF(MY_WME))) == MY_FILE_ERROR) |
174 |
return (size_t) -1; |
|
175 |
||
176 |
/* Kludge to pretend every nonempty file ends with a newline. */
|
|
177 |
if (!read_count && bufbytes && buffer->end[-1] != '\n') |
|
178 |
{
|
|
179 |
buffer->eof = read_count = 1; |
|
180 |
*buffer->end = '\n'; |
|
181 |
}
|
|
182 |
buffer->end_of_line=(buffer->start_of_line=buffer->buffer)+bufbytes; |
|
183 |
buffer->end+=read_count; |
|
184 |
*buffer->end=0; /* Sentinel */ |
|
185 |
return read_count; |
|
186 |
}
|
|
187 |
||
188 |
||
189 |
||
288
by Brian Aker
ulong cleanp in client apps |
190 |
char *intern_read_line(LINE_BUFFER *buffer,uint32_t *out_length) |
1
by brian
clean slate |
191 |
{
|
192 |
char *pos; |
|
193 |
size_t length; |
|
142.1.2
by Patrick
All DBUG_x removed from client/ |
194 |
|
1
by brian
clean slate |
195 |
|
196 |
buffer->start_of_line=buffer->end_of_line; |
|
197 |
for (;;) |
|
198 |
{
|
|
199 |
pos=buffer->end_of_line; |
|
200 |
while (*pos != '\n' && *pos) |
|
201 |
pos++; |
|
202 |
if (pos == buffer->end) |
|
203 |
{
|
|
204 |
if ((uint) (pos - buffer->start_of_line) < buffer->max_size) |
|
205 |
{
|
|
206 |
if (!(length=fill_buffer(buffer)) || length == (size_t) -1) |
|
142.1.2
by Patrick
All DBUG_x removed from client/ |
207 |
return(0); |
1
by brian
clean slate |
208 |
continue; |
209 |
}
|
|
210 |
pos--; /* break line here */ |
|
211 |
}
|
|
212 |
buffer->end_of_line=pos+1; |
|
288
by Brian Aker
ulong cleanp in client apps |
213 |
*out_length=(uint32_t) (pos + 1 - buffer->eof - buffer->start_of_line); |
142.1.2
by Patrick
All DBUG_x removed from client/ |
214 |
return(buffer->start_of_line); |
1
by brian
clean slate |
215 |
}
|
216 |
}
|