/*{{{}}}*/
/*{{{  #includes*/
#define _POSIX_SOURCE   1
#define _POSIX_C_SOURCE 2

#include <assert.h>
#include <ctype.h>
#include <float.h>
#include <math.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>

#include "cat.h"
#include "misc.h"
/*}}}  */

/*{{{  posnumber -- match positive integer*/
long int posnumber(const char *s, const char **endptr)
{
  unsigned char base=10;
  unsigned char c;
  register const char *nptr = s;
  long int result = 0L;
  int saw_a_digit = 0;

  if (*nptr == '0')
  {
    if ((c = *++nptr) == 'x' || c == 'X')
    {
      ++nptr;
      base = 16;
    }
    else
    {
      saw_a_digit = 1;
      base = 8;
    }
  }

  --nptr;
  while ((c=*++nptr))
  {
    if (isdigit(c)) c -= '0';
    else if (isupper(c)) c -= ('A'-10);
    else if (islower(c)) c -= ('a'-10);
    else break;
    if (c>=base) break;
    saw_a_digit = 1;
    result = result*base+c;
  }

  *endptr=(saw_a_digit ? nptr : s);
  return result;
}
/*}}}  */
/*{{{  order     -- sort two integers*/
void order(int *x, int *y)
{
  /*{{{  variables*/
  int t;
  /*}}}  */

  assert(x!=(int*)0);
  assert(y!=(int*)0);
  if (*x>*y)
  {
    t=*x;
    *x=*y;
    *y=t;
  }
}
/*}}}  */
/*{{{  strmalloc -- return malloced copy of string*/
char *strmalloc(const char *str)
{
  return (strcpy(malloc(strlen(str)+1),str));
}
/*}}}  */
/*{{{  isfinite  -- return error message about number or null*/
static volatile int caughtfpe;

static void catchfpe(int n)
{
  caughtfpe=1;
}

const char *isfinite(double x)
{
  struct sigaction act;
  
  caughtfpe=0;
  act.sa_handler=catchfpe;
  act.sa_flags=0;
  sigemptyset(&act.sa_mask);
  sigaction(SIGFPE,&act,(struct sigaction*)0);
  if (x==0.0)
  {
    if (caughtfpe) return NOTFINITE; /* who knows */
    else return (const char*)0;
  }
  else
  {
    if (caughtfpe) return NOTFINITE;
    /* If one comparison was allowed, more won't hurt either. */
    if (x<0.0)
    {
      if (x<-DBL_MAX) return NOTFINITE; /* -infinite */
      else return (const char*)0;
    }
    else if (x>0.0)
    {
      if (x>DBL_MAX) return NOTFINITE; /* +infinite */
      else return (const char*)0;
    }
    else return NOTFINITE; /* NaN */
  }
}
/*}}}  */
