]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - libxcmd/input.c
libfrog: move conversion factors out of libxcmd
[thirdparty/xfsprogs-dev.git] / libxcmd / input.c
1 /*
2 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "platform_defs.h"
20 #include "input.h"
21 #include <ctype.h>
22 #include <stdbool.h>
23
24 #if defined(ENABLE_READLINE)
25 # include <readline/history.h>
26 # include <readline/readline.h>
27 #elif defined(ENABLE_EDITLINE)
28 # include <histedit.h>
29 #endif
30
31 extern char *progname;
32
33 static char *
34 get_prompt(void)
35 {
36 static char prompt[FILENAME_MAX + 2 /*"> "*/ + 1 /*"\0"*/ ];
37
38 if (!prompt[0])
39 snprintf(prompt, sizeof(prompt), "%s> ", progname);
40 return prompt;
41 }
42
43 #if defined(ENABLE_READLINE)
44 char *
45 fetchline(void)
46 {
47 char *line;
48
49 line = readline(get_prompt());
50 if (line && *line)
51 add_history(line);
52 return line;
53 }
54 #elif defined(ENABLE_EDITLINE)
55 static char *el_get_prompt(EditLine *e) { return get_prompt(); }
56 char *
57 fetchline(void)
58 {
59 static EditLine *el;
60 static History *hist;
61 HistEvent hevent;
62 char *line;
63 int count;
64
65 if (!el) {
66 hist = history_init();
67 history(hist, &hevent, H_SETSIZE, 100);
68 el = el_init(progname, stdin, stdout, stderr);
69 el_source(el, NULL);
70 el_set(el, EL_SIGNAL, 1);
71 el_set(el, EL_PROMPT, el_get_prompt);
72 el_set(el, EL_HIST, history, (const char *)hist);
73 }
74 line = strdup(el_gets(el, &count));
75 if (line) {
76 if (count > 0)
77 line[count-1] = '\0';
78 if (*line)
79 history(hist, &hevent, H_ENTER, line);
80 }
81 return line;
82 }
83 #else
84 # define MAXREADLINESZ 1024
85 char *
86 fetchline(void)
87 {
88 char *p, *line = malloc(MAXREADLINESZ);
89
90 if (!line)
91 return NULL;
92 printf("%s", get_prompt());
93 fflush(stdout);
94 if (!fgets(line, MAXREADLINESZ, stdin)) {
95 free(line);
96 return NULL;
97 }
98 p = line + strlen(line);
99 if (p != line && p[-1] == '\n')
100 p[-1] = '\0';
101 return line;
102 }
103 #endif
104
105 char **
106 breakline(
107 char *input,
108 int *count)
109 {
110 int c = 0;
111 char *p;
112 char **rval = calloc(sizeof(char *), 1);
113
114 while (rval && (p = strsep(&input, " ")) != NULL) {
115 if (!*p)
116 continue;
117 c++;
118 rval = realloc(rval, sizeof(*rval) * (c + 1));
119 if (!rval) {
120 c = 0;
121 break;
122 }
123 rval[c - 1] = p;
124 rval[c] = NULL;
125 }
126 *count = c;
127 return rval;
128 }
129
130 void
131 doneline(
132 char *input,
133 char **vec)
134 {
135 free(input);
136 free(vec);
137 }
138
139 struct timeval
140 tsub(struct timeval t1, struct timeval t2)
141 {
142 t1.tv_usec -= t2.tv_usec;
143 if (t1.tv_usec < 0) {
144 t1.tv_usec += 1000000;
145 t1.tv_sec--;
146 }
147 t1.tv_sec -= t2.tv_sec;
148 return t1;
149 }
150
151 double
152 tdiv(double value, struct timeval tv)
153 {
154 return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
155 }
156
157 #define HOURS(sec) ((sec) / (60 * 60))
158 #define MINUTES(sec) (((sec) % (60 * 60)) / 60)
159 #define SECONDS(sec) ((sec) % 60)
160
161 void
162 timestr(
163 struct timeval *tv,
164 char *ts,
165 size_t size,
166 int format)
167 {
168 double usec = (double)tv->tv_usec / 1000000.0;
169
170 if (format & TERSE_FIXED_TIME) {
171 if (!HOURS(tv->tv_sec)) {
172 snprintf(ts, size, "%u:%02u.%02u",
173 (unsigned int) MINUTES(tv->tv_sec),
174 (unsigned int) SECONDS(tv->tv_sec),
175 (unsigned int) usec * 100);
176 return;
177 }
178 format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */
179 }
180
181 if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
182 snprintf(ts, size, "%u:%02u:%02u.%02u",
183 (unsigned int) HOURS(tv->tv_sec),
184 (unsigned int) MINUTES(tv->tv_sec),
185 (unsigned int) SECONDS(tv->tv_sec),
186 (unsigned int) usec * 100);
187 } else {
188 snprintf(ts, size, "0.%04u sec", (unsigned int) usec * 10000);
189 }
190 }
191
192 /*
193 * Convert from a pair of arbitrary user strings into a timespec.
194 */
195
196 int
197 timespec_from_string(
198 const char * secs,
199 const char * nsecs,
200 struct timespec * ts)
201 {
202 char* p;
203 if (!secs || !nsecs || !ts)
204 return 1;
205 ts->tv_sec = strtoull(secs, &p, 0);
206 if (*p)
207 return 1;
208 ts->tv_nsec = strtoull(nsecs, &p, 0);
209 if (*p)
210 return 1;
211 return 0;
212 }
213
214 bool isdigits_only(
215 const char *str)
216 {
217 int i;
218
219 for (i = 0; i < strlen(str); i++) {
220 if (!isdigit(str[i]))
221 return false;
222 }
223 return true;
224 }
225
226 #define HAVE_FTW_H 1 /* TODO: configure me */
227
228 #ifndef HAVE_FTW_H
229 int
230 nftw(
231 char *dir,
232 int (*fn)(const char *, const struct stat *, int, struct FTW *),
233 int depth,
234 int flags)
235 {
236 fprintf(stderr, "%s: not implemented, no recursion available\n",
237 __FUNCTION__);
238 return 0;
239 }
240 #endif