1 /* 2 * Copyright (c) Artem Bityutskiy, 2007, 2008 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the 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 to the Free Software 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 /* Imported from mtd-utils by dehrenberg */ 20 21 #ifndef __MTD_UTILS_COMMON_H__ 22 #define __MTD_UTILS_COMMON_H__ 23 24 #include <stdbool.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <ctype.h> 28 #include <string.h> 29 #include <fcntl.h> 30 #include <errno.h> 31 #include <features.h> 32 #include <inttypes.h> 33 #include <sys/sysmacros.h> 34 35 #ifndef PROGRAM_NAME 36 # error "You must define PROGRAM_NAME before including this header" 37 #endif 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 #ifndef MIN /* some C lib headers define this for us */ 44 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 45 #endif 46 #ifndef MAX 47 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 48 #endif 49 #define min(a, b) MIN(a, b) /* glue for linux kernel source */ 50 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 51 52 #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) 53 #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) 54 55 #define min_t(t,x,y) ({ \ 56 typeof((x)) _x = (x); \ 57 typeof((y)) _y = (y); \ 58 (_x < _y) ? _x : _y; \ 59 }) 60 61 #define max_t(t,x,y) ({ \ 62 typeof((x)) _x = (x); \ 63 typeof((y)) _y = (y); \ 64 (_x > _y) ? _x : _y; \ 65 }) 66 67 #ifndef O_CLOEXEC 68 #define O_CLOEXEC 0 69 #endif 70 71 /* define a print format specifier for off_t */ 72 #ifdef __USE_FILE_OFFSET64 73 #define PRIxoff_t PRIx64 74 #define PRIdoff_t PRId64 75 #else 76 #define PRIxoff_t "l"PRIx32 77 #define PRIdoff_t "l"PRId32 78 #endif 79 80 /* Verbose messages */ 81 #define bareverbose(verbose, fmt, ...) do { \ 82 if (verbose) \ 83 printf(fmt, ##__VA_ARGS__); \ 84 } while(0) 85 #define verbose(verbose, fmt, ...) \ 86 bareverbose(verbose, "%s: " fmt "\n", PROGRAM_NAME, ##__VA_ARGS__) 87 88 /* Normal messages */ 89 #define normsg_cont(fmt, ...) do { \ 90 printf("%s: " fmt, PROGRAM_NAME, ##__VA_ARGS__); \ 91 } while(0) 92 #define normsg(fmt, ...) do { \ 93 normsg_cont(fmt "\n", ##__VA_ARGS__); \ 94 } while(0) 95 96 /* Error messages */ 97 #define errmsg(fmt, ...) ({ \ 98 fprintf(stderr, "%s: error!: " fmt "\n", PROGRAM_NAME, ##__VA_ARGS__); \ 99 -1; \ 100 }) 101 #define errmsg_die(fmt, ...) do { \ 102 exit(errmsg(fmt, ##__VA_ARGS__)); \ 103 } while(0) 104 105 /* System error messages */ 106 #define sys_errmsg(fmt, ...) ({ \ 107 int _err = errno; \ 108 errmsg(fmt, ##__VA_ARGS__); \ 109 fprintf(stderr, "%*serror %d (%s)\n", (int)sizeof(PROGRAM_NAME) + 1,\ 110 "", _err, strerror(_err)); \ 111 -1; \ 112 }) 113 #define sys_errmsg_die(fmt, ...) do { \ 114 exit(sys_errmsg(fmt, ##__VA_ARGS__)); \ 115 } while(0) 116 117 /* Warnings */ 118 #define warnmsg(fmt, ...) do { \ 119 fprintf(stderr, "%s: warning!: " fmt "\n", PROGRAM_NAME, ##__VA_ARGS__); \ 120 } while(0) 121 122 #if defined(__UCLIBC__) 123 /* uClibc versions before 0.9.34 don't have rpmatch() */ 124 #if __UCLIBC_MAJOR__ == 0 && \ 125 (__UCLIBC_MINOR__ < 9 || \ 126 (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ < 34)) 127 #undef rpmatch 128 #define rpmatch __rpmatch 129 static inline int __rpmatch(const char *resp) 130 { 131 return (resp[0] == 'y' || resp[0] == 'Y') ? 1 : 132 (resp[0] == 'n' || resp[0] == 'N') ? 0 : -1; 133 } 134 #endif 135 #endif 136 137 /** 138 * prompt the user for confirmation 139 */ 140 static inline bool prompt(const char *msg, bool def) 141 { 142 char *line = NULL; 143 size_t len; 144 bool ret = def; 145 146 do { 147 normsg_cont("%s (%c/%c) ", msg, def ? 'Y' : 'y', def ? 'n' : 'N'); 148 fflush(stdout); 149 150 while (getline(&line, &len, stdin) == -1) { 151 printf("failed to read prompt; assuming '%s'\n", 152 def ? "yes" : "no"); 153 break; 154 } 155 156 if (strcmp("\n", line) != 0) { 157 switch (rpmatch(line)) { 158 case 0: ret = false; break; 159 case 1: ret = true; break; 160 case -1: 161 puts("unknown response; please try again"); 162 continue; 163 } 164 } 165 break; 166 } while (1); 167 168 free(line); 169 170 return ret; 171 } 172 173 static inline int is_power_of_2(unsigned long long n) 174 { 175 return (n != 0 && ((n & (n - 1)) == 0)); 176 } 177 178 /** 179 * simple_strtoX - convert a hex/dec/oct string into a number 180 * @snum: buffer to convert 181 * @error: set to 1 when buffer isn't fully consumed 182 * 183 * These functions are similar to the standard strtoX() functions, but they are 184 * a little bit easier to use if you want to convert full string of digits into 185 * the binary form. The typical usage: 186 * 187 * int error = 0; 188 * unsigned long num; 189 * 190 * num = simple_strtoul(str, &error); 191 * if (error || ... if needed, your check that num is not out of range ...) 192 * error_happened(); 193 */ 194 #define simple_strtoX(func, type) \ 195 static inline type simple_##func(const char *snum, int *error) \ 196 { \ 197 char *endptr; \ 198 type ret = func(snum, &endptr, 0); \ 199 \ 200 if (error && (!*snum || *endptr)) { \ 201 errmsg("%s: unable to parse the number '%s'", #func, snum); \ 202 *error = 1; \ 203 } \ 204 \ 205 return ret; \ 206 } 207 simple_strtoX(strtol, long int) 208 simple_strtoX(strtoll, long long int) 209 simple_strtoX(strtoul, unsigned long int) 210 simple_strtoX(strtoull, unsigned long long int) 211 212 /* Simple version-printing for utils */ 213 #define common_print_version() \ 214 do { \ 215 printf("%s %s\n", PROGRAM_NAME, VERSION); \ 216 } while (0) 217 218 #include "libmtd_xalloc.h" 219 220 #ifdef __cplusplus 221 } 222 #endif 223 224 #endif /* !__MTD_UTILS_COMMON_H__ */ 225