
#include "string-support.h"
#include "misc.h"

#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <stdio.h>
#include <ctype.h>



#define MXBUFF	  10000			     /* can be made bigger for sprintf */

String strGetUsername()
{
  static String rslt = NULLSTRING;
  char *s;

  if (rslt != NULLSTRING) {		     /* already looked it up. */
    return rslt;
  }
  else if ((s = getenv("USER")) != (char *) NULL) {
    return strInit(rslt, s);		     /* return value string */
  }
  else {
    return NULLSTRING;
  }
}

String strGetMachineName()
{
  static String rslt = NULLSTRING;
  char *s;

  
  if (rslt != NULLSTRING) {		     /* already looked it up. */
    return rslt;
  }
  else if ((s = getenv("HOST")) != (char *) NULL) {
    return strInit(rslt, s);		     /* return value string */
  }
  else {
    return NULLSTRING;
  }
}

String strGetEnvVar(char *search)	     /* dont free the return string */
{
  static String rslt = NULLSTRING;
  char *s;
  
  if ((s = getenv(search)) != (char *) NULL) {
    return strInit(rslt, s);		     /* return value string */
  }
  else {
    return NULLSTRING;
  }
}

String strGetCurrentTime()		     /* dont free the return string */
{
  struct timeb t;
  struct tm *localtm;
  static char buff[50];
  static String rslt = NULLSTRING;
  extern int ftime(struct timeb *t);

  if (rslt == NULLSTRING) {
    rslt = strNew(50);

    if (rslt == NULLSTRING)
      return NULLSTRING;
  }
  
  if (ftime(&t) == -1  ||
      (localtm = localtime(&(t.time))) == NULL  ||
      strftime(buff, 49, "%a %b %d %H:%M:%S.%%03d %Y", localtm) != 29  ||
      t.millitm >= 1000  ||
      strPrintF(rslt, buff, t.millitm) == NULLSTRING) {
    strPrintF(rslt, "Time & Date not available");
  }

  return rslt;
}

static boolean HasSpace(char *s)
{
  for ( ; *s != (char) 0; s++)
    if (*s == ' ')
      return TRUE;

  return FALSE;
}

#define AddChar(c)    (chars_line++, strAddChar(cmdline, (c)))

String strCmdLine(int argc, char **argv)     /* dont free the return string */
{
  static String cmdline = NULLSTRING;
  char *sp;
  int chars_line = 0;
  int i, j;


  if (cmdline == NULLSTRING) {
    cmdline = strNew(100);

    if (cmdline == NULLSTRING)
      return NULLSTRING;
  }

  strClear(cmdline);

  for (i = 0; i < argc; i++) {
    boolean hs  = HasSpace(argv[i]);
    int  len = strlen(argv[i]);

    if (chars_line + len > 70  &&  (len < 60  ||  chars_line > 60)) { /* break */
      AddChar('\n');
      chars_line = 0;
      for (j = 0; j < 10; j++)
	AddChar(' ');
    }
    
    if (hs)  AddChar('\"');
    for (sp = argv[i]; *sp != (char) 0; sp++) {
      if (chars_line > 80) {		     /* break now */
	AddChar('\\');
	AddChar('\n');
	chars_line = 0;
	for (j = 0; j < 10; j++)
	  AddChar(' ');
      }
      
      if (*sp == '\"') {
	AddChar('\\');   AddChar('\"');
      }
      else if (*sp == '\n') {
	AddChar('\\');   AddChar('\n');
      }
      else if (*sp == '\t') {
	AddChar('\\');   AddChar('\t');
      }
      else if (*sp == '\v') {
	AddChar('\\');   AddChar('\v');
      }
      else if (*sp == '\b') {
	AddChar('\\');   AddChar('\b');
      }
      else if (*sp == '\r') {
	AddChar('\\');   AddChar('\r');
      }
      else if (*sp == '\f') {
	AddChar('\\');   AddChar('\f');
      }
      else if (*sp == '\a') {
	AddChar('\\');   AddChar('\a');
      }
      else if (!isprint(*sp)) {
	AddChar('\\');
	AddChar('0' + (((*sp)&0xC0) >> 6));
	AddChar('0' + (((*sp)&0x38) >> 3));
	AddChar('0' + (((*sp)&0x07)));
      }
      else
	AddChar(*sp);
    }
    if (hs)  AddChar('\"');
    AddChar(' ');
  }

  return cmdline;    
}

#undef AddChar


extern vsprintf(char *s, const char *fmt, va_list args);

/* String strPrintF(String str, char *fmt, va_list args) */
String strPrintF(va_alist)		     /* allocate if str == NULLSTRING */
va_dcl
{
  va_list argptr;
  static char buff[MXBUFF + 1];
  String str;
  char *fmt;
  

  va_start(argptr);
  str = va_arg(argptr, String);
  fmt = va_arg(argptr, char *);
  vsprintf(buff, fmt, argptr);
  va_end(argptr);

  return strInit_(&str, buff);
}

#if 0					     /* there is no vsscanf !!! */
/* int strScanF(String str, char *fmt, va_list args) */
int strScanF(va_alist)
va_dcl
{
  va_list argptr;
  String str;
  char *fmt;
  int val;
  

  va_start(argptr);
  str = va_arg(argptr, String);
  fmt = va_arg(argptr, char *);
  val = vssscanf(strGet(str), fmt, argptr);
  va_end(argptr);

  return val;
}
#endif 

/* be sure strCmdLine handles all non-print  chars correctly*/
/* eventually want %S: String  for printf*/


String strNewComment(int argc, char **argv, char **envp, String prev, String extra)
{
  String new = strNewCopy(prev);
  String add = strPrintF(NULLSTRING, "\n>> By %s@%s, on %s%s%s\n>> ",
			 strGet(strGetUsername()),
			 strGet(strGetMachineName()),
			 strGet(strGetCurrentTime()),
			 (extra ? "  ---  " : ""),
			 strGet(extra));
  strCat(new, add);
  strFree(add);
  strCat(new, strCmdLine(argc, argv));

  return new;
}
