source: mainline/uspace/lib/clui/nchoice.c@ 959b7ec

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 959b7ec was b7fd2a0, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

Use errno_t in all uspace and kernel code.

Change type of every variable, parameter and return value that holds an
<errno.h> constant to either errno_t (the usual case), or sys_errno_t
(some places in kernel). This is for the purpose of self-documentation,
as well as for type-checking with a bit of type definition hackery.

Although this is a massive commit, it is a simple text replacement, and thus
is very easy to verify. Simply do the following:

`
git checkout <this commit's hash>
git reset HEAD
git add .
tools/srepl '\berrno_t\b' int
git add .
tools/srepl '\bsys_errno_t\b' sysarg_t
git reset
git diff
`

While this doesn't ensure that the replacements are correct, it does ensure
that the commit doesn't do anything except those replacements. Since errno_t
is typedef'd to int in the usual case (and sys_errno_t to sysarg_t), even if
incorrect, this commit cannot change behavior.

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 * Copyright (c) 2015 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/** @addtogroup libclui
29 * @{
30 */
31/**
32 * @file Numerical choice
33 */
34
35#include <errno.h>
36#include <nchoice.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <str.h>
40#include <tinput.h>
41
42/** Create numerical choice
43 *
44 */
45errno_t nchoice_create(nchoice_t **rchoice)
46{
47 nchoice_t *choice = NULL;
48 errno_t rc;
49
50 choice = calloc(1, sizeof(nchoice_t));
51 if (choice == NULL)
52 goto error;
53
54 list_initialize(&choice->opts);
55
56 choice->tinput = tinput_new();
57 if (choice->tinput == NULL)
58 goto error;
59
60 rc = tinput_set_prompt(choice->tinput, "Choice> ");
61 if (rc != EOK) {
62 assert(rc == ENOMEM);
63 goto error;
64 }
65
66 *rchoice = choice;
67 return EOK;
68error:
69 nchoice_destroy(choice);
70 return ENOMEM;
71}
72
73/** Destroy numerical choice */
74void nchoice_destroy(nchoice_t *choice)
75{
76 if (choice == NULL)
77 return;
78
79 tinput_destroy(choice->tinput);
80 free(choice);
81}
82
83/** Set numerica choice prompt text */
84errno_t nchoice_set_prompt(nchoice_t *choice, const char *prompt)
85{
86 char *pstr;
87
88 pstr = str_dup(prompt);
89 if (pstr == NULL)
90 return ENOMEM;
91
92 free(choice->prompt);
93 choice->prompt = pstr;
94 return EOK;
95}
96
97/** Add option to numerical choice */
98errno_t nchoice_add(nchoice_t *choice, const char *opttext, void *arg,
99 nchoice_flag_t flags)
100{
101 nchoice_opt_t *opt;
102 char *ptext;
103
104 opt = calloc(1, sizeof(nchoice_opt_t));
105 if (opt == NULL)
106 return ENOMEM;
107
108 ptext = str_dup(opttext);
109 if (ptext == NULL) {
110 free(opt);
111 return ENOMEM;
112 }
113
114 opt->text = ptext;
115 opt->arg = arg;
116 list_append(&opt->lchoice, &choice->opts);
117
118 if ((flags & ncf_default) != 0) {
119 /* Set this option as the default */
120 assert(choice->def_opt == NULL);
121
122 choice->def_opt = opt;
123 }
124
125 return EOK;
126}
127
128/** Get numerical choice from user */
129errno_t nchoice_get(nchoice_t *choice, void **rarg)
130{
131 int i;
132 errno_t rc;
133 int ret;
134 char *str;
135 unsigned long c;
136 char *eptr;
137 char *istr;
138 int def_i;
139
140again:
141 printf("%s\n", choice->prompt);
142
143 def_i = 0;
144 i = 1;
145 list_foreach(choice->opts, lchoice, nchoice_opt_t, opt) {
146 printf("%d: %s%s\n", i, opt->text, opt == choice->def_opt ?
147 " [default]" : "");
148 if (opt == choice->def_opt)
149 def_i = i;
150 ++i;
151 }
152
153 if (def_i > 0) {
154 ret = asprintf(&istr, "%d", def_i);
155 if (ret < 0)
156 return ENOMEM;
157 } else {
158 istr = str_dup("");
159 if (istr == NULL)
160 return ENOMEM;
161 }
162
163 rc = tinput_read_i(choice->tinput, istr, &str);
164 free(istr);
165
166 if (rc != EOK) {
167 assert(rc == EIO || rc == ENOENT);
168
169 if (rc == ENOENT) {
170 return ENOENT;
171 } else {
172 /* rc == EIO */
173 return EIO;
174 }
175 }
176
177 c = strtoul(str, &eptr, 10);
178 if (*eptr != '\0' || c < 1 || c > (unsigned long)i - 1) {
179 printf("Invalid choice. Try again.\n");
180 free(str);
181 goto again;
182 }
183
184 free(str);
185
186 i = 1;
187 list_foreach(choice->opts, lchoice, nchoice_opt_t, opt) {
188 if ((unsigned long)i == c) {
189 *rarg = opt->arg;
190 return EOK;
191 }
192 ++i;
193 }
194
195 assert(false);
196 return ENOENT;
197}
198
199/** @}
200 */
Note: See TracBrowser for help on using the repository browser.