#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>


// TO DO !!!!!

// Best Practices for va_list:  When intercepting variadic functions like vprintf,
// remember that va_list is a pointer-like object. If you need to read the arguments
// (e.g., to log them) and pass them to the real vprintf, you must first duplicate
// the argument list using va_copy and clean up with va_end to prevent memory corruption:

// https://stackoverflow.com/questions/10807310/platform-inconsistencies-with-vsprintf-and-va-list
// https://onlinedocs.microchip.com/oxy/GUID-07E1F2AB-C1A0-411C-966F-8738802C42B9-en-US-4/GUID-24E22499-EAEA-4FB2-A99D-739C4A28D618.html
// https://bumbershootsoft.wordpress.com/2022/07/24/custom-printf-wrapping-variadic-functions-in-c/

//va_list ap_copy;
//va_copy(ap_copy, ap);
// Now you can safely use ap_copy with va_arg() or similar,
// while ap goes to the original vprintf.
//va_end(ap_copy);


int systemf(char *s, ...) {
  extern int system(const char *command);
  /* Size the string by vfprint'ing it to /dev/null... */
  /* then malloc an appropriate area                   */
  char *APPROPRIATE_STRING;
  va_list ap;
  static FILE *nullfile = NULL;
  int string_length;

  if (nullfile == NULL) nullfile = fopen("/dev/null", "w");
  if (nullfile == NULL) {
    fprintf(stderr, "Major error - cannot open /dev/null\n");
    fflush(stderr);
    exit(1);
  }
  va_start(ap, s);
  string_length = vfprintf(nullfile, s, ap);
  va_end(ap);
  /* fclose(nullfile); */
  APPROPRIATE_STRING = malloc(string_length+1);
  va_start(ap, s);
  vsprintf(APPROPRIATE_STRING, s, ap);
  va_end(ap);
  return system(APPROPRIATE_STRING);
}
