summaryrefslogtreecommitdiff
path: root/ccc/filelib.c
diff options
context:
space:
mode:
Diffstat (limited to 'ccc/filelib.c')
-rw-r--r--ccc/filelib.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/ccc/filelib.c b/ccc/filelib.c
new file mode 100644
index 0000000..57a27c3
--- /dev/null
+++ b/ccc/filelib.c
@@ -0,0 +1,87 @@
+#include "filelib.h"
+
+
+typedef struct
+{
+ hFile b_;
+ FILE* fp;
+} hFile_;
+
+typedef struct
+{
+ hFile b_;
+ gzFile* fp;
+} hgzFile;
+
+gzmode(const char* mode)
+{
+ // TODO
+ return true;
+}
+
+hgzFile*
+gzmakef(char* fname, const char* mode)
+{
+ hgzFile* hgz = malloc(sizeof(hgzFile));
+ hgz->b_.name = fname;
+ hgz->b_.gz = true;
+ gzFile* fp = malloc(sizeof(gzFile));
+ *fp = gzopen(fname, mode);
+ hgz->fp = fp;
+ return hgz;
+}
+
+hFile*
+makef(char* fname, const char* mode)
+{
+ if (endswith(fname, GZIP_EXT))
+ return gzmakef(fname, mode);
+ hFile_* f = malloc(sizeof(hFile_));
+ if (!f) return NULL;
+ f->b_.name = fname;
+ f->b_.gz = false;
+ if (!strcmp(fname, "-")) {
+ if (!strcmp(mode, "r") && !strcmp(mode, "r+")) f->fp = stdin;
+ else f->fp = stdout;
+ } else {
+ f->fp = fopen(fname, mode);
+ }
+ return f;
+}
+
+bool
+gzwriteln(const char* s, hFile* f)
+{
+ unsigned len = strlen(s);
+ gzwrite(*((hgzFile*)f)->fp, s, len);
+ gzwrite(*((hgzFile*)f)->fp, "\n", 1);
+ return gzflush(*((hgzFile*)f)->fp, Z_FINISH) == Z_OK;
+}
+
+bool
+writeln(const char* s, hFile* f)
+{
+ if (f->gz)
+ return gzwriteln(s, f);
+ return fputs(s, ((hFile_*)f)->fp)&&fputs("\n", ((hFile_*)f)->fp);
+}
+
+bool
+gzclosef(hFile* f)
+{
+ bool ret = gzclose(*((hgzFile*)f)->fp);
+ free(((hgzFile*)f)->fp);
+ free(f);
+ return ret;
+}
+
+bool
+closef(hFile* f)
+{
+ if (f->gz)
+ return gzclosef(f);
+ bool ret = fclose(((hFile_*)f)->fp);
+ free(f);
+ return ret;
+}
+