#pragma once /* * listfmt_json.h -- shared cJSON array/object plumbing for xce_test's * listing commands' JSON output mode (xce-test-cli-ux spec, task 2.2; * Requirements 5.1, 5.3). * * This module owns ONLY the JSON array/object lifecycle: start an array, * append a new row object to it, add string/number fields to a row, then * print + free the whole array. It does NOT know about workerlist's/ * joblist's/reslist's own field sets -- each command's existing row * struct already exists and is stable (design.md's Simplification lens), * so this library introduces no generic "record"/"row" abstraction beyond * the bare cJSON object handle itself. Wiring this into cmd_workerlist/ * cmd_joblist/cmd_reslist (their field mapping, their --json flag) is * task 3.4, not this one. * * cJSON is already linked into xce_test (struct2json_dep, per * research.md) and already used for job exdata blobs (test.c's * build_job_envs()) -- this module reuses that exact same cJSON API * surface, not a different one. */ #include /* Creates a new, empty JSON array meant to hold one object per output * row. The caller passes the returned array to listfmt_json_new_row() * once per row, then to listfmt_json_finish() exactly once when done. * Returns NULL on allocation failure. */ cJSON* listfmt_json_begin(void); /* Adds a string field `key`: `val` to `row`. `val` is copied in full, * regardless of its length -- no field is ever truncated or dropped for * being "too long" (Requirement 5.3). A NULL `val` is stored as an * explicit JSON null rather than silently omitted or crashing. No-op if * `row` or `key` is NULL. */ void listfmt_json_add_string(cJSON* row, const char* key, const char* val); /* Adds a numeric field `key`: `val` to `row`. No-op if `row` or `key` is * NULL. */ void listfmt_json_add_number(cJSON* row, const char* key, double val); /* Creates a new, empty JSON object, appends it to `array`, and returns * that object so the caller can then call listfmt_json_add_string()/ * listfmt_json_add_number() on it for each of this row's fields. Returns * NULL (leaving `array` unmodified) if `array` is NULL or the new object * could not be allocated. */ cJSON* listfmt_json_new_row(cJSON* array); /* Prints `array` to stdout as JSON -- command-RESULT data, per * Requirement 3's stdout/stderr discipline, so it is written to stdout * only, never stderr -- and then frees the entire cJSON structure * (`array` and every row/field it holds). `array` must not be * referenced again after this call. No-op if `array` is NULL. */ void listfmt_json_finish(cJSON* array);