//! @file rts-char.c
//! @author J. Marcel van der Veer
//
//! @section Copyright
//
// This file is part of VIF - vintage FORTRAN compiler.
// Copyright 2020-2025 J. Marcel van der Veer <algol68g@xs4all.nl>.
//
//! @section License
//
// This program is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation; either version 3 of the License, or 
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
// more details. You should have received a copy of the GNU General Public 
// License along with this program. If not, see <http://www.gnu.org/licenses/>.

//! @section Synopsis
//!
//! Runtime support for character - integer/real conversion.

#include <vif.h>

int_4 _str_to_int4 (char *str)
{
  int_4 sum = 0, fact = 1, len = strlen (str);
  for (int_4 k = 0; k < 4 && k < len; k++) {
    sum += fact * (int_4) str[k];
    fact <<= CHAR_BIT;
  }
  return sum;
}

real_8 _str_to_real8 (char *str)
{
  real_8 sum = 0.0;
  int_8 fact = 1, len = strlen (str);
  for (int_4 k = 0; k < (DBL_MANT_DIG / CHAR_BIT) && k < len; k++) {
    sum += fact * (int_4) str[k];
    fact <<= CHAR_BIT;
  }
  return sum;
}

char *bufcpy (char *dst, char *src, int_4 len)
{
// Fortran string lengths are len+1, last one is for null.
  memset (dst, '\0', len + 1);
  strncpy (dst, src, len);
  return dst;
}

char *bufcat (char *dst, char *src, int_4 len)
{
// Fortran string lengths are len+1, last one is for null.
  int_4 N = len - (int_4) strlen (dst);
  if (N > 0) {
    strncat (dst, src, N);
    dst[len] = '\0';
  }
  return dst;
}

char *bufrep (char *dst, char *src)
{
// Replace first chars of dst with src without its null char.
// A(I:J) = B
  while (src[0] != 0 && dst[0] != 0) {
    (dst++)[0] = (src++)[0];
  }
  return dst;
}

char *_bufsub(char *dst, char *src, int_4 i, int_4 f)
{ 
  int_4 N = f - i + 1;
  if (N > 0 && i >= 1) {
    bufcpy (dst, &src[i - 1], N);
    dst[N] = '\0';
  } else {
    dst[0] = '\0';
  }
  return dst;
}

char *concat (char *dst, char *lhs, char *rhs)
{
// Fortran // operator.
  strcpy (dst, lhs);
  strcat (dst, rhs);
  return dst;
}

char *_char (int c)
{
#define N_CHARS 256
  static char _ch[N_CHARS][2];
  int N = c % N_CHARS;
  _ch[N][0] = (char) N;
  _ch[N][1] = '\0';
  return &_ch[N][0];
#undef N_CHARS
}

int_4 _index (char *stack, char *needle)
{
   char *p = strstr (stack, needle);
   if (p == NO_TEXT) {
     return 0;
   }
   ptrdiff_t N = p - stack;
   return abs (N) + 1;
}
