int main(int argc, char **argv) { uint8_t data[BUFF_LEN]; parserutils_buffer *buf; int i; UNUSED(argc); UNUSED(argv); assert(parserutils_buffer_create(&buf) == PARSERUTILS_OK); /* Populate the data with '4's */ for (i = 0; i < BUFF_LEN; i++) data[i] = '4'; assert(parserutils_buffer_append(buf, data, BUFF_LEN) == PARSERUTILS_OK); /* Double the size, appending 'c's */ for (i = 0; i < BUFF_LEN; i++) data[i] = 'c'; assert(parserutils_buffer_append(buf, data, BUFF_LEN) == PARSERUTILS_OK); assert(buf->length == 2 * BUFF_LEN); /* Now reduce the length by half */ /* Buffer length is all '4's now */ buf->length = BUFF_LEN; /* Now discard half of the 4s from the middle of the buffer */ assert(parserutils_buffer_discard(buf, BUFF_LEN / 4, BUFF_LEN / 2) == PARSERUTILS_OK); /* Now check that the length is what we expect */ assert(buf->length == BUFF_LEN / 2); /* Now check that the buffer contains what we expect */ for (i = 0; i < BUFF_LEN / 2; i++) assert(buf->data[i] == '4'); /* Now check that the space we allocated beyond the buffer length is * as we expect, and not overwritten with 'c', which should be beyond * what the buffer_ code is allowed to move. */ for (i = BUFF_LEN / 2; i < BUFF_LEN; i++) assert(buf->data[i] != 'c'); assert(parserutils_buffer_destroy(buf) == PARSERUTILS_OK); printf("PASS\n"); return 0; }
/** * Create a string from a list of IDENT/S tokens * * \param c Parsing context * \param vector Vector containing tokens * \param ctx Vector iteration context * \param reserved Callback to determine if an identifier is reserved * \param result Pointer to location to receive resulting string * \return CSS_OK on success, appropriate error otherwise. * * Post condition: \a *ctx is updated with the next token to process * If the input is invalid, then \a *ctx remains unchanged. * * The resulting string's reference is passed to the caller */ css_error css__ident_list_to_string(css_language *c, const parserutils_vector *vector, int *ctx, bool (*reserved)(css_language *c, const css_token *ident), lwc_string **result) { int orig_ctx = *ctx; const css_token *token; css_error error = CSS_OK; parserutils_buffer *buffer; parserutils_error perror; lwc_string *interned; lwc_error lerror; perror = parserutils_buffer_create((parserutils_alloc) c->alloc, c->pw, &buffer); if (perror != PARSERUTILS_OK) return css_error_from_parserutils_error(perror); /* We know this token exists, and is an IDENT */ token = parserutils_vector_iterate(vector, ctx); /* Consume all subsequent IDENT or S tokens */ while (token != NULL && (token->type == CSS_TOKEN_IDENT || token->type == CSS_TOKEN_S)) { if (token->type == CSS_TOKEN_IDENT) { /* IDENT -- if reserved, reject style */ if (reserved != NULL && reserved(c, token)) { error = CSS_INVALID; goto cleanup; } perror = parserutils_buffer_append(buffer, (const uint8_t *) lwc_string_data(token->idata), lwc_string_length(token->idata)); } else { /* S */ perror = parserutils_buffer_append(buffer, (const uint8_t *) " ", 1); } if (perror != PARSERUTILS_OK) { error = css_error_from_parserutils_error(perror); goto cleanup; } token = parserutils_vector_iterate(vector, ctx); } /* Rewind context by one step if we consumed an unacceptable token */ if (token != NULL) *ctx = *ctx - 1; /* Strip trailing whitespace */ while (buffer->length > 0 && buffer->data[buffer->length - 1] == ' ') buffer->length--; /* Intern the buffer contents */ lerror = lwc_intern_string((char *) buffer->data, buffer->length, &interned); if (lerror != lwc_error_ok) { error = css_error_from_lwc_error(lerror); goto cleanup; } *result = interned; cleanup: parserutils_buffer_destroy(buffer); if (error != CSS_OK) *ctx = orig_ctx; return error; }