/*(( "Kopf" */
/* -----------------------------------------------------------------------------

   $Id: util.h,v 1.4 1997/06/29 19:24:13 mshopf Exp mshopf $

   GoldED API client, ©1997 Matthias Hopf.
   Compiled with SasC.


   Utility functions.

   ------------------------------------------------------------------------------
*/

/*)) */
#ifndef _UTIL_H
#define _UTIL_H

/*(( "Includes" */

#include "smartindent.h"

#include <proto/exec.h>

#include <stdio.h>
#include <ctype.h>
#include <string.h>

/*)) */
/*(( "Constants" */

#define MODE_LINE     1
#define MODE_LASTLINE 2
#define MODE_BLOCK    4
#define MODE_CURSOR   8

#define ADD_SPARSE_INDENTATION 8    /* Allocate more memory than needed for future same line intendations */

/*)) */
/*(( "Data" */

extern struct Conf      Config;
extern struct Semantic *Semantics[];

extern int ExecVersion;
extern int MemAllocSmallFlags;


/*)) */
/*(( "Common Errors" */

/* Errors that are not specific to a semantic parser */

extern const char *SYNTAX_ERROR;
extern const char *UNMATCHED_BRACE_ERROR;
extern const char *PRAEPROCESSOR_ERROR;
extern const char *SUSPICIOUS_ERROR;
extern const char *STRING_TERMINATION_ERROR;
extern const char *INTERNAL_ERROR;

/* Errors that are not parser related */

extern const char *UNKNOWN_MODE_ERROR;
extern const char *UNSPECIFIED_MODE_ERROR;

/*))*/


// Comment this out if you don't want debugging enabled
#define DEBUG 1
/*(( "Debugging" */

#ifdef DEBUG
extern  int Dbug;
#define D_WORD     1
#define D_MOVE     2
#define D_ERROR    4
#define D_PARSER   8
#define D_RETURN   16
#define D_KEY      32
#define D_CURSOR   64
#define D_REQUESTS 128

#define debug(a,b)    do { if (Dbug & a) Printf b; } while (0)
#else
#define debug(a,b)    ((void)0)
#define dcheck        ((void)0)
#endif

/*)) */
/*(( "Macros" */

#define offsetof(s,c)  (((char *)&((s *)0)->c) - (char *)0)
#define OrderString(o) ((char *)((o)+1))
#define streq(a,b)     (strcmp ((a), (b)) == 0)

/**** still to be done better (remove sprintf() here) */
#define Error(c,e)     do { if (! (c)->ErrTxt) { c->ErrTxt = c->ErrBuffer; sprintf (c->ErrBuffer, e, c->CurrentLine+1); } debug (D_ERROR, ("***%s on line/pos %ld/%ld*** \t", e, c->CurrentLine, c->CurrentPos)); } while (0)
#define ErrRet(c,e)    do { Error (c, e); return; } while (0)

/*)) */

/*(( "Prototypes" */

/*
 * Only process lines in increasing line number order!
 * Otherwise neat effects may happen as the system only
 * keeps track of the last modfied line and does not
 * scan all ModifyRequest that are already done.
 */

/*
 * Initialize.
 */
void InitIndent (sc_t *c, int BeginLine, int EndLine, int Mode);

/*
 * Cleanup and add any remaining APIOrders.
 */
void CleanupIndent (sc_t *c);

/*
 * Free the APIOrder, APIModifyRequest and the string space.
 */
void FreeRequest (sc_t *c, struct SmartOrder *Req);

/*
 * Get *real* current line text and length.
 */

void GetText (sc_t *c, char **Text, int *Len);

/*
 * Move current line contents at position Pos when indentation is enabled
 * for the current line.
 * Perform indentation correctness checks.
 */
void Move (sc_t *c, int Pos, int NewPos);

/*
 * Get the next word (maximum length MAX_WORD_LEN-1).
 * Returns an empty word after EOF.
 * Sets Current* when Flag is set.
 */
void NextWord (sc_t *c, char *buf, int Flag);

/*
 * Unget the current word.
 * CurrentPos will not point to the very correct Place, but it will be a good
 * guess nevertheless. At least it still works for BeginOfLine determination
 * after the next GET. LastPos will not be correct at all.
 */
void LastWord (sc_t *c);

/*)) */

#endif /* _UTIL_H_ */

