Add trace_agg_cli_tool/main.c

This commit is contained in:
Mika 2025-12-08 09:42:01 +00:00
commit 21bb96bf54

124
trace_agg_cli_tool/main.c Normal file
View file

@ -0,0 +1,124 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdbool.h>
#include <sys/stat.h>
/*
* trace_agg_cli_tool
* -------------------
* Kleines Linux-CLI-Programm, das das Python-Skript "trace_agg.py"
* als Backend nutzt. Es stellt eine einfache C-CLI bereit, die
* eine Funktion "aggregate_data" nachbildet.
*
* Aufruf:
* ./trace_agg_cli_tool <input_file> <output_file>
*
* Verhalten:
* - Führt das Python-Skript "trace_agg.py" (im selben Verzeichnis
* wie dieses Binary) aus.
* - Übergibt die Pfade zu Eingabe- und Ausgabedatei als Argumente.
* - Gibt 0 bei Erfolg und 1 bei Fehler zurück ("boolean"-ähnlich).
*
* Hinweise:
* - Es werden keine Dateien gelöscht oder überschrieben, außer
* der explizit angegebene Ausgabepfad, den das Python-Skript
* selbst erzeugt/überschreibt.
* - Es werden keine Netzwerk-Operationen ausgeführt.
*/
/* Hilfsfunktion: prüft, ob eine Datei existiert (lesbar). */
static bool file_exists(const char *path) {
struct stat st;
return (stat(path, &st) == 0 && S_ISREG(st.st_mode));
}
/*
* aggregate_data
* --------------
* Entspricht der im Artifact beschriebenen Funktion.
* Ruft intern das Python-Skript "trace_agg.py" auf.
*
* Parameter:
* input_file - Pfad zur Eingabedatei (CSV/Trace).
* output_file - Pfad zur Ausgabedatei.
*
* Rückgabe:
* true bei Erfolg (Exit-Code 0 vom Python-Skript),
* false bei Fehler.
*/
static bool aggregate_data(const char *input_file, const char *output_file) {
if (input_file == NULL || output_file == NULL) {
fprintf(stderr, "aggregate_data: null pointer argument\n");
return false;
}
if (!file_exists(input_file)) {
fprintf(stderr, "Eingabedatei existiert nicht: %s\n", input_file);
return false;
}
/* Kommando für system(): python3 trace_agg.py <input> <output> */
const char *python = "python3";
const char *script = "trace_agg.py";
if (!file_exists(script)) {
fprintf(stderr, "Python-Skript nicht gefunden im aktuellen Verzeichnis: %s\n", script);
return false;
}
/* Puffer für das aufzurufende Kommando. */
char cmd[4096];
/*
* Wir quoten die Argumente sehr einfach mit einfachen Anführungszeichen,
* um Leerzeichen einigermaßen sicher zu handhaben. Für die vorgesehene
* Nutzung (lokale Pfade) ist das ausreichend.
*/
int n = snprintf(cmd, sizeof(cmd), "%s '%s' '%s' '%s'",
python, script, input_file, output_file);
if (n < 0 || (size_t)n >= sizeof(cmd)) {
fprintf(stderr, "Kommando zu lang oder Formatfehler.\n");
return false;
}
int ret = system(cmd);
if (ret == -1) {
perror("system");
return false;
}
/* system() gibt den Exit-Status kodiert zurück. Wir werten 0 als Erfolg. */
if (WIFEXITED(ret) && WEXITSTATUS(ret) == 0) {
return true;
}
fprintf(stderr, "trace_agg.py meldete einen Fehler (Exit-Code=%d).\n",
WIFEXITED(ret) ? WEXITSTATUS(ret) : -1);
return false;
}
static void print_usage(const char *prog) {
fprintf(stderr,
"Nutzung: %s <input_file> <output_file>\n"
"Beschreibung: Ruft trace_agg.py zur Aggregation von Trace-Daten auf.\n",
prog);
}
int main(int argc, char *argv[]) {
if (argc != 3) {
print_usage(argv[0]);
return 1;
}
const char *input_file = argv[1];
const char *output_file = argv[2];
bool ok = aggregate_data(input_file, output_file);
if (!ok) {
return 1; /* "false" im Sinne des beschriebenen API-Verhaltens */
}
return 0; /* Erfolg */
}