2 * edit.c edit string to ascii, and ascii to internal
4 * Kern Sibbald, December MMII
10 Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of
15 the License, or (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public
23 License along with this program; if not, write to the Free
24 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
31 /* We assume ASCII input and don't worry about overflow */
32 uint64_t str_to_uint64(char *str)
34 register char *p = str;
35 register uint64_t value = 0;
37 while (B_ISSPACE(*p)) {
43 while (B_ISDIGIT(*p)) {
44 value = value * 10 + *p - '0';
50 int64_t str_to_int64(char *str)
52 register char *p = str;
53 register int64_t value;
56 while (B_ISSPACE(*p)) {
61 } else if (*p == '-') {
65 value = str_to_uint64(p);
75 * Edit an integer number with commas, the supplied buffer
76 * must be at least 27 bytes long. The incoming number
77 * is always widened to 64 bits.
79 char *edit_uint64_with_commas(uint64_t val, char *buf)
81 sprintf(buf, "%" lld, val);
82 return add_commas(buf, buf);
86 * Edit an integer number, the supplied buffer
87 * must be at least 27 bytes long. The incoming number
88 * is always widened to 64 bits.
90 char *edit_uint64(uint64_t val, char *buf)
92 sprintf(buf, "%" lld, val);
98 * Convert a string duration to utime_t (64 bit seconds)
100 1: if OK, and value stored in value
102 int duration_to_utime(char *str, utime_t *value)
106 static int mod[] = {'*', 's', 'n', 'h', 'd', 'w', 'm', 'q', 'y', 0};
107 static int mult[] = {1, 1, 60, 60*60, 60*60*24, 60*60*24*7, 60*60*24*30,
108 60*60*24*91, 60*60*24*365};
110 /* Look for modifier */
118 while (mod[++i] != 0) {
121 str[len] = 0; /* strip modifier */
126 if (mod[i] == 0 || !is_a_number(str)) {
129 val = strtod(str, NULL);
130 if (errno != 0 || val < 0) {
133 *value = (utime_t)(val * mult[i]);
139 * Edit a utime "duration" into ASCII
141 char *edit_utime(utime_t val, char *buf)
144 static int mult[] = {60*60*24*365, 60*60*24*30, 60*60*24, 60*60, 60};
145 static char *mod[] = {"year", "month", "day", "hour", "min"};
150 for (i=0; i<5; i++) {
151 times = val / mult[i];
153 val = val - (utime_t)times * mult[i];
154 sprintf(mybuf, "%d %s%s ", times, mod[i], times>1?"s":"");
158 if (val == 0 && strlen(buf) == 0) {
159 strcat(buf, "0 secs");
160 } else if (val != 0) {
161 sprintf(mybuf, "%d sec%s", (uint32_t)val, val>1?"s":"");
168 * Convert a size size in bytes to uint64_t
169 * Returns 0: if error
170 1: if OK, and value stored in value
172 int size_to_uint64(char *str, int str_len, uint64_t *rtn_value)
176 int mod[] = {'*', 'k', 'm', 'g', 0}; /* first item * not used */
177 uint64_t mult[] = {1, /* byte */
179 1048576, /* megabyte */
180 1073741824}; /* gigabyte */
182 #ifdef we_have_a_compiler_that_works
183 int mod[] = {'*', 'k', 'm', 'g', 't', 0};
184 uint64_t mult[] = {1, /* byte */
186 1048576, /* megabyte */
187 1073741824, /* gigabyte */
188 1099511627776};/* terabyte */
191 Dmsg0(400, "Enter sized to uint64\n");
193 /* Look for modifier */
194 ch = str[str_len - 1];
200 while (mod[++i] != 0) {
203 str[str_len] = 0; /* strip modifier */
208 if (mod[i] == 0 || !is_a_number(str)) {
211 Dmsg3(400, "size str=:%s: %f i=%d\n", str, strtod(str, NULL), i);
213 value = (uint64_t)strtod(str, NULL);
214 Dmsg1(400, "Int value = %d\n", (int)value);
215 if (errno != 0 || value < 0) {
218 *rtn_value = (uint64_t)(value * mult[i]);
219 Dmsg2(400, "Full value = %f %" lld "\n", strtod(str, NULL) * mult[i],
225 * Check if specified string is a number or not.
226 * Taken from SQLite, cool, thanks.
228 int is_a_number(const char *n)
232 if( *n == '-' || *n == '+' ) {
235 while (B_ISDIGIT(*n)) {
239 if (digit_seen && *n == '.') {
241 while (B_ISDIGIT(*n)) { n++; }
243 if (digit_seen && (*n == 'e' || *n == 'E')
244 && (B_ISDIGIT(n[1]) || ((n[1]=='-' || n[1] == '+') && B_ISDIGIT(n[2])))) {
245 n += 2; /* skip e- or e+ or e digit */
246 while (B_ISDIGIT(*n)) { n++; }
248 return digit_seen && *n==0;
252 * Add commas to a string, which is presumably
255 char *add_commas(char *val, char *buf)
273 for (i=0; i < 3; i++) {