/*
*  ChkTeX, utility functions -- header file.
*  Copyright (C) 1995-96 Jens T. Berger Thielemann
*
*  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 2 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, write to the Free Software
*  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*  Contact the author at:
*              Jens Berger
*              Spektrumvn. 4
*              N-0666 Oslo
*              Norway
*              E-mail: <[email protected]>
*
*
*/

#ifndef UTILITY_H
#define UTILITY_H 1

#include "ChkTeX.h"
#include "OpSys.h"

/*
* How many indexes we'll allocate first time
*/
#define MINPUDDLE       256

/*
* How many bytes we want in front/end of each char buffer. > 2
*/
#define WALLBYTES       4

#ifndef HASH_SIZE
#  define HASH_SIZE    1009     /* A reasonably large prime */
#endif

#define FORWL(ind, list)  for(ind = 0; ind < (list).Stack.Used; ind++)


enum Strip
{
   STRP_LFT = 0x01,
   STRP_RGT = 0x02,
   STRP_BTH = 0x03
};

struct HashEntry
{
   struct HashEntry *Next;
   char *Str;
};

struct Hash
{
   struct HashEntry **Index;
};

struct Stack
{
   void **Data;
   unsigned long Size, Used;
};

struct WordList
{
   unsigned long MaxLen;
   int NonEmpty;
   struct Stack Stack;
   struct Hash Hash;
};
#define WORDLIST_DEFINED

struct FileNode
{
   char *Name;
   FILE *fh;
   unsigned long Line;
};

/* Subtract 1 because sizeof includes the null terminator.
* WARNING: To use this on a variable, the type should be char[]
* rather than char*, since for some versions of gcc these give
* different values. */
#define STRLEN(x)  (sizeof(x)/sizeof(x[0]) - 1)

int fexists(const char *Filename);

void *sfmemset(void *to, int c, long n);
void *saferealloc(void *old, size_t newsize);

int strafter(const char *Str, const char *Cmp);
void strrep(char *String, const char From, const char To);
void strxrep(char *Buf, const char *Prot, const char To);
char *strip(char *String, const enum Strip What);
void strwrite(char *To, const char *From, unsigned long Len);
int strinfront(const char *Str, const char *Cmp);
char *strdupx(const char *String, int Extra);
void strmove(char *a, const char *b);

void ClearHash(struct Hash *h);
void InsertHash(char *a, struct Hash *h);
char *HasHash(const char *a, const struct Hash *h);

int InsertWord(const char *Word, struct WordList *WL);
char *HasWord(const char *Word, struct WordList *WL);
void MakeLower(struct WordList *wl);
void ListRep(struct WordList *wl, const char From, const char To);
void ClearWord(struct WordList *WL);

int StkPush(void *Data, struct Stack *Stack);
void *StkPop(struct Stack *Stack);
void *StkTop(struct Stack *Stack);

FILE *CurStkFile(struct Stack *stack);
const char *CurStkName(struct Stack *stack);
unsigned long CurStkLine(struct Stack *stack);
long CurStkMode(struct Stack *stack);
long *PushMode(long mode, struct Stack *stack);
char *FGetsStk(char *Dest, unsigned long len, struct Stack *stack);
int PushFileName(const char *Name, struct Stack *stack);
int PushFile(const char *, FILE *, struct Stack *);


void FreeErrInfo(struct ErrInfo *ei);
struct ErrInfo *PushChar(const char c, const unsigned long Line,
                        const unsigned long Column, struct Stack *Stk,
                        const char *LineCpy);
struct ErrInfo *PushErr(const char *Data, const unsigned long Line,
                       const unsigned long Column,
                       const unsigned long ErrLen, const char *LineCpy,
                       struct Stack *Stk);
struct ErrInfo *TopChar(struct Stack *Stack);
struct ErrInfo *TopErr(struct Stack *Stack);
struct ErrInfo *PopErr(struct Stack *Stack);
struct ErrInfo *TopMatch(struct Stack *Stack, char *String);

long BrackIndex(const char c);
void AddBracket(const char c);
char MatchBracket(const char c);



short substring(const char *source, char *dest, unsigned long pos, long len);

#ifndef  HAVE_STRLWR
#  define  strlwr  mystrlwr
char *mystrlwr(char *String);
#endif

#ifndef  HAVE_STRDUP
#  define  strdup  mystrdup
char *mystrdup(const char *String);
#endif


#ifndef HAVE_STRCASECMP
int strcasecmp(char *a, char *b);
#endif

#if !(defined HAVE_DECL_STPCPY && HAVE_DECL_STPCPY)
static inline char * stpcpy(char *dest, const char *src)
{
   return strcpy(dest, src) + strlen(src);
}
#endif


#endif /* UTILITY_H */