static int textRead(TEXT * const textP, FILE * const fileP) { int retval; char * s; char buf[128]; int used, alloced, len; if (textP == NULL) return 0; textP->r->offset = (uint32_t)ftell(fileP); /* * What a pain in the ass! Why the hell isn't there a length * attached to the text record? I suppose the designer wasn't * concerned about non-seekable (i.e. pipes) input streams. * Perhaps I'm being a little harsh, the lack of a length probably * isn't much of an issue on the Pilot. */ used = 0; alloced = 0; s = NULL; retval = 0; /* initial value */ while ((len = fread(buf, 1, sizeof(buf), fileP)) != 0 && retval == 0) { if (buf[len - 1] == '\0') --len; if (used + len > alloced) { alloced += 2 * sizeof(buf); REALLOCARRAY(s, alloced); if (s == NULL) retval = ENOMEM; } if (retval == 0) { memcpy(s + used, buf, len); used += len; } } if (retval == 0) { textP->data = calloc(1, used + 1); if (textP->data == NULL) retval = ENOMEM; else memcpy(textP->data, s, used); } if (s) free(s); return retval; }
static void handleArrayAllocation(png_text ** const arrayP, unsigned int * const allocatedChunkCtP, unsigned int const chunkIdx) { if (chunkIdx >= *allocatedChunkCtP) { *allocatedChunkCtP *= 2; REALLOCARRAY(*arrayP, *allocatedChunkCtP); if (*arrayP == NULL) pm_error("unable to allocate memory for %u text chunks", *allocatedChunkCtP); } }
static void makeRoomInArgList(xmlrpc_env * const envP, struct xmlrpc_signature * const signatureP, unsigned int const minArgCount) { if (signatureP->argListSpace < minArgCount) { REALLOCARRAY(signatureP->argList, minArgCount); if (signatureP->argList == NULL) { xmlrpc_faultf(envP, "Couldn't get memory for a argument list for " "a method signature with %u arguments", minArgCount); signatureP->argListSpace = 0; } } }
static void getText(const char cmdline_text[], struct font * const fontP, struct text * const input_textP) { struct text input_text; if (cmdline_text) { MALLOCARRAY_NOFAIL(input_text.textArray, 1); input_text.allocatedLineCount = 1; input_text.lineCount = 1; fixControlChars(cmdline_text, fontP, (const char**)&input_text.textArray[0]); } else { /* Read text from stdin. */ unsigned int maxlines; /* Maximum number of lines for which we presently have space in the text array */ char buf[5000]; char ** text_array; unsigned int lineCount; maxlines = 50; /* initial value */ MALLOCARRAY_NOFAIL(text_array, maxlines); lineCount = 0; /* initial value */ while (fgets(buf, sizeof(buf), stdin) != NULL) { if (strlen(buf) + 1 >= sizeof(buf)) pm_error("A line of input text is longer than %u characters." "Cannot process.", (unsigned)sizeof(buf)-1); if (lineCount >= maxlines) { maxlines *= 2; REALLOCARRAY(text_array, maxlines); if (text_array == NULL) pm_error("out of memory"); } fixControlChars(buf, fontP, (const char **)&text_array[lineCount]); if (text_array[lineCount] == NULL) pm_error("out of memory"); ++lineCount; } input_text.textArray = text_array; input_text.lineCount = lineCount; input_text.allocatedLineCount = lineCount; } *input_textP = input_text; }
static void readScriptFile(const char * const scriptFileName, const char ** const scriptP) { FILE * scriptFileP; char * script; size_t scriptAllocation; size_t bytesReadSoFar; scriptAllocation = 4096; MALLOCARRAY(script, scriptAllocation); if (script == NULL) pm_error("out of memory reading script from file"); scriptFileP = pm_openr(scriptFileName); bytesReadSoFar = 0; while (!feof(scriptFileP)) { size_t bytesRead; if (scriptAllocation - bytesReadSoFar < 2) { scriptAllocation += 4096; REALLOCARRAY(script, scriptAllocation); if (script == NULL) pm_error("out of memory reading script from file"); } bytesRead = fread(script + bytesReadSoFar, 1, scriptAllocation - bytesReadSoFar - 1, scriptFileP); bytesReadSoFar += bytesRead; } pm_close(scriptFileP); { unsigned int i; for (i = 0; i < bytesReadSoFar; ++i) if (!isprint(script[i]) && !isspace(script[i])) pm_error("Script contains byte that is not printable ASCII " "character: 0x%02x", script[i]); } script[bytesReadSoFar] = '\0'; /* terminating NUL */ *scriptP = script; }
void pamd_fill_drawproc(tuple ** const tuples, unsigned int const cols, unsigned int const rows, unsigned int const depth, sample const maxval, pamd_point const p, const void * const clientdata) { const fillobj * const fillObjP = clientdata; struct fillState * const stateP = fillObjP->stateP; /* Make room for two more coords, the max we might add. */ if (stateP->n + 2 > stateP->size) { stateP->size += SOME; REALLOCARRAY(stateP->coords, stateP->size); if (stateP->coords == NULL) pm_error("out of memory enlarging a fillhandle"); } if (stateP->n == 0) { /* Start first segment. */ stateP->segstart = stateP->n; stateP->ydir = 0; stateP->startydir = 0; addCoord(stateP, p); } else { pamd_point const prevPoint = stateP->coords[stateP->n - 1].point; int const dx = p.x - prevPoint.x; int const dy = p.y - prevPoint.y; if (dx == 0 && dy == 0) { /* These are the same coords we had last time; don't bother */ } else { if (abs(dx) > 1 || abs(dy) > 1) startNewSegment(stateP); else continueSegment(stateP, dy); addCoord(stateP, p); } } }
void pm_system_lp(const char * const progName, void stdinFeeder(int, void *), void * const feederParm, void stdoutAccepter(int, void *), void * const accepterParm, ...) { /*---------------------------------------------------------------------------- same as pm_system_vp() except with arguments as variable arguments instead of an array. -----------------------------------------------------------------------------*/ va_list args; bool endOfArgs; const char ** argArray; unsigned int n; va_start(args, accepterParm); endOfArgs = FALSE; argArray = NULL; for (endOfArgs = FALSE, argArray = NULL, n = 0; !endOfArgs; ) { const char * const arg = va_arg(args, const char *); REALLOCARRAY(argArray, n+1); argArray[n++] = arg; if (!arg) endOfArgs = TRUE; } va_end(args); pm_system_vp(progName, argArray, stdinFeeder, feederParm, stdoutAccepter, accepterParm); free(argArray); }
void srf_create_img(struct srf * const srfP, uint16_t const width, uint16_t const height) { /*---------------------------------------------------------------------------- Add an "image" to the SRF. An image is a horizontal series of 36 square frames, each showing a different angle view of an object, 10 degrees about. At least that's what it's supposed to be. We don't really care -- it's just an arbitrary rectangular raster image to us. -----------------------------------------------------------------------------*/ ++srfP->header.img_cnt; REALLOCARRAY(srfP->imgs, srfP->header.img_cnt); if (!srfP->imgs) pm_error("Could not allocate memory for %u images", srfP->header.img_cnt); srf_img_init(&srfP->imgs[srfP->header.img_cnt-1], width, height); }
static void continueTextString(png_text * const textChunkP, char const textline[], unsigned int const lineLength) { /*---------------------------------------------------------------------------- Update the text chunk *textChunkP by adding to it the text from textline[], which is a continuation line from a text string file. 'textline' is not NUL-terminated. Its length is 'lineLength', and it is at least one character long. 'textline' does not contain a newline character. -----------------------------------------------------------------------------*/ unsigned int cursor; /* cursor into textline[] */ unsigned int const newTextLength = textChunkP->text_length + lineLength + 1 + 1; REALLOCARRAY(textChunkP->text, newTextLength); if (textChunkP->text == NULL) pm_error("Unable to allocate %u bytes of memory for text string", newTextLength); textChunkP->text[textChunkP->text_length++] = '\n'; cursor = 0; skipWhiteSpace(textline, lineLength, &cursor); memcpy(textChunkP->text + textChunkP->text_length, textline + cursor, lineLength - cursor); textChunkP->text_length += lineLength - cursor; textChunkP->text[textChunkP->text_length] = '\0'; /* for safety */ }
static void fixControlChars(const char * const input, struct font * const fontP, const char ** const outputP) { /*---------------------------------------------------------------------------- Return a translation of input[] that can be rendered as glyphs in the font 'fontP'. Return it as newly malloced *outputP. Expand tabs to spaces. Remove any trailing newline. (But leave intermediate ones as line delimiters). Turn anything that isn't a code point in the font to a single space (which isn't guaranteed to be in the font either, of course). -----------------------------------------------------------------------------*/ /* We don't know in advance how big the output will be because of the tab expansions. So we make sure before processing each input character that there is space in the output buffer for a worst case tab expansion, plus a terminating NUL, reallocating as necessary. And we originally allocate enough for the entire line assuming no tabs. */ unsigned int const tabSize = 8; unsigned int inCursor, outCursor; char * output; /* Output buffer. Malloced */ size_t outputSize; /* Currently allocated size of 'output' */ outputSize = strlen(input) + 1 + tabSize; /* Leave room for one worst case tab expansion and NUL terminator */ MALLOCARRAY(output, outputSize); if (output == NULL) pm_error("Couldn't allocate %u bytes for a line of text.", (unsigned)outputSize); for (inCursor = 0, outCursor = 0; input[inCursor] != '\0'; ++inCursor) { if (outCursor + 1 + tabSize > outputSize) { outputSize = outCursor + 1 + 4 * tabSize; REALLOCARRAY(output, outputSize); if (output == NULL) pm_error("Couldn't allocate %u bytes for a line of text.", (unsigned)outputSize); } if (input[inCursor] == '\n' && input[inCursor+1] == '\0') { /* This is a terminating newline. We don't do those. */ } else if (input[inCursor] == '\t') { /* Expand this tab into the right number of spaces. */ unsigned int const nextTabStop = (outCursor + tabSize) / tabSize * tabSize; while (outCursor < nextTabStop) output[outCursor++] = ' '; } else if (!fontP->glyph[(unsigned char)input[inCursor]]) { /* Turn this unknown char into a single space. */ output[outCursor++] = ' '; } else output[outCursor++] = input[inCursor]; assert(outCursor <= outputSize); } output[outCursor++] = '\0'; assert(outCursor <= outputSize); *outputP = output; }
static void getFileLine(FILE * const fileP, const char ** const textP, unsigned int * const lengthP) { /*---------------------------------------------------------------------------- Read the next line (characters from current position through the first newline character) and return it. Put the text in newly malloc'ed storage. Do not include the newline. Add a terminating NUL for safety, but note that you can't rely on this as the end of line marker because the line may contain a NUL. *lengthP does not include the NUL that we add. If there are no more characters in the file, return NULL. -----------------------------------------------------------------------------*/ char * textline; /* malloc'ed */ unsigned int cursor; /* cursor into textline[] */ unsigned int allocatedSz; /* The number of characters of space that are allocated for 'textline' */ bool eol; bool gotSomething; allocatedSz = 128; /* initial value */ MALLOCARRAY(textline, allocatedSz); if (textline == NULL) pm_error("Unable to allocate buffer to read a line of a file."); cursor = 0; eol = FALSE; gotSomething = FALSE; while (!eol) { int const c = getc(fileP); if (c != EOF) gotSomething = TRUE; if (c == '\n' || c == EOF) eol = TRUE; else { /* leave space for safety NUL */ if (cursor > allocatedSz - 1 - 1) { allocatedSz *= 2; REALLOCARRAY(textline, allocatedSz); if (textline == NULL) pm_error("Unable to allocate buffer to read a line of " "a file."); } textline[cursor++] = c; } } textline[cursor] = '\0'; /* For safety; not part of line */ if (gotSomething) { *textP = textline; *lengthP = cursor; } else { free(textline); *textP = NULL; } }