pagr

A 'static site generator', built using dati.
Log | Files | Refs | Atom

commit 012b6addd19104dcaee9a9df1d116ac7da4926fb
parent 2597446a7de2a063b985341ddbc1b02ab30943fb
Author: gearsix <gearsix@tuta.io>
Date:   Wed, 24 Nov 2021 14:52:24 +0000

new copy.go#CopyFile, uses copyf (C func) - around x2 faster

Diffstat:
MMakefile | 2+-
Acopy.go | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpage.go | 21---------------------
Mpagr.go | 2+-
4 files changed, 76 insertions(+), 23 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,5 +1,5 @@ OUT=./pagr -SRC=pagr.go config.go page.go template.go +SRC=pagr.go config.go page.go template.go copy.go all: go clean diff --git a/copy.go b/copy.go @@ -0,0 +1,74 @@ +package main + +/* +#include <stdio.h> +#include <stdlib.h> + +int copyf(const char *src, const char *dst) +{ + int ret = EXIT_FAILURE; + + FILE *srcf, *dstf; + if ((!(srcf = fopen(src, "r"))) || + (!(dstf = fopen(dst, "w")))) + goto ABORT; + + char buf[BUFSIZ]; + int n; + do { + n = fread(buf, sizeof(char), BUFSIZ, srcf); + if (ferror(srcf)) perror("fread failure"); + else { + fwrite(buf, sizeof(char), n, dstf); + if (ferror(dstf)) perror("fwrite failure"); + } + } while (!feof(srcf) && !ferror(srcf) && !ferror(dstf)); + ret = EXIT_SUCCESS; + +ABORT: + if (srcf) fclose(srcf); + if (dstf) fclose(dstf); + return ret; +} +*/ +import "C" +import ( + "fmt" + "path/filepath" + "os" + "unsafe" +) + +func CopyFile(src, dst string) (err error) { + var srcfi, dstfi os.FileInfo + + if err = os.MkdirAll(filepath.Dir(dst), 0777); err != nil { + return err + } + + if srcfi, err = os.Stat(src); err != nil { + return err + } else if !srcfi.Mode().IsRegular() { + return fmt.Errorf("cannot copy from non-regular source file %s (%q)", + srcfi.Name(), srcfi.Mode().String()) + } + + if dstfi, err = os.Stat(dst); err != nil && !os.IsNotExist(err) { + return err + } else if !dstfi.Mode().IsRegular() { + return fmt.Errorf("cannot copy to non-regular destination file %s (%q)", + dstfi.Name(), dstfi.Mode().String()) + } else if os.SameFile(srcfi, dstfi) { + return nil + } + + cSrc := C.CString(src) + cDst := C.CString(dst) + if uint32(C.copyf(cSrc, cDst)) != 0 { + err = fmt.Errorf("copyf failed ('%s' -> '%s')", src, dst) + } + C.free(unsafe.Pointer(cSrc)) + C.free(unsafe.Pointer(cDst)) + + return +} diff --git a/page.go b/page.go @@ -346,27 +346,6 @@ func (p *Page) CopyAssets(srcDir, outDir string) (err error) { return } -func CopyFile(src, dst string) (err error) { - if err = os.MkdirAll(filepath.Dir(dst), 0777); err != nil { - return err - } - - var srcf, dstf *os.File - if srcf, err = os.Open(src); err != nil { - return err - } - defer srcf.Close() - if dstf, err = os.OpenFile(dst, os.O_RDWR|os.O_CREATE, 0644); err != nil { - return err - } - defer dstf.Close() - - if _, err = io.Copy(dstf, srcf); err != nil { - return err - } - return dstf.Sync() -} - func (p *Page) Build(outDir string, t suti.Template) (out string, err error) { var buf bytes.Buffer if buf, err = t.Execute(p); err == nil { diff --git a/pagr.go b/pagr.go @@ -124,7 +124,7 @@ func copyAssets(wg sync.WaitGroup, cfg Config) (n int) { a = filepath.Clean(a) path := strings.TrimPrefix(src, a) n++ - CopyFile(src, filepath.Join(cfg.Output, path)) + check(CopyFile(src, filepath.Join(cfg.Output, path))) vlog("-> %s", path) } return err