aboutsummaryrefslogtreecommitdiff
path: root/flatcc/src/compiler/fileio.c
diff options
context:
space:
mode:
Diffstat (limited to 'flatcc/src/compiler/fileio.c')
-rw-r--r--flatcc/src/compiler/fileio.c225
1 files changed, 225 insertions, 0 deletions
diff --git a/flatcc/src/compiler/fileio.c b/flatcc/src/compiler/fileio.c
new file mode 100644
index 0000000..56d88c1
--- /dev/null
+++ b/flatcc/src/compiler/fileio.c
@@ -0,0 +1,225 @@
+#include <string.h>
+#include <stdio.h>
+
+/* Ensures portable headers are included such as inline. */
+#include "config.h"
+#include "fileio.h"
+#include "pstrutil.h"
+
+char *fb_copy_path_n(const char *path, size_t len)
+{
+ size_t n;
+ char *s;
+
+ n = strnlen(path, len);
+ if ((s = malloc(n + 1))) {
+ memcpy(s, path, n);
+ s[n] = '\0';
+ }
+ return s;
+}
+
+char *fb_copy_path(const char *path)
+{
+ size_t n;
+ char *s;
+
+ n = strlen(path);
+ if ((s = malloc(n + 1))) {
+ memcpy(s, path, n);
+ s[n] = '\0';
+ }
+ return s;
+}
+
+size_t fb_chomp(const char *path, size_t len, const char *ext)
+{
+ size_t ext_len = ext ? strlen(ext) : 0;
+ if (len > ext_len && 0 == strncmp(path + len - ext_len, ext, ext_len)) {
+ len -= ext_len;
+ }
+ return len;
+}
+
+char *fb_create_join_path_n(const char *prefix, size_t prefix_len,
+ const char *suffix, size_t suffix_len, const char *ext, int path_sep)
+{
+ char *path;
+ size_t ext_len = ext ? strlen(ext) : 0;
+ size_t n;
+
+ if (!prefix ||
+ (suffix_len > 0 && (suffix[0] == '/' || suffix[0] == '\\')) ||
+ (suffix_len > 1 && suffix[1] == ':')) {
+ prefix_len = 0;
+ }
+ if (path_sep && (prefix_len == 0 ||
+ (prefix[prefix_len - 1] == '/' || prefix[prefix_len - 1] == '\\'))) {
+ path_sep = 0;
+ }
+ path = malloc(prefix_len + !!path_sep + suffix_len + ext_len + 1);
+ if (!path) {
+ return 0;
+ }
+ n = 0;
+ if (prefix_len > 0) {
+ memcpy(path, prefix, prefix_len);
+ n += prefix_len;
+ }
+ if (path_sep) {
+ path[n++] = '/';
+ }
+ memcpy(path + n, suffix, suffix_len);
+ n += suffix_len;
+ memcpy(path + n, ext, ext_len);
+ n += ext_len;
+ path[n] = '\0';
+ return path;
+}
+
+char *fb_create_join_path(const char *prefix, const char *suffix, const char *ext, int path_sep)
+{
+ return fb_create_join_path_n(prefix, prefix ? strlen(prefix) : 0,
+ suffix, suffix ? strlen(suffix) : 0, ext, path_sep);
+}
+
+char *fb_create_path_ext_n(const char *path, size_t path_len, const char *ext)
+{
+ return fb_create_join_path_n(0, 0, path, path_len, ext, 0);
+}
+
+char *fb_create_path_ext(const char *path, const char *ext)
+{
+ return fb_create_join_path(0, path, ext, 0);
+}
+
+char *fb_create_make_path_n(const char *path, size_t len)
+{
+ size_t i, j, n;
+ char *s;
+
+ if (len == 1 && (path[0] == ' ' || path[0] == '\\')) {
+ if (!(s = malloc(3))) {
+ return 0;
+ }
+ s[0] = '\\';
+ s[1] = path[0];
+ s[2] = '\0';
+ return s;
+ }
+ if (len <= 1) {
+ return fb_copy_path_n(path, len);
+ }
+ for (i = 0, n = len; i < len - 1; ++i) {
+ if (path[i] == '\\' && path[i + 1] == ' ') {
+ ++n;
+ }
+ n += path[i] == ' ';
+ }
+ n += path[i] == ' ';
+ if (!(s = malloc(n + 1))) {
+ return 0;
+ }
+ for (i = 0, j = 0; i < len - 1; ++i, ++j) {
+ if (path[i] == '\\' && path[i + 1] == ' ') {
+ s[j++] = '\\';
+ }
+ if (path[i] == ' ') {
+ s[j++] = '\\';
+ }
+ s[j] = path[i];
+ }
+ if (path[i] == ' ') {
+ s[j++] = '\\';
+ }
+ s[j++] = path[i];
+ s[j] = 0;
+ return s;
+}
+
+char *fb_create_make_path(const char *path)
+{
+ return fb_create_make_path_n(path, strlen(path));
+}
+
+size_t fb_find_basename(const char *path, size_t len)
+{
+ char *p = (char *)path;
+
+ p += len;
+ while(p != path) {
+ --p;
+ if (*p == '/' || *p == '\\') {
+ ++p;
+ break;
+ }
+ }
+ return (size_t)(p - path);
+}
+
+char *fb_create_basename(const char *path, size_t len, const char *ext)
+{
+ size_t pos;
+ char *s;
+
+ pos = fb_find_basename(path, len);
+ path += pos;
+ len -= pos;
+ len = fb_chomp(path, len, ext);
+ if ((s = malloc(len + 1))) {
+ memcpy(s, path, len);
+ s[len] = '\0';
+ }
+ return s;
+}
+
+char *fb_read_file(const char *filename, size_t max_size, size_t *size_out)
+{
+ FILE *fp;
+ long k;
+ size_t size, pos, n, _out;
+ char *buf;
+
+ size_out = size_out ? size_out : &_out;
+
+ fp = fopen(filename, "rb");
+ size = 0;
+ buf = 0;
+
+ if (!fp) {
+ goto fail;
+ }
+ fseek(fp, 0L, SEEK_END);
+ k = ftell(fp);
+ if (k < 0) goto fail;
+ size = (size_t)k;
+ *size_out = size;
+ if (max_size > 0 && size > max_size) {
+ goto fail;
+ }
+ rewind(fp);
+ buf = malloc(size ? size : 1);
+ if (!buf) {
+ goto fail;
+ }
+ pos = 0;
+ while ((n = fread(buf + pos, 1, size - pos, fp))) {
+ pos += n;
+ }
+ if (pos != size) {
+ goto fail;
+ }
+ fclose(fp);
+ *size_out = size;
+ return buf;
+
+fail:
+ if (fp) {
+ fclose(fp);
+ }
+ if (buf) {
+ free(buf);
+ }
+ *size_out = size;
+ return 0;
+}