static void RenderHTMLContent(Buffer *out, const char *input, size_t len) { for (size_t i = 0; i < len; i++) { switch (input[i]) { case '&': BufferAppendString(out, "&"); break; case '"': BufferAppendString(out, """); break; case '<': BufferAppendString(out, "<"); break; case '>': BufferAppendString(out, ">"); break; default: BufferAppendChar(out, input[i]); break; } } }
void BufferAppendPromiseStr(Buffer *buf, const char *promiser) { for (const char *ch = promiser; *ch != '\0'; ch++) { switch (*ch) { case '*': BufferAppendChar(buf, ':'); break; case '#': BufferAppendChar(buf, '.'); break; default: BufferAppendChar(buf, *ch); break; } } }
Buffer* BufferFilter(Buffer *buffer, BufferFilterFn filter, const bool invert) { assert(buffer); Buffer *filtered = BufferNew(); for (unsigned int i = 0; i < buffer->used; ++i) { bool test = (*filter)(buffer->buffer[i]); if (invert) { test = !test; } if (test) { BufferAppendChar(filtered, buffer->buffer[i]); } } return filtered; }
/** @brief parse elements in a list passed through use_module @param[in] str: is the string to parse @param[out] newlist: rlist of elements found @retval 0: successful > 0: failed */ static int LaunchParsingMachine(const char *str, Rlist **newlist) { const char *s = str; state current_state = ST_OPENED; int ret; Buffer *buf = BufferNewWithCapacity(CF_MAXVARSIZE); assert(newlist); while (current_state != ST_CLOSED && *s) { switch(current_state) { case ST_ERROR: Log(LOG_LEVEL_ERR, "Parsing error : Malformed string"); ret = 1; goto clean; case ST_OPENED: if (CLASS_BLANK(*s)) { current_state = ST_OPENED; } else if (CLASS_BRA1(*s)) { current_state = ST_IO; } else if (CLASS_ANY0(*s)) { current_state = ST_ERROR; } s++; break; case ST_IO: if (CLASS_BLANK(*s)) { current_state = ST_IO; } else if (CLASS_START1(*s)) { BufferClear(buf); current_state = ST_ELM1; } else if (CLASS_START2(*s)) { BufferClear(buf); current_state = ST_ELM2; } else if (CLASS_ANY1(*s)) { current_state = ST_ERROR; } s++; break; case ST_ELM1: if (CLASS_END1(*s)) { RlistAppendScalar(newlist, BufferData(buf)); BufferClear(buf); current_state = ST_END1; } else if (CLASS_ANY2(*s)) { BufferAppendChar(buf, *s); current_state = ST_ELM1; } s++; break; case ST_ELM2: if (CLASS_END2(*s)) { RlistAppendScalar(newlist, BufferData(buf)); BufferClear(buf); current_state = ST_END2; } else if (CLASS_ANY3(*s)) { BufferAppendChar(buf, *s); current_state = ST_ELM2; } s++; break; case ST_END1: if (CLASS_SEP(*s)) { current_state = ST_SEP; } else if (CLASS_BRA2(*s)) { current_state = ST_PRECLOSED; } else if (CLASS_BLANK(*s)) { current_state = ST_END1; } else if (CLASS_ANY4(*s)) { current_state = ST_ERROR; } s++; break; case ST_END2: if (CLASS_SEP(*s)) { current_state = ST_SEP; } else if (CLASS_BRA2(*s)) { current_state = ST_PRECLOSED; } else if (CLASS_BLANK(*s)) { current_state = ST_END2; } else if (CLASS_ANY5(*s)) { current_state = ST_ERROR; } s++; break; case ST_SEP: if (CLASS_BLANK(*s)) { current_state = ST_SEP; } else if (CLASS_START1(*s)) { current_state = ST_ELM1; } else if (CLASS_START2(*s)) { current_state = ST_ELM2; } else if (CLASS_ANY6(*s)) { current_state = ST_ERROR; } s++; break; case ST_PRECLOSED: if (CLASS_BLANK(*s)) { current_state = ST_PRECLOSED; } else if (CLASS_EOL(*s)) { current_state = ST_CLOSED; } else if (CLASS_ANY7(*s)) { current_state = ST_ERROR; } s++; break; default: Log(LOG_LEVEL_ERR, "Parsing logic error: unknown state"); ret = 2; goto clean; break; } } if (current_state != ST_CLOSED && current_state != ST_PRECLOSED ) { Log(LOG_LEVEL_ERR, "Parsing error : Malformed string (unexpected end of input)"); ret = 3; goto clean; } BufferDestroy(buf); return 0; clean: BufferDestroy(buf); RlistDestroy(*newlist); assert(ret != 0); return ret; }
bool ExpandScalar(const EvalContext *ctx, const char *ns, const char *scope, const char *string, Buffer *out) { assert(string); bool returnval = true; if (strlen(string) == 0) { return false; } // TODO: cleanup, optimize this mess Buffer *var = BufferNew(); Buffer *current_item = BufferNew(); Buffer *temp = BufferNew(); for (const char *sp = string; /* No exit */ ; sp++) /* check for varitems */ { char varstring = false; size_t increment = 0; if (*sp == '\0') { break; } BufferZero(current_item); ExtractScalarPrefix(current_item, sp, strlen(sp)); BufferAppend(out, BufferData(current_item), BufferSize(current_item)); sp += BufferSize(current_item); if (*sp == '\0') { break; } BufferZero(var); if (*sp == '$') { switch (*(sp + 1)) { case '(': varstring = ')'; ExtractScalarReference(var, sp, strlen(sp), false); if (BufferSize(var) == 0) { BufferAppendChar(out, '$'); continue; } break; case '{': varstring = '}'; ExtractScalarReference(var, sp, strlen(sp), false); if (BufferSize(var) == 0) { BufferAppendChar(out, '$'); continue; } break; default: BufferAppendChar(out, '$'); continue; } } BufferZero(current_item); { BufferZero(temp); ExtractScalarReference(temp, sp, strlen(sp), true); if (IsCf3VarString(BufferData(temp))) { ExpandScalar(ctx, ns, scope, BufferData(temp), current_item); } else { BufferAppend(current_item, BufferData(temp), BufferSize(temp)); } } increment = BufferSize(var) - 1; char name[CF_MAXVARSIZE] = ""; if (!IsExpandable(BufferData(current_item))) { DataType type = DATA_TYPE_NONE; const void *value = NULL; { VarRef *ref = VarRefParseFromNamespaceAndScope(BufferData(current_item), ns, scope, CF_NS, '.'); value = EvalContextVariableGet(ctx, ref, &type); VarRefDestroy(ref); } if (value) { switch (type) { case DATA_TYPE_STRING: case DATA_TYPE_INT: case DATA_TYPE_REAL: BufferAppend(out, value, strlen(value)); break; case DATA_TYPE_STRING_LIST: case DATA_TYPE_INT_LIST: case DATA_TYPE_REAL_LIST: case DATA_TYPE_NONE: if (varstring == '}') { snprintf(name, CF_MAXVARSIZE, "${%s}", BufferData(current_item)); } else { snprintf(name, CF_MAXVARSIZE, "$(%s)", BufferData(current_item)); } BufferAppend(out, name, strlen(name)); returnval = false; break; default: Log(LOG_LEVEL_DEBUG, "Returning Unknown Scalar ('%s' => '%s')", string, BufferData(out)); BufferDestroy(var); BufferDestroy(current_item); BufferDestroy(temp); return false; } } else { if (varstring == '}') { snprintf(name, CF_MAXVARSIZE, "${%s}", BufferData(current_item)); } else { snprintf(name, CF_MAXVARSIZE, "$(%s)", BufferData(current_item)); } BufferAppend(out, name, strlen(name)); returnval = false; } } sp += increment; BufferZero(current_item); } BufferDestroy(var); BufferDestroy(current_item); BufferDestroy(temp); return returnval; }
PromiseResult VerifyClassPromise(EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param) { assert(param == NULL); Attributes a = GetClassContextAttributes(ctx, pp); if (!StringMatchFull("[a-zA-Z0-9_]+", pp->promiser)) { Log(LOG_LEVEL_VERBOSE, "Class identifier '%s' contains illegal characters - canonifying", pp->promiser); xsnprintf(pp->promiser, strlen(pp->promiser) + 1, "%s", CanonifyName(pp->promiser)); } if (a.context.nconstraints == 0) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "No constraints for class promise '%s'", pp->promiser); return PROMISE_RESULT_FAIL; } if (a.context.nconstraints > 1) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Irreconcilable constraints in classes for '%s'", pp->promiser); return PROMISE_RESULT_FAIL; } if (EvalClassExpression(ctx, a.context.expression, pp)) { if (!ValidClassName(pp->promiser)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Attempted to name a class '%s', which is an illegal class identifier", pp->promiser); return PROMISE_RESULT_FAIL; } else { char *tags = NULL; { Buffer *tag_buffer = BufferNew(); BufferAppendString(tag_buffer, "classes promise,attribute_name=label,source=promise"); for (const Rlist *rp = PromiseGetConstraintAsList(ctx, "meta", pp); rp; rp = rp->next) { BufferAppendChar(tag_buffer, ','); BufferAppendString(tag_buffer, RlistScalarValue(rp)); } tags = BufferClose(tag_buffer); } if (/* Persistent classes are always global: */ a.context.persistent > 0 || /* Namespace-scope is global: */ a.context.scope == CONTEXT_SCOPE_NAMESPACE || /* If there is no explicit scope, common bundles define global * classes, other bundles define local classes: */ (a.context.scope == CONTEXT_SCOPE_NONE && 0 == strcmp(PromiseGetBundle(pp)->type, "common"))) { Log(LOG_LEVEL_VERBOSE, "C: + Global class: %s ", pp->promiser); EvalContextClassPutSoft(ctx, pp->promiser, CONTEXT_SCOPE_NAMESPACE, tags); } else { Log(LOG_LEVEL_VERBOSE, "C: + Private class: %s ", pp->promiser); EvalContextClassPutSoft(ctx, pp->promiser, CONTEXT_SCOPE_BUNDLE, tags); } if (a.context.persistent > 0) { Log(LOG_LEVEL_VERBOSE, "C: + Persistent class: '%s'. (%d minutes)", pp->promiser, a.context.persistent); EvalContextHeapPersistentSave(ctx, pp->promiser, a.context.persistent, CONTEXT_STATE_POLICY_RESET, tags); } free(tags); return PROMISE_RESULT_NOOP; } } return PROMISE_RESULT_NOOP; }