/*
 *  The Regina Rexx Interpreter
 *  Copyright (C) 1992-1994  Anders Christensen <anders@pvv.unit.no>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 * $Id: strings.h,v 1.4 1993/05/07 16:25:19 anders Exp anders $
 */


#ifndef _STRINGS_ALREADY_DEFINED_
#define _STRINGS_ALREADY_DEFINED_

typedef struct strengtype {
   int len, max ;
   char value[4] ;
} streng ;

/*
 #define Str_len(a) ((a)?(a->len):(0))
 #define Str_max(a) ((a)?(a->max):(0))
 #define Str_in(a,b) (Str_len(a)>(b))
 #define Str_end(a) ((a)->value+Str_len(a))
 #define Str_zero(a) ((Str_len(a)<Str_max(a)) && ((a)->value[(a)->len]==0x00))
*/

#define Str_len(a) ((a)->len)
#define Str_max(a) ((a)->max)
#define Str_in(a,b) (Str_len(a)>(b))
#define Str_end(a) ((a)->value+Str_len(a))
#define Str_zero(a) ((Str_len(a)<Str_max(a)) && ((a)->value[(a)->len]==0x00))


#define STRHEAD (sizeof(int)<<1)

/*
 * Routines in strings.c
 */
extern streng *Str_ndup( streng *name, int length ) ;
extern streng *Str_nodup( streng *name, int length, int offset ) ;
extern streng *Str_dup( streng *name ) ;
extern streng *Str_ncpy( streng *to, streng *from, int length ) ;
extern streng *Str_ncre( char *from, int length ) ;
extern streng *Str_cat( streng *to, streng *from ) ;
extern streng *Str_ncat( streng *to, streng *from, int length ) ;
extern streng *Str_nocat( streng *to, streng *from, int length, int offset ) ;
extern int Str_ncmp( streng *one, streng  *two, int length ) ;
extern int Str_cmp( streng *one, streng *two ) ;
extern int Str_ccmp( streng *one, streng *two ) ;
extern int Str_cncmp( streng *one, streng *two, int length ) ; 
extern int Str_cnocmp( streng *one, streng *two, int length, int offset ) ;
extern streng *Str_cre( char *value ) ;
extern streng *Str_catstr( streng *in, char *more ) ;
extern streng *Str_ncatstr( streng *in, char *more, int length ) ;
extern streng *Str_ify( streng *in ) ;

#define DIVTYPE_NORMAL   0
#define DIVTYPE_INTEGER  1
#define DIVTYPE_REMINDER 2
#define DIVTYPE_BOTH     3 

#define str_div(a,b) str_all_div(a,b,DIVTYPE_NORMAL)
#define str_rem(a,b) str_all_div(a,b,DIVTYPE_REMINDER)
#define str_idiv(a,b) str_all_div(a,b,DIVTYPE_INTEGER)

#if !defined(FLISTS) || defined(TRACEMEM)
   extern streng *Str_make( int size ) ;
#else  
#  define Str_make(a) get_a_streng(a)
#endif


int descr_sign( void * ) ;
streng *str_all_div( streng*, streng*, int ) ;
streng *str_mul( streng*, streng* ) ;
streng *str_pow( streng*, streng* ) ;
streng *str_add( streng*, streng* ) ;
streng *str_add2( void*, streng* ) ;
streng *str_sub( streng*, streng* ) ;
streng *str_neg( streng* ) ;
streng *str_trunc( streng*, int ) ;
streng *str_log_or( streng*, streng* ) ;
streng *str_log_xor( streng*, streng* ) ; 
streng *str_normalize( streng* ) ;
streng *str_log_and( streng*, streng* ) ;
streng *str_digitize( streng*, int, int ) ;
streng *str_format( streng*, int, int, int, int ) ;
streng *str_binerize( streng*, int ) ;
int str_true( streng* ) ;
streng *str_abs( streng* ) ;
int str_test( streng*, streng* ) ;
int str_test2( void*, streng* ) ;
int str_test3( streng*, streng* ) ;
void* get_a_descr( streng* ) ;
void free_a_descr( void* ) ;
#ifdef TRACEMEM
void mark_descrs() ;
#endif     

typedef struct num_descr_type
{
   char *num ;     /* pointer to matissa of presicion + 1 */
   int negative ;  /* boolean, true if negative number */
   int exp ;       /* value of exponent */
   int size ;      /* how much of num is actually used */
   int max ;       /* how much can num actually take */
} num_descr ;

num_descr *string_incr( num_descr* ) ;
void string_mul( num_descr *f, num_descr *s, num_descr *r ) ;
void string_div( num_descr *f, num_descr *s, num_descr *r, int type ) ;
int myiswnumber( streng *number ) ;
void str_round( num_descr *descr, int size ) ;
void string_pow( num_descr *num, int power, num_descr *acc, num_descr *res ) ;
int descr_to_int( num_descr *input ) ;
num_descr *is_a_descr( streng *input ) ;
int getdescr( streng *num, num_descr *descr ) ;
int string_test( num_descr *fdescr, num_descr *sdescr ) ;
void string_add( num_descr *f, num_descr *s, num_descr *r ) ;
void str_strip( num_descr *num ) ;
streng *str_norm( num_descr *in, streng *try )  ;
int *streng_to_int( streng *input ) ;

#endif /* _STRINGS_ALREADY_INCLUDED_ */
