Add trace_agg_cli_tool/main.c
This commit is contained in:
commit
21bb96bf54
1 changed files with 124 additions and 0 deletions
124
trace_agg_cli_tool/main.c
Normal file
124
trace_agg_cli_tool/main.c
Normal 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 */
|
||||
}
|
||||
Loading…
Reference in a new issue