1 /*****************************************************************************/
2 /* Stream Class Library Copyright (c) 1999-2000 Sakai Hiroaki.               */
3 /* All Rights Reserved.                                                      */
4 /*===========================================================================*/
5 /* This program is free software; you can redistribute it and/or modify      */
6 /* it under the terms of the GNU General Public License as published by      */
7 /* the Free Software Foundation; either version 2, or (at your option)       */
8 /* any later version.                                                        */
9 /*                                                                           */
10 /* This program is distributed in the hope that it will be useful,           */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of            */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
13 /* GNU General Public License for more details.                              */
14 /*                                                                           */
15 /* You should have received a copy of the GNU General Public License         */
16 /* along with this program; see the file COPYING.  If not, write to          */
17 /* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.     */
18 /*****************************************************************************/
19 
20 /*****************************************************************************/
21 /* ��������                                                                  */
22 /*****************************************************************************/
23 
24 #include "StreamP.h"
25 
26 /*****************************************************************************/
27 /* �ؿ������                                                                */
28 /*****************************************************************************/
29 
30 /*===========================================================================*/
31 /* ���顼����                                                                */
32 /*===========================================================================*/
33 
Stream_ErrorExit(char * function,char * message)34 static void Stream_ErrorExit(char * function, char * message)
35 {
36   fprintf(stderr, "Error in %s():%s\n", function, message);
37   exit(1);
38 }
39 
40 /*===========================================================================*/
41 /* ���֥������Ȥ�����                                                        */
42 /*===========================================================================*/
43 
44 /*---------------------------------------------------------------------------*/
45 /* ���֥������Ȥ�����                                                        */
46 /*---------------------------------------------------------------------------*/
47 
Stream_Create(CreateStreamFrom from,void * object)48 Stream Stream_Create(CreateStreamFrom from, void * object)
49 {
50   Stream this;
51 
52   this = (Stream)malloc(sizeof(_Stream));
53   if (this == NULL)
54     Stream_ErrorExit("Stream_Create", "Canot allocate memory.");
55 
56   this->unget_buffer = NULL;
57   this->end_flag = 0;
58   this->from = from;
59 
60   switch (this->from) {
61 
62   case CREATE_NO_STREAM :
63     this->type = STREAM_TYPE_NONE;
64     this->object.dummy = NULL;
65     break;
66 
67   case CREATE_STREAM_FROM_FILE :
68     this->type = STREAM_TYPE_FILE_POINTER;
69     this->object.file_pointer = fopen((char *)object, "rt");
70     if (this->object.file_pointer == NULL) {
71       free(this);
72       return (NULL);
73     }
74     break;
75 
76   case CREATE_STREAM_FROM_FILE_POINTER :
77     this->type = STREAM_TYPE_FILE_POINTER;
78     this->object.file_pointer = (FILE *)object;
79     break;
80 
81   case CREATE_STREAM_FROM_CHARACTERS :
82     this->type = STREAM_TYPE_CHARACTERS;
83     this->object.characters = (char *)object;
84     break;
85 
86   default :
87     Stream_ErrorExit("Stream_Create", "Invalid type.");
88   }
89 
90   return (this);
91 }
92 
93 /*---------------------------------------------------------------------------*/
94 /* �ʤˤ�ʤ��Ȥ���������(���ߡ���)                                        */
95 /*---------------------------------------------------------------------------*/
96 
Stream_CreateFromNone()97 Stream Stream_CreateFromNone()
98 {
99   return (Stream_Create(CREATE_NO_STREAM, (void *)NULL));
100 }
101 
102 /*---------------------------------------------------------------------------*/
103 /* �ե����뤫������                                                          */
104 /*---------------------------------------------------------------------------*/
105 
Stream_CreateFromFile(char * filename)106 Stream Stream_CreateFromFile(char * filename)
107 {
108   return (Stream_Create(CREATE_STREAM_FROM_FILE, (void *)filename));
109 }
110 
111 /*---------------------------------------------------------------------------*/
112 /* �ե�����ݥ�����������                                                  */
113 /*---------------------------------------------------------------------------*/
114 
Stream_CreateFromFilePointer(FILE * fp)115 Stream Stream_CreateFromFilePointer(FILE * fp)
116 {
117   return (Stream_Create(CREATE_STREAM_FROM_FILE_POINTER, (void *)fp));
118 }
119 
120 /*---------------------------------------------------------------------------*/
121 /* ʸ����(char * ��)��������                                                 */
122 /*---------------------------------------------------------------------------*/
123 
Stream_CreateFromCharacters(char * characters)124 Stream Stream_CreateFromCharacters(char * characters)
125 {
126   return (Stream_Create(CREATE_STREAM_FROM_CHARACTERS, (void *)characters));
127 }
128 
129 /*===========================================================================*/
130 /* ���֥������Ȥξõ�                                                        */
131 /*===========================================================================*/
132 
Stream_Destroy(Stream this)133 int Stream_Destroy(Stream this)
134 {
135   UngetBuffer * p;
136 
137   if (!this) Stream_ErrorExit("Stream_Destroy", "Object is not created.");
138 
139   switch (this->from) {
140   case CREATE_NO_STREAM :
141     break;
142   case CREATE_STREAM_FROM_FILE :
143     fclose(this->object.file_pointer);
144     break;
145   case CREATE_STREAM_FROM_FILE_POINTER :
146     break;
147   case CREATE_STREAM_FROM_CHARACTERS :
148     break;
149   default :
150     break;
151   }
152 
153   while (this->unget_buffer) {
154     p = this->unget_buffer->next;
155     free(this->unget_buffer);
156     this->unget_buffer = p;
157   }
158 
159   free(this);
160 
161   return (0);
162 }
163 
164 /*===========================================================================*/
165 /* ʸ����μ���                                                              */
166 /*===========================================================================*/
167 
168 /*---------------------------------------------------------------------------*/
169 /* �ɤ߹���ʸ�����ޤ����뤫�ɤ���                                            */
170 /*---------------------------------------------------------------------------*/
171 
Stream_IsEnd(Stream this)172 int Stream_IsEnd(Stream this)
173 {
174   return (this->end_flag);
175 }
176 
177 /*---------------------------------------------------------------------------*/
178 /* Stream ���飱ʸ�������(get)���롥                                        */
179 /*---------------------------------------------------------------------------*/
180 
Stream_GetCharacter(Stream this)181 int Stream_GetCharacter(Stream this)
182 {
183   UngetBuffer * p;
184   int c;
185 
186   if (!this) Stream_ErrorExit("Stream_GetCharacter", "Object is not created.");
187 
188   if (this->end_flag) {
189     c = EOF;
190   } else if (this->unget_buffer) {
191     c = this->unget_buffer->character;
192     p = this->unget_buffer->next;
193     free(this->unget_buffer);
194     this->unget_buffer = p;
195   } else {
196     switch (this->type) {
197 
198     case STREAM_TYPE_NONE :
199       c = EOF;
200       this->end_flag = 1;
201       break;
202 
203     case STREAM_TYPE_FILE_POINTER :
204       c = fgetc(this->object.file_pointer);
205       if (c == EOF) this->end_flag = 1;
206       break;
207 
208     case STREAM_TYPE_CHARACTERS :
209       c = (int)(*(this->object.characters));
210       if (c == '\0') {
211 	c = EOF;
212 	this->end_flag = 1;
213       } else {
214 	(this->object.characters)++;
215       }
216       break;
217 
218     default :
219       Stream_ErrorExit("Stream_GetCharacter", "Invalid type.");
220     }
221   }
222   return (c);
223 }
224 
225 /*---------------------------------------------------------------------------*/
226 /* Stream �ˣ�ʸ�����ֵ�(unget)���롥                                        */
227 /*---------------------------------------------------------------------------*/
228 
Stream_UngetCharacter(Stream this,int c)229 int Stream_UngetCharacter(Stream this, int c)
230 {
231   UngetBuffer * p;
232   char character = (char)c;
233 
234   if (!this)
235     Stream_ErrorExit("Stream_UngetCharacter", "Object is not created.");
236 
237   if (c == EOF) {
238     this->end_flag = 1;
239     return (EOF);
240   }
241 
242   p = (UngetBuffer *)malloc(sizeof(UngetBuffer));
243   if (!p) Stream_ErrorExit("Stream_UngetCharacter", "Cannot allocate memory.");
244 
245   this->end_flag = 0;
246   p->character = character;
247   p->next = this->unget_buffer;
248   this->unget_buffer = p;
249 
250   return (character);
251 }
252 
253 /*---------------------------------------------------------------------------*/
254 /* Stream ��ʸ������ֵ�(unget)���롥                                        */
255 /*---------------------------------------------------------------------------*/
256 
Stream_UngetCharacters(Stream this,char * characters)257 int Stream_UngetCharacters(Stream this, char * characters)
258 {
259   int n = 0;
260   int i;
261 
262   if (!this)
263     Stream_ErrorExit("Stream_UngetCharacters", "Object is not created.");
264 
265   for (i = 0; characters[i] != '\0'; i++) { /* None */ }
266   for(i--; i >= 0; i--) {
267     Stream_UngetCharacter(this, characters[i]);
268     n++;
269   }
270 
271   return (n);
272 }
273 
274 /*---------------------------------------------------------------------------*/
275 /* ʸ�������ʸ�������뤫�ɤ�����Ƚ��                                        */
276 /*---------------------------------------------------------------------------*/
277 
CheckWord(char * s,int c)278 static int CheckWord(char * s, int c)
279 {
280   if (c == EOF) return (0);
281   if (s == NULL) return (0);
282 
283   while (*s != '\0') {
284     if (c == *s) return (1);
285     s++;
286   }
287 
288   return (0);
289 }
290 
291 /*---------------------------------------------------------------------------*/
292 /* ʸ�����ʸ�����ɲ�                                                        */
293 /*---------------------------------------------------------------------------*/
294 
AddCharacter(char * buffer,int * buf_len,int * i,char c,int extend)295 static char * AddCharacter(char * buffer, int * buf_len, int * i, char c,
296 			   int extend)
297 {
298   if (*i >= *buf_len - 1) {
299     if (!extend) return (buffer);
300     (*buf_len) *= 2;
301     if (!buffer) buffer = (char *)malloc(sizeof(char) * (*buf_len));
302     else buffer = (char *)realloc((void *)buffer, sizeof(char) * (*buf_len));
303     if (!buffer) Stream_ErrorExit("AddCharacter", "Cannot allocate memory.");
304   }
305 
306   buffer[*i] = c;
307   (*i)++;
308   return (buffer);
309 }
310 
311 /*---------------------------------------------------------------------------*/
312 /* Stream ����ȡ�����Ƕ��ڤä�ʸ������ɤ߹��ߡ�ʸ����(String ��)���֤���  */
313 /* ������䥳���ȹԤβ���Ԥ���                                          */
314 /*---------------------------------------------------------------------------*/
315 /* split1 �ϡ�ʣ���ζ��ڤ�ʸ����Ϣ³������ˤ⡤�̥�ʸ���Ȥ����ڤ�ʬ���롥 */
316 /* split2 �ϡ�ʣ���ζ��ڤ�ʸ����Ϣ³������ˤϡ��ҤȤĤζ��ڤ�ʸ���Ȥ���   */
317 /* �������롥                                                                */
318 /*---------------------------------------------------------------------------*/
319 
Stream_GetWord(Stream this,char * buffer,int buffer_length,char * split1,char * split2,char * comment,char * lineend,char * quotation,char * head_skip,char * tail_skip)320 char * Stream_GetWord(Stream this,      /* �ɤ߹��߸��� Stream */
321 		      char * buffer,
322 		      int buffer_length,
323 		      char * split1,    /* ����ʸ�����ڤ�ʬ���� */
324 		      char * split2,    /* ����ʸ���Ǥ��ڤ�ʬ���� */
325 		      char * comment,   /* �����ȹԤ���Ƭʸ�� '#' �ʤ� */
326 		      char * lineend,   /* ����ʸ�� '\n' �ʤ� */
327 		      char * quotation, /* ������ʸ�� '\"' �ʤ� */
328 		      char * head_skip, /* ʸ������Ƭ���ɤߤȤФ�ʸ�� */
329 		      char * tail_skip  /* ʸ�����������ɤߤȤФ�ʸ�� */
330 		      )
331 {
332   int c;
333   int i = 0;
334   int extend = 0; /* �Хåե����ĥ�Ǥ��뤫 */
335 
336   if (!this) Stream_ErrorExit("Stream_GetWord", "Object is not created.");
337 
338   do {
339     c = Stream_GetCharacter(this);
340     if (CheckWord(comment, c)) {
341       do {
342 	c = Stream_GetCharacter(this);
343       } while (!CheckWord(lineend, c) && (c != EOF));
344     }
345   } while (CheckWord(split2, c) || CheckWord(comment, c) ||
346 	   CheckWord(lineend, c));
347 
348   if (c == EOF) return (NULL); /* �ɤ߽Ф�ñ�줬¸�ߤ��ʤ� */
349 
350   if (!buffer) {
351     extend = 1;
352     buffer_length = 10;
353     buffer = (char *)malloc(sizeof(char) * buffer_length);
354     if (!buffer) Stream_ErrorExit("Stream_GetWord", "Cannot allocate memory.");
355   }
356 
357   if (CheckWord(quotation, c)) {
358     while (1) {
359       c = Stream_GetCharacter(this);
360       if (CheckWord(quotation, c) || (c == EOF)) break;
361       buffer = AddCharacter(buffer, &buffer_length, &i, c, extend);
362     }
363   } else {
364 
365     while (CheckWord(head_skip, c) && (c != EOF))
366       c = Stream_GetCharacter(this);
367 
368     while (1) {
369       if (c == EOF) {
370 	break;
371       }
372       if (CheckWord(comment, c) || CheckWord(quotation, c) ||
373 	  CheckWord(split1, c) || CheckWord(split2, c) ||
374 	  CheckWord(lineend, c)) {
375 	Stream_UngetCharacter(this, c);
376 	break;
377       }
378       buffer = AddCharacter(buffer, &buffer_length, &i, c, extend);
379       c = Stream_GetCharacter(this);
380     }
381 
382     while ((i > 0) && (CheckWord(tail_skip, buffer[i - 1]))) i--;
383   }
384 
385   if (i <= buffer_length - 1) buffer[i] = '\0';
386 
387   return (buffer);
388 }
389 
390 /*****************************************************************************/
391 /* �����ޤ�                                                                  */
392 /*****************************************************************************/
393 
394 /*****************************************************************************/
395 /* End of File.                                                              */
396 /*****************************************************************************/
397