source: mainline/uspace/app/sbi/src/input.c@ 6c39a907

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 6c39a907 was 074444f, checked in by Jiri Svoboda <jiri@…>, 15 years ago

Update SBI to rev. 184.

  • Property mode set to 100644
File size: 6.0 KB
Line 
1/*
2 * Copyright (c) 2010 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
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.
16 *
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.
27 */
28
29/** @file Input module
30 *
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
33 * from the user.
34 */
35
36#include <stdio.h>
37#include <stdlib.h>
38#include "mytypes.h"
39#include "os/os.h"
40#include "strtab.h"
41
42#include "input.h"
43
44/** Size of input buffer. XXX This limits the maximum line length. */
45#define INPUT_BUFFER_SIZE 256
46
47static int input_init_file(input_t *input, const char *fname);
48static void input_init_interactive(input_t *input);
49static void input_init_string(input_t *input, const char *str);
50
51/** Create new input object for reading from file.
52 *
53 * @param input Place to store pointer to new input object.
54 * @param fname Name of file to read from.
55 *
56 * @return EOK on success, ENOMEM when allocation fails,
57 * ENOENT when opening file fails.
58 */
59int input_new_file(input_t **input, const char *fname)
60{
61 *input = malloc(sizeof(input_t));
62 if (*input == NULL)
63 return ENOMEM;
64
65 return input_init_file(*input, fname);
66}
67
68/** Create new input object for reading from interactive input.
69 *
70 * @param input Place to store pointer to new input object.
71 * @return EOK on success, ENOMEM when allocation fails.
72 */
73int input_new_interactive(input_t **input)
74{
75 *input = malloc(sizeof(input_t));
76 if (*input == NULL)
77 return ENOMEM;
78
79 input_init_interactive(*input);
80 return EOK;
81}
82
83/** Create new input object for reading from string.
84 *
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.
88 */
89int input_new_string(input_t **input, const char *str)
90{
91 *input = malloc(sizeof(input_t));
92 if (*input == NULL)
93 return ENOMEM;
94
95 input_init_string(*input, str);
96 return EOK;
97}
98
99/** Initialize input object for reading from file.
100 *
101 * @param input Input object.
102 * @param fname Name of file to read from.
103 *
104 * @return EOK on success, ENOENT when opening file fails.
105*/
106static int input_init_file(input_t *input, const char *fname)
107{
108 FILE *f;
109
110 f = fopen(fname, "rt");
111 if (f == NULL)
112 return ENOENT;
113
114 input->buffer = malloc(INPUT_BUFFER_SIZE);
115 if (input->buffer == NULL) {
116 printf("Memory allocation failed.\n");
117 exit(1);
118 }
119
120 input->str = NULL;
121 input->line_no = 0;
122 input->fin = f;
123 return EOK;
124}
125
126/** Initialize input object for reading from interactive input.
127 *
128 * @param input Input object.
129 */
130static void input_init_interactive(input_t *input)
131{
132 input->buffer = malloc(INPUT_BUFFER_SIZE);
133 if (input->buffer == NULL) {
134 printf("Memory allocation failed.\n");
135 exit(1);
136 }
137
138 input->str = NULL;
139 input->line_no = 0;
140 input->fin = NULL;
141}
142
143/** Initialize input object for reading from string.
144 *
145 * @param input Input object.
146 * @param str String literal from which to read input.
147 */
148static void input_init_string(input_t *input, const char *str)
149{
150 input->buffer = malloc(INPUT_BUFFER_SIZE);
151 if (input->buffer == NULL) {
152 printf("Memory allocation failed.\n");
153 exit(1);
154 }
155
156 input->str = str;
157 input->line_no = 0;
158 input->fin = NULL;
159}
160
161/** Get next line of input.
162 *
163 * The pointer stored in @a line is owned by @a input and is valid until the
164 * next call to input_get_line(). The caller is not to free it. The returned
165 * line is terminated with '\n' if another line is coming (potentially empty).
166 * An empty line ("") signals end of input.
167 *
168 * @param input Input object.
169 * @param line Place to store pointer to next line.
170 *
171 * @return EOK on success, EIO on failure.
172 */
173int input_get_line(input_t *input, char **line)
174{
175 const char *sp;
176 char *dp;
177 char *line_p;
178 size_t cnt;
179
180 if (input->fin != NULL) {
181 /* Reading from file. */
182 if (fgets(input->buffer, INPUT_BUFFER_SIZE, input->fin) == NULL)
183 input->buffer[0] = '\0';
184
185 if (ferror(input->fin))
186 return EIO;
187
188 *line = input->buffer;
189 } else if (input->str != NULL) {
190 /* Reading from a string constant. */
191
192 /* Copy one line. */
193 sp = input->str;
194 dp = input->buffer;
195 cnt = 0;
196 while (*sp != '\n' && *sp != '\0' &&
197 cnt < INPUT_BUFFER_SIZE - 2) {
198 *dp++ = *sp++;
199 }
200
201 /* Advance to start of next line. */
202 if (*sp == '\n')
203 *dp++ = *sp++;
204
205 *dp++ = '\0';
206 input->str = sp;
207 *line = input->buffer;
208 } else {
209 /* Interactive mode */
210 if (input->line_no == 0)
211 printf("sbi> ");
212 else
213 printf("... ");
214
215 fflush(stdout);
216 if (os_input_line(&line_p) != EOK)
217 return EIO;
218
219 *line = line_p;
220 }
221
222 ++input->line_no;
223 return EOK;
224}
225
226/** Get number of the last provided line of input.
227 *
228 * @param input Input module.
229 * @return Line number of the last provided input line (counting
230 * from 1 up).
231 */
232int input_get_line_no(input_t *input)
233{
234 return input->line_no;
235}
Note: See TracBrowser for help on using the repository browser.