#include "flex.h"

#include "stringpool.h"
static int Stringpool_nextfree = 0;

DECLARE(Stringpool, OUR_CHAR, 256000000); // max size is only used if we inhibit the flex module

StrpoolIDX wstrtopool(const OUR_CHAR *wstr) {
  StrpoolIDX result = Stringpool_nextfree;
  for (;;) {
    OUR_CHAR wch = *wstr++;
    _Stringpool(Stringpool_nextfree++) = wch;
    if (wch == '\0') break;
  }
  return result;
}

StrpoolIDX strtopool(const char *str) {
  StrpoolIDX result = Stringpool_nextfree;
  for (;;) {
    char ch = *str++;
    _Stringpool(Stringpool_nextfree++) = ch;
    if (ch == '\0') break;
  }
  return result;
}

StrpoolIDX StrToPool(const char *s) {
  int p = Stringpool_nextfree;
  for (;;) {
    char c = *s++;
    _Stringpool(Stringpool_nextfree++) = c;
    if (c == '\0') break;
  }
  return p;
}

OUR_CHAR *pooltowstr_inner(StrpoolIDX p, const char *file, const int line) {
  if (p == -1) {
    fprintf(stderr, "* Error: pooltowstr passed -1 (uninitialised string) from %s, line %d\n", file, line);
  }
  return &Stringpool(p);
}

char *pooltostr_inner(StrpoolIDX p, const char *file, const int line) {
  if (p == -1) {
    fprintf(stderr,
            "* Error: pooltostr passed -1 (uninitialised string) from %s, line %d\n",
            file, line);
  }
  char *tmp;
  tmp = malloc(256); // this is going to be hella wasteful on the heap, but the code was *not* re-entrant before
  // and a procedure that called this twice (eg dump_code("%s %s", strtopool(a), strtopool(b)) would return the same string
  // for both calls!  It would have been OK if it returned the actual entire string off the stack but not a pointer...
  int warn = 0, idx = 0, pidx = p;
  
  for (;;) {
    int ch = Stringpool(pidx); pidx += 1;
    if (ch & 0xFFFFFF00) warn = 1;
    if (ch == '\0') break;
    tmp[idx] = ch&0xFF;
    if (++idx == 255) break;
  }
  tmp[idx] = '\0';
  
  if (warn) {
    fprintf(stderr, "* Error: pooltostr should not need to return a wide character string: \"" STR "\"\n", &Stringpool(p));
    fprintf(stderr, "         (Called from %s, line %d)\n", file, line);
    exit(1);
  }
  
  return tmp;
}
