MBED port of https://github.com/ys1382/filagree . The only change is adding #define MBED
util.c@0:1a89e28dea91, 2012-05-30 (annotated)
- Committer:
- yusufx
- Date:
- Wed May 30 21:13:01 2012 +0000
- Revision:
- 0:1a89e28dea91
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yusufx | 0:1a89e28dea91 | 1 | #include "struct.h" |
yusufx | 0:1a89e28dea91 | 2 | #include "util.h" |
yusufx | 0:1a89e28dea91 | 3 | #include <string.h> |
yusufx | 0:1a89e28dea91 | 4 | #include <stdarg.h> |
yusufx | 0:1a89e28dea91 | 5 | |
yusufx | 0:1a89e28dea91 | 6 | #ifdef ANDROID |
yusufx | 0:1a89e28dea91 | 7 | #include <android/log.h> |
yusufx | 0:1a89e28dea91 | 8 | #define TAG "filagree" |
yusufx | 0:1a89e28dea91 | 9 | #endif |
yusufx | 0:1a89e28dea91 | 10 | |
yusufx | 0:1a89e28dea91 | 11 | #ifdef MBED |
yusufx | 0:1a89e28dea91 | 12 | |
yusufx | 0:1a89e28dea91 | 13 | #include "mbed.h" |
yusufx | 0:1a89e28dea91 | 14 | |
yusufx | 0:1a89e28dea91 | 15 | static Serial usbTxRx(USBTX, USBRX); |
yusufx | 0:1a89e28dea91 | 16 | |
yusufx | 0:1a89e28dea91 | 17 | size_t strnlen(char *s, size_t maxlen) |
yusufx | 0:1a89e28dea91 | 18 | { |
yusufx | 0:1a89e28dea91 | 19 | size_t i; |
yusufx | 0:1a89e28dea91 | 20 | for (i= 0; i<maxlen && *s; i++, s++); |
yusufx | 0:1a89e28dea91 | 21 | return i; |
yusufx | 0:1a89e28dea91 | 22 | } |
yusufx | 0:1a89e28dea91 | 23 | |
yusufx | 0:1a89e28dea91 | 24 | char *strnstr(const char *s, const char *find, size_t slen) |
yusufx | 0:1a89e28dea91 | 25 | { |
yusufx | 0:1a89e28dea91 | 26 | char c, sc; |
yusufx | 0:1a89e28dea91 | 27 | size_t len; |
yusufx | 0:1a89e28dea91 | 28 | |
yusufx | 0:1a89e28dea91 | 29 | if ((c = *find++) != '\0') { |
yusufx | 0:1a89e28dea91 | 30 | len = strlen(find); |
yusufx | 0:1a89e28dea91 | 31 | do { |
yusufx | 0:1a89e28dea91 | 32 | do { |
yusufx | 0:1a89e28dea91 | 33 | if (slen-- < 1 || (sc = *s++) == '\0') |
yusufx | 0:1a89e28dea91 | 34 | return (NULL); |
yusufx | 0:1a89e28dea91 | 35 | } while (sc != c); |
yusufx | 0:1a89e28dea91 | 36 | if (len > slen) |
yusufx | 0:1a89e28dea91 | 37 | return (NULL); |
yusufx | 0:1a89e28dea91 | 38 | } while (strncmp(s, find, len) != 0); |
yusufx | 0:1a89e28dea91 | 39 | s--; |
yusufx | 0:1a89e28dea91 | 40 | } |
yusufx | 0:1a89e28dea91 | 41 | return ((char *)s); |
yusufx | 0:1a89e28dea91 | 42 | } |
yusufx | 0:1a89e28dea91 | 43 | |
yusufx | 0:1a89e28dea91 | 44 | #endif // MBED |
yusufx | 0:1a89e28dea91 | 45 | |
yusufx | 0:1a89e28dea91 | 46 | |
yusufx | 0:1a89e28dea91 | 47 | #define MESSAGE_MAX 100 |
yusufx | 0:1a89e28dea91 | 48 | |
yusufx | 0:1a89e28dea91 | 49 | void log_print(const char *format, ...) |
yusufx | 0:1a89e28dea91 | 50 | { |
yusufx | 0:1a89e28dea91 | 51 | static char log_message[MESSAGE_MAX+1] = ""; |
yusufx | 0:1a89e28dea91 | 52 | char one_line[MESSAGE_MAX]; |
yusufx | 0:1a89e28dea91 | 53 | |
yusufx | 0:1a89e28dea91 | 54 | char *newline; |
yusufx | 0:1a89e28dea91 | 55 | va_list list; |
yusufx | 0:1a89e28dea91 | 56 | va_start(list, format); |
yusufx | 0:1a89e28dea91 | 57 | const char *message = make_message(format, list); |
yusufx | 0:1a89e28dea91 | 58 | va_end(list); |
yusufx | 0:1a89e28dea91 | 59 | size_t log_len = strnlen(log_message, MESSAGE_MAX); |
yusufx | 0:1a89e28dea91 | 60 | strncat(log_message, message, MESSAGE_MAX - log_len); |
yusufx | 0:1a89e28dea91 | 61 | log_len = strnlen(log_message, MESSAGE_MAX); |
yusufx | 0:1a89e28dea91 | 62 | if (log_len == MESSAGE_MAX) |
yusufx | 0:1a89e28dea91 | 63 | log_message[MESSAGE_MAX-1] = '\n'; |
yusufx | 0:1a89e28dea91 | 64 | if (!(newline = strnstr(log_message, "\n", MESSAGE_MAX))) |
yusufx | 0:1a89e28dea91 | 65 | return; |
yusufx | 0:1a89e28dea91 | 66 | size_t line_len = newline - log_message; |
yusufx | 0:1a89e28dea91 | 67 | memcpy(one_line, log_message, line_len); |
yusufx | 0:1a89e28dea91 | 68 | one_line[line_len] = 0; |
yusufx | 0:1a89e28dea91 | 69 | |
yusufx | 0:1a89e28dea91 | 70 | #ifdef ANDROID |
yusufx | 0:1a89e28dea91 | 71 | __android_log_write(ANDROID_LOG_ERROR, TAG, one_line); |
yusufx | 0:1a89e28dea91 | 72 | #elifdef IOS |
yusufx | 0:1a89e28dea91 | 73 | NSLog(@"%s", one_line); |
yusufx | 0:1a89e28dea91 | 74 | #elifdef MBED |
yusufx | 0:1a89e28dea91 | 75 | usbTxRx.printf("%s\n", one_line); |
yusufx | 0:1a89e28dea91 | 76 | #else |
yusufx | 0:1a89e28dea91 | 77 | printf("%s\n", one_line); |
yusufx | 0:1a89e28dea91 | 78 | #endif |
yusufx | 0:1a89e28dea91 | 79 | |
yusufx | 0:1a89e28dea91 | 80 | memmove(log_message, newline+1, log_len-line_len); |
yusufx | 0:1a89e28dea91 | 81 | } |
yusufx | 0:1a89e28dea91 | 82 | |
yusufx | 0:1a89e28dea91 | 83 | const char *make_message(const char *format, va_list ap) |
yusufx | 0:1a89e28dea91 | 84 | { |
yusufx | 0:1a89e28dea91 | 85 | static char message[MESSAGE_MAX]; |
yusufx | 0:1a89e28dea91 | 86 | vsnprintf(message, MESSAGE_MAX, format, ap); |
yusufx | 0:1a89e28dea91 | 87 | return message; |
yusufx | 0:1a89e28dea91 | 88 | } |
yusufx | 0:1a89e28dea91 | 89 | |
yusufx | 0:1a89e28dea91 | 90 | void exit_message2(const char *format, va_list list) |
yusufx | 0:1a89e28dea91 | 91 | { |
yusufx | 0:1a89e28dea91 | 92 | const char *message = make_message(format, list); |
yusufx | 0:1a89e28dea91 | 93 | log_print("%s\n", message); |
yusufx | 0:1a89e28dea91 | 94 | va_end(list); |
yusufx | 0:1a89e28dea91 | 95 | exit(1); |
yusufx | 0:1a89e28dea91 | 96 | } |
yusufx | 0:1a89e28dea91 | 97 | |
yusufx | 0:1a89e28dea91 | 98 | void assert_message(bool assertion, const char *format, ...) |
yusufx | 0:1a89e28dea91 | 99 | { |
yusufx | 0:1a89e28dea91 | 100 | if (assertion) |
yusufx | 0:1a89e28dea91 | 101 | return; |
yusufx | 0:1a89e28dea91 | 102 | va_list list; |
yusufx | 0:1a89e28dea91 | 103 | va_start(list, format); |
yusufx | 0:1a89e28dea91 | 104 | exit_message2(format, list); |
yusufx | 0:1a89e28dea91 | 105 | } |
yusufx | 0:1a89e28dea91 | 106 | |
yusufx | 0:1a89e28dea91 | 107 | void *exit_message(const char *format, ...) |
yusufx | 0:1a89e28dea91 | 108 | { |
yusufx | 0:1a89e28dea91 | 109 | va_list list; |
yusufx | 0:1a89e28dea91 | 110 | va_start(list, format); |
yusufx | 0:1a89e28dea91 | 111 | exit_message2(format, list); |
yusufx | 0:1a89e28dea91 | 112 | return NULL; |
yusufx | 0:1a89e28dea91 | 113 | } |
yusufx | 0:1a89e28dea91 | 114 | |
yusufx | 0:1a89e28dea91 | 115 | void null_check(const void *pointer) { |
yusufx | 0:1a89e28dea91 | 116 | if (!pointer) |
yusufx | 0:1a89e28dea91 | 117 | exit_message("null pointer"); |
yusufx | 0:1a89e28dea91 | 118 | } |
yusufx | 0:1a89e28dea91 | 119 | |
yusufx | 0:1a89e28dea91 | 120 | const char* num_to_string(const struct number_string *ns, int num_items, int num) |
yusufx | 0:1a89e28dea91 | 121 | { |
yusufx | 0:1a89e28dea91 | 122 | for (int i=0; i<num_items; i++) // reverse lookup nonterminal string |
yusufx | 0:1a89e28dea91 | 123 | if (num == ns[i].number) |
yusufx | 0:1a89e28dea91 | 124 | return ns[i].chars; |
yusufx | 0:1a89e28dea91 | 125 | exit_message("num not found"); |
yusufx | 0:1a89e28dea91 | 126 | return NULL; |
yusufx | 0:1a89e28dea91 | 127 | } |
yusufx | 0:1a89e28dea91 | 128 | |
yusufx | 0:1a89e28dea91 | 129 | // file |
yusufx | 0:1a89e28dea91 | 130 | |
yusufx | 0:1a89e28dea91 | 131 | #define INPUT_MAX_LEN 10000 |
yusufx | 0:1a89e28dea91 | 132 | #define ERROR_BIG "Input file is too big" |
yusufx | 0:1a89e28dea91 | 133 | |
yusufx | 0:1a89e28dea91 | 134 | |
yusufx | 0:1a89e28dea91 | 135 | long fsize(FILE* file) { |
yusufx | 0:1a89e28dea91 | 136 | if (!fseek(file, 0, SEEK_END)) { |
yusufx | 0:1a89e28dea91 | 137 | long size = ftell(file); |
yusufx | 0:1a89e28dea91 | 138 | if (size >= 0 && !fseek(file, 0, SEEK_SET)) |
yusufx | 0:1a89e28dea91 | 139 | return size; |
yusufx | 0:1a89e28dea91 | 140 | } |
yusufx | 0:1a89e28dea91 | 141 | return -1; |
yusufx | 0:1a89e28dea91 | 142 | } |
yusufx | 0:1a89e28dea91 | 143 | |
yusufx | 0:1a89e28dea91 | 144 | struct byte_array *read_file(const struct byte_array *filename_ba) |
yusufx | 0:1a89e28dea91 | 145 | { |
yusufx | 0:1a89e28dea91 | 146 | FILE * file; |
yusufx | 0:1a89e28dea91 | 147 | size_t read; |
yusufx | 0:1a89e28dea91 | 148 | uint8_t *str; |
yusufx | 0:1a89e28dea91 | 149 | long size; |
yusufx | 0:1a89e28dea91 | 150 | |
yusufx | 0:1a89e28dea91 | 151 | const char* filename_str = byte_array_to_string(filename_ba); |
yusufx | 0:1a89e28dea91 | 152 | |
yusufx | 0:1a89e28dea91 | 153 | if (!(file = fopen(filename_str, "rb"))) |
yusufx | 0:1a89e28dea91 | 154 | exit_message(ERROR_FOPEN); |
yusufx | 0:1a89e28dea91 | 155 | if ((size = fsize(file)) < 0) |
yusufx | 0:1a89e28dea91 | 156 | exit_message(ERROR_FSIZE); |
yusufx | 0:1a89e28dea91 | 157 | else if (size > INPUT_MAX_LEN) |
yusufx | 0:1a89e28dea91 | 158 | exit_message(ERROR_BIG); |
yusufx | 0:1a89e28dea91 | 159 | if (!(str = (uint8_t*)malloc((size_t)size)))// + 1))) |
yusufx | 0:1a89e28dea91 | 160 | exit_message(ERROR_ALLOC); |
yusufx | 0:1a89e28dea91 | 161 | |
yusufx | 0:1a89e28dea91 | 162 | read = fread(str, 1, (size_t)size, file); |
yusufx | 0:1a89e28dea91 | 163 | if (feof(file) || ferror(file)) |
yusufx | 0:1a89e28dea91 | 164 | exit_message(ERROR_FREAD); |
yusufx | 0:1a89e28dea91 | 165 | |
yusufx | 0:1a89e28dea91 | 166 | if (fclose(file)) |
yusufx | 0:1a89e28dea91 | 167 | exit_message(ERROR_FCLOSE); |
yusufx | 0:1a89e28dea91 | 168 | |
yusufx | 0:1a89e28dea91 | 169 | struct byte_array* ba = byte_array_new_size(read); |
yusufx | 0:1a89e28dea91 | 170 | ba->data = str; |
yusufx | 0:1a89e28dea91 | 171 | byte_array_reset(ba); |
yusufx | 0:1a89e28dea91 | 172 | return ba; |
yusufx | 0:1a89e28dea91 | 173 | } |
yusufx | 0:1a89e28dea91 | 174 | |
yusufx | 0:1a89e28dea91 | 175 | int write_byte_array(struct byte_array* ba, FILE* file) { |
yusufx | 0:1a89e28dea91 | 176 | uint16_t len = ba->length; |
yusufx | 0:1a89e28dea91 | 177 | int n = fwrite(ba->data, 1, len, file); |
yusufx | 0:1a89e28dea91 | 178 | return len - n; |
yusufx | 0:1a89e28dea91 | 179 | } |
yusufx | 0:1a89e28dea91 | 180 | |
yusufx | 0:1a89e28dea91 | 181 | int write_file(const struct byte_array* filename, struct byte_array* bytes) |
yusufx | 0:1a89e28dea91 | 182 | { |
yusufx | 0:1a89e28dea91 | 183 | const char *fname = byte_array_to_string(filename); |
yusufx | 0:1a89e28dea91 | 184 | FILE* file = fopen(fname, "w"); |
yusufx | 0:1a89e28dea91 | 185 | if (!file) { |
yusufx | 0:1a89e28dea91 | 186 | DEBUGPRINT("could not open file %s\n", fname); |
yusufx | 0:1a89e28dea91 | 187 | return -1; |
yusufx | 0:1a89e28dea91 | 188 | } |
yusufx | 0:1a89e28dea91 | 189 | |
yusufx | 0:1a89e28dea91 | 190 | int r = fwrite(bytes->data, 1, bytes->length, file); |
yusufx | 0:1a89e28dea91 | 191 | DEBUGPRINT("\twrote %d bytes\n", r); |
yusufx | 0:1a89e28dea91 | 192 | int s = fclose(file); |
yusufx | 0:1a89e28dea91 | 193 | return (r<0) || s; |
yusufx | 0:1a89e28dea91 | 194 | } |
yusufx | 0:1a89e28dea91 | 195 | |
yusufx | 0:1a89e28dea91 | 196 | char* build_path(const char* dir, const char* name) |
yusufx | 0:1a89e28dea91 | 197 | { |
yusufx | 0:1a89e28dea91 | 198 | int dirlen = dir ? strlen(dir) : 0; |
yusufx | 0:1a89e28dea91 | 199 | char* path = (char*)malloc(dirlen + 1 + strlen(name)); |
yusufx | 0:1a89e28dea91 | 200 | const char* slash = (dir && dirlen && (dir[dirlen] != '/')) ? "/" : ""; |
yusufx | 0:1a89e28dea91 | 201 | sprintf(path, "%s%s%s", dir ? dir : "", slash, name); |
yusufx | 0:1a89e28dea91 | 202 | return path; |
yusufx | 0:1a89e28dea91 | 203 | } |