262 lines
9.0 KiB
C
262 lines
9.0 KiB
C
#ifndef PARS_H
|
|
/*
|
|
* Simple ASCII file parsing object.
|
|
* Used as a base for the CGATS.5 and IT8.7 family file I/O class
|
|
*/
|
|
|
|
/*
|
|
* Version 2.01
|
|
*
|
|
* Author: Graeme W. Gill
|
|
* Date: 20/12/95
|
|
*
|
|
* Copyright 1995, 1996, 2002 Graeme W. Gill
|
|
* All rights reserved.
|
|
*
|
|
* This material is licensed with an "MIT" free use license:-
|
|
* see the License4.txt file in this directory for licensing details.
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#undef CGATS_DEBUG_MALLOC /* Turns on partial support for filename and linenumber capture */
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - */
|
|
#define CGATS_ERRM_LENGTH 2000 /* try and keep in sync with ICM_ERRM_SIZE */
|
|
|
|
typedef struct {
|
|
int c; /* Error code */
|
|
char m[CGATS_ERRM_LENGTH]; /* Error message */
|
|
} cgats_err;
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/* System interface objects. The defaults can be replaced */
|
|
/* for adaption to different system environments */
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
#ifdef CGATS_DEBUG_MALLOC
|
|
|
|
/* Heap allocator class interface definition */
|
|
#define CGATS_ALLOC_BASE \
|
|
/* Public: */ \
|
|
\
|
|
void *(*dmalloc) (struct _cgatsAlloc *p, size_t size, char *file, int line); \
|
|
void *(*dcalloc) (struct _cgatsAlloc *p, size_t num, size_t size, char *file, int line);\
|
|
void *(*drealloc)(struct _cgatsAlloc *p, void *ptr, size_t size, char *file, int line); \
|
|
void (*dfree) (struct _cgatsAlloc *p, void *ptr, char *file, int line); \
|
|
\
|
|
/* we're done with the allocator object */ \
|
|
void (*del)(struct _cgatsAlloc *p); \
|
|
|
|
#if defined(_PARS_C_) || defined(_CGATS_C_) || defined(_PARSSTD_C_) /* only inside implimentation */
|
|
#define malloc( p, size ) dmalloc( p, size, __FILE__, __LINE__ )
|
|
#define calloc( p, num, size ) dcalloc( p, num, size, __FILE__, __LINE__ )
|
|
#define realloc( p, ptr, size ) drealloc( p, ptr, size, __FILE__, __LINE__ )
|
|
#define free( p, ptr ) dfree( p, ptr , __FILE__, __LINE__ )
|
|
#endif
|
|
|
|
#else /* !CGATS_DEBUG_MALLOC */
|
|
|
|
/* Heap allocator class interface definition */
|
|
#define CGATS_ALLOC_BASE \
|
|
/* Public: */ \
|
|
\
|
|
void *(*malloc) (struct _cgatsAlloc *p, size_t size); \
|
|
void *(*calloc) (struct _cgatsAlloc *p, size_t num, size_t size); \
|
|
void *(*realloc)(struct _cgatsAlloc *p, void *ptr, size_t size); \
|
|
void (*free) (struct _cgatsAlloc *p, void *ptr); \
|
|
\
|
|
/* we're done with the allocator object */ \
|
|
void (*del)(struct _cgatsAlloc *p); \
|
|
|
|
#endif /* !CGATS_DEBUG_MALLOC */
|
|
|
|
/* Common heap allocator interface class */
|
|
struct _cgatsAlloc {
|
|
CGATS_ALLOC_BASE
|
|
}; typedef struct _cgatsAlloc cgatsAlloc;
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/* Available when SEPARATE_STD is not defined: */
|
|
/* Implementation of heap class based on standard system malloc */
|
|
struct _cgatsAllocStd {
|
|
CGATS_ALLOC_BASE
|
|
}; typedef struct _cgatsAllocStd cgatsAllocStd;
|
|
|
|
/* Create a standard alloc object */
|
|
cgatsAlloc *new_cgatsAllocStd(void);
|
|
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/* File access class interface definition */
|
|
#define CGATS_FILE_BASE \
|
|
/* Public: */ \
|
|
\
|
|
/* Get the size of the file (Only valid for reading file). */ \
|
|
size_t (*get_size) (struct _cgatsFile *p); \
|
|
\
|
|
/* Set current position to offset. Return 0 on success, nz on failure. */ \
|
|
int (*seek) (struct _cgatsFile *p, unsigned int offset); \
|
|
\
|
|
/* Read count items of size length. Return number of items successfully read. */ \
|
|
size_t (*read) (struct _cgatsFile *p, void *buffer, size_t size, size_t count); \
|
|
\
|
|
/* Read a single character */ \
|
|
int (*getch) (struct _cgatsFile *p); \
|
|
\
|
|
/* write count items of size length. Return number of items successfully written. */ \
|
|
size_t (*write)(struct _cgatsFile *p, void *buffer, size_t size, size_t count); \
|
|
\
|
|
/* printf to the file */ \
|
|
int (*gprintf)(struct _cgatsFile *p, const char *format, ...); \
|
|
\
|
|
/* flush all write data out to secondary storage. Return nz on failure. */ \
|
|
int (*flush)(struct _cgatsFile *p); \
|
|
\
|
|
/* return the filename if known, NULL if not */ \
|
|
char *(*fname)(struct _cgatsFile *p); \
|
|
\
|
|
/* Return the memory buffer. Error if not cgatsFileMem */ \
|
|
int (*get_buf)(struct _cgatsFile *p, unsigned char **buf, size_t *len); \
|
|
\
|
|
/* we're done with the file object, close & free it */ \
|
|
/* return nz on failure */ \
|
|
int (*del)(struct _cgatsFile *p); \
|
|
|
|
/* Common file interface class */
|
|
struct _cgatsFile {
|
|
CGATS_FILE_BASE
|
|
}; typedef struct _cgatsFile cgatsFile;
|
|
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/* Available when SEPARATE_STD is not defined: */
|
|
|
|
/* Implementation of file access class based on standard file I/O */
|
|
struct _cgatsFileStd {
|
|
CGATS_FILE_BASE
|
|
|
|
/* Private: */
|
|
cgatsAlloc *al; /* Heap allocator */
|
|
int del_al; /* NZ if heap allocator should be deleted */
|
|
FILE *fp;
|
|
int doclose; /* nz if free should close */
|
|
char *filename; /* NULL if not known */
|
|
|
|
/* Private: */
|
|
size_t size; /* Size of the file (For read) */
|
|
|
|
}; typedef struct _cgatsFileStd cgatsFileStd;
|
|
|
|
/* Create given a file name */
|
|
cgatsFile *new_cgatsFileStd_name(const char *name, const char *mode);
|
|
|
|
/* Create given a (binary) FILE* */
|
|
cgatsFile *new_cgatsFileStd_fp(FILE *fp);
|
|
|
|
/* Create given a file name and allocator */
|
|
cgatsFile *new_cgatsFileStd_name_a(const char *name, const char *mode, cgatsAlloc *al);
|
|
|
|
/* Create given a (binary) FILE* and allocator */
|
|
cgatsFile *new_cgatsFileStd_fp_a(FILE *fp, cgatsAlloc *al);
|
|
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - */
|
|
/* Implementation of file access class based on a memory image */
|
|
/* The buffer is assumed to be allocated with the given heap allocator */
|
|
/* Pass base = NULL, length = 0 for no initial buffer */
|
|
|
|
/* ~~ should ad method that returns buffer and length */
|
|
|
|
struct _cgatsFileMem {
|
|
CGATS_FILE_BASE
|
|
|
|
/* Private: */
|
|
cgatsAlloc *al; /* Heap allocator */
|
|
int del_al; /* NZ if heap allocator should be deleted */
|
|
int del_buf; /* NZ if memory file buffer should be deleted */
|
|
unsigned char *start, *cur, *end, *aend;
|
|
|
|
}; typedef struct _cgatsFileMem cgatsFileMem;
|
|
|
|
/* Create a memory image file access class with given allocator */
|
|
/* The buffer is not delete with the object. */
|
|
cgatsFile *new_cgatsFileMem_a(void *base, size_t length, cgatsAlloc *al);
|
|
|
|
/* Create a memory image file access class with given allocator */
|
|
/* and delete buffer when cgatsFile is deleted. */
|
|
cgatsFile *new_cgatsFileMem_ad(void *base, size_t length, cgatsAlloc *al);
|
|
|
|
/* This is avalailable if SEPARATE_STD is not defined: */
|
|
|
|
/* Create a memory image file access class with the std allocator */
|
|
/* The buffer is not delete with the object. */
|
|
cgatsFile *new_cgatsFileMem(void *base, size_t length);
|
|
|
|
/* Create a memory image file access class with the std allocator */
|
|
/* and delete buffer when cgatsFile is deleted. */
|
|
cgatsFile *new_cgatsFileMem_d(void *base, size_t length);
|
|
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
struct _parse {
|
|
/* Public Variables */
|
|
int line; /* Current line number */
|
|
int token; /* Current token number */
|
|
|
|
/* Public Methods */
|
|
void (*del)(struct _parse *p); /* Delete the object */
|
|
void (*reset_del)(struct _parse *p); /* Reset the parsing delimiters */
|
|
void (*add_del)(struct _parse *p, /* Add to the parsing delimiters */
|
|
char *t, char *nr,
|
|
char *c, char *q);
|
|
int (*read_line)(struct _parse *p); /* Read in a line. Return 0 if read failed, */
|
|
/* -1 on other error */
|
|
char *(*get_token)(struct _parse *p); /* Return a pointer to the next token, */
|
|
/* NULL if no tokens. set e.c NZ on other error */
|
|
|
|
/* Private */
|
|
cgatsAlloc *al; /* Memory allocator */
|
|
int del_al; /* Flag to indicate we al->del() */
|
|
cgatsFile *fp; /* File we're dealing with */
|
|
int ltflag; /* Last terminator flag */
|
|
int q; /* Quote */
|
|
char *b; /* Line buffer */
|
|
int bs; /* Buffer size */
|
|
int bo; /* Next buffer offset */
|
|
int to; /* Token parsing offset into b */
|
|
char *tb; /* Token buffer */
|
|
int tbs; /* Token buffer size */
|
|
char delf[256]; /* Parsing delimiter flags */
|
|
/* Parsing flags */
|
|
#define PARS_TERM 0x01 /* Terminates a token */
|
|
#define PARS_SKIP 0x02 /* Character is not read */
|
|
#define PARS_COMM 0x04 /* Character starts a comment */
|
|
#define PARS_QUOTE 0x08 /* Character starts/ends a quoted string */
|
|
|
|
cgats_err e; /* Error message * code */
|
|
|
|
}; typedef struct _parse parse;
|
|
|
|
/* Creator */
|
|
extern parse *new_parse_al(cgatsAlloc *al, cgatsFile *fp); /* With allocator class */
|
|
|
|
/* Available when SEPARATE_STD is not defined: */
|
|
extern parse *new_parse(cgatsFile *fp); /* Default allocator */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#define PARS_H
|
|
#endif /* PARS_H */
|
|
|