This commit is contained in:
156
dump_json_append.c
Normal file
156
dump_json_append.c
Normal file
@@ -0,0 +1,156 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "cJSON.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
char *strndup(const char *s, size_t n) {
|
||||
size_t len = strnlen(s, n);
|
||||
char *p = (char *)malloc(len + 1);
|
||||
if (!p) return NULL;
|
||||
memcpy(p, s, len);
|
||||
p[len] = '\0';
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *level;
|
||||
char *message;
|
||||
char *title;
|
||||
char *file;
|
||||
int line;
|
||||
int end_line;
|
||||
int col;
|
||||
int end_col;
|
||||
} LogMessage;
|
||||
|
||||
char *read_stdin_line() {
|
||||
size_t size = 4096;
|
||||
char *line = malloc(size);
|
||||
if (!fgets(line, size, stdin)) {
|
||||
free(line);
|
||||
return NULL;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
char *extract_field(const char *src, const char *key) {
|
||||
const char *start = strstr(src, key);
|
||||
if (!start) return NULL;
|
||||
|
||||
start += strlen(key);
|
||||
const char *end = strchr(start, ',');
|
||||
if (!end) end = strstr(start, "::");
|
||||
if (!end) return strdup(start);
|
||||
return strndup(start, end - start);
|
||||
}
|
||||
|
||||
char *extract_message(const char *src) {
|
||||
const char *start = strstr(src, "::");
|
||||
if (!start) return NULL;
|
||||
start = strstr(start + 2, "::");
|
||||
if (!start) return NULL;
|
||||
return strdup(start + 2);
|
||||
}
|
||||
|
||||
LogMessage parse_log_line(const char *line) {
|
||||
LogMessage msg = {0};
|
||||
|
||||
if (strstr(line, "::warning")) msg.level = strdup("warning");
|
||||
else if (strstr(line, "::error")) msg.level = strdup("error");
|
||||
else msg.level = strdup("info");
|
||||
|
||||
msg.file = extract_field(line, "file=");
|
||||
char *line_str = extract_field(line, "line=");
|
||||
char *col_str = extract_field(line, "col=");
|
||||
|
||||
msg.line = line_str ? atoi(line_str) : 0;
|
||||
msg.col = col_str ? atoi(col_str) : 0;
|
||||
|
||||
msg.message = extract_message(line);
|
||||
|
||||
free(line_str);
|
||||
free(col_str);
|
||||
return msg;
|
||||
}
|
||||
|
||||
cJSON *log_message_to_json(const LogMessage *msg) {
|
||||
cJSON *obj = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(obj, "level", msg->level);
|
||||
cJSON_AddStringToObject(obj, "message", msg->message ? msg->message : "");
|
||||
cJSON_AddStringToObject(obj, "title", msg->title ? msg->title : NULL);
|
||||
cJSON_AddStringToObject(obj, "file", msg->file ? msg->file : NULL);
|
||||
if (msg->line) cJSON_AddNumberToObject(obj, "line", msg->line);
|
||||
if (msg->end_line) cJSON_AddNumberToObject(obj, "end_line", msg->end_line);
|
||||
if (msg->col) cJSON_AddNumberToObject(obj, "col", msg->col);
|
||||
if (msg->end_col) cJSON_AddNumberToObject(obj, "end_col", msg->end_col);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void append_log_to_file(const char *filename, const LogMessage *msg) {
|
||||
FILE *fp = fopen(filename, "r");
|
||||
long length = 0;
|
||||
char *data = NULL;
|
||||
cJSON *array = NULL;
|
||||
|
||||
if (fp) {
|
||||
fseek(fp, 0, SEEK_END);
|
||||
length = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
data = malloc(length + 1);
|
||||
fread(data, 1, length, fp);
|
||||
data[length] = 0;
|
||||
fclose(fp);
|
||||
array = cJSON_Parse(data);
|
||||
free(data);
|
||||
}
|
||||
|
||||
if (!array || !cJSON_IsArray(array)) {
|
||||
if (array) cJSON_Delete(array);
|
||||
array = cJSON_CreateArray();
|
||||
}
|
||||
|
||||
cJSON_AddItemToArray(array, log_message_to_json(msg));
|
||||
|
||||
char *json_out = cJSON_Print(array);
|
||||
fp = fopen(filename, "w");
|
||||
if (fp) {
|
||||
fputs(json_out, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
free(json_out);
|
||||
cJSON_Delete(array);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
const char *filename = NULL;
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (strcmp(argv[i], "-file") == 0 && i + 1 < argc) {
|
||||
filename = argv[++i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
fprintf(stderr, "Usage: dump_json_append -file <filename>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *line = read_stdin_line();
|
||||
if (!line) {
|
||||
fprintf(stderr, "No input read.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
LogMessage msg = parse_log_line(line);
|
||||
append_log_to_file(filename, &msg);
|
||||
free(line);
|
||||
free(msg.level);
|
||||
free(msg.message);
|
||||
free(msg.title);
|
||||
free(msg.file);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user