|
@@ -1,188 +0,0 @@
|
|
|
-#include <stdlib.h>
|
|
|
-#include <string.h>
|
|
|
-#include <stdio.h>
|
|
|
-#include <errno.h>
|
|
|
-
|
|
|
-
|
|
|
-#include "strings.h"
|
|
|
-#include "strings.h"
|
|
|
-#include "strings.h"
|
|
|
-#include "strings.h"
|
|
|
-
|
|
|
-struct goal_ref {
|
|
|
- int count;
|
|
|
- void (*free)(void *);
|
|
|
-};
|
|
|
-
|
|
|
-typedef struct goal_ref goref;
|
|
|
-
|
|
|
-goref mkref(void (*f)(void *)) {
|
|
|
- goref r;
|
|
|
- r.free = f;
|
|
|
- r.count = 1;
|
|
|
- return r;
|
|
|
-}
|
|
|
-
|
|
|
-goref* ref(void *p) {
|
|
|
- goref *r;
|
|
|
- r = (goref*)((char*)(p));
|
|
|
- r->count++;
|
|
|
- return r;
|
|
|
-}
|
|
|
-
|
|
|
-goref* done(void *p) {
|
|
|
- goref *r;
|
|
|
- r = (goref*)((char*)(p));
|
|
|
- r->count--;
|
|
|
- if (r->count <= 0 && r->free) {
|
|
|
- r->free(p);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- return r;
|
|
|
-}
|
|
|
-
|
|
|
-struct goal_string {
|
|
|
- goref goref;
|
|
|
- char *buf;
|
|
|
- size_t len;
|
|
|
-};
|
|
|
-
|
|
|
-typedef struct goal_string string;
|
|
|
-
|
|
|
-void string_free(void * p) {
|
|
|
- string *r = (string*)((char*)(p));
|
|
|
- free(r->buf);
|
|
|
-}
|
|
|
-
|
|
|
-string string_dup(char* zbuf) {
|
|
|
- string res;
|
|
|
- res.buf = strdup(zbuf);
|
|
|
- res.len = strlen(zbuf);
|
|
|
- res.goref = mkref(string_free);
|
|
|
- return res;
|
|
|
-}
|
|
|
-
|
|
|
-static string strings_c(char * buf) {
|
|
|
- string r = string_dup(buf);
|
|
|
- return r;
|
|
|
-}
|
|
|
-
|
|
|
-static string strings_clone(string in) {
|
|
|
- string r = string_dup(in.buf);
|
|
|
- return r;
|
|
|
-}
|
|
|
-
|
|
|
-struct strings_package strings = {
|
|
|
- strings_c,
|
|
|
- strings_clone,
|
|
|
-};
|
|
|
-
|
|
|
-typedef int error;
|
|
|
-
|
|
|
-struct io_writer {
|
|
|
- void * impl;
|
|
|
- error (*write)(size_t *written, struct io_writer *, void * ptr, size_t size);
|
|
|
-};
|
|
|
-
|
|
|
-typedef struct io_writer io_Writer;
|
|
|
-
|
|
|
-struct file_writer {
|
|
|
- goref ref;
|
|
|
- FILE * file;
|
|
|
- struct io_writer io_writer;
|
|
|
-};
|
|
|
-
|
|
|
-typedef struct file_writer File;
|
|
|
-
|
|
|
-void File_free(void * p) {
|
|
|
- File *r = (File*)((char*)(p));
|
|
|
- fclose(r->file);
|
|
|
-}
|
|
|
-
|
|
|
-error File_write(size_t *written, struct io_writer * iow, void * ptr, size_t size) {
|
|
|
- error err = 0;
|
|
|
- size_t wr = 0;
|
|
|
- File *r = (File*)((char*)(iow->impl));
|
|
|
- // errno = 0;
|
|
|
- size_t nmem = 1;
|
|
|
- wr = fwrite(ptr, size, nmem, r->file);
|
|
|
- err = (error)(errno);
|
|
|
- if (written) {
|
|
|
- *written = wr;
|
|
|
- }
|
|
|
- return err;
|
|
|
-}
|
|
|
-
|
|
|
-void File_C(File* res, FILE * f) {
|
|
|
- res->file = f;
|
|
|
- res->io_writer.impl = res;
|
|
|
- res->io_writer.write = File_write;
|
|
|
- res->ref = mkref(File_free);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-error PrintWriter_write(size_t *written, struct io_writer * iow, void * ptr, size_t size) {
|
|
|
- error err = 0;
|
|
|
- size_t wr = 0;
|
|
|
- FILE *r = (FILE*)((char*)(iow->impl));
|
|
|
- // errno = 0;
|
|
|
- size_t nmem = 1;
|
|
|
- wr = fwrite(ptr, size, nmem, r);
|
|
|
- err = (error)(errno);
|
|
|
- if (written) {
|
|
|
- *written = wr;
|
|
|
- }
|
|
|
- return err;
|
|
|
-}
|
|
|
-
|
|
|
-io_Writer PrintWriter() {
|
|
|
- io_Writer res;
|
|
|
- res.impl = stdout;
|
|
|
- res.write = PrintWriter_write;
|
|
|
- return res;
|
|
|
-}
|
|
|
-
|
|
|
-error File_COpen(File* res, const char * name, const char *mode) {
|
|
|
- FILE * f = 0;
|
|
|
- error err = 0;
|
|
|
- errno = 0;
|
|
|
- f = fopen(name, mode);
|
|
|
- err = (error)(errno);
|
|
|
- if (f) {
|
|
|
- if (res) {
|
|
|
- File_C(res, f);
|
|
|
- } else {
|
|
|
- fclose(f);
|
|
|
- }
|
|
|
- }
|
|
|
- return err;
|
|
|
-}
|
|
|
-
|
|
|
-error (say_Hello)(io_Writer *wr) {
|
|
|
- return wr->write(0, wr, "hello\n", 6);
|
|
|
-}
|
|
|
-
|
|
|
-int main(void) {
|
|
|
- string hi = strings.C("hi");
|
|
|
- string dup = strings.Clone(hi);
|
|
|
- File fout = {0};
|
|
|
- error err = 0;
|
|
|
- io_Writer pw = PrintWriter();
|
|
|
- if ((err = File_COpen(&fout, "out.txt", "w"))) {
|
|
|
- printf("error %d %s\n", err, strerror(err));
|
|
|
- goto done;
|
|
|
- }
|
|
|
-
|
|
|
- say_Hello(&fout.io_writer);
|
|
|
- say_Hello(&pw);
|
|
|
- ref(&hi);
|
|
|
- puts(hi.buf);
|
|
|
- done(&hi);
|
|
|
- puts(dup.buf);
|
|
|
-
|
|
|
- done:
|
|
|
- done(&hi);
|
|
|
- done(&dup);
|
|
|
- done(&fout);
|
|
|
- return err;
|
|
|
-}
|