コード例 #1
0
ファイル: anddown.c プロジェクト: kevinsawicki/cwac-anddown
JNIEXPORT jstring JNICALL Java_com_commonsware_cwac_anddown_AndDown_markdownToHtml
  (JNIEnv *env, jobject o, jstring raw) {
	struct buf *ib, *ob;
	int ret;
  jstring result;

	struct sd_callbacks callbacks;
	struct html_renderopt options;
	struct sd_markdown *markdown;

  const char* str;
  str = (*env)->GetStringUTFChars(env, raw, NULL);

	ib = bufnew(INPUT_UNIT);
  bufputs(ib, str);
	ob = bufnew(OUTPUT_UNIT);

  (*env)->ReleaseStringUTFChars(env, raw, str);

	sdhtml_renderer(&callbacks, &options, 0);
	markdown = sd_markdown_new(0, 16, &callbacks, &options);

	sd_markdown_render(ob, ib->data, ib->size, markdown);
	sd_markdown_free(markdown);

  result=(*env)->NewStringUTF(env, bufcstr(ob));

	/* cleanup */
	bufrelease(ib);
	bufrelease(ob);

  return(result);
}
コード例 #2
0
ファイル: mainwindow.cpp プロジェクト: xchz/qarkdown
static QString markdown(QString in){
    struct buf *ib, *ob;
    struct sd_callbacks cbs;
    struct html_renderopt opts;
    struct sd_markdown *mkd;

    if(in.size() > 0){
        QByteArray qba = in.toUtf8();
        const char *txt = qba.constData();
        if(NULL == txt) qDebug() << "txt was null!";
        if(0 < qba.size()){
            ib = bufnew(qba.size());
            bufputs(ib,txt);
            ob = bufnew(64);
            sdhtml_renderer(&cbs,&opts,0);
            mkd = sd_markdown_new(0,16,&cbs,&opts);
            sd_markdown_render(ob,ib->data,ib->size,mkd);
            sd_markdown_free(mkd);
            return QString::fromUtf8(bufcstr(ob));
        }
        else
            qDebug() <<"qstrlen was null";
    }
    return "";
}
コード例 #3
0
ファイル: lua_sundown.c プロジェクト: saml/gistbl
/* sundown.markdown(input_string) ==> output_string */
static int sundown_markdown(lua_State *L) {
    const char *indoc;
    size_t indocSize;
    struct buf *inbuf;
    struct buf *outbuf;
    struct html_renderopt options;
    struct sd_callbacks callbacks;
    struct sd_markdown *markdown;

    /* read input_string */
    indoc = luaL_checklstring(L, 1, &indocSize);
    inbuf = bufnew(READ_UNIT);
    bufgrow(inbuf, indocSize);
    bufput(inbuf, indoc, indocSize);

    /* prepare for output_string */
    outbuf = bufnew(OUTPUT_UNIT);
    sdhtml_renderer(&callbacks, &options, 0);
    markdown = sd_markdown_new(0, 16, &callbacks, &options);

    /* write output_string */
    sd_markdown_render(outbuf, inbuf->data, inbuf->size, markdown);
    lua_pushlstring(L, (const char*) outbuf->data, outbuf->size);
    
    bufrelease(inbuf);
    bufrelease(outbuf);
    sd_markdown_free(markdown);
    
    return 1;
}
コード例 #4
0
ファイル: mdtohtml.cpp プロジェクト: AChinaProgrammer/liteide
QByteArray md2html(const QByteArray &data, int ext)
{
    if (data.isEmpty()) {
        return data;
    }

    struct buf *ob;

    struct sd_callbacks callbacks;
    struct html_renderopt options;
    struct sd_markdown *markdown;

    /* performing markdown parsing */
    ob = bufnew(OUTPUT_UNIT);

    sdhtml_renderer(&callbacks, &options, 0);
    markdown = sd_markdown_new(ext, 16, &callbacks, &options);

    sd_markdown_render(ob, (uint8_t*)data.constData(), data.size(), markdown);
    sd_markdown_free(markdown);

    QByteArray out((char*)ob->data,ob->size);
    /* cleanup */
    bufrelease(ob);

    return out;
}
コード例 #5
0
ファイル: snudown.c プロジェクト: Zariel/snudown
PyMODINIT_FUNC initsnudown(void)
{
    PyObject *module;

    module = Py_InitModule3("snudown", snudown_methods, snudown_module__doc__);
    if (module == NULL)
        return;

    /* initialize the html renderer */
    sdhtml_renderer(&_state.callbacks,
                    (struct html_renderopt *)&_state.options,
                    snudown_render_flags);

    _state.options.html.link_attributes = &snudown_link_attr;

    /* initialize the markdown parser */
    sundown = sd_markdown_new(
                  snudown_md_flags,
                  16,
                  &_state.callbacks,
                  &_state.options
              );

    /* Version */
    PyModule_AddStringConstant(module, "__version__", "1.0.3");
}
コード例 #6
0
ファイル: snudown.c プロジェクト: empyrical/snudown
static struct sd_markdown* make_custom_renderer(struct module_state* state,
												const unsigned int renderflags,
												const unsigned int markdownflags,
												int toc_renderer) {
	if(toc_renderer) {
		sdhtml_toc_renderer(&state->callbacks,
			(struct html_renderopt *)&state->options);
	} else {
		sdhtml_renderer(&state->callbacks,
			(struct html_renderopt *)&state->options,
			renderflags);
	}

	state->options.html.link_attributes = &snudown_link_attr;
	state->options.html.html_element_whitelist = html_element_whitelist;
	state->options.html.html_attr_whitelist = html_attr_whitelist;

	return sd_markdown_new(
		markdownflags,
		16,
		64,
		&state->callbacks,
		&state->options
	);
}
コード例 #7
0
BOOL convMd2Html(LPCTSTR outpath, const CString& csspath)
{
	struct buf *ob;
	int ret;
	FILE *outf = NULL;
	unsigned int extensions = 0xff;
	char hHead[] = "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=""utf-8"">\n";
	char hSym[] = "<link href=""%s"" rel=""stylesheet""></link>\n</head>\n<body>\n";
	char hTail[] = "</body>\n</html>";
	char *hCSS = NULL;

	struct sd_callbacks callbacks;
	struct html_renderopt options;
	struct sd_markdown *markdown;

	char *cssbuf = unicode2Utf8((LPCTSTR)csspath, csspath.GetLength());
	int aclen = strlen(cssbuf) + strlen(hSym);

	hCSS = (char*)malloc(aclen+1);
	memset(hCSS, 0, aclen);
	sprintf(hCSS, "<link href=""%s"" rel=""stylesheet""></link>\n</head>\n<body>\n", cssbuf);
	free(cssbuf);


	/* performing markdown parsing */
	ob = bufnew(OUTPUT_UNIT);

	//extensions = MKDEXT_TABLES|MKDEXT_FENCED_CODE|MKDEXT_AUTOLINK|MKDEXT_STRIKETHROUGH|MKDEXT_SUPERSCRIPT|MKDEXT_LAX_SPACING;

	sdhtml_renderer(&callbacks, &options, 0);
	markdown = sd_markdown_new(extensions, 16, &callbacks, &options);

	sd_markdown_render(ob, mib_utf8->data, mib_utf8->size, markdown);
	sd_markdown_free(markdown);

	outf = _tfopen(outpath, _T("w"));
	if(outf != NULL) {
		fwrite(hHead, 1, strlen(hHead), outf);
		fwrite(hCSS, 1, strlen(hCSS), outf);
		/* writing the result to stdout */
		ret = fwrite(ob->data, 1, ob->size, outf);
		fwrite(hTail, 1, strlen(hTail), outf);
		fclose(outf);
	}

	/* cleanup */
	free(hCSS);
	bufrelease(mib_utf8);
	bufrelease(ob);
	mib_utf8 = NULL;

	return TRUE;
}
コード例 #8
0
ファイル: java_markdown.c プロジェクト: LzIManD/gfm-plugin
/* Init the default pipeline */
static void ghmd_init_md(void) {
    struct sd_callbacks callbacks;

    /* No extra flags to the Markdown renderer */
    sdhtml_renderer(&callbacks, &g_markdown.render_opts, 0);
    callbacks.blockcode = &rndr_blockcode_github;

    g_markdown.md = sd_markdown_new(
            GITHUB_MD_FLAGS,
            GITHUB_MD_NESTING,
            &callbacks,
            &g_markdown.render_opts
    );
}
コード例 #9
0
ファイル: backdown.c プロジェクト: kaneshin/backdown
bd_status_t
bd_render(struct buf *ob, const struct buf *ib)
{
	struct sd_callbacks callbacks;
	struct html_renderopt options;
	struct sd_markdown *markdown;

	unsigned int flags = HTML_USE_XHTML;
	sdhtml_renderer(&callbacks, &options, flags);
	markdown = sd_markdown_new(0, 16, &callbacks, &options);
	sd_markdown_render(ob, ib->data, ib->size, markdown);
	sd_markdown_free(markdown);
	return BD_SUCCESS;
}
コード例 #10
0
ファイル: sundown.c プロジェクト: 3rdpaw/MdCharm
/* main • main function, interfacing STDIO with the parser */
int
main(int argc, char **argv)
{
	struct buf *ib, *ob;
	int ret;
	FILE *in = stdin;

	struct sd_callbacks callbacks;
	struct html_renderopt options;
	struct sd_markdown *markdown;

	/* opening the file if given from the command line */
	if (argc > 1) {
		in = fopen(argv[1], "r");
		if (!in) {
			fprintf(stderr,"Unable to open input file \"%s\": %s\n", argv[1], strerror(errno));
			return 1;
		}
	}

	/* reading everything */
	ib = bufnew(READ_UNIT);
	bufgrow(ib, READ_UNIT);
	while ((ret = fread(ib->data + ib->size, 1, ib->asize - ib->size, in)) > 0) {
		ib->size += ret;
		bufgrow(ib, ib->size + READ_UNIT);
	}

	if (in != stdin)
		fclose(in);

	/* performing markdown parsing */
	ob = bufnew(OUTPUT_UNIT);

	sdhtml_renderer(&callbacks, &options, 0);
	markdown = sd_markdown_new(0, 16, &callbacks, &options);

	sd_markdown_render(ob, ib->data, ib->size, markdown);
	sd_markdown_free(markdown);

	/* writing the result to stdout */
	ret = fwrite(ob->data, 1, ob->size, stdout);

	/* cleanup */
	bufrelease(ib);
	bufrelease(ob);

	return (ret < 0) ? -1 : 0;
}
コード例 #11
0
ファイル: rc_render.c プロジェクト: kannans/shoes
static VALUE rb_redcarpet_html_init(int argc, VALUE *argv, VALUE self)
{
    struct rb_redcarpet_rndr *rndr;
    unsigned int render_flags = 0;
    VALUE hash;

    Data_Get_Struct(self, struct rb_redcarpet_rndr, rndr);

    if (rb_scan_args(argc, argv, "01", &hash) == 1)
    {
        Check_Type(hash, T_HASH);

        /* filter_html */
        if (rb_hash_aref(hash, CSTR2SYM("filter_html")) == Qtrue)
            render_flags |= HTML_SKIP_HTML;

        /* no_image */
        if (rb_hash_aref(hash, CSTR2SYM("no_images")) == Qtrue)
            render_flags |= HTML_SKIP_IMAGES;

        /* no_links */
        if (rb_hash_aref(hash, CSTR2SYM("no_links")) == Qtrue)
            render_flags |= HTML_SKIP_LINKS;

        /* filter_style */
        if (rb_hash_aref(hash, CSTR2SYM("no_styles")) == Qtrue)
            render_flags |= HTML_SKIP_STYLE;

        /* safelink */
        if (rb_hash_aref(hash, CSTR2SYM("safe_links_only")) == Qtrue)
            render_flags |= HTML_SAFELINK;

        if (rb_hash_aref(hash, CSTR2SYM("with_toc_data")) == Qtrue)
            render_flags |= HTML_TOC;

        if (rb_hash_aref(hash, CSTR2SYM("hard_wrap")) == Qtrue)
            render_flags |= HTML_HARD_WRAP;

        if (rb_hash_aref(hash, CSTR2SYM("xhtml")) == Qtrue)
            render_flags |= HTML_USE_XHTML;
    }

    sdhtml_renderer(&rndr->callbacks, (struct html_renderopt *)&rndr->options.html, render_flags);
    rb_redcarpet__overload(self, rb_cRenderHTML);

    return Qnil;
}
コード例 #12
0
ファイル: util.cpp プロジェクト: msjoberg/pumpa
QString markDown(QString text) {
  struct sd_callbacks callbacks;
  struct html_renderopt options;
  sdhtml_renderer(&callbacks, &options, 0);

  struct sd_markdown* markdown = sd_markdown_new(0, 16, &callbacks, &options);

  struct buf* ob = bufnew(64);
  // QByteArray ba = text.toLocal8Bit();
  QByteArray ba = text.toUtf8();

  sd_markdown_render(ob, (const unsigned char*)ba.constData(), ba.size(),
                     markdown);
  sd_markdown_free(markdown);

  // QString ret = QString::fromLocal8Bit((char*)ob->data, ob->size);
  QString ret = QString::fromUtf8((char*)ob->data, ob->size);
  bufrelease(ob);

  return ret.trimmed();
}
コード例 #13
0
ファイル: Rmarkdown.c プロジェクト: jimhester/markdown
static Rboolean render_to_html(struct buf *ib, struct buf *ob,
                                  SEXP Soptions, SEXP Sextensions)
{
   struct sd_callbacks callbacks;
   struct html_renderopt renderopt;
   unsigned int exts=0, options=0;
   struct sd_markdown *markdown;
   struct buf *htmlbuf;
   Rboolean toc = FALSE, smarty = FALSE;

   /* Marshal extensions */
   if (isString(Sextensions))
   {
      int i;
      for (i = 0; i < LENGTH(Sextensions); i++)
      {
         if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)),
                        "NO_INTRA_EMPHASIS") == 0)
            exts |= MKDEXT_NO_INTRA_EMPHASIS;
         else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)),
                        "TABLES") == 0)
            exts |= MKDEXT_TABLES;
         else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)),
                        "FENCED_CODE") == 0)
            exts |= MKDEXT_FENCED_CODE;
         else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)),
                        "AUTOLINK") == 0)
            exts |= MKDEXT_AUTOLINK;
         else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)),
                        "STRIKETHROUGH") == 0)
            exts |= MKDEXT_STRIKETHROUGH;
         else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)),
                        "LAX_SPACING") == 0)
            exts |= MKDEXT_LAX_SPACING;
         else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)),
                        "SPACE_HEADERS") == 0)
            exts |= MKDEXT_SPACE_HEADERS;
         else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)),
                        "SUPERSCRIPT") == 0)
            exts |= MKDEXT_SUPERSCRIPT;
         else if (strcasecmp(CHAR(STRING_ELT(Sextensions,i)),
                        "LATEX_MATH") == 0)
            exts |= MKDEXT_LATEX_MATH;
      }
   }

   /* Marshal HTML options */
   if (isString(Soptions))
   {
      int i;
      for (i = 0; i < LENGTH(Soptions); i++)
      {
         if (strcasecmp(CHAR(STRING_ELT(Soptions,i)),
                        "SKIP_HTML") == 0)
            options |= HTML_SKIP_HTML;
         else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)),
                        "SKIP_STYLE") == 0)
            options |= HTML_SKIP_STYLE;
         else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)),
                        "SKIP_IMAGES") == 0)
            options |= HTML_SKIP_IMAGES;
         else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)),
                        "SKIP_LINKS") == 0)
            options |= HTML_SKIP_LINKS;
         else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)),
                        "SAFELINK") == 0)
            options |= HTML_SAFELINK;
         else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)),
                        "TOC") == 0)
         {
            options |= HTML_TOC;
            toc = TRUE;
         }
         else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)),
                        "HARD_WRAP") == 0)
            options |= HTML_HARD_WRAP;
         else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)),
                        "USE_XHTML") == 0)
            options |= HTML_USE_XHTML;
         else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)),
                        "ESCAPE") == 0)
            options |= HTML_ESCAPE;
         else if (strcasecmp(CHAR(STRING_ELT(Soptions,i)),
                        "SMARTYPANTS") == 0)
            smarty = TRUE;
      }
   }

   htmlbuf = bufnew(OUTPUT_UNIT);
   if (!htmlbuf)
   {
      RMD_WARNING_NOMEM;
      return FALSE;
   }

   if (toc==TRUE)
   {
      struct buf *tocbuf = bufnew(OUTPUT_UNIT);

      if (!tocbuf)
      {
         RMD_WARNING_NOMEM;
         return FALSE;
      }

      sdhtml_toc_renderer(&callbacks, &renderopt);
      markdown = sd_markdown_new(exts,16,&callbacks,(void *)&renderopt);
      if (!markdown)
      {
         RMD_WARNING_NOMEM;
         return FALSE;
      }
      
      sd_markdown_render(tocbuf, ib->data, ib->size, markdown);
      sd_markdown_free(markdown);

      bufputs(htmlbuf,"<div id=\"toc\">\n");
      bufputs(htmlbuf,"<div id=\"toc_header\">Table of Contents</div>\n");
      bufput(htmlbuf,tocbuf->data,tocbuf->size);
      bufputs(htmlbuf,"</div>\n");
      bufputs(htmlbuf,"\n");
      bufrelease(tocbuf);
   }

   sdhtml_renderer(&callbacks, &renderopt, options);

   markdown = sd_markdown_new(exts,16,&callbacks,(void *)&renderopt);
   if (!markdown)
   {
      RMD_WARNING_NOMEM;
      return FALSE;
   }

   sd_markdown_render(htmlbuf, ib->data, ib->size, markdown);

   sd_markdown_free(markdown);

   if (smarty==TRUE)
   {
      struct buf *smartybuf = bufnew(OUTPUT_UNIT);
      if (!smartybuf)
      {
         RMD_WARNING_NOMEM;
         return FALSE;
      }
      sdhtml_smartypants(smartybuf,htmlbuf->data,htmlbuf->size);
      bufrelease(htmlbuf);
      htmlbuf = smartybuf;
   }

   bufput(ob,htmlbuf->data,htmlbuf->size);

   bufrelease(htmlbuf);

   return TRUE;
}
コード例 #14
0
ファイル: renderer.cpp プロジェクト: johanneshilden/lessedit
sd_markdown *tdRenderer::initSundown()
{
    sdhtml_renderer(&m_callbacks, &m_options, 0);
    return sd_markdown_new(m_ext, 16, &m_callbacks, &m_options);
}
コード例 #15
0
ファイル: rc_render.c プロジェクト: vmg/redcarpet
static VALUE rb_redcarpet_html_init(int argc, VALUE *argv, VALUE self)
{
	struct rb_redcarpet_rndr *rndr;
	unsigned int render_flags = 0;
	VALUE hash, link_attr = Qnil;

	Data_Get_Struct(self, struct rb_redcarpet_rndr, rndr);

	if (rb_scan_args(argc, argv, "01", &hash) == 1) {
		Check_Type(hash, T_HASH);

		/* Give access to the passed options through `@options` */
		rb_iv_set(self, "@options", hash);

		/* escape_html */
		if (rb_hash_aref(hash, CSTR2SYM("escape_html")) == Qtrue)
			render_flags |= HTML_ESCAPE;

		/* filter_html */
		if (rb_hash_aref(hash, CSTR2SYM("filter_html")) == Qtrue)
			render_flags |= HTML_SKIP_HTML;

		/* no_image */
		if (rb_hash_aref(hash, CSTR2SYM("no_images")) == Qtrue)
			render_flags |= HTML_SKIP_IMAGES;

		/* no_links */
		if (rb_hash_aref(hash, CSTR2SYM("no_links")) == Qtrue)
			render_flags |= HTML_SKIP_LINKS;

		/* prettify */
		if (rb_hash_aref(hash, CSTR2SYM("prettify")) == Qtrue)
			render_flags |= HTML_PRETTIFY;

		/* filter_style */
		if (rb_hash_aref(hash, CSTR2SYM("no_styles")) == Qtrue)
			render_flags |= HTML_SKIP_STYLE;

		/* safelink */
		if (rb_hash_aref(hash, CSTR2SYM("safe_links_only")) == Qtrue)
			render_flags |= HTML_SAFELINK;

		if (rb_hash_aref(hash, CSTR2SYM("with_toc_data")) == Qtrue)
			render_flags |= HTML_TOC;

		if (rb_hash_aref(hash, CSTR2SYM("hard_wrap")) == Qtrue)
			render_flags |= HTML_HARD_WRAP;

		if (rb_hash_aref(hash, CSTR2SYM("xhtml")) == Qtrue)
			render_flags |= HTML_USE_XHTML;

		link_attr = rb_hash_aref(hash, CSTR2SYM("link_attributes"));
	}

	sdhtml_renderer(&rndr->callbacks, (struct html_renderopt *)&rndr->options.html, render_flags);
	rb_redcarpet__overload(self, rb_cRenderHTML);

	if (!NIL_P(link_attr)) {
		rndr->options.link_attributes = link_attr;
		rndr->options.html.link_attributes = &rndr_link_attributes;
	}

	return Qnil;
}
コード例 #16
0
int markdown_convert(strarg_t const dst, strarg_t const src) {
	int file = -1, fd = -1;
	byte_t const *in = NULL;
	struct buf *out = NULL;

	file = open(dst, O_CREAT | O_EXCL | O_RDWR, 0400);
	if(file < 0) {
		fprintf(stderr, "Can't create %s: %s\n", dst, strerror(errno));
		goto err;
	}

	fd = open(src, O_RDONLY, 0000);
	if(fd < 0) {
		fprintf(stderr, "Can't open %s: %s\n", src, strerror(errno));
		goto err;
	}

	struct stat stats[1];
	int rc = fstat(fd, stats);
	if(rc < 0) {
		fprintf(stderr, "Can't stat %s: %s\n", src, strerror(errno));
		goto err;
	}
	size_t const size = stats->st_size;
	if(size > CONVERT_MAX) {
		fprintf(stderr, "File too large %s: %zu\n", src, size);
		goto err;
	}

	in = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
	close(fd); fd = -1;
	if(MAP_FAILED == in) {
		fprintf(stderr, "Can't read %s: %s\n", src, strerror(errno));
		goto err;
	}


#ifdef MARKDOWN_STANDALONE
// TODO: chroot, drop privileges?
#endif

	unsigned int const rflags =
		HTML_ESCAPE |
		HTML_HARD_WRAP |
		0;
	unsigned int const mflags =
		MKDEXT_AUTOLINK |
		MKDEXT_FENCED_CODE |
		MKDEXT_NO_INTRA_EMPHASIS |
		MKDEXT_SUPERSCRIPT |
		0;
	size_t const nesting = 10;

	struct sd_callbacks callbacks[1];
	struct markdown_state state[1];
	sdhtml_renderer(callbacks, &state->opts, rflags);
	state->link = callbacks->link;
	state->autolink = callbacks->autolink;
	callbacks->link = markdown_link;
	callbacks->autolink = markdown_autolink;

	struct sd_markdown *parser = sd_markdown_new(mflags, nesting, callbacks, state);
	out = bufnew(1024 * 8); // Sundown grows this as needed.
	sd_markdown_render(out, in, size, parser);
	sd_markdown_free(parser); parser = NULL;

	// TODO: How is this supposed to work? Aren't we only writing the first 8K?
	// TODO: Are we even freeing `out`?

	size_t written = 0;
	for(;;) {
		ssize_t const r = TEMP_FAILURE_RETRY(write(file, out->data+written, out->size-written));
		if(r < 0) {
			fprintf(stderr, "Can't write %s: %s\n", dst, strerror(errno));
			goto err;
		}
		written += (size_t)r;
		if(written >= out->size) break;
	}
	if(fdatasync(file) < 0) {
		fprintf(stderr, "Can't sync %s: %s\n", dst, strerror(errno));
		goto err;
	}

	int const close_err = close(file); file = -1;
	if(close_err < 0) {
		fprintf(stderr, "Error while closing %s: %s\n", dst, strerror(errno));
		goto err;
	}
	munmap((byte_t *)in, size); in = NULL;
	bufrelease(out); out = NULL;
	return 0;

err:
	unlink(dst);
	close(file); file = -1;
	munmap((byte_t *)in, size); in = NULL;
	bufrelease(out); out = NULL;
	return -1;
}