/** * Add a string to the end of the current string in a string-builder-object. * The internal buffer is reallocated as needed. * If reallocation fails, the program halts. * * @param strbuilder The object to initialze. Must be initialized with * dc_strbuilder_init(). * @param text Null-terminated string to add to the end of the string-builder-string. * @return Returns a pointer to the copy of the given text. * The returned pointer is a pointer inside dc_strbuilder_t::buf and MUST NOT * be freed. If the string-builder was empty before, the returned * pointer is equal to dc_strbuilder_t::buf. * If the given text is NULL, NULL is returned and the string-builder-object is not modified. */ char* dc_strbuilder_cat(dc_strbuilder_t* strbuilder, const char* text) { // this function MUST NOT call logging functions as it is used to output the log if (strbuilder==NULL || text==NULL) { return NULL; } int len = strlen(text); if (len > strbuilder->free) { int add_bytes = DC_MAX(len, strbuilder->allocated); int old_offset = (int)(strbuilder->eos - strbuilder->buf); strbuilder->allocated = strbuilder->allocated + add_bytes; strbuilder->buf = realloc(strbuilder->buf, strbuilder->allocated+add_bytes); if (strbuilder->buf==NULL) { exit(39); } strbuilder->free = strbuilder->free + add_bytes; strbuilder->eos = strbuilder->buf + old_offset; } char* ret = strbuilder->eos; strcpy(strbuilder->eos, text); strbuilder->eos += len; strbuilder->free -= len; return ret; }
/* the six output registers %o0-%o5 are always loaded, thus we need to ensure the argument buffer has space for at least 24 bytes. */ static DCCallVM* dc_callvm_new_sparc(DCCallVM_vt* vt, DCsize size) { size=DC_MAX(size,sizeof(void*)*(6+1)); DCCallVM_sparc* self = (DCCallVM_sparc*) dcAllocMem(sizeof(DCCallVM_sparc)+size); dc_callvm_base_init(&self->mInterface, vt); dcVecInit(&self->mVecHead,size); return (DCCallVM*)self; }
void dc_callvm_call_mips_n64(DCCallVM* in_self, DCpointer target) { DCCallVM_mips_n64* self = (DCCallVM_mips_n64*)in_self; /* at minimum provide 16-bytes which hold the first four integer register as spill area and are automatically loaded to $4-$7 */ size_t size = DC_MAX(16, ( ( (unsigned) dcVecSize(&self->mVecHead) ) +7UL ) & (-8UL) ); dcCall_mips_n64(target, &self->mRegData, size, dcVecData(&self->mVecHead)); }
void dc_callvm_call_ppc32_darwin(DCCallVM* in_self, DCpointer target) { DCCallVM_ppc32* self = (DCCallVM_ppc32*)in_self; dcCall_ppc32_darwin( target, &self->mRegData, DC_MAX(dcVecSize(&self->mVecHead), 8*4), dcVecData(&self->mVecHead) ); }
/** * Init a string-builder-object. * A string-builder-object is placed typically on the stack and contains a string-buffer * which is initially empty. * * You can add data to the string-buffer using eg. dc_strbuilder_cat() or * dc_strbuilder_catf() - the buffer is reallocated as needed. * * When you're done with string building, the ready-to-use, null-terminates * string can be found at dc_strbuilder_t::buf, you can do whatever you like * with this buffer, however, never forget to call free() when done. * * @param strbuilder The object to initialze. * @param init_bytes The number of bytes to reserve for the string. If you have an * idea about how long the resulting string will be, you can give this as a hint here; * this avoids some reallocations; if the string gets longer, reallocation is done. * If you do not know how larget the string will be, give 0 here. * @return None. */ void dc_strbuilder_init(dc_strbuilder_t* strbuilder, int init_bytes) { if (strbuilder==NULL) { return; } strbuilder->allocated = DC_MAX(init_bytes, 128); /* use a small default minimum, we may use _many_ of these objects at the same time */ strbuilder->buf = malloc(strbuilder->allocated); if (strbuilder->buf==NULL) { exit(38); } strbuilder->buf[0] = 0; strbuilder->free = strbuilder->allocated - 1 /*the nullbyte! */; strbuilder->eos = strbuilder->buf; }