input.c

00001 /*
00002  * Copyright (c) 2010 Jiri Svoboda
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include "mytypes.h"
00039 #include "os/os.h"
00040 #include "strtab.h"
00041 
00042 #include "input.h"
00043 
00045 #define INPUT_BUFFER_SIZE 256
00046 
00047 static int input_init_file(input_t *input, const char *fname);
00048 static void input_init_interactive(input_t *input);
00049 static void input_init_string(input_t *input, const char *str);
00050 
00059 int input_new_file(input_t **input, const char *fname)
00060 {
00061         *input = malloc(sizeof(input_t));
00062         if (*input == NULL)
00063                 return ENOMEM;
00064 
00065         return input_init_file(*input, fname);
00066 }
00067 
00073 int input_new_interactive(input_t **input)
00074 {
00075         *input = malloc(sizeof(input_t));
00076         if (*input == NULL)
00077                 return ENOMEM;
00078 
00079         input_init_interactive(*input);
00080         return EOK;
00081 }
00082 
00089 int input_new_string(input_t **input, const char *str)
00090 {
00091         *input = malloc(sizeof(input_t));
00092         if (*input == NULL)
00093                 return ENOMEM;
00094 
00095         input_init_string(*input, str);
00096         return EOK;
00097 }
00098 
00106 static int input_init_file(input_t *input, const char *fname)
00107 {
00108         FILE *f;
00109 
00110         f = fopen(fname, "rt");
00111         if (f == NULL)
00112                 return ENOENT;
00113 
00114         input->buffer = malloc(INPUT_BUFFER_SIZE);
00115         if (input->buffer == NULL) {
00116                 printf("Memory allocation failed.\n");
00117                 exit(1);
00118         }
00119 
00120         input->name = os_str_dup(fname);
00121         input->str = NULL;
00122         input->line_no = 0;
00123         input->fin = f;
00124         return EOK;
00125 }
00126 
00131 static void input_init_interactive(input_t *input)
00132 {
00133         input->buffer = malloc(INPUT_BUFFER_SIZE);
00134         if (input->buffer == NULL) {
00135                 printf("Memory allocation failed.\n");
00136                 exit(1);
00137         }
00138 
00139         input->name = "<user-input>";
00140         input->str = NULL;
00141         input->line_no = 0;
00142         input->fin = NULL;
00143 }
00144 
00150 static void input_init_string(input_t *input, const char *str)
00151 {
00152         input->buffer = malloc(INPUT_BUFFER_SIZE);
00153         if (input->buffer == NULL) {
00154                 printf("Memory allocation failed.\n");
00155                 exit(1);
00156         }
00157 
00158         input->name = "<builtin>";
00159         input->str = str;
00160         input->line_no = 0;
00161         input->fin = NULL;
00162 }
00163 
00176 int input_get_line(input_t *input, char **line)
00177 {
00178         const char *sp;
00179         char *dp;
00180         char *line_p;
00181         size_t cnt;
00182 
00183         if (input->fin != NULL) {
00184                 /* Reading from file. */
00185                 if (fgets(input->buffer, INPUT_BUFFER_SIZE, input->fin) == NULL)
00186                         input->buffer[0] = '\0';
00187 
00188                 if (ferror(input->fin))
00189                         return EIO;
00190 
00191                 *line = input->buffer;
00192         } else if (input->str != NULL) {
00193                 /* Reading from a string constant. */
00194 
00195                 /* Copy one line. */
00196                 sp = input->str;
00197                 dp = input->buffer;
00198                 cnt = 0;
00199                 while (*sp != '\n' && *sp != '\0' &&
00200                     cnt < INPUT_BUFFER_SIZE - 2) {
00201                         *dp++ = *sp++;
00202                 }
00203 
00204                 /* Advance to start of next line. */
00205                 if (*sp == '\n')
00206                         *dp++ = *sp++;
00207 
00208                 *dp = '\0';
00209                 input->str = sp;
00210                 *line = input->buffer;
00211         } else {
00212                 /* Interactive mode */
00213                 if (input->line_no == 0)
00214                         printf("sbi> ");
00215                 else
00216                         printf("...  ");
00217 
00218                 fflush(stdout);
00219                 if (os_input_line(&line_p) != EOK)
00220                         return EIO;
00221 
00222                 *line = line_p;
00223         }
00224 
00225         ++input->line_no;
00226         return EOK;
00227 }
00228 
00235 int input_get_line_no(input_t *input)
00236 {
00237         return input->line_no;
00238 }

Generated on Thu Jun 2 07:45:41 2011 for HelenOS/USB by  doxygen 1.4.7