int vasprintf(char **strp, const char *fmt, va_list ap) { size_t size; char *buf; buf = (char*)malloc(size = 128); if (buf == NULL) return -1; while (1) { int len; char *oldbuf; # if defined(HAVE_VA_COPY) || defined(HAVE___VA_COPY) va_list args; va_copy(args, ap); len = sprintfv(fmt, args); # else /* ! HAVE_VA_COPY */ len = sprintfv(fmt, ap); # endif if (len < size) { buf = realloc(buf, len + 1); *strp = buf; return len; } if (len == -1) size *= 2; else size = len + 1; buf = realloc(oldbuf = buf, size *= 2); if (buf == NULL) { free(oldbuf); return -1; } } }
/** * guts of the template file/line functions */ static SCM do_tpl_file_line(int line_delta, char const * fmt) { void * args[2] = { [0] = (void*)pCurTemplate->pzTplFile, [1] = (void*)((long)pCurMacro->lineNo + line_delta) }; char * buf = strrchr(args[0], DIRCH); if (buf != NULL) args[0] = buf + 1; { size_t sz = strlen(fmt) + strlen(args[0]) + 24; buf = ag_scribble(sz); } sprintfv(buf, fmt, (snv_constpointer*)args); return AG_SCM_STR02SCM(buf); }
/*=gfunc def_file_line * * what: get a definition file+line number * * exparg: ag-name, name of AutoGen value * exparg: msg-fmt, formatting for line message, optional * * doc: * Returns the file and line number of a AutoGen defined value, using * either the default format, "from %s line %d", or else the format you * supply. For example, if you want to insert a "C" language file-line * directive, you would supply the format "# %2$d \"%1$s\"", but that * is also already supplied with the scheme variable * @xref{SCM c-file-line-fmt}. You may use it thus: * * @example * (def-file-line "ag-def-name" c-file-line-fmt) * @end example * * It is also safe to use the formatting string, "%2$d". AutoGen uses * an argument vector version of printf: @xref{snprintfv}. =*/ SCM ag_scm_def_file_line(SCM obj, SCM fmt) { static char const zFmt[] = "from %s line %d"; char const * pzFmt = zFmt; char * buf; ag_bool x; tDefEntry * pE = findDefEntry(ag_scm2zchars(obj, "ag value"), &x); /* * IF we did not find the entry we are looking for * THEN return UNDEFINED */ if (pE == NULL) return SCM_UNDEFINED; if (AG_SCM_STRING_P(fmt)) pzFmt = ag_scm2zchars(fmt, "file/line format"); { void * args[2] = { (void*)pE->pzSrcFile, (void*)(long)pE->srcLineNum }; size_t maxlen; buf = strrchr(args[0], DIRCH); if (buf != NULL) args[0] = buf + 1; maxlen = strlen(args[0]) + strlen(pzFmt) + LOG10_2to32 + 1; buf = ag_scribble(maxlen); sprintfv(buf, pzFmt, (snv_constpointer*)args); } return AG_SCM_STR02SCM(buf); }