/* $Id$ */ /* * * Copyright (C) 2001-2004 EPFL (Swiss Federal Institute of Technology, * Lausanne) This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * * In addition, as a special exception, EPFL gives permission to link * the code of this program with the Qt non-commercial edition library * (or with modified versions of Qt non-commercial edition that use the * same license as Qt non-commercial edition), and distribute linked * combinations including the two. You must obey the GNU General * Public License in all respects for all of the code used other than * Qt non-commercial edition. If you modify this file, you may extend * this exception to your version of the file, but you are not * obligated to do so. If you do not wish to do so, delete this * exception statement from your version. * * Authors : Nicolas Aspert, Diego Santa-Cruz and Davy Jacquet * * Web site : http://mesh.epfl.ch * * Reference : * "MESH : Measuring Errors between Surfaces using the Hausdorff distance" * in Proceedings of IEEE Intl. Conf. on Multimedia and Expo (ICME) 2002, * vol. I, pp. 705-708, available on http://mesh.epfl.ch * */ #include <reporting.h> #include <assert.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <xalloc.h> /* Minimum amount of free space in buffer */ #define OUTBUF_MIN_FREE (2*OUTBUF_MAX_SZ) /* --------------------------------------------------------------------------* * External functions * * --------------------------------------------------------------------------*/ /* see reporting.h */ struct outbuf *outbuf_new(outbuf_flush_cb_t *flush_cb, void *cb_out) { struct outbuf *ob; ob = xa_malloc(sizeof(*ob)); ob->strbuf = xa_malloc(OUTBUF_MIN_FREE); ob->strbuf[0] = '\0'; ob->pos = ob->strbuf; ob->end = ob->strbuf + OUTBUF_MIN_FREE; ob->flush = flush_cb; ob->cb_out = cb_out; return ob; } /* see reporting.h */ void outbuf_delete(struct outbuf *ob) { if (ob != NULL) { free(ob->strbuf); free(ob); } } /* see reporting.h */ void outbuf_flush(struct outbuf *ob) { assert(*(ob->pos) == '\0'); if (ob->flush != NULL) { ob->flush(ob->cb_out,ob->strbuf); ob->pos = ob->strbuf; if (ob->end > ob->pos) *(ob->pos) = '\0'; } } /* see reporting.h */ void outbuf_printf(struct outbuf *ob, const char *format, ...) { va_list ap; int len; int free_sz; size_t new_sz,off; assert(ob->strbuf != NULL && ob->pos != NULL && ob->end != NULL); /* Ensure a minimum amount of free bytes */ free_sz = ob->end - ob->pos; if (free_sz < OUTBUF_MAX_SZ) { off = ob->pos-ob->strbuf; new_sz = ob->end-ob->strbuf+OUTBUF_MIN_FREE; ob->strbuf = xa_realloc(ob->strbuf,new_sz); ob->pos = ob->strbuf+off; ob->end = ob->strbuf+new_sz; free_sz = ob->end - ob->pos; } /* Print to string buffer */ va_start(ap,format); len = vsprintf(ob->pos,format,ap); va_end(ap); /* Check that buffer was large enough. Ensuring that we have enough free * space requires C99 or some ugly black magic. This should be enough for us * anyhow. */ if (len >= free_sz) { fprintf(stderr,"PANIC: String buffer size exceeded. " "Memory possibly corrupted."); } ob->pos += len; } /* see reporting.h */ void prog_report(struct prog_reporter *pr, int p) { pr->prog(pr->cb_out,p); } /* see reporting.h */ void stdio_puts(void *out, const char *str) { fputs(str,(FILE*)out); fflush((FILE*)out); } /* see reporting.h */ void stdio_prog(void *out, int p) { FILE *fout; fout = (FILE*)out; if(p < 0) { fprintf(fout,"\r \r"); /* Remove progress message */ } else { fprintf(fout,"\rProgress %3d %%",p); } fflush(fout); }