2 * Copyright (c) 2010 Jiri Svoboda
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 /** @file Input module
31 * Reads source code. Currently input can be read from a file (standard
32 * case), from a string literal (when parsing builtin code) or interactively
44 /** Size of input buffer. XXX This limits the maximum line length. */
45 #define INPUT_BUFFER_SIZE 256
47 static errno_t
input_init_file(input_t
*input
, const char *fname
);
48 static void input_init_interactive(input_t
*input
);
49 static void input_init_string(input_t
*input
, const char *str
);
51 /** Create new input object for reading from file.
53 * @param input Place to store pointer to new input object.
54 * @param fname Name of file to read from.
56 * @return EOK on success, ENOMEM when allocation fails,
57 * ENOENT when opening file fails.
59 errno_t
input_new_file(input_t
**input
, const char *fname
)
61 *input
= malloc(sizeof(input_t
));
65 return input_init_file(*input
, fname
);
68 /** Create new input object for reading from interactive input.
70 * @param input Place to store pointer to new input object.
71 * @return EOK on success, ENOMEM when allocation fails.
73 errno_t
input_new_interactive(input_t
**input
)
75 *input
= malloc(sizeof(input_t
));
79 input_init_interactive(*input
);
83 /** Create new input object for reading from string.
85 * @param input Place to store pointer to new input object.
86 * @param str String literal from which to read input.
87 * @return EOK on success, ENOMEM when allocation fails.
89 errno_t
input_new_string(input_t
**input
, const char *str
)
91 *input
= malloc(sizeof(input_t
));
95 input_init_string(*input
, str
);
99 /** Initialize input object for reading from file.
101 * @param input Input object.
102 * @param fname Name of file to read from.
104 * @return EOK on success, ENOENT when opening file fails.
106 static errno_t
input_init_file(input_t
*input
, const char *fname
)
110 f
= fopen(fname
, "rt");
114 input
->buffer
= malloc(INPUT_BUFFER_SIZE
);
115 if (input
->buffer
== NULL
) {
116 printf("Memory allocation failed.\n");
120 input
->name
= os_str_dup(fname
);
127 /** Initialize input object for reading from interactive input.
129 * @param input Input object.
131 static void input_init_interactive(input_t
*input
)
133 input
->buffer
= malloc(INPUT_BUFFER_SIZE
);
134 if (input
->buffer
== NULL
) {
135 printf("Memory allocation failed.\n");
139 input
->name
= "<user-input>";
145 /** Initialize input object for reading from string.
147 * @param input Input object.
148 * @param str String literal from which to read input.
150 static void input_init_string(input_t
*input
, const char *str
)
152 input
->buffer
= malloc(INPUT_BUFFER_SIZE
);
153 if (input
->buffer
== NULL
) {
154 printf("Memory allocation failed.\n");
158 input
->name
= "<builtin>";
164 /** Get next line of input.
166 * The pointer stored in @a line is owned by @a input and is valid until the
167 * next call to input_get_line(). The caller is not to free it. The returned
168 * line is terminated with '\n' if another line is coming (potentially empty).
169 * An empty line ("") signals end of input.
171 * @param input Input object.
172 * @param line Place to store pointer to next line.
174 * @return EOK on success, EIO on failure.
176 errno_t
input_get_line(input_t
*input
, char **line
)
184 if (input
->fin
!= NULL
) {
185 /* Reading from file. */
186 if (fgets(input
->buffer
, INPUT_BUFFER_SIZE
, input
->fin
) == NULL
)
187 input
->buffer
[0] = '\0';
189 if (ferror(input
->fin
))
192 *line
= input
->buffer
;
193 } else if (input
->str
!= NULL
) {
194 /* Reading from a string constant. */
200 while (*sp
!= '\n' && *sp
!= '\0' &&
201 cnt
< INPUT_BUFFER_SIZE
- 2) {
205 /* Advance to start of next line. */
211 *line
= input
->buffer
;
213 /* Interactive mode */
214 if (input
->line_no
== 0)
220 if (os_input_line(prompt
, &line_p
) != EOK
)
230 /** Get number of the last provided line of input.
232 * @param input Input object.
233 * @return Line number of the last provided input line (counting
236 int input_get_line_no(input_t
*input
)
238 return input
->line_no
;