Ejemplo n.º 1
0
static char *LogAddPrefix(LoggingPrivContext *log_ctx,
                          ARG_UNUSED LogLevel level,
                          const char *raw)
{
    const char *ip_addr = log_ctx->param;
    return ip_addr ? StringConcatenate(4, "[", ip_addr, "] ", raw) : xstrdup(raw);
}
Ejemplo n.º 2
0
bool ClassTablePut(ClassTable *table,
                   const char *ns, const char *name,
                   bool is_soft, ContextScope scope, const char *tags)
{
    assert(name);
    assert(is_soft || (!ns || strcmp("default", ns) == 0)); // hard classes should have default namespace
    assert(is_soft || scope == CONTEXT_SCOPE_NAMESPACE); // hard classes cannot be local

    if (ns == NULL)
    {
        ns = "default";
    }

    Class *cls = xmalloc(sizeof(*cls));
    ClassInit(cls, ns, name, is_soft, scope, tags);

    /* (cls->name != name) because canonification has happened. */
    char *fullname = StringConcatenate(3, ns, ":", cls->name);

    Log(LOG_LEVEL_DEBUG, "Setting %sclass: %s",
        is_soft ? "" : "hard ",
        fullname);

    return ClassMapInsert(table->classes, fullname, cls);
}
Ejemplo n.º 3
0
task Display_LCD(){
  bLCDBacklight = true;
  while(true){
    // Converting autonN to a string.
    //string autonNstring = autonN;

    // Battery level indicator
    string display = "R:";
  	string regularBat, backupBat;
    StringFormat(regularBat, "%1.2f", (float)nImmediateBatteryLevel/1000);
    //StringFormat(expand_bat, "%1.2f", (float)SensorValue[]/275);
    StringFormat(backupBat, "%1.2f", (float)BackupBatteryLevel/1000);
    StringConcatenate(display, regularBat);
    StringConcatenate(display, "V B:");
    StringConcatenate(display, backupBat);
    StringConcatenate(display, "V ");

    clearLCDLine(0);
    clearLCDLine(1);

    if(vexRT[Btn7L] == 1)
    {
    	displayLCDCenteredString(0, "Battery Power:");
    	displayLCDCenteredString(1, display);
  	}
    else
    {
    	if((float)nImmediateBatteryLevel/1000 < 6.45)
    	{
    		displayLCDCenteredString(0, "***WARNING***");
    		displayLCDCenteredString(1, "*LOW BATTERY*");
    	}
    	else
    	{
    		// Default screen:
    		string left = SensorValue[LeftLine];
    		string right = SensorValue[RightLine];
    		string arm = armRotation;
    		string lolbeav = isBeingIntaken;
    		displayLCDCenteredString(0, left);
    	  displayLCDCenteredString(1, lolbeav);
    	}
    }
    wait1Msec(100);

  }
}
Ejemplo n.º 4
0
static bool BundlesMigrationVersion0(DBHandle *db)
{
    bool errors = false;
    DBCursor *cursor;

    if (!NewDBCursor(db, &cursor))
    {
        return false;
    }

    char *key;
    void *value;
    int ksize, vsize;

    while (NextDB(cursor, &key, &ksize, &value, &vsize))
    {
        if (ksize == 0)
        {
            Log(LOG_LEVEL_INFO, "BundlesMigrationVersion0: Database structure error -- zero-length key.");
            continue;
        }

        if (strchr(key, '.')) // is qualified name?
        {
            continue;
        }

        char *fqname = StringConcatenate(3, "default", ".", key);
        if (!WriteDB(db, fqname, value, vsize))
        {
            Log(LOG_LEVEL_INFO, "Unable to write version 1 bundle entry for '%s'", key);
            errors = true;
            continue;
        }

        if (!DBCursorDeleteEntry(cursor))
        {
            Log(LOG_LEVEL_INFO, "Unable to delete version 0 bundle entry for '%s'", key);
            errors = true;
        }
    }

    if (DeleteDBCursor(cursor) == false)
    {
        Log(LOG_LEVEL_ERR, "BundlesMigrationVersion0: Unable to close cursor");
        errors = true;
    }

    if ((!errors) && (!WriteDB(db, "version", "1", sizeof("1"))))
    {
        errors = true;
    }

    return !errors;
}
Ejemplo n.º 5
0
static void test_concatenate(void)
{
    char *new_string = StringConcatenate(2, "snookie", "sitch");
    assert_string_equal(new_string, "snookiesitch");
    free(new_string);

    new_string = StringConcatenate(4, "a", NULL, "c", "d");
    assert_string_equal(new_string, "acd");
    free(new_string);

    new_string = StringConcatenate(3, "a", "b", "c", "d");
    assert_string_equal(new_string, "abc");
    free(new_string);

    new_string = StringConcatenate(1, "stuff");
    assert_string_equal(new_string, "stuff");
    free(new_string);

    new_string = StringConcatenate(0, NULL);
    assert_false(new_string);
}
Ejemplo n.º 6
0
static const char *LogHook(LoggingPrivContext *pctx, const char *message)
{
    PromiseLoggingContext *plctx = pctx->param;

    if (plctx->promise_level)
    {
        free(plctx->last_message);
        if (LEGACY_OUTPUT)
        {
            plctx->last_message = xstrdup(message);
        }
        else
        {
            plctx->last_message = StringConcatenate(3, plctx->stack_path, ": ", message);
        }

        return plctx->last_message;
    }
    else
    {
        return message;
    }
}
Ejemplo n.º 7
0
void VarRefSetMeta(VarRef *ref, bool enabled)
{
    if (enabled)
    {
        if (!VarRefIsMeta(ref))
        {
            char *tmp = ref->scope;
            memcpy(ref->scope, StringConcatenate(2, ref->scope, "_meta"), sizeof(char*));
            free(tmp);
        }
    }
    else
    {
        if (VarRefIsMeta(ref))
        {
            char *tmp = ref->scope;
            size_t len = strlen(ref->scope);
            memcpy(ref->scope, StringSubstring(ref->scope, len, 0, len - strlen("_meta")), sizeof(char*));
            free(tmp);
        }
    }

    ref->hash = VarRefHash(ref);
}
Ejemplo n.º 8
0
Archivo: server.c Proyecto: tzz/core
static char *LogHook(LoggingPrivContext *log_ctx, const char *message)
{
    const char *ipaddr = log_ctx->param;
    return StringConcatenate(3, ipaddr, "> ", message);
}
Ejemplo n.º 9
0
//-----------------------------------------------------------------------------------------------
int start()   {

   // E Farrell 2013
   // Store these values at the start
   // because they are dynamic and
   // get changed during processing later.
   int store_bars              = Bars;
   int store_indicator_counted = IndicatorCounted();
   int store_counted_bars      = store_bars - store_indicator_counted - 1;


   // Three ways of debugging:
   // Alert(...):    display popup MessageBox
   // Comment(...):  display on left corner of MAIN chart
   // Print(...):    write to "experts log"

   if (DEBUG == 1)
   {
     // Print msg to "Experts Log"
     // i.e. not to debug file
     bar_info = "";
     bar_info = StringConcatenate(bar_info, "Store_bars: ", DoubleToStr(store_bars,0), "; ");
     bar_info = StringConcatenate(bar_info, "store_indicator_counted: ", DoubleToStr(store_indicator_counted,0), "; ");
     Print (bar_info);
   }

   // Create X-Axis line along zero value
   ObjectCreate ("X-Axis", OBJ_HLINE, 1, 0, 0);
   ObjectSet    ("X-Axis", OBJPROP_COLOR, Black);
   ObjectSet    ("X-Axis", OBJPROP_WIDTH, 2);


   // vols[]
   // Compute stochastic volatility
   calc_volatility (store_bars, store_counted_bars);


   // levy_signal[]
   // Compute Levy Index
   // of Closing Price (i.e. the signal)
   calc_alpha_signal (Close, store_counted_bars);


   // levy_vol[]
   // Compute Levy Index
   // of stochastic volatility.
   calc_alpha_volatility (vols, store_counted_bars);


   // phase_wrapped[]
   // Compute WRAPPED phase
   // of levy_signal[] and levy_vol[].
   // i.e. instantaneous phase between -PI and +PI
   calc_phase (store_counted_bars);


   // Make a copy of the "phase_wrapped" array.
   // The new copy "phase_unwrapped" will be
   // worked on by the "calc_unwrap" function.
   for (int i = store_counted_bars; i >= 0; i--)
   {
         phase_unwrapped[i] = phase_wrapped[i];
   }


   // phase_unwrapped[]
   // UNWRAP the instantaneous phase
   calc_unwrap (phase_unwrapped, store_counted_bars);


   // least_squares_line[]
   // Compute regression line for unwrapped phase
   calc_regression (phase_unwrapped, phase_lookback);


   // phase_adjusted[]
   // Create a "lower" unwrapped Phase which hugs the x-axis
   calc_phase_adjusted (phase_lookback);


   return(0);
}
Ejemplo n.º 10
0
//-----------------------------------------------------------------------------------------------
int init()
{
   // E Farrell 2013

   IndicatorDigits(10);
   IndicatorShortName("LEVY PHASE (F. Farrell)");

   // Show or Hide a particular line?
   //
   // Use "DRAW_NONE" to hide a line
   // Use "DRAW_LINE" to display a line

   // Line 0:
   // Stochastic Volatility Line
   SetIndexBuffer     (0, vols);
   SetIndexLabel      (0, "Volatility");
   SetIndexDrawBegin  (0, Lookback);
   SetIndexStyle      (0, DRAW_NONE);
   //SetIndexStyle      (0, DRAW_LINE);


   // Line 1:
   // Levy Index of closing price (signal)
   SetIndexBuffer     (1, levy_signal);
   SetIndexLabel      (1, "levy_signal");
   SetIndexDrawBegin  (1, Lookback*2);
   SetIndexStyle      (1, DRAW_NONE);
   //SetIndexStyle      (1, DRAW_LINE);


   // Line 2:
   // Levy Index of Volatility
   SetIndexBuffer     (2, levy_vol);
   SetIndexLabel      (2, "levy_vol");
   SetIndexDrawBegin  (2, Lookback*2);
   SetIndexStyle      (2, DRAW_NONE);
   //SetIndexStyle      (2, DRAW_LINE);


   // Line 3:
   // Wrapped Phase Line
   SetIndexBuffer     (3, phase_wrapped);
   SetIndexLabel      (3, "Phase (wrapped)");
   SetIndexDrawBegin  (3, Lookback*2);
   //SetIndexStyle      (3, DRAW_NONE);
   SetIndexStyle      (3, DRAW_LINE);

   // Line 4:
   // Unwrapped Phase Line
   SetIndexBuffer     (4, phase_unwrapped);
   SetIndexLabel      (4, "Phase (Unwrapped)");
   SetIndexDrawBegin  (4, Lookback*2);
   //SetIndexStyle      (4, DRAW_NONE);
   SetIndexStyle      (4, DRAW_LINE);

  // Line 5:
  // Linear approximation of unwrapped phase
  SetIndexBuffer      (5, least_squares_line);
  SetIndexLabel       (5, "Regression Line");
  SetIndexDrawBegin   (5, Lookback*2);
  //SetIndexStyle       (5, DRAW_NONE);
  SetIndexStyle       (5, DRAW_LINE);

  // Line 6:
  // Final Adjusted Phase Line
  SetIndexBuffer      (6, phase_adjusted);
  SetIndexLabel       (6, "Phase (Adjusted)");
  SetIndexDrawBegin   (6, Lookback*2);
  SetIndexStyle       (6, DRAW_LINE);



   if (DEBUG == 1)
   {
      // Create Debug File to show array values.
      // It is CSV style, with ";" as field seperators.
      //
      // Name:       'Debug File HH-MM.txt'
      // Location:   'c:\<<alpari directory>>\experts\files\'
      //
      file_name  = "DebugFile ";
      file_name  = StringConcatenate (file_name, DoubleToStr(Hour()-2,0), "-");
      file_name  = StringConcatenate (file_name, DoubleToStr(Minute(),0), ".txt");

      file_handle = FileOpen (file_name, FILE_CSV|FILE_WRITE, ";");
      Print (file_name, " was opened.");

      if(file_handle == -1) {
         // File Error occurred
         Alert ("An error while opening the file. Last Error: ", GetLastError());
      }
   }

   return(0);
}
Ejemplo n.º 11
0
void VerifyVarPromise(EvalContext *ctx, const Promise *pp, bool allow_duplicates)
{
    ConvergeVariableOptions opts = CollectConvergeVariableOptions(ctx, pp, allow_duplicates);
    if (!opts.should_converge)
    {
        return;
    }

    char *scope = NULL;
    if (strcmp("meta", pp->parent_promise_type->name) == 0)
    {
        scope = StringConcatenate(2, PromiseGetBundle(pp)->name, "_meta");
    }
    else
    {
        scope = xstrdup(PromiseGetBundle(pp)->name);
    }

    //More consideration needs to be given to using these
    //a.transaction = GetTransactionConstraints(pp);
    Attributes a = { {0} };
    a.classes = GetClassDefinitionConstraints(ctx, pp);

    Rval existing_var_rval;
    DataType existing_var_type = DATA_TYPE_NONE;
    EvalContextVariableGet(ctx, (VarRef) { NULL, scope, pp->promiser }, &existing_var_rval, &existing_var_type);
    Buffer *qualified_scope = BufferNew();
    int result = 0;
    if (strcmp(PromiseGetNamespace(pp), "default") == 0)
    {
        result = BufferSet(qualified_scope, scope, strlen(scope));
        if (result < 0)
        {
            /*
             * Even though there will be no problems with memory allocation, there
             * might be other problems.
             */
            UnexpectedError("Problems writing to buffer");
            free(scope);
            BufferDestroy(&qualified_scope);
            return;
        }
    }
    else
    {
        if (strchr(scope, ':') == NULL)
        {
            result = BufferPrintf(qualified_scope, "%s:%s", PromiseGetNamespace(pp), scope);
            if (result < 0)
            {
                /*
                 * Even though there will be no problems with memory allocation, there
                 * might be other problems.
                 */
                UnexpectedError("Problems writing to buffer");
                free(scope);
                BufferDestroy(&qualified_scope);
                return;
            }
        }
        else
        {
            result = BufferSet(qualified_scope, scope, strlen(scope));
            if (result < 0)
            {
                /*
                 * Even though there will be no problems with memory allocation, there
                 * might be other problems.
                 */
                UnexpectedError("Problems writing to buffer");
                free(scope);
                BufferDestroy(&qualified_scope);
                return;
            }
        }
    }

    PromiseResult promise_result;

    Rval rval = opts.cp_save->rval;

    if (rval.item != NULL)
    {
        FnCall *fp = (FnCall *) rval.item;

        if (opts.cp_save->rval.type == RVAL_TYPE_FNCALL)
        {
            if (existing_var_type != DATA_TYPE_NONE)
            {
                // Already did this
                free(scope);
                BufferDestroy(&qualified_scope);
                return;
            }

            FnCallResult res = FnCallEvaluate(ctx, fp, pp);

            if (res.status == FNCALL_FAILURE)
            {
                /* We do not assign variables to failed fn calls */
                RvalDestroy(res.rval);
                free(scope);
                BufferDestroy(&qualified_scope);
                return;
            }
            else
            {
                rval = res.rval;
            }
        }
        else
        {
            Buffer *conv = BufferNew();

            if (strcmp(opts.cp_save->lval, "int") == 0)
            {
                result = BufferPrintf(conv, "%ld", IntFromString(opts.cp_save->rval.item));
                if (result < 0)
                {
                    /*
                     * Even though there will be no problems with memory allocation, there
                     * might be other problems.
                     */
                    UnexpectedError("Problems writing to buffer");
                    free(scope);
                    BufferDestroy(&qualified_scope);
                    BufferDestroy(&conv);
                    return;
                }
                rval = RvalCopy((Rval) {(char *)BufferData(conv), opts.cp_save->rval.type});
            }
            else if (strcmp(opts.cp_save->lval, "real") == 0)
            {
                double real_value = 0.0;
                if (DoubleFromString(opts.cp_save->rval.item, &real_value))
                {
                    result = BufferPrintf(conv, "%lf", real_value);
                }
                else
                {
                    result = BufferPrintf(conv, "(double conversion error)");
                }

                if (result < 0)
                {
                    /*
                     * Even though there will be no problems with memory allocation, there
                     * might be other problems.
                     */
                    UnexpectedError("Problems writing to buffer");
                    free(scope);
                    BufferDestroy(&conv);
                    BufferDestroy(&qualified_scope);
                    return;
                }
                rval = RvalCopy((Rval) {(char *)BufferData(conv), opts.cp_save->rval.type});
            }
            else
            {
                rval = RvalCopy(opts.cp_save->rval);
            }

            if (rval.type == RVAL_TYPE_LIST)
            {
                Rlist *rval_list = RvalRlistValue(rval);
                RlistFlatten(ctx, &rval_list);
                rval.item = rval_list;
            }

            BufferDestroy(&conv);
        }

        if (Epimenides(ctx, PromiseGetBundle(pp)->name, pp->promiser, rval, 0))
        {
            Log(LOG_LEVEL_ERR, "Variable \"%s\" contains itself indirectly - an unkeepable promise", pp->promiser);
            exit(1);
        }
        else
        {
            /* See if the variable needs recursively expanding again */

            Rval returnval = EvaluateFinalRval(ctx, BufferData(qualified_scope), rval, true, pp);

            RvalDestroy(rval);

            // freed before function exit
            rval = returnval;
        }

        if (existing_var_type != DATA_TYPE_NONE)
        {
            if (opts.ok_redefine)    /* only on second iteration, else we ignore broken promises */
            {
                ScopeDeleteVariable(BufferData(qualified_scope), pp->promiser);
            }
            else if ((THIS_AGENT_TYPE == AGENT_TYPE_COMMON) && (CompareRval(existing_var_rval, rval) == false))
            {
                switch (rval.type)
                {
                case RVAL_TYPE_SCALAR:
                    Log(LOG_LEVEL_VERBOSE, "Redefinition of a constant scalar \"%s\" (was %s now %s)",
                          pp->promiser, RvalScalarValue(existing_var_rval), RvalScalarValue(rval));
                    PromiseRef(LOG_LEVEL_VERBOSE, pp);
                    break;

                case RVAL_TYPE_LIST:
                    {
                        Log(LOG_LEVEL_VERBOSE, "Redefinition of a constant list \"%s\".", pp->promiser);
                        Writer *w = StringWriter();
                        RlistWrite(w, existing_var_rval.item);
                        char *oldstr = StringWriterClose(w);
                        Log(LOG_LEVEL_VERBOSE, "Old value: %s", oldstr);
                        free(oldstr);

                        w = StringWriter();
                        RlistWrite(w, rval.item);
                        char *newstr = StringWriterClose(w);
                        Log(LOG_LEVEL_VERBOSE, " New value: %s", newstr);
                        free(newstr);
                        PromiseRef(LOG_LEVEL_VERBOSE, pp);
                    }
                    break;

                default:
                    break;
                }
            }
        }

        if (IsCf3VarString(pp->promiser))
        {
            // Unexpanded variables, we don't do anything with
            RvalDestroy(rval);
            free(scope);
            BufferDestroy(&qualified_scope);
            return;
        }

        if (!FullTextMatch("[a-zA-Z0-9_\200-\377.]+(\\[.+\\])*", pp->promiser))
        {
            Log(LOG_LEVEL_ERR, "Variable identifier contains illegal characters");
            PromiseRef(LOG_LEVEL_ERR, pp);
            RvalDestroy(rval);
            free(scope);
            BufferDestroy(&qualified_scope);
            return;
        }

        if (opts.drop_undefined && rval.type == RVAL_TYPE_LIST)
        {
            for (Rlist *rp = rval.item; rp != NULL; rp = rp->next)
            {
                if (IsNakedVar(rp->item, '@'))
                {
                    free(rp->item);
                    rp->item = xstrdup(CF_NULL_VALUE);
                }
            }
        }

        if (!EvalContextVariablePut(ctx, (VarRef) { NULL, BufferData(qualified_scope), pp->promiser }, rval, DataTypeFromString(opts.cp_save->lval)))
        {
            Log(LOG_LEVEL_VERBOSE, "Unable to converge %s.%s value (possibly empty or infinite regression)", BufferData(qualified_scope), pp->promiser);
            PromiseRef(LOG_LEVEL_VERBOSE, pp);
            promise_result = PROMISE_RESULT_FAIL;
        }
        else
        {
            promise_result = PROMISE_RESULT_CHANGE;
        }
    }
    else
    {
        Log(LOG_LEVEL_ERR, "Variable %s has no promised value", pp->promiser);
        Log(LOG_LEVEL_ERR, "Rule from %s at/before line %zu", PromiseGetBundle(pp)->source_path, opts.cp_save->offset.line);
        promise_result = PROMISE_RESULT_FAIL;
    }

    /*
     * FIXME: Variable promise are exempt from normal evaluation logic still, so
     * they are not pushed to evaluation stack before being evaluated. Due to
     * this reason, we cannot call cfPS here to set classes, as it will error
     * out with ProgrammingError.
     *
     * In order to support 'classes' body for variables as well, we call
     * ClassAuditLog explicitly.
     */
    ClassAuditLog(ctx, pp, a, promise_result);

    free(scope);
    BufferDestroy(&qualified_scope);
    RvalDestroy(rval);
}
Ejemplo n.º 12
0
GenericAgentConfig *CheckOpts(int argc, char **argv)
{
    extern char *optarg;
    int c;
    GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_COMMON, GetTTYInteractive());
    config->tag_release_dir = NULL;

    while ((c = getopt_long(argc, argv, "dvnIw:f:D:N:VSrxMb:i:p:s:cg:hW:C::T:l",
                            OPTIONS, NULL))
           != -1)
    {
        switch (c)
        {
        case OPT_EVAL_FUNCTIONS:
            if (!optarg)
            {
                optarg = "yes";
            }
            config->agent_specific.common.eval_functions = strcmp("yes", optarg) == 0;
            break;

        case OPT_SHOW_CLASSES:
            config->agent_specific.common.show_classes = true;
            break;

        case OPT_SHOW_VARS:
            config->agent_specific.common.show_variables = true;
            break;

        case 'w':
            Log(LOG_LEVEL_INFO, "Setting workdir to '%s'", optarg);
            putenv(StringConcatenate(2, "CFENGINE_TEST_OVERRIDE_WORKDIR=", optarg));
            break;

        case 'c':
            config->check_runnable = true;
            break;

        case 'f':
            GenericAgentConfigSetInputFile(config, GetInputDir(), optarg);
            MINUSF = true;
            break;

        case 'd':
            LogSetGlobalLevel(LOG_LEVEL_DEBUG);
            break;

        case 'b':
            if (optarg)
            {
                Rlist *bundlesequence = RlistFromSplitString(optarg, ',');
                GenericAgentConfigSetBundleSequence(config, bundlesequence);
                RlistDestroy(bundlesequence);
            }
            break;

        case 'p':
            if (strcmp("none", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_NONE;
            }
            else if (strcmp("cf", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF;
            }
            else if (strcmp("json", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON;
            }
             else if (strcmp("cf-full", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF_FULL;
            }
            else if (strcmp("json-full", optarg) == 0)
            {
                config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON_FULL;
            }
            else
            {
                Log(LOG_LEVEL_ERR, "Invalid policy output format: '%s'. Possible values are 'none', 'cf', 'json', 'cf-full', 'json-full'", optarg);
                exit(EXIT_FAILURE);
            }
            break;

        case 's':
            if (strcmp("none", optarg) == 0)
            {
                break;
            }
            else if (strcmp("json", optarg) == 0)
            {
                JsonElement *json_syntax = SyntaxToJson();
                Writer *out = FileWriter(stdout);
                JsonWrite(out, json_syntax, 0);
                FileWriterDetach(out);
                JsonDestroy(json_syntax);
                exit(EXIT_SUCCESS);
            }
            else
            {
                Log(LOG_LEVEL_ERR, "Invalid syntax description output format: '%s'. Possible values are 'none', 'json'", optarg);
                exit(EXIT_FAILURE);
            }
            break;

        case 'K':
            config->ignore_locks = true;
            break;

        case 'D':
            {
                StringSet *defined_classes = StringSetFromString(optarg, ',');
                if (! config->heap_soft)
                {
                    config->heap_soft = defined_classes;
                }
                else
                {
                    StringSetJoin(config->heap_soft, defined_classes);
                    free(defined_classes);
                }
            }
            break;

        case 'N':
            {
                StringSet *negated_classes = StringSetFromString(optarg, ',');
                if (! config->heap_negated)
                {
                    config->heap_negated = negated_classes;
                }
                else
                {
                    StringSetJoin(config->heap_negated, negated_classes);
                    free(negated_classes);
                }
            }
            break;

        case 'I':
            LogSetGlobalLevel(LOG_LEVEL_INFO);
            break;

        case 'v':
            LogSetGlobalLevel(LOG_LEVEL_VERBOSE);
            break;

        case 'n':
            DONTDO = true;
            config->ignore_locks = true;
            break;

        case 'V':
        {
            Writer *w = FileWriter(stdout);
            GenericAgentWriteVersion(w);
            FileWriterDetach(w);
        }
        exit(EXIT_SUCCESS);

        case 'h':
        {
            Writer *w = FileWriter(stdout);
            GenericAgentWriteHelp(w, "cf-promises", OPTIONS, HINTS, true);
            FileWriterDetach(w);
        }
        exit(EXIT_SUCCESS);

        case 'M':
        {
            Writer *out = FileWriter(stdout);
            ManPageWrite(out, "cf-promises", time(NULL),
                         CF_PROMISES_SHORT_DESCRIPTION,
                         CF_PROMISES_MANPAGE_LONG_DESCRIPTION,
                         OPTIONS, HINTS,
                         true);
            FileWriterDetach(out);
            exit(EXIT_SUCCESS);
        }

        case 'r':
            Log(LOG_LEVEL_ERR, "Option '-r' has been deprecated");
            exit(EXIT_FAILURE);
            break;

        case 'W':
            if (!GenericAgentConfigParseWarningOptions(config, optarg))
            {
                Log(LOG_LEVEL_ERR, "Error parsing warning option");
                exit(EXIT_FAILURE);
            }
            break;

        case 'x':
            Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired.");
            exit(EXIT_SUCCESS);

        case 'C':
            if (!GenericAgentConfigParseColor(config, optarg))
            {
                exit(EXIT_FAILURE);
            }
            break;

        case 'T':
            GenericAgentConfigSetInputFile(config, optarg, "promises.cf");
            MINUSF = true;
            config->tag_release_dir = xstrdup(optarg);
            break;

        case 'l':
            LoggingEnableTimestamps(true);
            break;

        default:
        {
            Writer *w = FileWriter(stdout);
            GenericAgentWriteHelp(w, "cf-promises", OPTIONS, HINTS, true);
            FileWriterDetach(w);
        }
        exit(EXIT_FAILURE);

        }
    }

    if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind))
    {
        Log(LOG_LEVEL_ERR, "Too many arguments");
        exit(EXIT_FAILURE);
    }

    return config;
}