// Start of util.h. // // Various helper functions that are useful in all generated C code. static const char *fut_progname = "(embedded Futhark)"; static void futhark_panic(int eval, const char *fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s: ", fut_progname); vfprintf(stderr, fmt, ap); va_end(ap); exit(eval); } // For generating arbitrary-sized error messages. It is the callers // responsibility to free the buffer at some point. static char* msgprintf(const char *s, ...) { va_list vl; va_start(vl, s); size_t needed = 1 + (size_t)vsnprintf(NULL, 0, s, vl); char *buffer = (char*) malloc(needed); va_start(vl, s); // Must re-init. vsnprintf(buffer, needed, s, vl); return buffer; } // Read a file into a NUL-terminated string; returns NULL on error. static void* slurp_file(const char *filename, size_t *size) { unsigned char *s; FILE *f = fopen(filename, "rb"); // To avoid Windows messing with linebreaks. if (f == NULL) return NULL; fseek(f, 0, SEEK_END); size_t src_size = ftell(f); fseek(f, 0, SEEK_SET); s = (unsigned char*) malloc(src_size + 1); if (fread(s, 1, src_size, f) != src_size) { free(s); s = NULL; } else { s[src_size] = '\0'; } fclose(f); if (size) { *size = src_size; } return s; } // Dump 'n' bytes from 'buf' into the file at the designated location. // Returns 0 on success. static int dump_file(const char *file, const void *buf, size_t n) { FILE *f = fopen(file, "w"); if (f == NULL) { return 1; } if (fwrite(buf, sizeof(char), n, f) != n) { return 1; } if (fclose(f) != 0) { return 1; } return 0; } struct str_builder { char *str; size_t capacity; // Size of buffer. size_t used; // Bytes used, *not* including final zero. }; static void str_builder_init(struct str_builder *b) { b->capacity = 10; b->used = 0; b->str = malloc(b->capacity); b->str[0] = 0; } static void str_builder(struct str_builder *b, const char *s, ...) { va_list vl; va_start(vl, s); size_t needed = (size_t)vsnprintf(NULL, 0, s, vl); while (b->capacity < b->used + needed + 1) { b->capacity *= 2; b->str = realloc(b->str, b->capacity); } va_start(vl, s); // Must re-init. vsnprintf(b->str+b->used, b->capacity-b->used, s, vl); b->used += needed; } // End of util.h.