summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--DESIGN81
-rw-r--r--include/libast.h35
-rw-r--r--include/libast/if.h37
-rw-r--r--include/libast/linked_list.h58
-rw-r--r--include/libast/list_if.h82
-rw-r--r--include/libast/obj.h129
-rw-r--r--include/libast/str.h3
-rw-r--r--include/libast/tok.h6
-rw-r--r--include/libast/types.h.in15
-rw-r--r--include/libast_internal.h7
-rw-r--r--src/conf.c1481
-rw-r--r--src/file.c38
-rw-r--r--src/linked_list.c295
-rw-r--r--src/mem.c543
-rw-r--r--src/obj.c103
-rw-r--r--src/str.c445
-rw-r--r--src/strings.c1008
-rw-r--r--src/tok.c54
-rw-r--r--test/.cvsignore2
-rw-r--r--test/perf.c27
-rw-r--r--test/test.c18
22 files changed, 2580 insertions, 1895 deletions
diff --git a/ChangeLog b/ChangeLog
index 4ddfc7d..bb08143 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -143,3 +143,11 @@ Sun Mar 3 01:44:51 2002 Michael Jennings (mej)
Added precision to the profiling stuff, and threw in the beginnings of
support for interface classes.
----------------------------------------------------------------------
+Thu Apr 4 20:45:30 2002 Michael Jennings (mej)
+
+Lots of updates. This should compile, but if it doesn't, don't blame
+me. (Well, blame me, just don't whine at me.) :-)
+
+Also a bit of a design doc here...hopefully it will clarify some
+things.
+----------------------------------------------------------------------
diff --git a/DESIGN b/DESIGN
new file mode 100644
index 0000000..292a032
--- /dev/null
+++ b/DESIGN
@@ -0,0 +1,81 @@
+LibAST Object Subsystem Design
+------------------------------
+
+ - All functions, data types, and other symbols will begin with
+ "spif_" in the appropriate case. "Spif," of course, is short for
+ "Spiffy," which in turn is represented by the 'S' in "LibAST."
+
+ - All macros will be named using uppercase ASCII characters.
+
+ - Macros will be used for all typecasting operations. Typecasting
+ macros will be named SPIF_type(), where "type" is the capitalized
+ base type name (e.g., SPIF_OBJ()). They will take exactly one
+ parameter, a variable of that type or that can be cast to that
+ type. The result will be that same parameter with the proper
+ typecast applied and can subsequently be used as if it were a
+ native pointer of that type.
+
+ - Object types will be named by enclosing the base type name between
+ "spif_" and "_t" (e.g., spif_obj_t). "spif_obj_t" is actually a
+ pointer to an object. There is a corresponding type for each
+ object class (e.g., spif_const_obj_t) which is the actual structure
+ type. In other words, spif_const_XXX_t is the typedef for a struct
+ which contains all the member variables. spif_XXX_t is a pointer
+ to a spif_const_XXX_t.
+
+ - Object member functions will always begin with "spif_" and the base
+ type name followed by what the function does (e.g. spif_obj_new).
+ All functions except for the *_new() functions will take an object
+ of that type as their first parameter. Additional parameters may
+ be required for different types of functions. Each member function
+ which operates on an existing object instance will refer to that
+ instance (its first parameter) as "self."
+
+ - There are two basic object types. The first one is
+ "spif_nullobj_t." In the strictest sense, it isn't an object at
+ all. It is merely a placeholder for objects which are
+ space-sensitive. It may not even be used.
+
+ - The primary object type is, of course, "spif_obj_t." This is a
+ very basic type which has only those properties common to all
+ types.
+
+ - All objects should have basic methods to accomplish the following:
+ - new Allocate memory for an object (also calls init)
+ - init Initialize the object members
+ - del Deallocate memory for the object (also calls done)
+ - done Free and re-initialize object members
+ - show Convert object to a string representation
+ - comp Compare two objects of the same type
+ - dup Create an independent copy of the object
+ - type Return the string representation of the object type
+
+ - All objects will have a corresponding "class" object which will
+ contain the string representation of the class name (as specified
+ by the SPIF_DECL_CNVALUE() macro) followed by a series of pointers
+ to the functions above. This externally-visible class object
+ allows for basic operations to be carried out on objects of
+ arbitrary/unknown type.
+
+ - Object subclasses will be derived from their parent classes by
+ declaring the first member of their structure as "parent" with the
+ same type as the parent class const type. For example, to declare
+ a child class of the "obj" type, you would have "spif_const_obj_t
+ parent;" as the first data member.
+
+ - To operate on properties of the parent class, simply use the
+ appropriate typecast macro (see above) to cast the pointer to the
+ parent type (e.g., SPIF_OBJ(str)).
+
+ - Some object types will not actually be defined per se, but rather
+ will define abstract methods of manipulating data whose
+ implementation is unimportant. As with Java, these are referred to
+ as "interface" classes. Interface classes have a single header
+ file for the interface along with a .c/.h set for each
+ implementation.
+
+ - The following should be defined for all objects (the "obj" type is
+ being used as a reference):
+ - SPIF_OBJ(obj) Typecast macro
+ - SPIF_OBJ_IS_OBJ(obj) Check for type (the second OBJ)
+ - SPIF_OBJ_ISNULL(obj) Check for NULL value of instance
diff --git a/include/libast.h b/include/libast.h
index b1570ff..b1c308c 100644
--- a/include/libast.h
+++ b/include/libast.h
@@ -35,6 +35,9 @@
# ifndef _BSD_SOURCE
# define _BSD_SOURCE
# endif
+# ifndef _XOPEN_SOURCE
+# define _XOPEN_SOURCE
+# endif
#endif
#include <stdio.h>
@@ -49,6 +52,9 @@
#include <dirent.h>
#include <errno.h>
#include <signal.h>
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+#endif
#ifdef WITH_DMALLOC
# include <dmalloc.h>
#elif defined(HAVE_MALLOC_H)
@@ -73,6 +79,9 @@
#include <libast/str.h>
#include <libast/tok.h>
+#include <libast/list_if.h>
+#include <libast/linked_list.h>
+
/******************************* GENERIC GOOP *********************************/
#define USE_VAR(x) (void) x
@@ -86,27 +95,21 @@
# define MIN(a,b) __extension__ ({__typeof__(a) aa = (a); __typeof__(b) bb = (b); (aa < bb) ? (aa) : (bb);})
# define MAX(a,b) __extension__ ({__typeof__(a) aa = (a); __typeof__(b) bb = (b); (aa > bb) ? (aa) : (bb);})
# define LOWER_BOUND(current, other) __extension__ ({__typeof__(other) o = (other); ((current) < o) ? ((current) = o) : (current);})
-# define AT_LEAST(current, other) LOWER_BOUND(current, other)
-# define MAX_IT(current, other) LOWER_BOUND(current, other)
# define UPPER_BOUND(current, other) __extension__ ({__typeof__(other) o = (other); ((current) > o) ? ((current) = o) : (current);})
-# define AT_MOST(current, other) UPPER_BOUND(current, other)
-# define MIN_IT(current, other) UPPER_BOUND(current, other)
# define BOUND(val, min, max) __extension__ ({__typeof__(min) m1 = (min); __typeof__(max) m2 = (max); ((val) < m1) ? ((val) = m1) : (((val) > m2) ? ((val) = m2) : (val));})
-# define CONTAIN(val, min, max) BOUND(val, min, max)
-# define SWAP_IT(one, two, tmp) do {(tmp) = (one); (one) = (two); (two) = (tmp);} while (0)
#else
# define MIN(a,b) (((a) < (b)) ? (a) : (b))
# define MAX(a,b) (((a) > (b)) ? (a) : (b))
# define LOWER_BOUND(current, other) (((current) < (other)) ? ((current) = (other)) : (current))
-# define AT_LEAST(current, other) LOWER_BOUND(current, other)
-# define MAX_IT(current, other) LOWER_BOUND(current, other)
# define UPPER_BOUND(current, other) (((current) > (other)) ? ((current) = (other)) : (current))
-# define AT_MOST(current, other) UPPER_BOUND(current, other)
-# define MIN_IT(current, other) UPPER_BOUND(current, other)
# define BOUND(val, min, max) (((val) < (min)) ? ((val) = (min)) : (((val) > (max)) ? ((val) = (max)) : (val)))
-# define CONTAIN(val, min, max) BOUND(val, min, max)
-# define SWAP_IT(one, two, tmp) do {(tmp) = (one); (one) = (two); (two) = (tmp);} while (0)
#endif
+#define AT_LEAST(current, other) LOWER_BOUND(current, other)
+#define MAX_IT(current, other) LOWER_BOUND(current, other)
+#define AT_MOST(current, other) UPPER_BOUND(current, other)
+#define MIN_IT(current, other) UPPER_BOUND(current, other)
+#define CONTAIN(val, min, max) BOUND(val, min, max)
+#define SWAP_IT(one, two, tmp) do {(tmp) = (one); (one) = (two); (two) = (tmp);} while (0)
/****************************** DEBUGGING GOOP ********************************/
#ifndef LIBAST_DEBUG_FD
@@ -194,7 +197,7 @@
# define REQUIRE_RVAL(x, v) do {if (!(x)) return (v);} while (0)
#endif
-#define NONULL(x) ((x) ? (x) : ("<null>"))
+#define NONULL(x) ((x) ? (x) : ("<" #x " null>"))
/* Macros for printing debugging messages */
#if DEBUG >= 1
@@ -288,9 +291,9 @@
/* Fast memset() macro contributed by vendu */
#if (SIZEOF_LONG == 8)
-# define MEMSET_LONG() l |= l<<32
+# define MEMSET_LONG() (l |= l<<32)
#else
-# define MEMSET_LONG() ((void)0)
+# define MEMSET_LONG() NOP
#endif
#define MEMSET(s, c, count) do { \
@@ -336,7 +339,7 @@
/******************************* STRINGS GOOP *********************************/
#ifdef __GNUC__
-# define SWAP(a, b) __extension__ ({__typeof__(a) tmp = (a); (a) = (b); (b) = tmp;})
+# define SWAP(a, b) (void) __extension__ ({__typeof__(a) tmp = (a); (a) = (b); (b) = tmp;})
#else
# define SWAP(a, b) do {void *tmp = ((void *)(a)); (a) = (b); (b) = tmp;} while (0)
#endif
diff --git a/include/libast/if.h b/include/libast/if.h
index e4d280d..c0e0f96 100644
--- a/include/libast/if.h
+++ b/include/libast/if.h
@@ -32,6 +32,9 @@
#define SPIF_IFINST(obj) ((spif_ifinst_t) (obj))
#define SPIF_IFCLASS(cls) ((spif_ifclass_t) (cls))
+/* Assembles the name of the interface class variable. */
+#define SPIF_IFCLASS_VAR(if, type) spif_ifclass_ ## if ## _ ## type
+
/* Access the implementation class member of an object. */
#define SPIF_IFINST_IFCLASS(obj) (SPIF_IFINST(obj)->ifclass)
@@ -39,42 +42,20 @@
#define SPIF_IF_CALL_METHOD(obj, meth) (SPIF_IFINST_IFCLASS(obj)->(meth))
/* Calls to the basic functions. */
-#define SPIF_IFCLASS_NEW(cls) (SPIF_IFCLASS(cls)->new)
-#define SPIF_IFINST_NEW(obj) (SPIF_IF_CALL_METHOD((obj), (new)))
+#define SPIF_IFCLASS_NEW(cls) (SPIF_IFCLASS(cls)->noo)
+#define SPIF_IFINST_NEW(obj) (SPIF_IF_CALL_METHOD((obj), (noo)))
#define SPIF_IFCLASS_INIT(cls) (SPIF_IFCLASS(cls)->init)
-#define SPIF_IFINST_INIT(obj) (SPIF_IF_CALL_METHOD((obj), (init)))
+#define SPIF_IFINST_INIT(obj) ((SPIF_IF_CALL_METHOD((obj), (init)))(obj))
#define SPIF_IFCLASS_DONE(cls) (SPIF_IFCLASS(cls)->done)
-#define SPIF_IFINST_DONE(obj) (SPIF_IF_CALL_METHOD((obj), (done)))
+#define SPIF_IFINST_DONE(obj) ((SPIF_IF_CALL_METHOD((obj), (done)))(obj))
#define SPIF_IFCLASS_DEL(cls) (SPIF_IFCLASS(cls)->del)
-#define SPIF_IFINST_DEL(obj) (SPIF_IF_CALL_METHOD((obj), (del)))
+#define SPIF_IFINST_DEL(obj) ((SPIF_IF_CALL_METHOD((obj), (del)))(obj))
#define SPIF_IFCLASS_SHOW(cls) (SPIF_IFCLASS(cls)->show)
-#define SPIF_IFINST_SHOW(obj) (SPIF_IF_CALL_METHOD((obj), (show)))
+#define SPIF_IFINST_SHOW(obj) ((SPIF_IF_CALL_METHOD((obj), (show)))(obj))
/* The ifclass object contains the function pointers for the interface methods. */
typedef struct spif_ifclass_t_struct *spif_ifclass_t;
typedef struct spif_ifclass_t_struct spif_const_ifclass_t;
-/* Generic function pointers. */
-typedef spif_obj_t (*spif_newfunc_t)(void);
-typedef spif_bool_t (*spif_memberfunc_t)(spif_obj_t);
-typedef void * (*spif_func_t)();
-
-struct spif_ifclass_t_struct {
- spif_newfunc_t new;
- spif_memberfunc_t init;
- spif_memberfunc_t done;
- spif_memberfunc_t del;
- spif_func_t show;
-};
-
-/* ifinst is the parent class for instances of interface classes. */
-typedef struct spif_ifinst_t_struct *spif_ifinst_t;
-typedef struct spif_ifinst_t_struct spif_const_ifinst_t;
-
-struct spif_ifinst_t_struct {
- spif_obj_t parent;
- spif_ifclass_t ifclass;
-};
-
#endif /* _LIBAST_IF_H_ */
diff --git a/include/libast/linked_list.h b/include/libast/linked_list.h
new file mode 100644
index 0000000..9cd79de
--- /dev/null
+++ b/include/libast/linked_list.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 1997-2002, Michael Jennings
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software, its documentation and marketing & publicity
+ * materials, and acknowledgment shall be given in the documentation, materials
+ * and software packages that this Software was used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _LIBAST_LINKED_LIST_H_
+#define _LIBAST_LINKED_LIST_H_
+
+/*
+ * interface goop
+ */
+
+/* Standard typecast macros.... */
+#define SPIF_LINKED_LIST(obj) ((spif_linked_list_t) (obj))
+
+/* Access the implementation class member of an object. */
+#define SPIF_LINKED_LIST_IFCLASS(obj) (SPIF_IFCLASS_VAR(list, linked_list))
+
+/* Call a method on an instance of an implementation class */
+#define SPIF_LINKED_LIST_CALL_METHOD(obj, meth) (SPIF_LINKED_LIST_IFCLASS(obj)->(meth))
+
+typedef struct spif_linked_list_item_t_struct *spif_linked_list_item_t;
+typedef struct spif_linked_list_item_t_struct spif_const_linked_list_item_t;
+
+struct spif_linked_list_item_t_struct {
+ spif_nullobj_t parent;
+ spif_obj_t data;
+ spif_linked_list_item_t next;
+};
+
+typedef struct spif_linked_list_t_struct *spif_linked_list_t;
+typedef struct spif_linked_list_t_struct spif_const_linked_list_t;
+
+struct spif_linked_list_t_struct {
+ spif_obj_t parent;
+ size_t len;
+ spif_linked_list_item_t head;
+};
+
+#endif /* _LIBAST_LINKED_LIST_H_ */
diff --git a/include/libast/list_if.h b/include/libast/list_if.h
new file mode 100644
index 0000000..9aba574
--- /dev/null
+++ b/include/libast/list_if.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 1997-2002, Michael Jennings
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software, its documentation and marketing & publicity
+ * materials, and acknowledgment shall be given in the documentation, materials
+ * and software packages that this Software was used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _LIBAST_LIST_IF_H_
+#define _LIBAST_LIST_IF_H_
+
+/*
+ * interface goop
+ */
+
+/* Standard typecast macros.... */
+#define SPIF_LIST_INST(obj) SPIF_IFINST(obj)
+#define SPIF_LIST_CLASS(cls) ((spif_ifclass_t) (cls))
+
+/* Access the implementation class member of an object. */
+#define SPIF_LIST_IFCLASS(obj) (SPIF_IFINST(obj)->ifclass)
+
+/* Call a method on an instance of an implementation class */
+#define SPIF_LIST_CALL_METHOD(obj, meth) (SPIF_LIST_IFCLASS(obj)->(meth))
+
+/* Calls to the basic functions. */
+#define SPIF_LIST_NEW(type) SPIF_IFCLASS_NEW(SPIF_IFCLASS_VAR(list, type))
+#define SPIF_LIST_INIT(obj) SPIF_IFINST_INIT(obj)
+#define SPIF_LIST_DONE(obj) SPIF_IFINST_DONE(obj)
+#define SPIF_LIST_DEL(obj) SPIF_IFINST_DEL(obj)
+#define SPIF_LIST_SHOW(obj) SPIF_IFINST_SHOW(obj)
+
+#define SPIF_LIST_APPEND(obj, item) ((SPIF_LIST_CALL_METHOD((obj), (append)))(obj, item))
+#define SPIF_LIST_CONTAINS(obj, item) ((SPIF_LIST_CALL_METHOD((obj), (contains)))(obj, item))
+#define SPIF_LIST_COUNT(obj) ((SPIF_LIST_CALL_METHOD((obj), (count)))(obj))
+#define SPIF_LIST_GET(obj, index) ((SPIF_LIST_CALL_METHOD((obj), (get)))(obj, index))
+#define SPIF_LIST_INDEX(obj, item) ((SPIF_LIST_CALL_METHOD((obj), (index)))(obj, item))
+#define SPIF_LIST_INSERT(obj, item) ((SPIF_LIST_CALL_METHOD((obj), (insert)))(obj, item))
+#define SPIF_LIST_INSERT_AT(obj, item, index) ((SPIF_LIST_CALL_METHOD((obj), (insert_at)))(obj, item, index))
+#define SPIF_LIST_ITERATOR(obj) ((SPIF_LIST_CALL_METHOD((obj), (iterator)))(obj))
+#define SPIF_LIST_NEXT(obj) ((SPIF_LIST_CALL_METHOD((obj), (next)))(obj))
+#define SPIF_LIST_PREPEND(obj, item) ((SPIF_LIST_CALL_METHOD((obj), (prepend)))(obj, item))
+#define SPIF_LIST_REMOVE(obj) ((SPIF_LIST_CALL_METHOD((obj), (remove)))(obj))
+#define SPIF_LIST_REMOVE_AT(obj, index) ((SPIF_LIST_CALL_METHOD((obj), (remove_at)))(obj, index))
+
+/* The ifclass object contains the function pointers for the interface methods. */
+typedef struct spif_list_ifclass_t_struct *spif_list_ifclass_t;
+typedef struct spif_list_ifclass_t_struct spif_const_list_ifclass_t;
+
+struct spif_list_ifclass_t_struct {
+ spif_const_class_t parent;
+
+ spif_memberfunc_t append;
+ spif_memberfunc_t contains;
+ spif_memberfunc_t count;
+ spif_memberfunc_t get;
+ spif_memberfunc_t index;
+ spif_memberfunc_t insert;
+ spif_memberfunc_t insert_at;
+ spif_memberfunc_t iterator;
+ spif_memberfunc_t next;
+ spif_memberfunc_t prepend;
+ spif_memberfunc_t remove;
+ spif_memberfunc_t remove_at;
+};
+
+#endif /* _LIBAST_LIST_IF_H_ */
diff --git a/include/libast/obj.h b/include/libast/obj.h
index f4a4b39..6becf05 100644
--- a/include/libast/obj.h
+++ b/include/libast/obj.h
@@ -29,95 +29,142 @@
*/
/* Macros to construct object types from the basenames of the types (obj, str, etc.) */
-#define SPIF_TYPE(type) (spif_ ## type ## _t)
-#define SPIF_CONST_TYPE(type) (spif_const_ ## type ## _t)
+#define SPIF_TYPE(type) spif_ ## type ## _t
+#define SPIF_CONST_TYPE(type) spif_const_ ## type ## _t
+
+/* Typecast macros */
+#define SPIF_CAST_C(type) (type)
+#define SPIF_CONST_CAST_C(type) (const type)
+#define SPIF_CAST(type) (SPIF_TYPE(type))
+#define SPIF_CONST_CAST(type) (const SPIF_TYPE(type))
/* Converts a type (such as "obj") to the name of its classname variable. */
#define SPIF_CLASSNAME_TYPE(type) ((spif_classname_t) (spif_ ## type ## _classname))
/* Cast the NULL pointer to a particular object type. */
-#define SPIF_NULL_TYPE(type) (SPIF_TYPE(type) (NULL))
+#define SPIF_NULL_TYPE(type) (SPIF_CAST(type) (NULL))
/* Converts a type (such as "obj") to a string denoting a NULL object of that type. */
#define SPIF_NULLSTR_TYPE(type) ("{ ((spif_" #type "_t) NULL) }")
/* Our own version of the sizeof() operator since objects are actually pointers. */
-#define SPIF_SIZEOF_TYPE(type) (sizeof SPIF_CONST_TYPE(type))
-
+#define SPIF_SIZEOF_TYPE(type) (sizeof(SPIF_CONST_TYPE(type)))
-/*
- * nullobj goop
- */
/* Cast an arbitrary object pointer to a pointer to a nullobj. Coincidentally,
a nullobj *is* an arbitrary object pointer. Even moreso than an obj. :-) */
#define SPIF_NULLOBJ(obj) ((spif_nullobj_t) (obj))
-/* Types for null objects */
-typedef struct spif_nullobj_t_struct *spif_nullobj_t;
-typedef struct spif_nullobj_t_struct spif_const_nullobj_t;
-/* A nullobj contains...well, nothing. Any class that is really small and/or
- needs to be very memory-efficient should be derived from this class. */
-struct spif_nullobj_t_struct {
-};
-
-extern spif_nullobj_t spif_nullobj_new(void);
-extern spif_bool_t spif_nullobj_del(spif_nullobj_t);
-extern spif_bool_t spif_nullobj_init(spif_nullobj_t);
-extern spif_bool_t spif_nullobj_done(spif_nullobj_t);
+#define SPIF_CLASS(cls) ((SPIF_TYPE(class)) (cls))
+#define SPIF_CONST_CLASS(cls) ((SPIF_CONST_TYPE(class)) (cls))
-
-
-/*
- * obj goop
- */
+/* Assembles the name of the object class variable. */
+#define SPIF_CLASS_VAR(type) spif_ ## type ## _class
/* Check to see if a pointer references an object. Increasing levels
of accuracy at the expense of some speed for the higher debug levels.
This is also internal. It's used by other SPIF_OBJ_IS_*() macros. */
+#define SPIF_OBJ_IS_TYPE(o, type) ((!SPIF_OBJ_ISNULL(o)) && (SPIF_OBJ_CLASSNAME(o) == SPIF_CLASSNAME_TYPE(type)))
#if DEBUG == 0
-# define SPIF_OBJ_IS_TYPE(o, type) (1)
+# define SPIF_OBJ_CHECK_TYPE(o, type) (1)
#elsif DEBUG <= 4
-# define SPIF_OBJ_IS_TYPE(o, type) (!SPIF_OBJ_ISNULL(o))
+# define SPIF_OBJ_CHECK_TYPE(o, type) (!SPIF_OBJ_ISNULL(o))
#else
-# define SPIF_OBJ_IS_TYPE(o, type) ((!SPIF_OBJ_ISNULL(o)) && (SPIF_OBJ_CLASSNAME(o) == SPIF_CLASSNAME_TYPE(type)))
+# define SPIF_OBJ_CHECK_TYPE(o, type) SPIF_OBJ_IS_TYPE(o, type)
#endif
/* Cast an arbitrary object pointer to an obj. Any object of sufficient size
and/or complexity should be derived from this type. */
-#define SPIF_OBJ(obj) ((spif_obj_t) (obj))
-
-/* Obtain the "classname" member of any instance of an object. */
-#define SPIF_OBJ_CLASSNAME(obj) (SPIF_OBJ(obj)->classname)
+#define SPIF_OBJ(obj) ((spif_obj_t) (obj))
/* Check to see if a pointer references an obj. */
-#define SPIF_OBJ_IS_OBJ(o) (SPIF_OBJ_IS_TYPE(o, obj))
+#define SPIF_OBJ_IS_OBJ(o) (SPIF_OBJ_IS_TYPE(o, obj))
/* Used for testing the NULL-ness of objects. */
-#define SPIF_OBJ_ISNULL(o) (SPIF_OBJ(o) == SPIF_NULL_TYPE(obj))
+#define SPIF_OBJ_ISNULL(o) (SPIF_OBJ(o) == SPIF_NULL_TYPE(obj))
-/* The type for the classname variables. I don't see any reason why this
- would be anything but a const char *, but you never know. :-) */
-typedef const char *spif_classname_t;
+/* Access the implementation class member of an object. */
+#define SPIF_OBJ_CLASS(obj) (SPIF_CLASS(SPIF_OBJ(obj)->cls))
+
+/* Get the classname...very cool. */
+#define SPIF_OBJ_CLASSNAME(obj) (SPIF_CAST(classname) (obj))
+
+/* Call a method on an instance of an implementation class */
+#define SPIF_OBJ_CALL_METHOD(obj, meth) (SPIF_OBJ_CLASS(obj)->(meth))
+
+/* Calls to the basic functions. */
+#define SPIF_OBJ_NEW() (SPIF_CLASS(SPIF_CLASS_VAR(obj)))->(noo)()
+#define SPIF_OBJ_INIT(obj) ((SPIF_OBJ_CALL_METHOD((obj), (init)))(obj))
+#define SPIF_OBJ_DONE(obj) ((SPIF_OBJ_CALL_METHOD((obj), (done)))(obj))
+#define SPIF_OBJ_DEL(obj) ((SPIF_OBJ_CALL_METHOD((obj), (del)))(obj))
+#define SPIF_OBJ_SHOW(obj) ((SPIF_OBJ_CALL_METHOD((obj), (show)))(obj, #obj))
+#define SPIF_OBJ_COMP(o1, o2) ((SPIF_OBJ_CALL_METHOD((o1), (comp)))(o1, o2))
+#define SPIF_OBJ_DUP(obj) ((SPIF_OBJ_CALL_METHOD((obj), (del)))(obj))
+#define SPIF_OBJ_TYPE(obj) ((SPIF_OBJ_CALL_METHOD((obj), (del)))(obj))
+
+
+
+/* Types for null objects */
+typedef struct spif_nullobj_t_struct *spif_nullobj_t;
+typedef struct spif_nullobj_t_struct spif_const_nullobj_t;
/* An obj is the most basic object type. It contains simply a pointer to
the class name (a const char * so you can test it with ==). */
typedef struct spif_obj_t_struct *spif_obj_t;
typedef struct spif_obj_t_struct spif_const_obj_t;
-struct spif_obj_t_struct {
+/* The type for the classname variables. I don't see any reason why this
+ would be anything but a const char *, but you never know. :-) */
+typedef const char *spif_classname_t;
+
+/* The class contains the function pointers for the generic object functions. */
+typedef struct spif_class_t_struct *spif_class_t;
+typedef struct spif_class_t_struct spif_const_class_t;
+
+/* Generic function pointers. */
+typedef spif_obj_t (*spif_newfunc_t)(void);
+typedef spif_bool_t (*spif_memberfunc_t)(spif_obj_t);
+typedef void * (*spif_func_t)();
+
+
+
+/* A nullobj contains...well, nothing. Any class that is really small and/or
+ needs to be very memory-efficient should be derived from this class. */
+struct spif_nullobj_t_struct {
+};
+
+struct spif_class_t_struct {
spif_classname_t classname;
+
+ spif_newfunc_t noo; /* FIXME: Do we really need this? */
+ spif_memberfunc_t init;
+ spif_memberfunc_t done;
+ spif_memberfunc_t del;
+ spif_func_t show;
+ spif_func_t comp;
+ spif_func_t dup;
+ spif_func_t type;
};
+struct spif_obj_t_struct {
+ spif_class_t cls;
+};
-extern spif_classname_t spif_obj_classname;
+extern spif_const_class_t SPIF_CLASS_VAR(obj);
+extern spif_nullobj_t spif_nullobj_new(void);
+extern spif_bool_t spif_nullobj_del(spif_nullobj_t);
+extern spif_bool_t spif_nullobj_init(spif_nullobj_t);
+extern spif_bool_t spif_nullobj_done(spif_nullobj_t);
extern spif_obj_t spif_obj_new(void);
extern spif_bool_t spif_obj_del(spif_obj_t);
extern spif_bool_t spif_obj_init(spif_obj_t);
extern spif_bool_t spif_obj_done(spif_obj_t);
-extern spif_classname_t spif_obj_get_classname(spif_obj_t);
-extern spif_bool_t spif_obj_set_classname(spif_obj_t, spif_classname_t);
+extern spif_class_t spif_obj_get_class(spif_obj_t);
+extern spif_bool_t spif_obj_set_class(spif_obj_t, spif_class_t);
extern spif_bool_t spif_obj_show(spif_obj_t, spif_charptr_t);
+extern spif_cmp_t spif_obj_comp(spif_obj_t, spif_obj_t);
+extern spif_obj_t spif_obj_dup(spif_obj_t);
+extern spif_classname_t spif_obj_type(spif_obj_t);
#endif /* _LIBAST_OBJ_H_ */
diff --git a/include/libast/str.h b/include/libast/str.h
index c39f509..a5974b9 100644
--- a/include/libast/str.h
+++ b/include/libast/str.h
@@ -43,7 +43,7 @@ struct spif_str_t_struct {
size_t mem, len;
};
-extern spif_classname_t spif_str_classname;
+extern spif_const_class_t SPIF_CLASS_VAR(str);
extern spif_str_t spif_str_new(void);
extern spif_str_t spif_str_new_from_ptr(spif_charptr_t);
extern spif_str_t spif_str_new_from_buff(spif_charptr_t, size_t);
@@ -84,5 +84,6 @@ extern spif_bool_t spif_str_set_size(spif_str_t, size_t);
extern size_t spif_str_get_len(spif_str_t);
extern spif_bool_t spif_str_set_len(spif_str_t, size_t);
extern spif_bool_t spif_str_show(spif_str_t, spif_charptr_t);
+extern spif_classname_t spif_str_type(spif_str_t);
#endif /* _LIBAST_STR_H_ */
diff --git a/include/libast/tok.h b/include/libast/tok.h
index 85f68b5..5e1a7bf 100644
--- a/include/libast/tok.h
+++ b/include/libast/tok.h
@@ -43,7 +43,7 @@ struct spif_tok_t_struct {
spif_str_t sep;
};
-extern spif_classname_t spif_tok_classname;
+extern spif_const_class_t SPIF_CLASS_VAR(tok);
extern spif_tok_t spif_tok_new(void);
extern spif_tok_t spif_tok_new_from_ptr(spif_charptr_t);
extern spif_tok_t spif_tok_new_from_fp(FILE *);
@@ -54,6 +54,10 @@ extern spif_bool_t spif_tok_init_from_ptr(spif_tok_t, spif_charptr_t);
extern spif_bool_t spif_tok_init_from_fp(spif_tok_t, FILE *);
extern spif_bool_t spif_tok_init_from_fd(spif_tok_t, int);
extern spif_bool_t spif_tok_done(spif_tok_t);
+extern spif_bool_t spif_tok_eval(spif_tok_t);
extern spif_bool_t spif_tok_show(spif_tok_t, spif_charptr_t);
+extern spif_cmp_t spif_tok_comp(spif_tok_t, spif_tok_t);
+extern spif_tok_t spif_tok_dup(spif_tok_t);
+extern spif_classname_t spif_tok_type(spif_tok_t);
#endif /* _LIBAST_TOK_H_ */
diff --git a/include/libast/types.h.in b/include/libast/types.h.in
index 14aaf19..0270d5b 100644
--- a/include/libast/types.h.in
+++ b/include/libast/types.h.in
@@ -46,6 +46,17 @@ typedef unsigned long spif_ulong_t;
/* Char pointer that enforces signedness of char type */
typedef spif_char_t *spif_charptr_t;
+/* Type for object comparisons */
+typedef enum {
+ SPIF_CMP_LESS = -1,
+ SPIF_CMP_EQUAL = 0,
+ SPIF_CMP_GREATER = 1
+} spif_cmp_t;
+#define SPIF_CMP_FROM_INT(i) (((i) < 0) ? (SPIF_CMP_LESS) : (((i) > 0) ? (SPIF_CMP_GREATER) : (SPIF_CMP_EQUAL)))
+#define SPIF_CMP_IS_LESS(cmp) ((cmp) == SPIF_CMP_LESS)
+#define SPIF_CMP_IS_EQUAL(cmp) ((cmp) == SPIF_CMP_EQUAL)
+#define SPIF_CMP_IS_GREATER(cmp) ((cmp) == SPIF_CMP_GREATER)
+
#undef false
#undef False
#undef FALSE
@@ -54,10 +65,14 @@ typedef spif_char_t *spif_charptr_t;
#undef TRUE
typedef enum {
+#ifndef __cplusplus
false = 0,
+#endif
False = 0,
FALSE = 0,
+#ifndef __cplusplus
true = 1,
+#endif
True = 1,
TRUE = 1
} spif_bool_t;
diff --git a/include/libast_internal.h b/include/libast_internal.h
index debf881..2829823 100644
--- a/include/libast_internal.h
+++ b/include/libast_internal.h
@@ -51,16 +51,15 @@
/* Macros to allocate and deallocate memory for an object. For use only in
object constructors/destructors, not in end-user programs. */
-#define SPIF_ALLOC(type) SPIF_TYPE(type) MALLOC(sizeof SPIF_CONST_TYPE(type))
+#define SPIF_ALLOC(type) SPIF_CAST(type) MALLOC(SPIF_SIZEOF_TYPE(type))
#define SPIF_DEALLOC(obj) FREE(obj)
/* Macros for specifying the classname variables for each class type. Each subclass of
spif_obj_t must define this variable using these macros. */
-#define SPIF_DECL_CNVALUE(type) "!spif_" #type "_t!"
-#define SPIF_DECL_CLASSNAME(type) spif_classname_t spif_ ## type ## _classname = SPIF_DECL_CNVALUE(type)
+#define SPIF_DECL_CLASSNAME(type) "!spif_" #type "_t!"
/* The declaration of an interface class. */
-#define SPIF_DECL_IFCLASS(if, type) spif_const_ifclass_t spif_ifclass_ ## if ## _ ## type
+#define SPIF_DECL_IFCLASS(if, type) spif_const_ ## if ## _ifclass_t SPIF_IFCLASS_VAR(if, type)
/******************************** MSGS GOOP ***********************************/
diff --git a/src/conf.c b/src/conf.c
index c98e87f..14aa3fa 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -48,10 +48,8 @@ static conf_func_t *builtins;
static unsigned char ctx_cnt, ctx_idx, ctx_state_idx, ctx_state_cnt, fstate_cnt, builtin_cnt, builtin_idx;
static conf_var_t *conf_vars = NULL;
-const char *true_vals[] =
-{"1", "on", "true", "yes"};
-const char *false_vals[] =
-{"0", "off", "false", "no"};
+const char *true_vals[] = { "1", "on", "true", "yes" };
+const char *false_vals[] = { "0", "off", "false", "no" };
fstate_t *fstate;
unsigned char fstate_idx;
@@ -60,397 +58,403 @@ unsigned char fstate_idx;
/* This function must be called before any other conf_*() function.
Otherwise you will be bitten by dragons. That's life. */
void
-conf_init_subsystem(void) {
-
- /* Initialize the context list and establish a catch-all "null" context */
- ctx_cnt = 20;
- ctx_idx = 0;
- context = (ctx_t *) MALLOC(sizeof(ctx_t) * ctx_cnt);
- MEMSET(context, 0, sizeof(ctx_t) * ctx_cnt);
- context[0].name = STRDUP("null");
- context[0].handler = parse_null;
-
- /* Initialize the context state stack and set the current context to "null" */
- ctx_state_cnt = 20;
- ctx_state_idx = 0;
- ctx_state = (ctx_state_t *) MALLOC(sizeof(ctx_state_t) * ctx_state_cnt);
- MEMSET(ctx_state, 0, sizeof(ctx_state_t) * ctx_state_cnt);
-
- /* Initialize the file state stack */
- fstate_cnt = 10;
- fstate_idx = 0;
- fstate = (fstate_t *) MALLOC(sizeof(fstate_t) * fstate_cnt);
- MEMSET(fstate, 0, sizeof(fstate_t) * fstate_cnt);
-
- /* Initialize the builtin function table */
- builtin_cnt = 10;
- builtin_idx = 0;
- builtins = (conf_func_t *) MALLOC(sizeof(conf_func_t) * builtin_cnt);
- MEMSET(builtins, 0, sizeof(conf_func_t) * builtin_cnt);
-
- /* Register the omni-present builtin functions */
- conf_register_builtin("appname", builtin_appname);
- conf_register_builtin("version", builtin_version);
- conf_register_builtin("exec", builtin_exec);
- conf_register_builtin("random", builtin_random);
- conf_register_builtin("get", builtin_get);
- conf_register_builtin("put", builtin_put);
- conf_register_builtin("dirscan", builtin_dirscan);
+conf_init_subsystem(void)
+{
+
+ /* Initialize the context list and establish a catch-all "null" context */
+ ctx_cnt = 20;
+ ctx_idx = 0;
+ context = (ctx_t *) MALLOC(sizeof(ctx_t) * ctx_cnt);
+ MEMSET(context, 0, sizeof(ctx_t) * ctx_cnt);
+ context[0].name = STRDUP("null");
+ context[0].handler = parse_null;
+
+ /* Initialize the context state stack and set the current context to "null" */
+ ctx_state_cnt = 20;
+ ctx_state_idx = 0;
+ ctx_state = (ctx_state_t *) MALLOC(sizeof(ctx_state_t) * ctx_state_cnt);
+ MEMSET(ctx_state, 0, sizeof(ctx_state_t) * ctx_state_cnt);
+
+ /* Initialize the file state stack */
+ fstate_cnt = 10;
+ fstate_idx = 0;
+ fstate = (fstate_t *) MALLOC(sizeof(fstate_t) * fstate_cnt);
+ MEMSET(fstate, 0, sizeof(fstate_t) * fstate_cnt);
+
+ /* Initialize the builtin function table */
+ builtin_cnt = 10;
+ builtin_idx = 0;
+ builtins = (conf_func_t *) MALLOC(sizeof(conf_func_t) * builtin_cnt);
+ MEMSET(builtins, 0, sizeof(conf_func_t) * builtin_cnt);
+
+ /* Register the omni-present builtin functions */
+ conf_register_builtin("appname", builtin_appname);
+ conf_register_builtin("version", builtin_version);
+ conf_register_builtin("exec", builtin_exec);
+ conf_register_builtin("random", builtin_random);
+ conf_register_builtin("get", builtin_get);
+ conf_register_builtin("put", builtin_put);
+ conf_register_builtin("dirscan", builtin_dirscan);
}
/* Register a new config file context */
unsigned char
-conf_register_context(char *name, ctx_handler_t handler) {
-
- if (++ctx_idx == ctx_cnt) {
- ctx_cnt *= 2;
- context = (ctx_t *) REALLOC(context, sizeof(ctx_t) * ctx_cnt);
- }
- context[ctx_idx].name = STRDUP(name);
- context[ctx_idx].handler = handler;
- D_CONF(("Added context \"%s\" with ID %d and handler 0x%08x\n", context[ctx_idx].name, ctx_idx, context[ctx_idx].handler));
- return (ctx_idx);
+conf_register_context(char *name, ctx_handler_t handler)
+{
+
+ if (++ctx_idx == ctx_cnt) {
+ ctx_cnt *= 2;
+ context = (ctx_t *) REALLOC(context, sizeof(ctx_t) * ctx_cnt);
+ }
+ context[ctx_idx].name = STRDUP(name);
+ context[ctx_idx].handler = handler;
+ D_CONF(("Added context \"%s\" with ID %d and handler 0x%08x\n", context[ctx_idx].name, ctx_idx, context[ctx_idx].handler));
+ return (ctx_idx);
}
/* Register a new file state structure */
unsigned char
-conf_register_fstate(FILE *fp, char *path, char *outfile, unsigned long line, unsigned char flags) {
-
- if (++fstate_idx == fstate_cnt) {
- fstate_cnt *= 2;
- fstate = (fstate_t *) REALLOC(fstate, sizeof(fstate_t) * fstate_cnt);
- }
- fstate[fstate_idx].fp = fp;
- fstate[fstate_idx].path = path;
- fstate[fstate_idx].outfile = outfile;
- fstate[fstate_idx].line = line;
- fstate[fstate_idx].flags = flags;
- return (fstate_idx);
+conf_register_fstate(FILE * fp, char *path, char *outfile, unsigned long line, unsigned char flags)
+{
+
+ if (++fstate_idx == fstate_cnt) {
+ fstate_cnt *= 2;
+ fstate = (fstate_t *) REALLOC(fstate, sizeof(fstate_t) * fstate_cnt);
+ }
+ fstate[fstate_idx].fp = fp;
+ fstate[fstate_idx].path = path;
+ fstate[fstate_idx].outfile = outfile;
+ fstate[fstate_idx].line = line;
+ fstate[fstate_idx].flags = flags;
+ return (fstate_idx);
}
/* Register a new builtin function */
unsigned char
-conf_register_builtin(char *name, conf_func_ptr_t ptr) {
-
- builtins[builtin_idx].name = STRDUP(name);
- builtins[builtin_idx].ptr = ptr;
- if (++builtin_idx == builtin_cnt) {
- builtin_cnt *= 2;
- builtins = (conf_func_t *) REALLOC(builtins, sizeof(conf_func_t) * builtin_cnt);
- }
- return (builtin_idx - 1);
+conf_register_builtin(char *name, conf_func_ptr_t ptr)
+{
+
+ builtins[builtin_idx].name = STRDUP(name);
+ builtins[builtin_idx].ptr = ptr;
+ if (++builtin_idx == builtin_cnt) {
+ builtin_cnt *= 2;
+ builtins = (conf_func_t *) REALLOC(builtins, sizeof(conf_func_t) * builtin_cnt);
+ }
+ return (builtin_idx - 1);
}
/* Register a new config file context */
unsigned char
-conf_register_context_state(unsigned char ctx_id) {
-
- if (++ctx_state_idx == ctx_state_cnt) {
- ctx_state_cnt *= 2;
- ctx_state = (ctx_state_t *) REALLOC(ctx_state, sizeof(ctx_state_t) * ctx_state_cnt);
- }
- ctx_state[ctx_state_idx].ctx_id = ctx_id;
- ctx_state[ctx_state_idx].state = NULL;
- return (ctx_state_idx);
+conf_register_context_state(unsigned char ctx_id)
+{
+
+ if (++ctx_state_idx == ctx_state_cnt) {
+ ctx_state_cnt *= 2;
+ ctx_state = (ctx_state_t *) REALLOC(ctx_state, sizeof(ctx_state_t) * ctx_state_cnt);
+ }
+ ctx_state[ctx_state_idx].ctx_id = ctx_id;
+ ctx_state[ctx_state_idx].state = NULL;
+ return (ctx_state_idx);
}
void
conf_free_subsystem(void)
{
- conf_var_t *v, *tmp;
- unsigned long i;
-
- for (v = conf_vars; v;) {
- tmp = v;
- v = v->next;
- conf_free_var(tmp);
- }
- for (i = 0; i < builtin_idx; i++) {
- FREE(builtins[i].name);
- }
- for (i = 0; i <= ctx_idx; i++) {
- FREE(context[i].name);
- }
- FREE(ctx_state);
- FREE(builtins);
- FREE(fstate);
- FREE(context);
+ conf_var_t *v, *tmp;
+ unsigned long i;
+
+ for (v = conf_vars; v;) {
+ tmp = v;
+ v = v->next;
+ conf_free_var(tmp);
+ }
+ for (i = 0; i < builtin_idx; i++) {
+ FREE(builtins[i].name);
+ }
+ for (i = 0; i <= ctx_idx; i++) {
+ FREE(context[i].name);
+ }
+ FREE(ctx_state);
+ FREE(builtins);
+ FREE(fstate);
+ FREE(context);
}
static conf_var_t *
conf_new_var(void)
{
- conf_var_t *v;
+ conf_var_t *v;
- v = (conf_var_t *) MALLOC(sizeof(conf_var_t));
- MEMSET(v, 0, sizeof(conf_var_t));
- return v;
+ v = (conf_var_t *) MALLOC(sizeof(conf_var_t));
+ MEMSET(v, 0, sizeof(conf_var_t));
+ return v;
}
static void
-conf_free_var(conf_var_t *v)
+conf_free_var(conf_var_t * v)
{
- if (v->var) {
- FREE(v->var);
- }
- if (v->value) {
- FREE(v->value);
- }
- FREE(v);
+ if (v->var) {
+ FREE(v->var);
+ }
+ if (v->value) {
+ FREE(v->value);
+ }
+ FREE(v);
}
static char *
conf_get_var(const char *var)
{
- conf_var_t *v;
+ conf_var_t *v;
- D_CONF(("var == \"%s\"\n", var));
- for (v = conf_vars; v; v = v->next) {
- if (!strcmp(v->var, var)) {
- D_CONF(("Found it at %8p: \"%s\" == \"%s\"\n", v, v->var, v->value));
- return (v->value);
+ D_CONF(("var == \"%s\"\n", var));
+ for (v = conf_vars; v; v = v->next) {
+ if (!strcmp(v->var, var)) {
+ D_CONF(("Found it at %8p: \"%s\" == \"%s\"\n", v, v->var, v->value));
+ return (v->value);
+ }
}
- }
- D_CONF(("Not found.\n"));
- return NULL;
+ D_CONF(("Not found.\n"));
+ return NULL;
}
static void
conf_put_var(char *var, char *val)
{
- conf_var_t *v, *loc = NULL, *tmp;
-
- ASSERT(var != NULL);
- D_CONF(("var == \"%s\", val == \"%s\"\n", var, val));
-
- for (v = conf_vars; v; loc = v, v = v->next) {
- int n;
-
- n = strcmp(var, v->var);
- D_CONF(("Comparing at %8p: \"%s\" -> \"%s\", n == %d\n", v, v->var, v->value, n));
- if (n == 0) {
- FREE(v->value);
- if (val) {
- v->value = val;
- D_CONF(("Variable already defined. Replacing its value with \"%s\"\n", v->value));
- } else {
- D_CONF(("Variable already defined. Deleting it.\n"));
- if (loc) {
- loc->next = v->next;
- } else {
- conf_vars = v->next;
+ conf_var_t *v, *loc = NULL, *tmp;
+
+ ASSERT(var != NULL);
+ D_CONF(("var == \"%s\", val == \"%s\"\n", var, val));
+
+ for (v = conf_vars; v; loc = v, v = v->next) {
+ int n;
+
+ n = strcmp(var, v->var);
+ D_CONF(("Comparing at %8p: \"%s\" -> \"%s\", n == %d\n", v, v->var, v->value, n));
+ if (n == 0) {
+ FREE(v->value);
+ if (val) {
+ v->value = val;
+ D_CONF(("Variable already defined. Replacing its value with \"%s\"\n", v->value));
+ } else {
+ D_CONF(("Variable already defined. Deleting it.\n"));
+ if (loc) {
+ loc->next = v->next;
+ } else {
+ conf_vars = v->next;
+ }
+ conf_free_var(v);
+ }
+ return;
+ } else if (n < 0) {
+ break;
}
- conf_free_var(v);
- }
- return;
- } else if (n < 0) {
- break;
- }
- }
- if (!val) {
- D_CONF(("Empty value given for non-existant variable \"%s\". Aborting.\n", var));
- return;
- }
- D_CONF(("Inserting new var/val pair between \"%s\" and \"%s\"\n", ((loc) ? loc->var : "-beginning-"), ((v) ? v->var : "-end-")));
- tmp = conf_new_var();
- if (loc == NULL) {
- tmp->next = conf_vars;
- conf_vars = tmp;
- } else {
- tmp->next = loc->next;
- loc->next = tmp;
- }
- tmp->var = var;
- tmp->value = val;
+ }
+ if (!val) {
+ D_CONF(("Empty value given for non-existant variable \"%s\". Aborting.\n", var));
+ return;
+ }
+ D_CONF(("Inserting new var/val pair between \"%s\" and \"%s\"\n", ((loc) ? loc->var : "-beginning-"), ((v) ? v->var : "-end-")));
+ tmp = conf_new_var();
+ if (loc == NULL) {
+ tmp->next = conf_vars;
+ conf_vars = tmp;
+ } else {
+ tmp->next = loc->next;
+ loc->next = tmp;
+ }
+ tmp->var = var;
+ tmp->value = val;
}
static char *
builtin_random(char *param)
{
- unsigned long n, index;
- static unsigned int rseed = 0;
+ unsigned long n, index;
+ static unsigned int rseed = 0;
- D_PARSE(("builtin_random(%s) called\n", NONULL(param)));
+ D_PARSE(("builtin_random(%s) called\n", NONULL(param)));
- if (rseed == 0) {
- rseed = (unsigned int) (getpid() * time(NULL) % ((unsigned int) -1));
- srand(rseed);
- }
- n = num_words(param);
- index = (int) (n * ((float) rand()) / (RAND_MAX + 1.0)) + 1;
- D_PARSE(("random index == %lu\n", index));
+ if (rseed == 0) {
+ rseed = (unsigned int) (getpid() * time(NULL) % ((unsigned int) -1));
+ srand(rseed);
+ }
+ n = num_words(param);
+ index = (int) (n * ((float) rand()) / (RAND_MAX + 1.0)) + 1;
+ D_PARSE(("random index == %lu\n", index));
- return (get_word(index, param));
+ return (get_word(index, param));
}
static char *
builtin_exec(char *param)
{
- unsigned long fsize;
- char *Command, *Output = NULL;
- char OutFile[256];
- FILE *fp;
- int fd;
-
- D_PARSE(("builtin_exec(%s) called\n", NONULL(param)));
-
- Command = (char *) MALLOC(CONFIG_BUFF);
- strcpy(OutFile, "Eterm-exec-");
- fd = libast_temp_file(OutFile, sizeof(OutFile));
- if ((fd < 0) || fchmod(fd, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
- print_error("Unable to create unique temporary file for \"%s\" -- %s\n", param, strerror(errno));
- return ((char *) NULL);
- }
- if (strlen(param) + strlen(OutFile) + 8 > CONFIG_BUFF) {
- print_error("Parse error in file %s, line %lu: Cannot execute command, line too long\n",
- file_peek_path(), file_peek_line());
- return ((char *) NULL);
- }
- strcpy(Command, param);
- strcat(Command, " >");
- strcat(Command, OutFile);
- system(Command);
- if ((fp = fdopen(fd, "rb")) != NULL) {
- fseek(fp, 0, SEEK_END);
- fsize = ftell(fp);
- rewind(fp);
- if (fsize) {
- Output = (char *) MALLOC(fsize + 1);
- fread(Output, fsize, 1, fp);
- Output[fsize] = 0;
- fclose(fp);
- remove(OutFile);
- Output = condense_whitespace(Output);
+ unsigned long fsize;
+ char *Command, *Output = NULL;
+ char OutFile[256];
+ FILE *fp;
+ int fd;
+
+ D_PARSE(("builtin_exec(%s) called\n", NONULL(param)));
+
+ Command = (char *) MALLOC(CONFIG_BUFF);
+ strcpy(OutFile, "Eterm-exec-");
+ fd = libast_temp_file(OutFile, sizeof(OutFile));
+ if ((fd < 0) || fchmod(fd, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
+ print_error("Unable to create unique temporary file for \"%s\" -- %s\n", param, strerror(errno));
+ return ((char *) NULL);
+ }
+ if (strlen(param) + strlen(OutFile) + 8 > CONFIG_BUFF) {
+ print_error("Parse error in file %s, line %lu: Cannot execute command, line too long\n", file_peek_path(), file_peek_line());
+ return ((char *) NULL);
+ }
+ strcpy(Command, param);
+ strcat(Command, " >");
+ strcat(Command, OutFile);
+ system(Command);
+ if ((fp = fdopen(fd, "rb")) != NULL) {
+ fseek(fp, 0, SEEK_END);
+ fsize = ftell(fp);
+ rewind(fp);
+ if (fsize) {
+ Output = (char *) MALLOC(fsize + 1);
+ fread(Output, fsize, 1, fp);
+ Output[fsize] = 0;
+ fclose(fp);
+ remove(OutFile);
+ Output = condense_whitespace(Output);
+ } else {
+ print_warning("Command at line %lu of file %s returned no output.\n", file_peek_line(), file_peek_path());
+ }
} else {
- print_warning("Command at line %lu of file %s returned no output.\n", file_peek_line(), file_peek_path());
+ print_warning("Output file %s could not be created. (line %lu of file %s)\n", NONULL(OutFile), file_peek_line(), file_peek_path());
}
- } else {
- print_warning("Output file %s could not be created. (line %lu of file %s)\n", NONULL(OutFile),
- file_peek_line(), file_peek_path());
- }
- FREE(Command);
+ FREE(Command);
- return (Output);
+ return (Output);
}
static char *
builtin_get(char *param)
{
- char *s, *f, *v;
- unsigned short n;
+ char *s, *f, *v;
+ unsigned short n;
- if (!param || ((n = num_words(param)) > 2)) {
- print_error("Parse error in file %s, line %lu: Invalid syntax for %get(). Syntax is: %get(variable)\n", file_peek_path(), file_peek_line());
- return NULL;
- }
-
- D_PARSE(("builtin_get(%s) called\n", param));
- s = get_word(1, param);
- if (n == 2) {
- f = get_word(2, param);
- } else {
- f = NULL;
- }
- v = conf_get_var(s);
- FREE(s);
- if (v) {
- if (f) {
- FREE(f);
- }
- return (STRDUP(v));
- } else if (f) {
- return f;
- } else {
- return NULL;
- }
+ if (!param || ((n = num_words(param)) > 2)) {
+ print_error("Parse error in file %s, line %lu: Invalid syntax for %get(). Syntax is: %get(variable)\n", file_peek_path(),
+ file_peek_line());
+ return NULL;
+ }
+
+ D_PARSE(("builtin_get(%s) called\n", param));
+ s = get_word(1, param);
+ if (n == 2) {
+ f = get_word(2, param);
+ } else {
+ f = NULL;
+ }
+ v = conf_get_var(s);
+ FREE(s);
+ if (v) {
+ if (f) {
+ FREE(f);
+ }
+ return (STRDUP(v));
+ } else if (f) {
+ return f;
+ } else {
+ return NULL;
+ }
}
static char *
builtin_put(char *param)
{
- char *var, *val;
+ char *var, *val;
- if (!param || (num_words(param) != 2)) {
- print_error("Parse error in file %s, line %lu: Invalid syntax for %put(). Syntax is: %put(variable value)\n", file_peek_path(), file_peek_line());
- return NULL;
- }
+ if (!param || (num_words(param) != 2)) {
+ print_error("Parse error in file %s, line %lu: Invalid syntax for %put(). Syntax is: %put(variable value)\n", file_peek_path(),
+ file_peek_line());
+ return NULL;
+ }
- D_PARSE(("builtin_put(%s) called\n", param));
- var = get_word(1, param);
- val = get_word(2, param);
- conf_put_var(var, val);
- return NULL;
+ D_PARSE(("builtin_put(%s) called\n", param));
+ var = get_word(1, param);
+ val = get_word(2, param);
+ conf_put_var(var, val);
+ return NULL;
}
static char *
builtin_dirscan(char *param)
{
- int i;
- unsigned long n;
- DIR *dirp;
- struct dirent *dp;
- struct stat filestat;
- char *dir, *buff;
-
- if (!param || (num_words(param) != 1)) {
- print_error("Parse error in file %s, line %lu: Invalid syntax for %dirscan(). Syntax is: %dirscan(directory)\n", file_peek_path(), file_peek_line());
- return NULL;
- }
- D_PARSE(("builtin_dirscan(%s)\n", param));
- dir = get_word(1, param);
- dirp = opendir(dir);
- if (!dirp) {
- return NULL;
- }
- buff = (char *) MALLOC(CONFIG_BUFF);
- *buff = 0;
- n = CONFIG_BUFF;
+ int i;
+ unsigned long n;
+ DIR *dirp;
+ struct dirent *dp;
+ struct stat filestat;
+ char *dir, *buff;
+
+ if (!param || (num_words(param) != 1)) {
+ print_error("Parse error in file %s, line %lu: Invalid syntax for %dirscan(). Syntax is: %dirscan(directory)\n",
+ file_peek_path(), file_peek_line());
+ return NULL;
+ }
+ D_PARSE(("builtin_dirscan(%s)\n", param));
+ dir = get_word(1, param);
+ dirp = opendir(dir);
+ if (!dirp) {
+ return NULL;
+ }
+ buff = (char *) MALLOC(CONFIG_BUFF);
+ *buff = 0;
+ n = CONFIG_BUFF;
- for (i = 0; (dp = readdir(dirp)) != NULL;) {
- char fullname[PATH_MAX];
+ for (i = 0; (dp = readdir(dirp)) != NULL;) {
+ char fullname[PATH_MAX];
- snprintf(fullname, sizeof(fullname), "%s/%s", dir, dp->d_name);
- if (stat(fullname, &filestat)) {
- D_PARSE((" -> Couldn't stat() file %s -- %s\n", fullname, strerror(errno)));
- } else {
- if (S_ISREG(filestat.st_mode)) {
- unsigned long len;
-
- len = strlen(dp->d_name);
- if (len < n) {
- strcat(buff, dp->d_name);
- strcat(buff, " ");
- n -= len + 1;
+ snprintf(fullname, sizeof(fullname), "%s/%s", dir, dp->d_name);
+ if (stat(fullname, &filestat)) {
+ D_PARSE((" -> Couldn't stat() file %s -- %s\n", fullname, strerror(errno)));
+ } else {
+ if (S_ISREG(filestat.st_mode)) {
+ unsigned long len;
+
+ len = strlen(dp->d_name);
+ if (len < n) {
+ strcat(buff, dp->d_name);
+ strcat(buff, " ");
+ n -= len + 1;
+ }
+ }
+ }
+ if (n < 2) {
+ break;
}
- }
- }
- if (n < 2) {
- break;
}
- }
- closedir(dirp);
- return buff;
+ closedir(dirp);
+ return buff;
}
static char *
builtin_version(char *param)
{
- USE_VAR(param);
- D_PARSE(("builtin_version(%s) called\n", NONULL(param)));
+ USE_VAR(param);
+ D_PARSE(("builtin_version(%s) called\n", NONULL(param)));
- return (STRDUP(libast_program_version));
+ return (STRDUP(libast_program_version));
}
static char *
builtin_appname(char *param)
{
- char buff[30];
+ char buff[30];
- USE_VAR(param);
- D_PARSE(("builtin_appname(%s) called\n", NONULL(param)));
+ USE_VAR(param);
+ D_PARSE(("builtin_appname(%s) called\n", NONULL(param)));
- snprintf(buff, sizeof(buff), "%s-%s", libast_program_name, libast_program_version);
- return (STRDUP(buff));
+ snprintf(buff, sizeof(buff), "%s-%s", libast_program_name, libast_program_version);
+ return (STRDUP(buff));
}
/* shell_expand() takes care of shell variable expansion, quote conventions,
@@ -458,487 +462,490 @@ builtin_appname(char *param)
char *
shell_expand(char *s)
{
- register char *tmp;
- register char *pbuff = s, *tmp1;
- register unsigned long j, k, l = 0;
- char new[CONFIG_BUFF];
- unsigned char in_single = 0, in_double = 0;
- unsigned long cnt1 = 0, cnt2 = 0;
- const unsigned long max = CONFIG_BUFF - 1;
- char *Command, *Output, *EnvVar;
+ register char *tmp;
+ register char *pbuff = s, *tmp1;
+ register unsigned long j, k, l = 0;
+ char newbuff[CONFIG_BUFF];
+ unsigned char in_single = 0, in_double = 0;
+ unsigned long cnt1 = 0, cnt2 = 0;
+ const unsigned long max = CONFIG_BUFF - 1;
+ char *Command, *Output, *EnvVar;
- ASSERT_RVAL(s != NULL, (char *) NULL);
+ ASSERT_RVAL(s != NULL, (char *) NULL);
#if 0
- new = (char *) MALLOC(CONFIG_BUFF);
+ newbuff = (char *) MALLOC(CONFIG_BUFF);
#endif
- for (j = 0; *pbuff && j < max; pbuff++, j++) {
- switch (*pbuff) {
- case '~':
- D_CONF(("Tilde detected.\n"));
- if (!in_single && !in_double) {
- strncpy(new + j, getenv("HOME"), max - j);
- cnt1 = strlen(getenv("HOME")) - 1;
- cnt2 = max - j - 1;
- j += MIN(cnt1, cnt2);
- } else {
- new[j] = *pbuff;
- }
- break;
- case '\\':
- D_CONF(("Escape sequence detected.\n"));
- if (!in_single || (in_single && *(pbuff + 1) == '\'')) {
- switch (tolower(*(++pbuff))) {
- case 'n':
- new[j] = '\n';
- break;
- case 'r':
- new[j] = '\r';
- break;
- case 't':
- new[j] = '\t';
- break;
- case 'b':
- new[j] = '\b';
- break;
- case 'f':
- new[j] = '\f';
- break;
- case 'a':
- new[j] = '\a';
- break;
- case 'v':
- new[j] = '\v';
- break;
- case 'e':
- new[j] = '\033';
- break;
- default:
- new[j] = *pbuff;
- break;
- }
- } else {
- new[j++] = *(pbuff++);
- new[j] = *pbuff;
- }
- break;
- case '%':
- D_CONF(("%% detected.\n"));
- for (k = 0, pbuff++; builtins[k].name != NULL; k++) {
- D_PARSE(("Checking for function %%%s, pbuff == \"%s\"\n", builtins[k].name, pbuff));
- l = strlen(builtins[k].name);
- if (!strncasecmp(builtins[k].name, pbuff, l) &&
- ((pbuff[l] == '(') || (pbuff[l] == ' ' && pbuff[l + 1] == ')'))) {
- break;
- }
- }
- if (builtins[k].name == NULL) {
- new[j] = *pbuff;
- } else {
- D_CONF(("Call to built-in function %s detected.\n", builtins[k].name));
- Command = (char *) MALLOC(CONFIG_BUFF);
- pbuff += l;
- if (*pbuff != '(')
- pbuff++;
- for (tmp1 = Command, pbuff++, l = 1; l && *pbuff; pbuff++, tmp1++) {
- switch (*pbuff) {
- case '(':
- l++;
- *tmp1 = *pbuff;
- break;
- case ')':
- l--;
- default:
- *tmp1 = *pbuff;
- break;
- }
- }
- *(--tmp1) = 0;
- if (l) {
- print_error("parse error in file %s, line %lu: Mismatched parentheses\n",
- file_peek_path(), file_peek_line());
- return ((char *) NULL);
- }
- Command = shell_expand(Command);
- Output = (builtins[k].ptr) (Command);
- FREE(Command);
- if (Output) {
- if (*Output) {
- l = strlen(Output) - 1;
- strncpy(new + j, Output, max - j);
- cnt2 = max - j - 1;
- j += MIN(l, cnt2);
- } else {
- j--;
- }
- FREE(Output);
- } else {
- j--;
- }
- pbuff--;
- }
- break;
- case '`':
+ for (j = 0; *pbuff && j < max; pbuff++, j++) {
+ switch (*pbuff) {
+ case '~':
+ D_CONF(("Tilde detected.\n"));
+ if (!in_single && !in_double) {
+ strncpy(newbuff + j, getenv("HOME"), max - j);
+ cnt1 = strlen(getenv("HOME")) - 1;
+ cnt2 = max - j - 1;
+ j += MIN(cnt1, cnt2);
+ } else {
+ newbuff[j] = *pbuff;
+ }
+ break;
+ case '\\':
+ D_CONF(("Escape sequence detected.\n"));
+ if (!in_single || (in_single && *(pbuff + 1) == '\'')) {
+ switch (tolower(*(++pbuff))) {
+ case 'n':
+ newbuff[j] = '\n';
+ break;
+ case 'r':
+ newbuff[j] = '\r';
+ break;
+ case 't':
+ newbuff[j] = '\t';
+ break;
+ case 'b':
+ newbuff[j] = '\b';
+ break;
+ case 'f':
+ newbuff[j] = '\f';
+ break;
+ case 'a':
+ newbuff[j] = '\a';
+ break;
+ case 'v':
+ newbuff[j] = '\v';
+ break;
+ case 'e':
+ newbuff[j] = '\033';
+ break;
+ default:
+ newbuff[j] = *pbuff;
+ break;
+ }
+ } else {
+ newbuff[j++] = *(pbuff++);
+ newbuff[j] = *pbuff;
+ }
+ break;
+ case '%':
+ D_CONF(("%% detected.\n"));
+ for (k = 0, pbuff++; builtins[k].name != NULL; k++) {
+ D_PARSE(("Checking for function %%%s, pbuff == \"%s\"\n", builtins[k].name, pbuff));
+ l = strlen(builtins[k].name);
+ if (!strncasecmp(builtins[k].name, pbuff, l) && ((pbuff[l] == '(') || (pbuff[l] == ' ' && pbuff[l + 1] == ')'))) {
+ break;
+ }
+ }
+ if (builtins[k].name == NULL) {
+ newbuff[j] = *pbuff;
+ } else {
+ D_CONF(("Call to built-in function %s detected.\n", builtins[k].name));
+ Command = (char *) MALLOC(CONFIG_BUFF);
+ pbuff += l;
+ if (*pbuff != '(')
+ pbuff++;
+ for (tmp1 = Command, pbuff++, l = 1; l && *pbuff; pbuff++, tmp1++) {
+ switch (*pbuff) {
+ case '(':
+ l++;
+ *tmp1 = *pbuff;
+ break;
+ case ')':
+ l--;
+ default:
+ *tmp1 = *pbuff;
+ break;
+ }
+ }
+ *(--tmp1) = 0;
+ if (l) {
+ print_error("parse error in file %s, line %lu: Mismatched parentheses\n", file_peek_path(), file_peek_line());
+ return ((char *) NULL);
+ }
+ Command = shell_expand(Command);
+ Output = (builtins[k].ptr) (Command);
+ FREE(Command);
+ if (Output) {
+ if (*Output) {
+ l = strlen(Output) - 1;
+ strncpy(newbuff + j, Output, max - j);
+ cnt2 = max - j - 1;
+ j += MIN(l, cnt2);
+ } else {
+ j--;
+ }
+ FREE(Output);
+ } else {
+ j--;
+ }
+ pbuff--;
+ }
+ break;
+ case '`':
#ifdef ALLOW_BACKQUOTE_EXEC
- D_CONF(("Backquotes detected. Evaluating expression.\n"));
- if (!in_single) {
- Command = (char *) MALLOC(CONFIG_BUFF);
- l = 0;
- for (pbuff++; *pbuff && *pbuff != '`' && l < max; pbuff++, l++) {
- Command[l] = *pbuff;
- }
- ASSERT(l < CONFIG_BUFF);
- Command[l] = 0;
- Command = shell_expand(Command);
- Output = builtin_exec(Command);
- FREE(Command);
- if (Output) {
- if (*Output) {
- l = strlen(Output) - 1;
- strncpy(new + j, Output, max - j);
- cnt2 = max - j - 1;
- j += MIN(l, cnt2);
- } else {
- j--;
- }
- FREE(Output);
- } else {
- j--;
- }
- } else {
- new[j] = *pbuff;
- }
+ D_CONF(("Backquotes detected. Evaluating expression.\n"));
+ if (!in_single) {
+ Command = (char *) MALLOC(CONFIG_BUFF);
+ l = 0;
+ for (pbuff++; *pbuff && *pbuff != '`' && l < max; pbuff++, l++) {
+ Command[l] = *pbuff;
+ }
+ ASSERT(l < CONFIG_BUFF);
+ Command[l] = 0;
+ Command = shell_expand(Command);
+ Output = builtin_exec(Command);
+ FREE(Command);
+ if (Output) {
+ if (*Output) {
+ l = strlen(Output) - 1;
+ strncpy(newbuff + j, Output, max - j);
+ cnt2 = max - j - 1;
+ j += MIN(l, cnt2);
+ } else {
+ j--;
+ }
+ FREE(Output);
+ } else {
+ j--;
+ }
+ } else {
+ newbuff[j] = *pbuff;
+ }
#else
- print_warning("Backquote execution support not compiled in, ignoring\n");
- new[j] = *pbuff;
+ print_warning("Backquote execution support not compiled in, ignoring\n");
+ newbuff[j] = *pbuff;
#endif
- break;
- case '$':
- D_CONF(("Environment variable detected. Evaluating.\n"));
- if (!in_single) {
- EnvVar = (char *) MALLOC(128);
- switch (*(++pbuff)) {
- case '{':
- for (pbuff++, k = 0; *pbuff != '}' && k < 127; k++, pbuff++)
- EnvVar[k] = *pbuff;
- break;
- case '(':
- for (pbuff++, k = 0; *pbuff != ')' && k < 127; k++, pbuff++)
- EnvVar[k] = *pbuff;
- break;
- default:
- for (k = 0; (isalnum(*pbuff) || *pbuff == '_') && k < 127; k++, pbuff++)
- EnvVar[k] = *pbuff;
- break;
- }
- EnvVar[k] = 0;
- if ((tmp = getenv(EnvVar))) {
- strncpy(new, tmp, max - j);
- cnt1 = strlen(tmp) - 1;
- cnt2 = max - j - 1;
- j += MIN(cnt1, cnt2);
- }
- pbuff--;
- } else {
- new[j] = *pbuff;
- }
- break;
- case '\"':
- D_CONF(("Double quotes detected.\n"));
- if (!in_single) {
- if (in_double) {
- in_double = 0;
- } else {
- in_double = 1;
- }
- }
- new[j] = *pbuff;
- break;
-
- case '\'':
- D_CONF(("Single quotes detected.\n"));
- if (in_single) {
- in_single = 0;
- } else {
- in_single = 1;
- }
- new[j] = *pbuff;
- break;
-
- default:
- new[j] = *pbuff;
+ break;
+ case '$':
+ D_CONF(("Environment variable detected. Evaluating.\n"));
+ if (!in_single) {
+ EnvVar = (char *) MALLOC(128);
+ switch (*(++pbuff)) {
+ case '{':
+ for (pbuff++, k = 0; *pbuff != '}' && k < 127; k++, pbuff++)
+ EnvVar[k] = *pbuff;
+ break;
+ case '(':
+ for (pbuff++, k = 0; *pbuff != ')' && k < 127; k++, pbuff++)
+ EnvVar[k] = *pbuff;
+ break;
+ default:
+ for (k = 0; (isalnum(*pbuff) || *pbuff == '_') && k < 127; k++, pbuff++)
+ EnvVar[k] = *pbuff;
+ break;
+ }
+ EnvVar[k] = 0;
+ if ((tmp = getenv(EnvVar))) {
+ strncpy(newbuff, tmp, max - j);
+ cnt1 = strlen(tmp) - 1;
+ cnt2 = max - j - 1;
+ j += MIN(cnt1, cnt2);
+ }
+ pbuff--;
+ } else {
+ newbuff[j] = *pbuff;
+ }
+ break;
+ case '\"':
+ D_CONF(("Double quotes detected.\n"));
+ if (!in_single) {
+ if (in_double) {
+ in_double = 0;
+ } else {
+ in_double = 1;
+ }
+ }
+ newbuff[j] = *pbuff;
+ break;
+
+ case '\'':
+ D_CONF(("Single quotes detected.\n"));
+ if (in_single) {
+ in_single = 0;
+ } else {
+ in_single = 1;
+ }
+ newbuff[j] = *pbuff;
+ break;
+
+ default:
+ newbuff[j] = *pbuff;
+ }
}
- }
- ASSERT(j < CONFIG_BUFF);
- new[j] = 0;
+ ASSERT(j < CONFIG_BUFF);
+ newbuff[j] = 0;
- D_PARSE(("shell_expand(%s) returning \"%s\"\n", s, new));
- D_PARSE((" strlen(s) == %lu, strlen(new) == %lu, j == %lu\n", strlen(s), strlen(new), j));
+ D_PARSE(("shell_expand(%s) returning \"%s\"\n", s, newbuff));
+ D_PARSE((" strlen(s) == %lu, strlen(newbuff) == %lu, j == %lu\n", strlen(s), strlen(newbuff), j));
- strcpy(s, new);
+ strcpy(s, newbuff);
#if 0
- FREE(new);
+ FREE(newbuff);
#endif
- return (s);
+ return (s);
}
/* The config file reader. This looks for the config file by searching CONFIG_SEARCH_PATH.
If it can't find a config file, it displays a warning but continues. -- mej */
char *
-conf_find_file(const char *file, const char *dir, const char *pathlist) {
-
- static char name[PATH_MAX], full_path[PATH_MAX];
- const char *path;
- char *p;
- short maxpathlen;
- unsigned short len;
- struct stat fst;
-
- REQUIRE_RVAL(file != NULL, NULL);
-
- getcwd(name, PATH_MAX);
- D_CONF(("conf_find_file(\"%s\", \"%s\", \"%s\") called from directory \"%s\".\n", file, NONULL(dir), NONULL(pathlist), name));
-
- if (dir) {
- strcpy(name, dir);
- strcat(name, "/");
- strcat(name, file);
- } else {
- strcpy(name, file);
- }
- len = strlen(name);
- D_CONF(("Checking for file \"%s\"\n", name));
- if ((!access(name, R_OK)) && (!stat(name, &fst)) && (!S_ISDIR(fst.st_mode))) {
- D_CONF(("Found \"%s\"\n", name));
- return ((char *) name);
- }
-
- /* maxpathlen is the longest possible path we can stuff into name[]. The - 2 saves room for
- an additional / and the trailing null. */
- if ((maxpathlen = sizeof(name) - len - 2) <= 0) {
- D_CONF(("Too big. I lose. :(\n", name));
- return ((char *) NULL);
- }
+conf_find_file(const char *file, const char *dir, const char *pathlist)
+{
+
+ static char name[PATH_MAX], full_path[PATH_MAX];
+ const char *path;
+ char *p;
+ short maxpathlen;
+ unsigned short len;
+ struct stat fst;
+
+ REQUIRE_RVAL(file != NULL, NULL);
- for (path = pathlist; path != NULL && *path != '\0'; path = p) {
- short n;
+ getcwd(name, PATH_MAX);
+ D_CONF(("conf_find_file(\"%s\", \"%s\", \"%s\") called from directory \"%s\".\n", file, NONULL(dir), NONULL(pathlist), name));
- /* Calculate the length of the next directory in the path */
- if ((p = strchr(path, ':')) != NULL) {
- n = p++ - path;
+ if (dir) {
+ strcpy(name, dir);
+ strcat(name, "/");
+ strcat(name, file);
} else {
- n = strlen(path);
- }
-
- /* Don't try if it's too long */
- if (n > 0 && n <= maxpathlen) {
- /* Compose the /path/file combo */
- strncpy(full_path, path, n);
- if (full_path[n - 1] != '/') {
- full_path[n++] = '/';
- }
- full_path[n] = '\0';
- strcat(full_path, name);
-
- D_CONF(("Checking for file \"%s\"\n", full_path));
- if ((!access(full_path, R_OK)) && (!stat(full_path, &fst)) && (!S_ISDIR(fst.st_mode))) {
- D_CONF(("Found \"%s\"\n", full_path));
- return ((char *) full_path);
- }
- }
- }
- D_CONF(("conf_find_file(): File \"%s\" not found in path.\n", name));
- return ((char *) NULL);
+ strcpy(name, file);
+ }
+ len = strlen(name);
+ D_CONF(("Checking for file \"%s\"\n", name));
+ if ((!access(name, R_OK)) && (!stat(name, &fst)) && (!S_ISDIR(fst.st_mode))) {
+ D_CONF(("Found \"%s\"\n", name));
+ return ((char *) name);
+ }
+
+ /* maxpathlen is the longest possible path we can stuff into name[]. The - 2 saves room for
+ an additional / and the trailing null. */
+ if ((maxpathlen = sizeof(name) - len - 2) <= 0) {
+ D_CONF(("Too big. I lose. :(\n", name));
+ return ((char *) NULL);
+ }
+
+ for (path = pathlist; path != NULL && *path != '\0'; path = p) {
+ short n;
+
+ /* Calculate the length of the next directory in the path */
+ if ((p = strchr(path, ':')) != NULL) {
+ n = p++ - path;
+ } else {
+ n = strlen(path);
+ }
+
+ /* Don't try if it's too long */
+ if (n > 0 && n <= maxpathlen) {
+ /* Compose the /path/file combo */
+ strncpy(full_path, path, n);
+ if (full_path[n - 1] != '/') {
+ full_path[n++] = '/';
+ }
+ full_path[n] = '\0';
+ strcat(full_path, name);
+
+ D_CONF(("Checking for file \"%s\"\n", full_path));
+ if ((!access(full_path, R_OK)) && (!stat(full_path, &fst)) && (!S_ISDIR(fst.st_mode))) {
+ D_CONF(("Found \"%s\"\n", full_path));
+ return ((char *) full_path);
+ }
+ }
+ }
+ D_CONF(("conf_find_file(): File \"%s\" not found in path.\n", name));
+ return ((char *) NULL);
}
FILE *
open_config_file(char *name)
{
- FILE *fp;
- int ver;
- char buff[256], test[30], *begin_ptr, *end_ptr;
-
- ASSERT(name != NULL);
-
- snprintf(test, sizeof(test), "<%s-", libast_program_name);
- fp = fopen(name, "rt");
- if (fp != NULL) {
- fgets(buff, 256, fp);
- if (strncasecmp(buff, test, strlen(test))) {
- print_warning("%s exists but does not contain the proper magic string (<%s-%s>)\n", name, libast_program_name, libast_program_version);
- fclose(fp);
- fp = NULL;
- } else {
- begin_ptr = strchr(buff, '-') + 1;
- if ((end_ptr = strchr(buff, '>')) != NULL) {
- *end_ptr = 0;
- }
- if ((ver = BEG_STRCASECMP(begin_ptr, libast_program_version)) > 0) {
- print_warning("Config file is designed for a newer version of %s\n", libast_program_name);
- }
- }
- }
- return (fp);
+ FILE *fp;
+ int ver;
+ char buff[256], test[30], *begin_ptr, *end_ptr;
+
+ ASSERT(name != NULL);
+
+ snprintf(test, sizeof(test), "<%s-", libast_program_name);
+ fp = fopen(name, "rt");
+ if (fp != NULL) {
+ fgets(buff, 256, fp);
+ if (strncasecmp(buff, test, strlen(test))) {
+ print_warning("%s exists but does not contain the proper magic string (<%s-%s>)\n", name, libast_program_name,
+ libast_program_version);
+ fclose(fp);
+ fp = NULL;
+ } else {
+ begin_ptr = strchr(buff, '-') + 1;
+ if ((end_ptr = strchr(buff, '>')) != NULL) {
+ *end_ptr = 0;
+ }
+ if ((ver = BEG_STRCASECMP(begin_ptr, libast_program_version)) > 0) {
+ print_warning("Config file is designed for a newer version of %s\n", libast_program_name);
+ }
+ }
+ }
+ return (fp);
}
#define CONF_PARSE_RET() do {if (!fp) {file_pop(); ctx_end();} return;} while (0)
void
-conf_parse_line(FILE *fp, char *buff)
+conf_parse_line(FILE * fp, char *buff)
{
- register unsigned long i = 0;
- unsigned char id;
- void *state = NULL;
-
- ASSERT(buff != NULL);
+ register unsigned long i = 0;
+ unsigned char id;
+ void *state = NULL;
- if (!(*buff) || *buff == '\n' || *buff == '#' || *buff == '<') {
- CONF_PARSE_RET();
- }
- if (fp == NULL) {
- file_push(NULL, "<argv>", NULL, 0, 0);
- ctx_begin(1);
- buff = get_pword(2, buff);
- if (!buff) {
- CONF_PARSE_RET();
- }
- }
- id = ctx_peek_id();
- chomp(buff);
- D_CONF(("Parsing line #%lu of file %s\n", file_peek_line(), file_peek_path()));
- switch (*buff) {
- case '#':
- case '\0':
- CONF_PARSE_RET();
- case '%':
- if (!BEG_STRCASECMP(get_pword(1, buff + 1), "include ")) {
- char *path;
- FILE *fp;
-
- shell_expand(buff);
- path = get_word(2, buff + 1);
- if ((fp = open_config_file(path)) == NULL) {
- print_error("Parsing file %s, line %lu: Unable to locate %%included config file %s (%s), continuing\n", file_peek_path(), file_peek_line(),
- path, strerror(errno));
- } else {
- file_push(fp, path, NULL, 1, 0);
- }
- } else if (!BEG_STRCASECMP(get_pword(1, buff + 1), "preproc ")) {
- char cmd[PATH_MAX], fname[PATH_MAX], *outfile;
- int fd;
- FILE *fp;
+ ASSERT(buff != NULL);
- if (file_peek_preproc()) {
- CONF_PARSE_RET();
- }
- strcpy(fname, "Eterm-preproc-");
- fd = libast_temp_file(fname, PATH_MAX);
- outfile = STRDUP(fname);
- snprintf(cmd, PATH_MAX, "%s < %s > %s", get_pword(2, buff), file_peek_path(), fname);
- system(cmd);
- fp = fdopen(fd, "rt");
- if (fp != NULL) {
- fclose(file_peek_fp());
- file_poke_fp(fp);
- file_poke_preproc(1);
- file_poke_outfile(outfile);
+ if (!(*buff) || *buff == '\n' || *buff == '#' || *buff == '<') {
+ CONF_PARSE_RET();
+ }
+ if (fp == NULL) {
+ file_push(NULL, "<argv>", NULL, 0, 0);
+ ctx_begin(1);
+ buff = get_pword(2, buff);
+ if (!buff) {
+ CONF_PARSE_RET();
}
- } else {
- if (file_peek_skip()) {
+ }
+ id = ctx_peek_id();
+ chomp(buff);
+ D_CONF(("Parsing line #%lu of file %s\n", file_peek_line(), file_peek_path()));
+ switch (*buff) {
+ case '#':
+ case '\0':
CONF_PARSE_RET();
- }
- shell_expand(buff);
- }
- break;
- case 'b':
- if (file_peek_skip()) {
- CONF_PARSE_RET();
- }
- if (!BEG_STRCASECMP(buff, "begin ")) {
- ctx_begin(2);
- break;
- }
- /* Intentional pass-through */
- case 'e':
- if (!BEG_STRCASECMP(buff, "end ") || !strcasecmp(buff, "end")) {
- ctx_end();
- break;
- }
- /* Intentional pass-through */
- default:
- if (file_peek_skip()) {
- CONF_PARSE_RET();
- }
- shell_expand(buff);
- ctx_poke_state((*ctx_id_to_func(id))(buff, ctx_peek_state()));
- }
- CONF_PARSE_RET();
+ case '%':
+ if (!BEG_STRCASECMP(get_pword(1, buff + 1), "include ")) {
+ char *path;
+ FILE *fp;
+
+ shell_expand(buff);
+ path = get_word(2, buff + 1);
+ if ((fp = open_config_file(path)) == NULL) {
+ print_error("Parsing file %s, line %lu: Unable to locate %%included config file %s (%s), continuing\n", file_peek_path(),
+ file_peek_line(), path, strerror(errno));
+ } else {
+ file_push(fp, path, NULL, 1, 0);
+ }
+ } else if (!BEG_STRCASECMP(get_pword(1, buff + 1), "preproc ")) {
+ char cmd[PATH_MAX], fname[PATH_MAX], *outfile;
+ int fd;
+ FILE *fp;
+
+ if (file_peek_preproc()) {
+ CONF_PARSE_RET();
+ }
+ strcpy(fname, "Eterm-preproc-");
+ fd = libast_temp_file(fname, PATH_MAX);
+ outfile = STRDUP(fname);
+ snprintf(cmd, PATH_MAX, "%s < %s > %s", get_pword(2, buff), file_peek_path(), fname);
+ system(cmd);
+ fp = fdopen(fd, "rt");
+ if (fp != NULL) {
+ fclose(file_peek_fp());
+ file_poke_fp(fp);
+ file_poke_preproc(1);
+ file_poke_outfile(outfile);
+ }
+ } else {
+ if (file_peek_skip()) {
+ CONF_PARSE_RET();
+ }
+ shell_expand(buff);
+ }
+ break;
+ case 'b':
+ if (file_peek_skip()) {
+ CONF_PARSE_RET();
+ }
+ if (!BEG_STRCASECMP(buff, "begin ")) {
+ ctx_begin(2);
+ break;
+ }
+ /* Intentional pass-through */
+ case 'e':
+ if (!BEG_STRCASECMP(buff, "end ") || !strcasecmp(buff, "end")) {
+ ctx_end();
+ break;
+ }
+ /* Intentional pass-through */
+ default:
+ if (file_peek_skip()) {
+ CONF_PARSE_RET();
+ }
+ shell_expand(buff);
+ ctx_poke_state((*ctx_id_to_func(id)) (buff, ctx_peek_state()));
+ }
+ CONF_PARSE_RET();
}
+
#undef CONF_PARSE_RET
char *
conf_parse(char *conf_name, const char *dir, const char *path)
{
- FILE *fp;
- char *name = NULL, *p = ".";
- char buff[CONFIG_BUFF], orig_dir[PATH_MAX];
-
- REQUIRE_RVAL(conf_name != NULL, 0);
-
- *orig_dir = 0;
- if (path) {
- if ((name = conf_find_file(conf_name, dir, path)) != NULL) {
- if ((p = strrchr(name, '/')) != NULL) {
- getcwd(orig_dir, PATH_MAX);
- *p = 0;
- p = name;
- chdir(name);
- } else {
- p = ".";
- }
- } else {
- return NULL;
+ FILE *fp;
+ char *name = NULL, *p = ".";
+ char buff[CONFIG_BUFF], orig_dir[PATH_MAX];
+
+ REQUIRE_RVAL(conf_name != NULL, 0);
+
+ *orig_dir = 0;
+ if (path) {
+ if ((name = conf_find_file(conf_name, dir, path)) != NULL) {
+ if ((p = strrchr(name, '/')) != NULL) {
+ getcwd(orig_dir, PATH_MAX);
+ *p = 0;
+ p = name;
+ chdir(name);
+ } else {
+ p = ".";
+ }
+ } else {
+ return NULL;
+ }
}
- }
- if ((fp = open_config_file(conf_name)) == NULL) {
- return NULL;
- }
- file_push(fp, conf_name, NULL, 1, 0); /* Line count starts at 1 because open_config_file() parses the first line */
-
- for (; fstate_idx > 0;) {
- for (; fgets(buff, CONFIG_BUFF, file_peek_fp());) {
- file_inc_line();
- if (!strchr(buff, '\n')) {
- print_error("Parse error in file %s, line %lu: line too long\n", file_peek_path(), file_peek_line());
- for (; fgets(buff, CONFIG_BUFF, file_peek_fp()) && !strrchr(buff, '\n'););
- continue;
- }
- conf_parse_line(fp, buff);
- }
- fclose(file_peek_fp());
- if (file_peek_preproc()) {
- remove(file_peek_outfile());
- FREE(file_peek_outfile());
- }
- file_pop();
- }
- if (*orig_dir) {
- chdir(orig_dir);
- }
- D_CONF(("Returning \"%s\"\n", p));
- return (STRDUP(p));
+ if ((fp = open_config_file(conf_name)) == NULL) {
+ return NULL;
+ }
+ file_push(fp, conf_name, NULL, 1, 0); /* Line count starts at 1 because open_config_file() parses the first line */
+
+ for (; fstate_idx > 0;) {
+ for (; fgets(buff, CONFIG_BUFF, file_peek_fp());) {
+ file_inc_line();
+ if (!strchr(buff, '\n')) {
+ print_error("Parse error in file %s, line %lu: line too long\n", file_peek_path(), file_peek_line());
+ for (; fgets(buff, CONFIG_BUFF, file_peek_fp()) && !strrchr(buff, '\n'););
+ continue;
+ }
+ conf_parse_line(fp, buff);
+ }
+ fclose(file_peek_fp());
+ if (file_peek_preproc()) {
+ remove(file_peek_outfile());
+ FREE(file_peek_outfile());
+ }
+ file_pop();
+ }
+ if (*orig_dir) {
+ chdir(orig_dir);
+ }
+ D_CONF(("Returning \"%s\"\n", p));
+ return (STRDUP(p));
}
static void *
-parse_null(char *buff, void *state) {
-
- if (*buff == CONF_BEGIN_CHAR) {
- return (NULL);
- } else if (*buff == CONF_END_CHAR) {
- return (NULL);
- } else {
- print_error("Parse error in file %s, line %lu: Not allowed in \"null\" context: \"%s\"\n", file_peek_path(), file_peek_line(), buff);
- return (state);
- }
+parse_null(char *buff, void *state)
+{
+
+ if (*buff == CONF_BEGIN_CHAR) {
+ return (NULL);
+ } else if (*buff == CONF_END_CHAR) {
+ return (NULL);
+ } else {
+ print_error("Parse error in file %s, line %lu: Not allowed in \"null\" context: \"%s\"\n", file_peek_path(), file_peek_line(),
+ buff);
+ return (state);
+ }
}
diff --git a/src/file.c b/src/file.c
index 26aa200..35e993a 100644
--- a/src/file.c
+++ b/src/file.c
@@ -30,26 +30,26 @@ static const char cvs_ident[] = "$Id$";
#include <libast_internal.h>
int
-libast_temp_file(char *template, size_t len)
+libast_temp_file(char *ftemplate, size_t len)
{
- char buff[256];
- int fd;
+ char buff[256];
+ int fd;
- if (getenv("TMPDIR")) {
- snprintf(buff, sizeof(buff), "%s/%sXXXXXX", getenv("TMPDIR"), template);
- } else if (getenv("TMP")) {
- snprintf(buff, sizeof(buff), "%s/%sXXXXXX", getenv("TMP"), template);
- } else {
- snprintf(buff, sizeof(buff), "/tmp/%sXXXXXX", template);
- }
- fd = mkstemp(buff);
- if ((fd < 0) || fchmod(fd, (S_IRUSR | S_IWUSR))) {
- return (-1);
- }
+ if (getenv("TMPDIR")) {
+ snprintf(buff, sizeof(buff), "%s/%sXXXXXX", getenv("TMPDIR"), ftemplate);
+ } else if (getenv("TMP")) {
+ snprintf(buff, sizeof(buff), "%s/%sXXXXXX", getenv("TMP"), ftemplate);
+ } else {
+ snprintf(buff, sizeof(buff), "/tmp/%sXXXXXX", ftemplate);
+ }
+ fd = mkstemp(buff);
+ if ((fd < 0) || fchmod(fd, (S_IRUSR | S_IWUSR))) {
+ return (-1);
+ }
- if (len) {
- strncpy(template, buff, len);
- template[len - 1] = 0;
- }
- return (fd);
+ if (len) {
+ strncpy(ftemplate, buff, len);
+ ftemplate[len - 1] = 0;
+ }
+ return (fd);
}
diff --git a/src/linked_list.c b/src/linked_list.c
new file mode 100644
index 0000000..22f791e
--- /dev/null
+++ b/src/linked_list.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 1997-2002, Michael Jennings
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software, its documentation and marketing & publicity
+ * materials, and acknowledgment shall be given in the documentation, materials
+ * and software packages that this Software was used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+static const char cvs_ident[] = "$Id$";
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libast_internal.h>
+
+static spif_linked_list_item_t spif_linked_list_item_new(void);
+static spif_bool_t spif_linked_list_item_init(spif_linked_list_item_t);
+static spif_bool_t spif_linked_list_item_done(spif_linked_list_item_t);
+static spif_bool_t spif_linked_list_item_del(spif_linked_list_item_t);
+static spif_bool_t spif_linked_list_item_show(spif_linked_list_item_t);
+static spif_obj_t spif_linked_list_item_get_data(spif_linked_list_item_t);
+static spif_bool_t spif_linked_list_item_set_data(spif_linked_list_item_t, spif_obj_t);
+
+static spif_linked_list_t spif_linked_list_new(void);
+static spif_bool_t spif_linked_list_init(spif_linked_list_t);
+static spif_bool_t spif_linked_list_done(spif_linked_list_t);
+static spif_bool_t spif_linked_list_del(spif_linked_list_t);
+static spif_bool_t spif_linked_list_show(spif_linked_list_t);
+static spif_bool_t spif_linked_list_append(spif_linked_list_t, spif_obj_t);
+static spif_bool_t spif_linked_list_contains(spif_linked_list_t, spif_obj_t);
+static size_t spif_linked_list_count(spif_linked_list_t);
+static spif_obj_t spif_linked_list_get(spif_linked_list_t, size_t);
+static size_t spif_linked_list_index(spif_linked_list_t, spif_obj_t);
+static spif_bool_t spif_linked_list_insert(spif_linked_list_t, spif_obj_t);
+static spif_bool_t spif_linked_list_insert_at(spif_linked_list_t, spif_obj_t, size_t);
+static spif_bool_t spif_linked_list_iterator(spif_linked_list_t);
+static spif_obj_t spif_linked_list_next(spif_linked_list_t);
+static spif_bool_t spif_linked_list_prepend(spif_linked_list_t, spif_obj_t);
+static spif_obj_t spif_linked_list_remove(spif_linked_list_t);
+static spif_obj_t spif_linked_list_remove_at(spif_linked_list_t, size_t);
+
+SPIF_DECL_IFCLASS(list, linked_list) = {
+ {
+ SPIF_DECL_CLASSNAME(linked_list),
+ (spif_newfunc_t) spif_linked_list_new,
+ (spif_memberfunc_t) spif_linked_list_init,
+ (spif_memberfunc_t) spif_linked_list_done,
+ (spif_memberfunc_t) spif_linked_list_del,
+ (spif_func_t) spif_linked_list_show,
+ (spif_func_t) spif_linked_list_comp,
+ (spif_func_t) spif_linked_list_dup,
+ (spif_func_t) spif_linked_list_type
+ },
+ (spif_memberfunc_t) spif_linked_list_append,
+ (spif_memberfunc_t) spif_linked_list_contains,
+ (spif_memberfunc_t) spif_linked_list_count,
+ (spif_memberfunc_t) spif_linked_list_get,
+ (spif_memberfunc_t) spif_linked_list_index,
+ (spif_memberfunc_t) spif_linked_list_insert,
+ (spif_memberfunc_t) spif_linked_list_insert_at,
+ (spif_memberfunc_t) spif_linked_list_iterator,
+ (spif_memberfunc_t) spif_linked_list_next,
+ (spif_memberfunc_t) spif_linked_list_prepend,
+ (spif_memberfunc_t) spif_linked_list_remove,
+ (spif_memberfunc_t) spif_linked_list_remove_at
+};
+
+static spif_linked_list_item_t
+spif_linked_list_item_new(void)
+{
+ spif_linked_list_item_t self;
+
+ self = SPIF_ALLOC(linked_list_item);
+ spif_linked_list_item_init(self);
+ return self;
+}
+
+static spif_bool_t
+spif_linked_list_item_init(spif_linked_list_item_t self)
+{
+ spif_obj_init(SPIF_OBJ(self));
+ spif_obj_set_classname(SPIF_OBJ(self), SPIF_CLASSNAME_TYPE(linked_list_item));
+ self->data = SPIF_NULL_TYPE(obj);
+ self->next = SPIF_NULL_TYPE(linked_list_item);
+ return TRUE;
+}
+
+static spif_bool_t
+spif_linked_list_item_done(spif_linked_list_item_t self)
+{
+ /* FIXME: Should we destroy the data objects? */
+ self->data = SPIF_NULL_TYPE(obj);
+ self->next = SPIF_NULL_TYPE(linked_list_item);
+ return TRUE;
+}
+
+static spif_bool_t
+spif_linked_list_item_del(spif_linked_list_item_t self)
+{
+ spif_linked_list_item_done(self);
+ SPIF_DEALLOC(self);
+ return TRUE;
+}
+
+static spif_bool_t
+spif_linked_list_item_show(spif_linked_list_item_t self)
+{
+ USE_VAR(self);
+ return TRUE;
+}
+
+static spif_obj_t
+spif_linked_list_item_get_data(spif_linked_list_item_t self)
+{
+ return (self->data);
+}
+
+static spif_bool_t
+spif_linked_list_item_set_data(spif_linked_list_item_t self, spif_obj_t obj)
+{
+ self->data = obj;
+ return TRUE;
+}
+
+static spif_linked_list_t
+spif_linked_list_new(void)
+{
+ spif_linked_list_t self;
+
+ self = SPIF_ALLOC(linked_list);
+ spif_linked_list_init(self);
+ return self;
+}
+
+static spif_bool_t
+spif_linked_list_init(spif_linked_list_t self)
+{
+ spif_obj_init(SPIF_OBJ(self));
+ spif_obj_set_classname(SPIF_OBJ(self), SPIF_CLASSNAME_TYPE(linked_list));
+ self->len = 0;
+ self->head = SPIF_NULL_TYPE(linked_list_item);
+ return TRUE;
+}
+
+static spif_bool_t
+spif_linked_list_done(spif_linked_list_t self)
+{
+ spif_linked_list_item_t current;
+
+ if (self->len) {
+ for (current = self->head; current; ) {
+ spif_linked_list_item_t tmp;
+
+ tmp = current;
+ current = current->next;
+ spif_linked_list_item_del(tmp);
+ }
+ self->len = 0;
+ self->head = SPIF_NULL_TYPE(linked_list_item);
+ }
+ return TRUE;
+}
+
+static spif_bool_t
+spif_linked_list_del(spif_linked_list_t self)
+{
+ spif_linked_list_done(self);
+ SPIF_DEALLOC(self);
+ return TRUE;
+}
+
+static spif_bool_t
+spif_linked_list_show(spif_linked_list_t self)
+{
+ USE_VAR(self);
+ return TRUE;
+}
+
+static spif_bool_t
+spif_linked_list_append(spif_linked_list_t self, spif_obj_t obj)
+{
+ spif_linked_list_item_t item, current;
+
+ /* Create list member object "item" */
+ item = spif_linked_list_item_new();
+ spif_linked_list_item_set_data(item, obj);
+
+ /* Append "item" to the end of the list. */
+ if (self->head) {
+ for (current = self->head; current->next; current = current->next);
+ current->next = item;
+ } else {
+ self->head = item;
+ }
+ item->next = SPIF_NULL_TYPE(linked_list_item);
+ self->len++;
+ return TRUE;
+}
+
+static spif_bool_t
+spif_linked_list_contains(spif_linked_list_t self, spif_obj_t obj)
+{
+ spif_linked_list_item_t current;
+
+ for (current = self->head; current; current = current->next) {
+ if (spif_linked_list_item_get_data(current) == obj) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static size_t
+spif_linked_list_count(spif_linked_list_t self)
+{
+ return self->len;
+}
+
+static spif_obj_t
+spif_linked_list_get(spif_linked_list_t self, size_t idx)
+{
+ size_t i;
+ spif_linked_list_item_t current;
+
+ for (current = self->head, i = 0; current && i < idx; i++, current = current->next);
+ return (current ? (current->data) : SPIF_NULL_TYPE(obj));
+}
+
+static size_t
+spif_linked_list_index(spif_linked_list_t self, spif_obj_t obj)
+{
+ size_t i;
+ spif_linked_list_item_t current;
+
+ for (current = self->head, i = 0; current && (current->data != obj); i++, current = current->next);
+ return (current ? i : ((size_t) (-1)));
+}
+
+static spif_bool_t
+spif_linked_list_insert(spif_linked_list_t self, spif_obj_t obj)
+{
+
+}
+
+static spif_bool_t
+spif_linked_list_insert_at(spif_linked_list_t self, spif_obj_t obj, size_t idx)
+{
+
+}
+
+static spif_bool_t
+spif_linked_list_iterator(spif_linked_list_t self)
+{
+
+}
+
+static spif_obj_t
+spif_linked_list_next(spif_linked_list_t self)
+{
+
+}
+
+static spif_bool_t
+spif_linked_list_prepend(spif_linked_list_t self, spif_obj_t obj)
+{
+
+}
+
+static spif_obj_t
+spif_linked_list_remove(spif_linked_list_t self)
+{
+
+}
+
+static spif_obj_t
+spif_linked_list_remove_at(spif_linked_list_t self, size_t idx)
+{
+
+}
diff --git a/src/mem.c b/src/mem.c
index 55187e1..f8283fa 100644
--- a/src/mem.c
+++ b/src/mem.c
@@ -54,285 +54,291 @@ static memrec_t malloc_rec, pixmap_rec, gc_rec;
void
memrec_init(void)
{
- D_MEM(("Constructing memory allocation records\n"));
- malloc_rec.ptrs = (ptr_t *) malloc(sizeof(ptr_t));
- pixmap_rec.ptrs = (ptr_t *) malloc(sizeof(ptr_t));
- gc_rec.ptrs = (ptr_t *) malloc(sizeof(ptr_t));
+ D_MEM(("Constructing memory allocation records\n"));
+ malloc_rec.ptrs = (ptr_t *) malloc(sizeof(ptr_t));
+ pixmap_rec.ptrs = (ptr_t *) malloc(sizeof(ptr_t));
+ gc_rec.ptrs = (ptr_t *) malloc(sizeof(ptr_t));
}
static void
-memrec_add_var(memrec_t *memrec, const char *filename, unsigned long line, void *ptr, size_t size)
+memrec_add_var(memrec_t * memrec, const char *filename, unsigned long line, void *ptr, size_t size)
{
- register ptr_t *p;
-
- ASSERT(memrec != NULL);
- memrec->cnt++;
- if ((memrec->ptrs = (ptr_t *) realloc(memrec->ptrs, sizeof(ptr_t) * memrec->cnt)) == NULL) {
- D_MEM(("Unable to reallocate pointer list -- %s\n", strerror(errno)));
- }
- p = memrec->ptrs + memrec->cnt - 1;
- D_MEM(("Adding variable (%8p, %lu bytes) from %s:%lu.\n", ptr, size, filename, line));
- D_MEM(("Storing as pointer #%lu at %8p (from %8p).\n", memrec->cnt, p, memrec->ptrs));
- p->ptr = ptr;
- p->size = size;
- strncpy(p->file, filename, LIBAST_FNAME_LEN);
- p->file[LIBAST_FNAME_LEN] = 0;
- p->line = line;
+ register ptr_t *p;
+
+ ASSERT(memrec != NULL);
+ memrec->cnt++;
+ if ((memrec->ptrs = (ptr_t *) realloc(memrec->ptrs, sizeof(ptr_t) * memrec->cnt)) == NULL) {
+ D_MEM(("Unable to reallocate pointer list -- %s\n", strerror(errno)));
+ }
+ p = memrec->ptrs + memrec->cnt - 1;
+ D_MEM(("Adding variable (%8p, %lu bytes) from %s:%lu.\n", ptr, size, filename, line));
+ D_MEM(("Storing as pointer #%lu at %8p (from %8p).\n", memrec->cnt, p, memrec->ptrs));
+ p->ptr = ptr;
+ p->size = size;
+ strncpy(p->file, filename, LIBAST_FNAME_LEN);
+ p->file[LIBAST_FNAME_LEN] = 0;
+ p->line = line;
}
static ptr_t *
-memrec_find_var(memrec_t *memrec, const void *ptr)
+memrec_find_var(memrec_t * memrec, const void *ptr)
{
- register ptr_t *p;
- register unsigned long i;
+ register ptr_t *p;
+ register unsigned long i;
- ASSERT(memrec != NULL);
- REQUIRE_RVAL(ptr != NULL, NULL);
+ ASSERT(memrec != NULL);
+ REQUIRE_RVAL(ptr != NULL, NULL);
- for (i = 0, p = memrec->ptrs; i < memrec->cnt; i++, p++) {
- if (p->ptr == ptr) {
- D_MEM(("Found pointer #%lu stored at %8p (from %8p)\n", i + 1, p, memrec->ptrs));
- return p;
+ for (i = 0, p = memrec->ptrs; i < memrec->cnt; i++, p++) {
+ if (p->ptr == ptr) {
+ D_MEM(("Found pointer #%lu stored at %8p (from %8p)\n", i + 1, p, memrec->ptrs));
+ return p;
+ }
}
- }
- return NULL;
+ return NULL;
}
static void
-memrec_rem_var(memrec_t *memrec, const char *var, const char *filename, unsigned long line, const void *ptr)
+memrec_rem_var(memrec_t * memrec, const char *var, const char *filename, unsigned long line, const void *ptr)
{
- register ptr_t *p;
-
- ASSERT(memrec != NULL);
-
- if ((p = memrec_find_var(memrec, ptr)) == NULL) {
- D_MEM(("ERROR: File %s, line %d attempted to free variable %s (%8p) which was not allocated with MALLOC/REALLOC\n", filename, line, var, ptr));
- return;
- }
- D_MEM(("Removing variable %s (%8p) of size %lu\n", var, ptr, p->size));
- if ((--memrec->cnt) > 0) {
- memmove(p, p + 1, sizeof(ptr_t) * (memrec->cnt - (p - memrec->ptrs)));
- memrec->ptrs = (ptr_t *) realloc(memrec->ptrs, sizeof(ptr_t) * memrec->cnt);
- }
+ register ptr_t *p;
+
+ ASSERT(memrec != NULL);
+
+ if ((p = memrec_find_var(memrec, ptr)) == NULL) {
+ D_MEM(("ERROR: File %s, line %d attempted to free variable %s (%8p) which was not allocated with MALLOC/REALLOC\n", filename, line,
+ var, ptr));
+ return;
+ }
+ D_MEM(("Removing variable %s (%8p) of size %lu\n", var, ptr, p->size));
+ if ((--memrec->cnt) > 0) {
+ memmove(p, p + 1, sizeof(ptr_t) * (memrec->cnt - (p - memrec->ptrs)));
+ memrec->ptrs = (ptr_t *) realloc(memrec->ptrs, sizeof(ptr_t) * memrec->cnt);
+ }
}
static void
-memrec_chg_var(memrec_t *memrec, const char *var, const char *filename, unsigned long line, const void *oldp, void *newp, size_t size)
+memrec_chg_var(memrec_t * memrec, const char *var, const char *filename, unsigned long line, const void *oldp, void *newp, size_t size)
{
- register ptr_t *p;
-
- ASSERT(memrec != NULL);
-
- if ((p = memrec_find_var(memrec, oldp)) == NULL) {
- D_MEM(("ERROR: File %s, line %d attempted to realloc variable %s (%8p) which was not allocated with MALLOC/REALLOC\n", filename, line, var, oldp));
- return;
- }
- D_MEM(("Changing variable %s (%8p, %lu -> %8p, %lu)\n", var, oldp, p->size, newp, size));
- p->ptr = newp;
- p->size = size;
- strncpy(p->file, filename, LIBAST_FNAME_LEN);
- p->line = line;
+ register ptr_t *p;
+
+ ASSERT(memrec != NULL);
+
+ if ((p = memrec_find_var(memrec, oldp)) == NULL) {
+ D_MEM(("ERROR: File %s, line %d attempted to realloc variable %s (%8p) which was not allocated with MALLOC/REALLOC\n", filename,
+ line, var, oldp));
+ return;
+ }
+ D_MEM(("Changing variable %s (%8p, %lu -> %8p, %lu)\n", var, oldp, p->size, newp, size));
+ p->ptr = newp;
+ p->size = size;
+ strncpy(p->file, filename, LIBAST_FNAME_LEN);
+ p->line = line;
}
static void
-memrec_dump_pointers(memrec_t *memrec)
+memrec_dump_pointers(memrec_t * memrec)
{
- register ptr_t *p;
- unsigned long i, j, k, l, total = 0;
- unsigned long len;
- unsigned char buff[9];
-
- ASSERT(memrec != NULL);
- fprintf(LIBAST_DEBUG_FD, "PTR: %lu pointers stored.\n", memrec->cnt);
- fprintf(LIBAST_DEBUG_FD, "PTR: Pointer | Filename | Line | Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII \n");
- fprintf(LIBAST_DEBUG_FD, "PTR: ---------+----------------------+--------+----------+--------+---------+-------------------------+---------\n");
- fflush(LIBAST_DEBUG_FD);
- len = sizeof(ptr_t) * memrec->cnt;
- memset(buff, 0, sizeof(buff));
-
- /* First, dump the contents of the memrec->ptrs[] array. */
- for (p = memrec->ptrs, j = 0; j < len; j += 8) {
- fprintf(LIBAST_DEBUG_FD, "PTR: %07lu | %20s | %6lu | %8p | %06lu | %07x | ", (unsigned long) 0, "", (unsigned long) 0, memrec->ptrs,
- (unsigned long) (sizeof(ptr_t) * memrec->cnt), (unsigned int) j);
- /* l is the number of characters we're going to output */
- l = ((len - j < 8) ? (len - j) : (8));
- /* Copy l bytes (up to 8) from memrec->ptrs[] (p) to buffer */
- memcpy(buff, ((char *) p) + j, l);
- buff[l] = 0;
- for (k = 0; k < l; k++) {
- fprintf(LIBAST_DEBUG_FD, "%02x ", buff[k]);
+ register ptr_t *p;
+ unsigned long i, j, k, l, total = 0;
+ unsigned long len;
+ unsigned char buff[9];
+
+ ASSERT(memrec != NULL);
+ fprintf(LIBAST_DEBUG_FD, "PTR: %lu pointers stored.\n", memrec->cnt);
+ fprintf(LIBAST_DEBUG_FD,
+ "PTR: Pointer | Filename | Line | Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII \n");
+ fprintf(LIBAST_DEBUG_FD,
+ "PTR: ---------+----------------------+--------+----------+--------+---------+-------------------------+---------\n");
+ fflush(LIBAST_DEBUG_FD);
+ len = sizeof(ptr_t) * memrec->cnt;
+ memset(buff, 0, sizeof(buff));
+
+ /* First, dump the contents of the memrec->ptrs[] array. */
+ for (p = memrec->ptrs, j = 0; j < len; j += 8) {
+ fprintf(LIBAST_DEBUG_FD, "PTR: %07lu | %20s | %6lu | %8p | %06lu | %07x | ", (unsigned long) 0, "", (unsigned long) 0,
+ memrec->ptrs, (unsigned long) (sizeof(ptr_t) * memrec->cnt), (unsigned int) j);
+ /* l is the number of characters we're going to output */
+ l = ((len - j < 8) ? (len - j) : (8));
+ /* Copy l bytes (up to 8) from memrec->ptrs[] (p) to buffer */
+ memcpy(buff, ((char *) p) + j, l);
+ buff[l] = 0;
+ for (k = 0; k < l; k++) {
+ fprintf(LIBAST_DEBUG_FD, "%02x ", buff[k]);
+ }
+ /* If we printed less than 8 bytes worth, pad with 3 spaces per byte */
+ for (; k < 8; k++) {
+ fprintf(LIBAST_DEBUG_FD, " ");
+ }
+ /* Finally, print the printable ASCII string for those l bytes */
+ fprintf(LIBAST_DEBUG_FD, "| %-8s\n", safe_str((char *) buff, l));
+ /* Flush after every line in case we crash */
+ fflush(LIBAST_DEBUG_FD);
}
- /* If we printed less than 8 bytes worth, pad with 3 spaces per byte */
- for (; k < 8; k++) {
- fprintf(LIBAST_DEBUG_FD, " ");
+
+ /* Now print out each pointer and its contents. */
+ for (i = 0; i < memrec->cnt; p++, i++) {
+ /* Add this pointer's size to our total */
+ total += p->size;
+ for (j = 0; j < p->size; j += 8) {
+ fprintf(LIBAST_DEBUG_FD, "PTR: %07lu | %20s | %6lu | %8p | %06lu | %07x | ", i + 1, NONULL(p->file), p->line, p->ptr,
+ (unsigned long) p->size, (unsigned int) j);
+ /* l is the number of characters we're going to output */
+ l = ((p->size - j < 8) ? (p->size - j) : (8));
+ /* Copy l bytes (up to 8) from p->ptr to buffer */
+ memcpy(buff, ((char *) p->ptr) + j, l);
+ buff[l] = 0;
+ for (k = 0; k < l; k++) {
+ fprintf(LIBAST_DEBUG_FD, "%02x ", buff[k]);
+ }
+ /* If we printed less than 8 bytes worth, pad with 3 spaces per byte */
+ for (; k < 8; k++) {
+ fprintf(LIBAST_DEBUG_FD, " ");
+ }
+ /* Finally, print the printable ASCII string for those l bytes */
+ fprintf(LIBAST_DEBUG_FD, "| %-8s\n", safe_str((char *) buff, l));
+ /* Flush after every line in case we crash */
+ fflush(LIBAST_DEBUG_FD);
+ }
}
- /* Finally, print the printable ASCII string for those l bytes */
- fprintf(LIBAST_DEBUG_FD, "| %-8s\n", safe_str((char *) buff, l));
- /* Flush after every line in case we crash */
+ fprintf(LIBAST_DEBUG_FD, "PTR: Total allocated memory: %10lu bytes\n", total);
fflush(LIBAST_DEBUG_FD);
- }
-
- /* Now print out each pointer and its contents. */
- for (i = 0; i < memrec->cnt; p++, i++) {
- /* Add this pointer's size to our total */
- total += p->size;
- for (j = 0; j < p->size; j += 8) {
- fprintf(LIBAST_DEBUG_FD, "PTR: %07lu | %20s | %6lu | %8p | %06lu | %07x | ", i + 1, NONULL(p->file), p->line, p->ptr, (unsigned long) p->size, (unsigned int) j);
- /* l is the number of characters we're going to output */
- l = ((p->size - j < 8) ? (p->size - j) : (8));
- /* Copy l bytes (up to 8) from p->ptr to buffer */
- memcpy(buff, ((char *) p->ptr) + j, l);
- buff[l] = 0;
- for (k = 0; k < l; k++) {
- fprintf(LIBAST_DEBUG_FD, "%02x ", buff[k]);
- }
- /* If we printed less than 8 bytes worth, pad with 3 spaces per byte */
- for (; k < 8; k++) {
- fprintf(LIBAST_DEBUG_FD, " ");
- }
- /* Finally, print the printable ASCII string for those l bytes */
- fprintf(LIBAST_DEBUG_FD, "| %-8s\n", safe_str((char *) buff, l));
- /* Flush after every line in case we crash */
- fflush(LIBAST_DEBUG_FD);
- }
- }
- fprintf(LIBAST_DEBUG_FD, "PTR: Total allocated memory: %10lu bytes\n", total);
- fflush(LIBAST_DEBUG_FD);
}
static void
-memrec_dump_resources(memrec_t *memrec)
+memrec_dump_resources(memrec_t * memrec)
{
- register ptr_t *p;
- unsigned long i, total;
- unsigned long len;
-
- ASSERT(memrec != NULL);
- len = memrec->cnt;
- fprintf(LIBAST_DEBUG_FD, "RES: %lu resources stored.\n", memrec->cnt);
- fprintf(LIBAST_DEBUG_FD, "RES: Index | Resource ID | Filename | Line | Size \n");
- fprintf(LIBAST_DEBUG_FD, "RES: -------+-------------+----------------------+--------+--------\n");
- fflush(LIBAST_DEBUG_FD);
-
- for (p = memrec->ptrs, i = 0, total = 0; i < len; i++, p++) {
- total += p->size;
- fprintf(LIBAST_DEBUG_FD, "RES: %5lu | 0x%08x | %20s | %6lu | %6lu\n", i, (unsigned) p->ptr, NONULL(p->file), p->line, (unsigned long) p->size);
- /* Flush after every line in case we crash */
+ register ptr_t *p;
+ unsigned long i, total;
+ unsigned long len;
+
+ ASSERT(memrec != NULL);
+ len = memrec->cnt;
+ fprintf(LIBAST_DEBUG_FD, "RES: %lu resources stored.\n", memrec->cnt);
+ fprintf(LIBAST_DEBUG_FD, "RES: Index | Resource ID | Filename | Line | Size \n");
+ fprintf(LIBAST_DEBUG_FD, "RES: -------+-------------+----------------------+--------+--------\n");
+ fflush(LIBAST_DEBUG_FD);
+
+ for (p = memrec->ptrs, i = 0, total = 0; i < len; i++, p++) {
+ total += p->size;
+ fprintf(LIBAST_DEBUG_FD, "RES: %5lu | 0x%08x | %20s | %6lu | %6lu\n", i, (unsigned) p->ptr, NONULL(p->file), p->line,
+ (unsigned long) p->size);
+ /* Flush after every line in case we crash */
+ fflush(LIBAST_DEBUG_FD);
+ }
+ fprintf(LIBAST_DEBUG_FD, "RES: Total size: %lu bytes\n", total);
fflush(LIBAST_DEBUG_FD);
- }
- fprintf(LIBAST_DEBUG_FD, "RES: Total size: %lu bytes\n", total);
- fflush(LIBAST_DEBUG_FD);
}
/******************** MEMORY ALLOCATION INTERFACE ********************/
void *
libast_malloc(const char *filename, unsigned long line, size_t size)
{
- void *temp;
+ void *temp;
#ifdef MALLOC_CALL_DEBUG
- ++malloc_count;
- if (!(malloc_count % MALLOC_MOD)) {
- fprintf(LIBAST_DEBUG_FD, "Calls to malloc(): %d\n", malloc_count);
- }
+ ++malloc_count;
+ if (!(malloc_count % MALLOC_MOD)) {
+ fprintf(LIBAST_DEBUG_FD, "Calls to malloc(): %d\n", malloc_count);
+ }
#endif
- D_MEM(("%lu bytes requested at %s:%lu\n", size, filename, line));
+ D_MEM(("%lu bytes requested at %s:%lu\n", size, filename, line));
- temp = (void *) malloc(size);
- ASSERT_RVAL(temp != NULL, NULL);
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_add_var(&malloc_rec, filename, line, temp, size);
- }
- return (temp);
+ temp = (void *) malloc(size);
+ ASSERT_RVAL(temp != NULL, NULL);
+ if (DEBUG_LEVEL >= DEBUG_MEM) {
+ memrec_add_var(&malloc_rec, filename, line, temp, size);
+ }
+ return (temp);
}
void *
libast_realloc(const char *var, const char *filename, unsigned long line, void *ptr, size_t size)
{
- void *temp;
+ void *temp;
#ifdef MALLOC_CALL_DEBUG
- ++realloc_count;
- if (!(realloc_count % REALLOC_MOD)) {
- D_MEM(("Calls to realloc(): %d\n", realloc_count));
- }
+ ++realloc_count;
+ if (!(realloc_count % REALLOC_MOD)) {
+ D_MEM(("Calls to realloc(): %d\n", realloc_count));
+ }
#endif
- D_MEM(("Variable %s (%8p -> %lu) at %s:%lu\n", var, ptr, (unsigned long) size, filename, line));
- if (ptr == NULL) {
- temp = (void *) libast_malloc(__FILE__, __LINE__, size);
- } else {
- temp = (void *) realloc(ptr, size);
- ASSERT_RVAL(temp != NULL, ptr);
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_chg_var(&malloc_rec, var, filename, line, ptr, temp, size);
+ D_MEM(("Variable %s (%8p -> %lu) at %s:%lu\n", var, ptr, (unsigned long) size, filename, line));
+ if (ptr == NULL) {
+ temp = (void *) libast_malloc(__FILE__, __LINE__, size);
+ } else {
+ temp = (void *) realloc(ptr, size);
+ ASSERT_RVAL(temp != NULL, ptr);
+ if (DEBUG_LEVEL >= DEBUG_MEM) {
+ memrec_chg_var(&malloc_rec, var, filename, line, ptr, temp, size);
+ }
}
- }
- return (temp);
+ return (temp);
}
void *
libast_calloc(const char *filename, unsigned long line, size_t count, size_t size)
{
- void *temp;
+ void *temp;
#ifdef MALLOC_CALL_DEBUG
- ++calloc_count;
- if (!(calloc_count % CALLOC_MOD)) {
- fprintf(LIBAST_DEBUG_FD, "Calls to calloc(): %d\n", calloc_count);
- }
+ ++calloc_count;
+ if (!(calloc_count % CALLOC_MOD)) {
+ fprintf(LIBAST_DEBUG_FD, "Calls to calloc(): %d\n", calloc_count);
+ }
#endif
- D_MEM(("%lu units of %lu bytes each requested at %s:%lu\n", count, size, filename, line));
- temp = (void *) calloc(count, size);
- ASSERT_RVAL(temp != NULL, NULL);
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_add_var(&malloc_rec, filename, line, temp, size * count);
- }
- return (temp);
+ D_MEM(("%lu units of %lu bytes each requested at %s:%lu\n", count, size, filename, line));
+ temp = (void *) calloc(count, size);
+ ASSERT_RVAL(temp != NULL, NULL);
+ if (DEBUG_LEVEL >= DEBUG_MEM) {
+ memrec_add_var(&malloc_rec, filename, line, temp, size * count);
+ }
+ return (temp);
}
void
libast_free(const char *var, const char *filename, unsigned long line, void *ptr)
{
#ifdef MALLOC_CALL_DEBUG
- ++free_count;
- if (!(free_count % FREE_MOD)) {
- fprintf(LIBAST_DEBUG_FD, "Calls to free(): %d\n", free_count);
- }
+ ++free_count;
+ if (!(free_count % FREE_MOD)) {
+ fprintf(LIBAST_DEBUG_FD, "Calls to free(): %d\n", free_count);
+ }
#endif
- D_MEM(("Variable %s (%8p) at %s:%lu\n", var, ptr, filename, line));
- if (ptr) {
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_rem_var(&malloc_rec, var, filename, line, ptr);
+ D_MEM(("Variable %s (%8p) at %s:%lu\n", var, ptr, filename, line));
+ if (ptr) {
+ if (DEBUG_LEVEL >= DEBUG_MEM) {
+ memrec_rem_var(&malloc_rec, var, filename, line, ptr);
+ }
+ free(ptr);
+ } else {
+ D_MEM(("ERROR: Caught attempt to free NULL pointer\n"));
}
- free(ptr);
- } else {
- D_MEM(("ERROR: Caught attempt to free NULL pointer\n"));
- }
}
char *
libast_strdup(const char *var, const char *filename, unsigned long line, const char *str)
{
- register char *newstr;
- register size_t len;
+ register char *newstr;
+ register size_t len;
- D_MEM(("Variable %s (%8p) at %s:%lu\n", var, str, filename, line));
+ D_MEM(("Variable %s (%8p) at %s:%lu\n", var, str, filename, line));
- len = strlen(str) + 1; /* Copy NUL byte also */
- newstr = (char *) libast_malloc(filename, line, len);
- strcpy(newstr, str);
- return (newstr);
+ len = strlen(str) + 1; /* Copy NUL byte also */
+ newstr = (char *) libast_malloc(filename, line, len);
+ strcpy(newstr, str);
+ return (newstr);
}
void
libast_dump_mem_tables(void)
{
- fprintf(LIBAST_DEBUG_FD, "Dumping memory allocation table:\n");
- memrec_dump_pointers(&malloc_rec);
+ fprintf(LIBAST_DEBUG_FD, "Dumping memory allocation table:\n");
+ memrec_dump_pointers(&malloc_rec);
}
#ifdef LIBAST_X11_SUPPORT
@@ -340,72 +346,73 @@ libast_dump_mem_tables(void)
/******************** PIXMAP ALLOCATION INTERFACE ********************/
Pixmap
-libast_x_create_pixmap(const char *filename, unsigned long line, Display *d, Drawable win, unsigned int w, unsigned int h, unsigned int depth)
+libast_x_create_pixmap(const char *filename, unsigned long line, Display * d, Drawable win, unsigned int w, unsigned int h,
+ unsigned int depth)
{
- Pixmap p;
+ Pixmap p;
- D_MEM(("Creating %ux%u pixmap of depth %u for window 0x%08x at %s:%lu\n", w, h, depth, win, filename, line));
+ D_MEM(("Creating %ux%u pixmap of depth %u for window 0x%08x at %s:%lu\n", w, h, depth, win, filename, line));
- p = XCreatePixmap(d, win, w, h, depth);
- ASSERT_RVAL(p != None, None);
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_add_var(&pixmap_rec, filename, line, (void *) p, w * h * (depth / 8));
- }
- return (p);
+ p = XCreatePixmap(d, win, w, h, depth);
+ ASSERT_RVAL(p != None, None);
+ if (DEBUG_LEVEL >= DEBUG_MEM) {
+ memrec_add_var(&pixmap_rec, filename, line, (void *) p, w * h * (depth / 8));
+ }
+ return (p);
}
void
-libast_x_free_pixmap(const char *var, const char *filename, unsigned long line, Display *d, Pixmap p)
+libast_x_free_pixmap(const char *var, const char *filename, unsigned long line, Display * d, Pixmap p)
{
- D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu\n", var, p, filename, line));
- if (p) {
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_rem_var(&pixmap_rec, var, filename, line, (void *) p);
+ D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu\n", var, p, filename, line));
+ if (p) {
+ if (DEBUG_LEVEL >= DEBUG_MEM) {
+ memrec_rem_var(&pixmap_rec, var, filename, line, (void *) p);
+ }
+ XFreePixmap(d, p);
+ } else {
+ D_MEM(("ERROR: Caught attempt to free NULL pixmap\n"));
}
- XFreePixmap(d, p);
- } else {
- D_MEM(("ERROR: Caught attempt to free NULL pixmap\n"));
- }
}
# ifdef LIBAST_IMLIB2_SUPPORT
void
libast_imlib_register_pixmap(const char *var, const char *filename, unsigned long line, Pixmap p)
{
- D_MEM(("Registering pixmap %s (0x%08x) created by Imlib2 at %s:%lu\n", var, p, filename, line));
- if (p) {
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- if (!memrec_find_var(&pixmap_rec, (void *) p)) {
- memrec_add_var(&pixmap_rec, filename, line, (void *) p, 1);
- } else {
- D_MEM(("Pixmap 0x%08x already registered.\n"));
- }
+ D_MEM(("Registering pixmap %s (0x%08x) created by Imlib2 at %s:%lu\n", var, p, filename, line));
+ if (p) {
+ if (DEBUG_LEVEL >= DEBUG_MEM) {
+ if (!memrec_find_var(&pixmap_rec, (void *) p)) {
+ memrec_add_var(&pixmap_rec, filename, line, (void *) p, 1);
+ } else {
+ D_MEM(("Pixmap 0x%08x already registered.\n"));
+ }
+ }
+ } else {
+ D_MEM(("ERROR: Refusing to register a NULL pixmap\n"));
}
- } else {
- D_MEM(("ERROR: Refusing to register a NULL pixmap\n"));
- }
}
void
libast_imlib_free_pixmap(const char *var, const char *filename, unsigned long line, Pixmap p)
{
- D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu using Imlib2\n", var, p, filename, line));
- if (p) {
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_rem_var(&pixmap_rec, var, filename, line, (void *) p);
+ D_MEM(("Freeing pixmap %s (0x%08x) at %s:%lu using Imlib2\n", var, p, filename, line));
+ if (p) {
+ if (DEBUG_LEVEL >= DEBUG_MEM) {
+ memrec_rem_var(&pixmap_rec, var, filename, line, (void *) p);
+ }
+ imlib_free_pixmap_and_mask(p);
+ } else {
+ D_MEM(("ERROR: Caught attempt to free NULL pixmap\n"));
}
- imlib_free_pixmap_and_mask(p);
- } else {
- D_MEM(("ERROR: Caught attempt to free NULL pixmap\n"));
- }
}
# endif
void
libast_dump_pixmap_tables(void)
{
- fprintf(LIBAST_DEBUG_FD, "Dumping X11 Pixmap allocation table:\n");
- memrec_dump_resources(&pixmap_rec);
+ fprintf(LIBAST_DEBUG_FD, "Dumping X11 Pixmap allocation table:\n");
+ memrec_dump_resources(&pixmap_rec);
}
@@ -413,39 +420,39 @@ libast_dump_pixmap_tables(void)
/********************** GC ALLOCATION INTERFACE **********************/
GC
-libast_x_create_gc(const char *filename, unsigned long line, Display *d, Drawable win, unsigned long mask, XGCValues *gcv)
+libast_x_create_gc(const char *filename, unsigned long line, Display * d, Drawable win, unsigned long mask, XGCValues * gcv)
{
- GC gc;
+ GC gc;
- D_MEM(("Creating gc for window 0x%08x at %s:%lu\n", win, filename, line));
+ D_MEM(("Creating gc for window 0x%08x at %s:%lu\n", win, filename, line));
- gc = XCreateGC(d, win, mask, gcv);
- ASSERT_RVAL(gc != None, None);
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_add_var(&gc_rec, filename, line, (void *) gc, sizeof(XGCValues));
- }
- return (gc);
+ gc = XCreateGC(d, win, mask, gcv);
+ ASSERT_RVAL(gc != None, None);
+ if (DEBUG_LEVEL >= DEBUG_MEM) {
+ memrec_add_var(&gc_rec, filename, line, (void *) gc, sizeof(XGCValues));
+ }
+ return (gc);
}
void
-libast_x_free_gc(const char *var, const char *filename, unsigned long line, Display *d, GC gc)
+libast_x_free_gc(const char *var, const char *filename, unsigned long line, Display * d, GC gc)
{
- D_MEM(("libast_x_free_gc() called for variable %s (0x%08x) at %s:%lu\n", var, gc, filename, line));
- if (gc) {
- if (DEBUG_LEVEL >= DEBUG_MEM) {
- memrec_rem_var(&gc_rec, var, filename, line, (void *) gc);
+ D_MEM(("libast_x_free_gc() called for variable %s (0x%08x) at %s:%lu\n", var, gc, filename, line));
+ if (gc) {
+ if (DEBUG_LEVEL >= DEBUG_MEM) {
+ memrec_rem_var(&gc_rec, var, filename, line, (void *) gc);
+ }
+ XFreeGC(d, gc);
+ } else {
+ D_MEM(("ERROR: Caught attempt to free NULL GC\n"));
}
- XFreeGC(d, gc);
- } else {
- D_MEM(("ERROR: Caught attempt to free NULL GC\n"));
- }
}
void
libast_dump_gc_tables(void)
{
- fprintf(LIBAST_DEBUG_FD, "Dumping X11 GC allocation table:\n");
- memrec_dump_resources(&gc_rec);
+ fprintf(LIBAST_DEBUG_FD, "Dumping X11 GC allocation table:\n");
+ memrec_dump_resources(&gc_rec);
}
#endif
@@ -453,16 +460,16 @@ libast_dump_gc_tables(void)
void
free_array(void **list, size_t count)
{
- register size_t i;
-
- REQUIRE(list != NULL);
-
- if (count == 0) {
- count = (size_t) -1;
- }
- for (i = 0; i < count && list[i]; i++) {
- FREE(list[i]);
- list[i] = NULL;
- }
- FREE(list);
+ register size_t i;
+
+ REQUIRE(list != NULL);
+
+ if (count == 0) {
+ count = (size_t) (-1);
+ }
+ for (i = 0; i < count && list[i]; i++) {
+ FREE(list[i]);
+ list[i] = NULL;
+ }
+ FREE(list);
}
diff --git a/src/obj.c b/src/obj.c
index a28065f..f8a1880 100644
--- a/src/obj.c
+++ b/src/obj.c
@@ -29,92 +29,123 @@ static const char cvs_ident[] = "$Id$";
#include <libast_internal.h>
-/*spif_classname_t spif_obj_classname = "spif_obj_t";*/
-SPIF_DECL_CLASSNAME(obj);
+spif_const_class_t SPIF_CLASS_VAR(obj) = {
+ SPIF_DECL_CLASSNAME(obj),
+ (spif_newfunc_t) spif_obj_new,
+ (spif_memberfunc_t) spif_obj_init,
+ (spif_memberfunc_t) spif_obj_done,
+ (spif_memberfunc_t) spif_obj_del,
+ (spif_func_t) spif_obj_show,
+ (spif_func_t) spif_obj_comp,
+ (spif_func_t) spif_obj_dup,
+ (spif_func_t) spif_obj_type
+};
+
spif_nullobj_t
spif_nullobj_new(void)
{
- /* DO NOT USE */
- return ((spif_nullobj_t) (NULL));
+ /* DO NOT USE */
+ return ((spif_nullobj_t) (NULL));
}
spif_bool_t
spif_nullobj_del(spif_nullobj_t self)
{
- /* DO NOT USE */
- USE_VAR(self);
- return TRUE;
+ /* DO NOT USE */
+ USE_VAR(self);
+ return TRUE;
}
spif_bool_t
spif_nullobj_init(spif_nullobj_t self)
{
- /* DO NOT USE */
- USE_VAR(self);
- return TRUE;
+ /* DO NOT USE */
+ USE_VAR(self);
+ return TRUE;
}
spif_bool_t
spif_nullobj_done(spif_nullobj_t self)
{
- /* DO NOT USE */
- USE_VAR(self);
- return TRUE;
+ /* DO NOT USE */
+ USE_VAR(self);
+ return TRUE;
}
-
spif_obj_t
spif_obj_new(void)
{
- spif_obj_t self;
+ spif_obj_t self;
- self = SPIF_ALLOC(obj);
- spif_obj_init(self);
- return self;
+ self = SPIF_ALLOC(obj);
+ spif_obj_init(self);
+ return self;
}
spif_bool_t
spif_obj_del(spif_obj_t self)
{
- spif_obj_done(self);
- SPIF_DEALLOC(self);
- return TRUE;
+ spif_obj_done(self);
+ SPIF_DEALLOC(self);
+ return TRUE;
}
spif_bool_t
spif_obj_init(spif_obj_t self)
{
- spif_obj_set_classname(self, SPIF_CLASSNAME_TYPE(obj));
- return TRUE;
+ spif_obj_set_class(self, &(SPIF_CLASS_VAR(obj)));
+ return TRUE;
}
spif_bool_t
spif_obj_done(spif_obj_t self)
{
- USE_VAR(self);
- return TRUE;
+ USE_VAR(self);
+ return TRUE;
}
-spif_classname_t
-spif_obj_get_classname(spif_obj_t self)
+spif_class_t
+spif_obj_get_class(spif_obj_t self)
{
- return ((self) ? (self->classname) : ((spif_classname_t) SPIF_NULLSTR_TYPE(obj)));
+ return ((self) ? (self->cls) : SPIF_NULL_TYPE(class));
}
spif_bool_t
-spif_obj_set_classname(spif_obj_t self, spif_classname_t newname)
+spif_obj_set_class(spif_obj_t self, spif_class_t cls)
{
- if (SPIF_OBJ_ISNULL(self)) {
- return FALSE;
- }
- SPIF_OBJ_CLASSNAME(self) = newname;
- return TRUE;
+ if (SPIF_OBJ_ISNULL(self)) {
+ return FALSE;
+ }
+ SPIF_OBJ_CLASS(self) = cls;
+ return TRUE;
}
spif_bool_t
spif_obj_show(spif_obj_t self, spif_charptr_t name)
{
- printf("%s: (spif_obj_t) { \"%s\" }\n", name, self->classname);
- return TRUE;
+ printf("%s: (spif_obj_t) { \"%s\" }\n", name, SPIF_OBJ_CLASSNAME(self));
+ return TRUE;
+}
+
+spif_cmp_t
+spif_obj_comp(spif_obj_t self, spif_obj_t other)
+{
+ return (self == other);
+}
+
+spif_obj_t
+spif_obj_dup(spif_obj_t self)
+{
+ spif_obj_t tmp;
+
+ tmp = spif_obj_new();
+ memcpy(tmp, self, SPIF_SIZEOF_TYPE(obj));
+ return tmp;
+}
+
+spif_classname_t
+spif_obj_type(spif_obj_t self)
+{
+ return (SPIF_CAST(classname) (self));
}
diff --git a/src/str.c b/src/str.c
index e1d6279..0b4cd14 100644
--- a/src/str.c
+++ b/src/str.c
@@ -29,423 +29,444 @@ static const char cvs_ident[] = "$Id$";
#include <libast_internal.h>
-/* Declaration for the spif_str_t classname variable. */
-SPIF_DECL_CLASSNAME(str);
+spif_const_class_t SPIF_CLASS_VAR(str) = {
+ SPIF_DECL_CLASSNAME(str),
+ (spif_newfunc_t) spif_str_new,
+ (spif_memberfunc_t) spif_str_init,
+ (spif_memberfunc_t) spif_str_done,
+ (spif_memberfunc_t) spif_str_del,
+ (spif_func_t) spif_str_show,
+ (spif_func_t) spif_str_cmp,
+ (spif_func_t) spif_str_dup,
+ (spif_func_t) spif_str_type
+};
+
const size_t buff_inc = 4096;
spif_str_t
spif_str_new(void)
{
- spif_str_t self;
+ spif_str_t self;
- self = SPIF_ALLOC(str);
- spif_str_init(self);
- return self;
+ self = SPIF_ALLOC(str);
+ spif_str_init(self);
+ return self;
}
spif_str_t
spif_str_new_from_ptr(spif_charptr_t old)
{
- spif_str_t self;
+ spif_str_t self;
- self = SPIF_ALLOC(str);
- spif_str_init_from_ptr(self, old);
- return self;
+ self = SPIF_ALLOC(str);
+ spif_str_init_from_ptr(self, old);
+ return self;
}
spif_str_t
spif_str_new_from_buff(spif_charptr_t buff, size_t size)
{
- spif_str_t self;
+ spif_str_t self;
- self = SPIF_ALLOC(str);
- spif_str_init_from_buff(self, buff, size);
- return self;
+ self = SPIF_ALLOC(str);
+ spif_str_init_from_buff(self, buff, size);
+ return self;
}
spif_str_t
-spif_str_new_from_fp(FILE *fp)
+spif_str_new_from_fp(FILE * fp)
{
- spif_str_t self;
+ spif_str_t self;
- self = SPIF_ALLOC(str);
- spif_str_init_from_fp(self, fp);
- return self;
+ self = SPIF_ALLOC(str);
+ spif_str_init_from_fp(self, fp);
+ return self;
}
spif_str_t
spif_str_new_from_fd(int fd)
{
- spif_str_t self;
+ spif_str_t self;
- self = SPIF_ALLOC(str);
- spif_str_init_from_fd(self, fd);
- return self;
+ self = SPIF_ALLOC(str);
+ spif_str_init_from_fd(self, fd);
+ return self;
}
spif_bool_t
spif_str_del(spif_str_t self)
{
- spif_str_done(self);
- SPIF_DEALLOC(self);
- return TRUE;
+ spif_str_done(self);
+ SPIF_DEALLOC(self);
+ return TRUE;
}
spif_bool_t
spif_str_init(spif_str_t self)
{
- spif_obj_init(SPIF_OBJ(self));
- spif_obj_set_classname(SPIF_OBJ(self), SPIF_CLASSNAME_TYPE(str));
- self->s = SPIF_NULL_TYPE(charptr);
- self->len = 0;
- self->mem = 0;
- return TRUE;
+ spif_obj_init(SPIF_OBJ(self));
+ spif_obj_set_class(SPIF_OBJ(self), & SPIF_CLASS_VAR(str));
+ self->s = SPIF_NULL_TYPE(charptr);
+ self->len = 0;
+ self->mem = 0;
+ return TRUE;
}
spif_bool_t
spif_str_init_from_ptr(spif_str_t self, spif_charptr_t old)
{
- self->len = strlen(old);
- self->mem = self->len + 1;
- self->s = SPIF_TYPE(charptr) MALLOC(self->mem);
- memcpy(self->s, old, self->mem);
- return TRUE;
+ self->len = strlen(SPIF_CONST_CAST_C(char *) old);
+ self->mem = self->len + 1;
+ self->s = SPIF_CAST(charptr) MALLOC(self->mem);
+ memcpy(self->s, old, self->mem);
+ return TRUE;
}
spif_bool_t
spif_str_init_from_buff(spif_str_t self, spif_charptr_t buff, size_t size)
{
- self->mem = size;
- self->len = strnlen(buff, size);
- if (self->mem == self->len) {
- self->mem++;
- }
- self->s = SPIF_TYPE(charptr) MALLOC(self->mem);
- memcpy(self->s, buff, self->len);
- self->s[self->len] = 0;
- return TRUE;
+ self->mem = size;
+ self->len = strnlen(SPIF_CONST_CAST_C(char *) buff, size);
+ if (self->mem == self->len) {
+ self->mem++;
+ }
+ self->s = SPIF_CAST(charptr) MALLOC(self->mem);
+ memcpy(self->s, buff, self->len);
+ self->s[self->len] = 0;
+ return TRUE;
}
spif_bool_t
-spif_str_init_from_fp(spif_str_t self, FILE *fp)
+spif_str_init_from_fp(spif_str_t self, FILE * fp)
{
- spif_charptr_t p, end = NULL;
+ spif_charptr_t p, end = NULL;
- self->mem = buff_inc;
- self->len = 0;
- self->s = SPIF_TYPE(charptr) MALLOC(self->mem);
-
- for (p = self->s; fgets(p, buff_inc, fp); p += buff_inc) {
- if ((end = strchr(p, '\n')) == NULL) {
- self->mem += buff_inc;
- self->s = SPIF_TYPE(charptr) REALLOC(self->s, self->mem);
- } else {
- *end = 0;
- break;
+ self->mem = buff_inc;
+ self->len = 0;
+ self->s = SPIF_CAST(charptr) MALLOC(self->mem);
+
+ for (p = self->s; fgets(SPIF_CAST_C(char *) p, buff_inc, fp); p += buff_inc) {
+ if ((end =
+ SPIF_CAST(charptr)
+ strchr(
+ SPIF_CONST_CAST_C(char *) p,
+ '\n')) == NULL) {
+ self->mem += buff_inc;
+ self->s = SPIF_CAST(charptr) REALLOC(self->s, self->mem);
+ } else {
+ *end = 0;
+ break;
+ }
}
- }
- self->len = (size_t) ((end)
- ? (end - self->s)
- : ((int) strlen(self->s)));
- self->mem = self->len + 1;
- self->s = SPIF_TYPE(charptr) REALLOC(self->s, self->mem);
- return TRUE;
+ self->len = (size_t) ((end)
+ ? (end - self->s)
+ : ((int) strlen(SPIF_CONST_CAST_C(char *) self->s)));
+ self->mem = self->len + 1;
+ self->s = SPIF_CAST(charptr) REALLOC(self->s, self->mem);
+ return TRUE;
}
spif_bool_t
spif_str_init_from_fd(spif_str_t self, int fd)
{
- int n;
- spif_charptr_t p;
+ int n;
+ spif_charptr_t p;
- self->mem = buff_inc;
- self->len = 0;
- self->s = SPIF_TYPE(charptr) MALLOC(self->mem);
+ self->mem = buff_inc;
+ self->len = 0;
+ self->s = SPIF_CAST(charptr) MALLOC(self->mem);
- for (p = self->s; ((n = read(fd, p, buff_inc)) > 0) || (errno == EINTR); ) {
- self->mem += n;
- self->s = SPIF_TYPE(charptr) REALLOC(self->s, self->mem);
- p += n;
- }
- self->len = self->mem - buff_inc;
- self->mem = self->len + 1;
- self->s = SPIF_TYPE(charptr) REALLOC(self->s, self->mem);
- self->s[self->len] = 0;
- return TRUE;
+ for (p = self->s; ((n = read(fd, p, buff_inc)) > 0) || (errno == EINTR);) {
+ self->mem += n;
+ self->s = SPIF_CAST(charptr) REALLOC(self->s, self->mem);
+ p += n;
+ }
+ self->len = self->mem - buff_inc;
+ self->mem = self->len + 1;
+ self->s = SPIF_CAST(charptr) REALLOC(self->s, self->mem);
+ self->s[self->len] = 0;
+ return TRUE;
}
spif_bool_t
spif_str_done(spif_str_t self)
{
- if (self->mem) {
- FREE(self->s);
- self->len = 0;
- self->mem = 0;
- self->s = SPIF_NULL_TYPE(charptr);
- }
- return TRUE;
+ if (self->mem) {
+ FREE(self->s);
+ self->len = 0;
+ self->mem = 0;
+ self->s = SPIF_NULL_TYPE(charptr);
+ }
+ return TRUE;
}
spif_str_t
spif_str_dup(spif_str_t orig)
{
- spif_str_t self;
+ spif_str_t self;
- self = SPIF_ALLOC(str);
- memcpy(self, orig, SPIF_SIZEOF_TYPE(str));
- self->s = STRDUP(SPIF_STR_STR(orig));
- self->len = orig->len;
- self->mem = orig->mem;
- return self;
+ self = SPIF_ALLOC(str);
+ memcpy(self, orig, SPIF_SIZEOF_TYPE(str));
+ self->s = SPIF_CAST(charptr) STRDUP(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(orig));
+ self->len = orig->len;
+ self->mem = orig->mem;
+ return self;
}
-int
+spif_cmp_t
spif_str_cmp(spif_str_t self, spif_str_t other)
{
- return (strcmp(SPIF_STR_STR(self), SPIF_STR_STR(other)));
+ return SPIF_CMP_FROM_INT(strcmp(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self), SPIF_CONST_CAST_C(char *) SPIF_STR_STR(other)));
}
-int
+spif_cmp_t
spif_str_cmp_with_ptr(spif_str_t self, spif_charptr_t other)
{
- return (strcmp(SPIF_STR_STR(self), other));
+ return SPIF_CMP_FROM_INT(strcmp(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self), SPIF_CONST_CAST_C(char *) other));
}
-int
+spif_cmp_t
spif_str_casecmp(spif_str_t self, spif_str_t other)
{
- return (strcasecmp(SPIF_STR_STR(self), SPIF_STR_STR(other)));
+ return SPIF_CMP_FROM_INT(strcasecmp(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self), SPIF_CONST_CAST_C(char *) SPIF_STR_STR(other)));
}
-int
+spif_cmp_t
spif_str_casecmp_with_ptr(spif_str_t self, spif_charptr_t other)
{
- return (strcasecmp(SPIF_STR_STR(self), other));
+ return SPIF_CMP_FROM_INT(strcasecmp(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self), SPIF_CONST_CAST_C(char *) other));
}
-int
+spif_cmp_t
spif_str_ncmp(spif_str_t self, spif_str_t other, size_t cnt)
{
- return (strncmp(SPIF_STR_STR(self), SPIF_STR_STR(other), cnt));
+ return SPIF_CMP_FROM_INT(strncmp(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self), SPIF_CONST_CAST_C(char *) SPIF_STR_STR(other), cnt));
}
-int
+spif_cmp_t
spif_str_ncmp_with_ptr(spif_str_t self, spif_charptr_t other, size_t cnt)
{
- return (strncmp(SPIF_STR_STR(self), other, cnt));
+ return SPIF_CMP_FROM_INT(strncmp(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self), SPIF_CONST_CAST_C(char *) other, cnt));
}
-int
+spif_cmp_t
spif_str_ncasecmp(spif_str_t self, spif_str_t other, size_t cnt)
{
- return (strncasecmp(SPIF_STR_STR(self), SPIF_STR_STR(other), cnt));
+ return SPIF_CMP_FROM_INT(strncasecmp(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self), SPIF_CONST_CAST_C(char *) SPIF_STR_STR(other), cnt));
}
-int
+spif_cmp_t
spif_str_ncasecmp_with_ptr(spif_str_t self, spif_charptr_t other, size_t cnt)
{
- return (strncasecmp(SPIF_STR_STR(self), other, cnt));
+ return SPIF_CMP_FROM_INT(strncasecmp(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self), SPIF_CONST_CAST_C(char *) other, cnt));
}
size_t
spif_str_index(spif_str_t self, spif_char_t c)
{
- return (size_t) ((int) (index(SPIF_STR_STR(self), c)) - (int) (SPIF_STR_STR(self)));
+ return (size_t) ((int) (index(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self), c)) - (int) (SPIF_STR_STR(self)));
}
size_t
spif_str_rindex(spif_str_t self, spif_char_t c)
{
- return (size_t) ((int) (rindex(SPIF_STR_STR(self), c)) - (int) (SPIF_STR_STR(self)));
+ return (size_t) ((int) (rindex(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self), c)) - (int) (SPIF_STR_STR(self)));
}
size_t
spif_str_find(spif_str_t self, spif_str_t other)
{
- return (size_t) ((int) (strstr(SPIF_STR_STR(self), SPIF_STR_STR(other))) - (int) (SPIF_STR_STR(self)));
+ return (size_t) ((int) (strstr(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self),
+ SPIF_CONST_CAST_C(char *) SPIF_STR_STR(other))) - (int) (SPIF_STR_STR(self)));
}
size_t
spif_str_find_from_ptr(spif_str_t self, spif_charptr_t other)
{
- return (size_t) ((int) (strstr(SPIF_STR_STR(self), other)) - (int) (SPIF_STR_STR(self)));
+ return (size_t) ((int) (strstr(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self),
+ SPIF_CONST_CAST_C(char *) other)) - (int) (SPIF_STR_STR(self)));
}
spif_str_t
spif_str_substr(spif_str_t self, spif_int32_t idx, spif_int32_t cnt)
{
- return spif_str_new_from_buff(SPIF_STR_STR(self) + ((idx < 0) ? (self->len) : (0)) + idx, cnt);
+ return spif_str_new_from_buff(SPIF_STR_STR(self) + ((idx < 0) ? (self->len) : (0)) + idx, cnt);
}
spif_charptr_t
spif_str_substr_to_ptr(spif_str_t self, spif_int32_t idx, spif_int32_t cnt)
{
- spif_charptr_t newstr;
+ spif_charptr_t newstr;
- newstr = SPIF_TYPE(charptr) MALLOC(cnt + 1);
- memcpy(newstr, SPIF_STR_STR(self) + ((idx < 0) ? (self->len) : (0)) + idx, cnt);
- newstr[cnt] = 0;
- return newstr;
+ newstr = SPIF_CAST(charptr) MALLOC(cnt + 1);
+ memcpy(newstr, SPIF_STR_STR(self) + ((idx < 0) ? (self->len) : (0)) + idx, cnt);
+ newstr[cnt] = 0;
+ return newstr;
}
size_t
spif_str_to_num(spif_str_t self, int base)
{
- return (size_t) (strtoul(SPIF_STR_STR(self), (char **) NULL, base));
+ return (size_t) (strtoul(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self), (char **) NULL, base));
}
double
spif_str_to_float(spif_str_t self)
{
- return (double) (strtod(SPIF_STR_STR(self), (char **) NULL));
+ return (double) (strtod(SPIF_CONST_CAST_C(char *) SPIF_STR_STR(self), (char **) NULL));
}
spif_bool_t
spif_str_append(spif_str_t self, spif_str_t other)
{
- self->mem += other->mem - 1;
- self->s = SPIF_TYPE(charptr) REALLOC(self->s, self->mem);
- memcpy(self->s + self->len, SPIF_STR_STR(other), other->len + 1);
- self->len += other->len;
- return TRUE;
+ self->mem += other->mem - 1;
+ self->s = SPIF_CAST(charptr) REALLOC(self->s, self->mem);
+ memcpy(self->s + self->len, SPIF_STR_STR(other), other->len + 1);
+ self->len += other->len;
+ return TRUE;
}
spif_bool_t
spif_str_append_from_ptr(spif_str_t self, spif_charptr_t other)
{
- size_t len;
+ size_t len;
- len = strlen(other);
- self->mem += len;
- self->s = SPIF_TYPE(charptr) REALLOC(self->s, self->mem);
- memcpy(self->s + self->len, other, len + 1);
- self->len += len;
- return TRUE;
+ len = strlen(SPIF_CONST_CAST_C(char *) other);
+ self->mem += len;
+ self->s = SPIF_CAST(charptr) REALLOC(self->s, self->mem);
+ memcpy(self->s + self->len, other, len + 1);
+ self->len += len;
+ return TRUE;
}
spif_bool_t
spif_str_trim(spif_str_t self)
{
- spif_charptr_t start, end;
+ spif_charptr_t start, end;
- start = self->s;
- end = self->s + self->len - 1;
- for (; isspace((spif_uchar_t) (*start)) && (start < end); start++);
- for (; isspace((spif_uchar_t) (*end)) && (start < end); end--);
- if (start > end) {
- return spif_str_done(self);
- }
- *(++end) = 0;
- self->len = (size_t) (end - start);
- self->mem = self->len + 1;
- memmove(self->s, start, self->mem);
- self->s = SPIF_TYPE(charptr) REALLOC(self->s, self->mem);
- return TRUE;
+ start = self->s;
+ end = self->s + self->len - 1;
+ for (; isspace((spif_uchar_t) (*start)) && (start < end); start++);
+ for (; isspace((spif_uchar_t) (*end)) && (start < end); end--);
+ if (start > end) {
+ return spif_str_done(self);
+ }
+ *(++end) = 0;
+ self->len = (size_t) (end - start);
+ self->mem = self->len + 1;
+ memmove(self->s, start, self->mem);
+ self->s = SPIF_CAST(charptr) REALLOC(self->s, self->mem);
+ return TRUE;
}
spif_bool_t
spif_str_splice(spif_str_t self, size_t idx, size_t cnt, spif_str_t other)
{
- spif_charptr_t tmp, ptmp;
- size_t newsize;
-
- newsize = self->len + ((SPIF_OBJ_ISNULL(other)) ? (0) : (other->len)) - cnt + 1;
- ptmp = tmp = SPIF_TYPE(charptr) MALLOC(newsize);
- memcpy(tmp, self->s, idx);
- ptmp += idx;
- if (!SPIF_OBJ_ISNULL(other)) {
- memcpy(ptmp, other->s, other->len);
- ptmp += other->len;
- }
- memcpy(ptmp, self->s + idx + cnt, self->len - idx - cnt + 1);
- if (self->mem < newsize) {
- self->s = SPIF_TYPE(charptr) REALLOC(self->s, newsize);
- self->mem = newsize;
- }
- self->len = newsize - 1;
- memcpy(self->s, tmp, newsize);
- return TRUE;
+ spif_charptr_t tmp, ptmp;
+ size_t newsize;
+
+ newsize = self->len + ((SPIF_OBJ_ISNULL(other)) ? (0) : (other->len)) - cnt + 1;
+ ptmp = tmp = SPIF_CAST(charptr) MALLOC(newsize);
+ memcpy(tmp, self->s, idx);
+ ptmp += idx;
+ if (!SPIF_OBJ_ISNULL(other)) {
+ memcpy(ptmp, other->s, other->len);
+ ptmp += other->len;
+ }
+ memcpy(ptmp, self->s + idx + cnt, self->len - idx - cnt + 1);
+ if (self->mem < newsize) {
+ self->s = SPIF_CAST(charptr) REALLOC(self->s, newsize);
+ self->mem = newsize;
+ }
+ self->len = newsize - 1;
+ memcpy(self->s, tmp, newsize);
+ return TRUE;
}
spif_bool_t
spif_str_splice_from_ptr(spif_str_t self, size_t idx, size_t cnt, spif_charptr_t other)
{
- spif_charptr_t tmp, ptmp;
- size_t len, newsize;
-
- len = (other ? strlen(other) : 0);
- newsize = self->len + len - cnt + 1;
- ptmp = tmp = SPIF_TYPE(charptr) MALLOC(newsize);
- memcpy(tmp, self->s, idx);
- ptmp += idx;
- if (len) {
- memcpy(ptmp, other, len);
- ptmp += len;
- }
- memcpy(ptmp, self->s + idx + cnt, self->len - idx - cnt + 1);
- if (self->mem < newsize) {
- self->s = SPIF_TYPE(charptr) REALLOC(self->s, newsize);
- self->mem = newsize;
- }
- self->len = newsize - 1;
- memcpy(self->s, tmp, newsize);
- return TRUE;
+ spif_charptr_t tmp, ptmp;
+ size_t len, newsize;
+
+ len = (other ? strlen(SPIF_CONST_CAST_C(char *) other) : 0);
+ newsize = self->len + len - cnt + 1;
+ ptmp = tmp = SPIF_CAST(charptr) MALLOC(newsize);
+ memcpy(tmp, self->s, idx);
+ ptmp += idx;
+ if (len) {
+ memcpy(ptmp, other, len);
+ ptmp += len;
+ }
+ memcpy(ptmp, self->s + idx + cnt, self->len - idx - cnt + 1);
+ if (self->mem < newsize) {
+ self->s = SPIF_CAST(charptr) REALLOC(self->s, newsize);
+ self->mem = newsize;
+ }
+ self->len = newsize - 1;
+ memcpy(self->s, tmp, newsize);
+ return TRUE;
}
spif_bool_t
spif_str_reverse(spif_str_t self)
{
- return ((strrev(self->s)) ? TRUE : FALSE);
+ return ((strrev(SPIF_CAST_C(char *) self->s)) ? TRUE : FALSE);
}
size_t
spif_str_get_size(spif_str_t self)
{
- return self->mem;
+ return self->mem;
}
spif_bool_t
spif_str_set_size(spif_str_t self, size_t size)
{
- if (size < self->mem) {
- return FALSE;
- } else if (size == self->mem) {
+ if (size < self->mem) {
+ return FALSE;
+ } else if (size == self->mem) {
+ return TRUE;
+ }
+ self->mem = size;
+ if (self->s) {
+ self->s = SPIF_CAST(charptr) REALLOC(self->s, size);
+ } else {
+ self->s = SPIF_CAST(charptr) MALLOC(size);
+ *(self->s) = 0;
+ self->len = 0;
+ }
return TRUE;
- }
- self->mem = size;
- if (self->s) {
- self->s = SPIF_TYPE(charptr) REALLOC(self->s, size);
- } else {
- self->s = SPIF_TYPE(charptr) MALLOC(size);
- *(self->s) = 0;
- self->len = 0;
- }
- return TRUE;
}
size_t
spif_str_get_len(spif_str_t self)
{
- return self->len;
+ return self->len;
}
spif_bool_t
spif_str_set_len(spif_str_t self, size_t len)
{
- /* Only a moron would use this function. */
- print_warning("spif_str_set_len() called. Moron detected.\n");
+ /* Only a moron would use this function. */
+ print_warning("spif_str_set_len() called. Moron detected.\n");
#if DEBUG <= 4
- return FALSE;
+ return FALSE;
#else
- self->len = len;
- return TRUE;
+ self->len = len;
+ return TRUE;
#endif
}
spif_bool_t
spif_str_show(spif_str_t self, spif_charptr_t name)
{
- printf("(spif_str_t) %s: { \"%s\", len %lu, size %lu }\n", name, self->s,
- (unsigned long) self->len, (unsigned long) self->mem);
- return TRUE;
+ printf("(spif_str_t) %s: { \"%s\", len %lu, size %lu }\n", name, self->s, (unsigned long) self->len, (unsigned long) self->mem);
+ return TRUE;
+}
+
+spif_classname_t
+spif_str_type(spif_str_t self)
+{
+ return (SPIF_CAST(classname) (self));
}
diff --git a/src/strings.c b/src/strings.c
index 10254ee..eec2f28 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -35,17 +35,17 @@ static const char cvs_ident[] = "$Id$";
void *
memmem(const void *haystack, register size_t haystacklen, const void *needle, register size_t needlelen)
{
- register char *hs = (char *) haystack;
- register char *n = (char *) needle;
- register unsigned long i;
- register size_t len = haystacklen - needlelen;
-
- for (i = 0; i < len; i++) {
- if (!memcmp(hs + i, n, needlelen)) {
- return (hs + i);
+ register char *hs = (char *) haystack;
+ register char *n = (char *) needle;
+ register unsigned long i;
+ register size_t len = haystacklen - needlelen;
+
+ for (i = 0; i < len; i++) {
+ if (!memcmp(hs + i, n, needlelen)) {
+ return (hs + i);
+ }
}
- }
- return (NULL);
+ return (NULL);
}
#endif
@@ -53,11 +53,12 @@ memmem(const void *haystack, register size_t haystacklen, const void *needle, re
size_t
strnlen(register const char *s, size_t maxlen)
{
- register size_t n;
+ register size_t n;
- if (!s) return 0;
- for (n = 0; *s && n < maxlen; s++, n++);
- return n;
+ if (!s)
+ return 0;
+ for (n = 0; *s && n < maxlen; s++, n++);
+ return n;
}
#endif
@@ -65,11 +66,11 @@ strnlen(register const char *s, size_t maxlen)
void
usleep(unsigned long usec)
{
- struct timeval delay;
+ struct timeval delay;
- delay.tv_sec = 0;
- delay.tv_usec = usec;
- select(0, NULL, NULL, NULL, &delay);
+ delay.tv_sec = 0;
+ delay.tv_usec = usec;
+ select(0, NULL, NULL, NULL, &delay);
}
@@ -88,55 +89,55 @@ nanosleep(unsigned long nsec) {
char *
left_str(const char *str, unsigned long cnt)
{
- char *tmpstr;
+ char *tmpstr;
- REQUIRE_RVAL(str != NULL, NULL);
- REQUIRE_RVAL(cnt <= strlen(str), NULL);
- REQUIRE_RVAL(cnt > 0, NULL);
+ REQUIRE_RVAL(str != NULL, NULL);
+ REQUIRE_RVAL(cnt <= strlen(str), NULL);
+ REQUIRE_RVAL(cnt > 0, NULL);
- tmpstr = (char *) MALLOC(cnt + 1);
- strncpy(tmpstr, str, cnt);
- tmpstr[cnt] = 0;
- return (tmpstr);
+ tmpstr = (char *) MALLOC(cnt + 1);
+ strncpy(tmpstr, str, cnt);
+ tmpstr[cnt] = 0;
+ return (tmpstr);
}
/* Return cnt characters from str, starting at position index (from 0) */
char *
mid_str(const char *str, unsigned long index, unsigned long cnt)
{
- char *tmpstr;
- const char *pstr = str;
- size_t len;
-
- REQUIRE_RVAL(str != NULL, NULL);
- len = strlen(str);
- REQUIRE_RVAL(index < len, NULL);
- REQUIRE_RVAL(cnt <= len, NULL);
- REQUIRE_RVAL(cnt > 0, NULL);
-
- tmpstr = (char *) MALLOC(cnt + 1);
- pstr += index;
- strncpy(tmpstr, pstr, cnt);
- tmpstr[cnt] = 0;
- return (tmpstr);
+ char *tmpstr;
+ const char *pstr = str;
+ size_t len;
+
+ REQUIRE_RVAL(str != NULL, NULL);
+ len = strlen(str);
+ REQUIRE_RVAL(index < len, NULL);
+ REQUIRE_RVAL(cnt <= len, NULL);
+ REQUIRE_RVAL(cnt > 0, NULL);
+
+ tmpstr = (char *) MALLOC(cnt + 1);
+ pstr += index;
+ strncpy(tmpstr, pstr, cnt);
+ tmpstr[cnt] = 0;
+ return (tmpstr);
}
/* Return the rightmost characters of str */
char *
right_str(const char *str, unsigned long cnt)
{
- char *tmpstr;
- const char *pstr = str;
-
- REQUIRE_RVAL(str != NULL, NULL);
- REQUIRE_RVAL(cnt <= strlen(str), NULL);
- REQUIRE_RVAL(cnt > 0, NULL);
-
- tmpstr = (char *) MALLOC(cnt + 1);
- pstr += strlen(str);
- pstr -= cnt;
- strcpy(tmpstr, pstr);
- return (tmpstr);
+ char *tmpstr;
+ const char *pstr = str;
+
+ REQUIRE_RVAL(str != NULL, NULL);
+ REQUIRE_RVAL(cnt <= strlen(str), NULL);
+ REQUIRE_RVAL(cnt > 0, NULL);
+
+ tmpstr = (char *) MALLOC(cnt + 1);
+ pstr += strlen(str);
+ pstr -= cnt;
+ strcpy(tmpstr, pstr);
+ return (tmpstr);
}
/* Returns TRUE if str matches regular expression pattern, FALSE otherwise */
@@ -144,60 +145,60 @@ right_str(const char *str, unsigned long cnt)
unsigned char
regexp_match(register const char *str, register const char *pattern)
{
- static regex_t *rexp = NULL;
- register int result;
- char errbuf[256];
-
- if (!rexp) {
- rexp = (regex_t *) MALLOC(sizeof(regex_t));
- }
-
- REQUIRE_RVAL(str != NULL, FALSE);
-
- if (pattern) {
- if ((result = regcomp(rexp, pattern, REG_EXTENDED)) != 0) {
- regerror(result, rexp, errbuf, 256);
- print_error("Unable to compile regexp %s -- %s.\n", pattern, errbuf);
- return (FALSE);
- }
- }
-
- if (((result = regexec(rexp, str, (size_t) 0, (regmatch_t *) NULL, 0))
- != 0) && (result != REG_NOMATCH)) {
- regerror(result, rexp, errbuf, 256);
- print_error("Error testing input string %s -- %s.\n", str, errbuf);
- return (FALSE);
- }
- return (!result);
+ static regex_t *rexp = NULL;
+ register int result;
+ char errbuf[256];
+
+ if (!rexp) {
+ rexp = (regex_t *) MALLOC(sizeof(regex_t));
+ }
+
+ REQUIRE_RVAL(str != NULL, FALSE);
+
+ if (pattern) {
+ if ((result = regcomp(rexp, pattern, REG_EXTENDED)) != 0) {
+ regerror(result, rexp, errbuf, 256);
+ print_error("Unable to compile regexp %s -- %s.\n", pattern, errbuf);
+ return (FALSE);
+ }
+ }
+
+ if (((result = regexec(rexp, str, (size_t) 0, (regmatch_t *) NULL, 0))
+ != 0) && (result != REG_NOMATCH)) {
+ regerror(result, rexp, errbuf, 256);
+ print_error("Error testing input string %s -- %s.\n", str, errbuf);
+ return (FALSE);
+ }
+ return (!result);
}
unsigned char
-regexp_match_r(register const char *str, register const char *pattern, register regex_t **rexp)
+regexp_match_r(register const char *str, register const char *pattern, register regex_t ** rexp)
{
- register int result;
- char errbuf[256];
-
- ASSERT_RVAL(rexp != NULL, FALSE);
- if (*rexp == NULL) {
- *rexp = (regex_t *) MALLOC(sizeof(regex_t));
- }
-
- if (pattern) {
- if ((result = regcomp(*rexp, pattern, REG_EXTENDED)) != 0) {
- regerror(result, *rexp, errbuf, 256);
- print_error("Unable to compile regexp %s -- %s.\n", pattern, errbuf);
- FREE(*rexp);
- return (FALSE);
- }
- }
-
- if (((result = regexec(*rexp, str, (size_t) 0, (regmatch_t *) NULL, 0))
- != 0) && (result != REG_NOMATCH)) {
- regerror(result, *rexp, errbuf, 256);
- print_error("Error testing input string %s -- %s.\n", str, errbuf);
- return (FALSE);
- }
- return (!result);
+ register int result;
+ char errbuf[256];
+
+ ASSERT_RVAL(rexp != NULL, FALSE);
+ if (*rexp == NULL) {
+ *rexp = (regex_t *) MALLOC(sizeof(regex_t));
+ }
+
+ if (pattern) {
+ if ((result = regcomp(*rexp, pattern, REG_EXTENDED)) != 0) {
+ regerror(result, *rexp, errbuf, 256);
+ print_error("Unable to compile regexp %s -- %s.\n", pattern, errbuf);
+ FREE(*rexp);
+ return (FALSE);
+ }
+ }
+
+ if (((result = regexec(*rexp, str, (size_t) 0, (regmatch_t *) NULL, 0))
+ != 0) && (result != REG_NOMATCH)) {
+ regerror(result, *rexp, errbuf, 256);
+ print_error("Error testing input string %s -- %s.\n", str, errbuf);
+ return (FALSE);
+ }
+ return (!result);
}
#endif
@@ -207,118 +208,118 @@ regexp_match_r(register const char *str, register const char *pattern, register
char **
split(const char *delim, const char *str)
{
- char **slist;
- register const char *pstr;
- register char *pdest;
- char quote = 0;
- unsigned short cnt = 0;
- unsigned long len;
-
- REQUIRE_RVAL(str != NULL, (char **) NULL);
-
- if ((slist = (char **) MALLOC(sizeof(char *))) == NULL) {
- print_error("split(): Unable to allocate memory -- %s\n", strerror(errno));
- return ((char **) NULL);
- }
-
- /* Before we do anything, skip leading "whitespace." */
- for (pstr = str; *pstr && IS_DELIM(*pstr); pstr++);
-
- /* The outermost for loop is where we traverse the string. Each new
- word brings us back to the top where we resize our string list. */
- for (; *pstr; cnt++) {
- /* First, resize the list to two bigger than our count. Why two?
- One for the string we're about to do, and one for a trailing NULL. */
- if ((slist = (char **) REALLOC(slist, sizeof(char *) * (cnt + 2))) == NULL) {
- print_error("split(): Unable to allocate memory -- %s\n", strerror(errno));
- return ((char **) NULL);
- }
-
- /* The string we're about to create can't possibly be larger than the remainder
- of the string we have yet to parse, so allocate that much space to start. */
- len = strlen(pstr) + 1;
- if ((slist[cnt] = (char *) MALLOC(len)) == NULL) {
- print_error("split(): Unable to allocate memory -- %s.\n", strerror(errno));
- return ((char **) NULL);
- }
- pdest = slist[cnt];
-
- /* This for loop is where we process each character. */
- for (; *pstr && (quote || !IS_DELIM(*pstr));) {
- if (*pstr == '\"' || *pstr == '\'') {
- /* It's a quote character, so set or reset the quote variable. */
- if (quote) {
- if (quote == *pstr) {
- quote = 0;
- } else {
- /* It's a single quote inside double quotes, or vice versa. Leave it alone. */
- *pdest++ = *pstr++;
- }
- } else {
- quote = *pstr;
+ char **slist;
+ register const char *pstr;
+ register char *pdest;
+ char quote = 0;
+ unsigned short cnt = 0;
+ unsigned long len;
+
+ REQUIRE_RVAL(str != NULL, (char **) NULL);
+
+ if ((slist = (char **) MALLOC(sizeof(char *))) == NULL) {
+ print_error("split(): Unable to allocate memory -- %s\n", strerror(errno));
+ return ((char **) NULL);
+ }
+
+ /* Before we do anything, skip leading "whitespace." */
+ for (pstr = str; *pstr && IS_DELIM(*pstr); pstr++);
+
+ /* The outermost for loop is where we traverse the string. Each new
+ word brings us back to the top where we resize our string list. */
+ for (; *pstr; cnt++) {
+ /* First, resize the list to two bigger than our count. Why two?
+ One for the string we're about to do, and one for a trailing NULL. */
+ if ((slist = (char **) REALLOC(slist, sizeof(char *) * (cnt + 2))) == NULL) {
+ print_error("split(): Unable to allocate memory -- %s\n", strerror(errno));
+ return ((char **) NULL);
+ }
+
+ /* The string we're about to create can't possibly be larger than the remainder
+ of the string we have yet to parse, so allocate that much space to start. */
+ len = strlen(pstr) + 1;
+ if ((slist[cnt] = (char *) MALLOC(len)) == NULL) {
+ print_error("split(): Unable to allocate memory -- %s.\n", strerror(errno));
+ return ((char **) NULL);
}
- pstr++;
- } else {
- /* Handle any backslashes that are escaping delimiters or quotes. */
- if ((*pstr == '\\') && (IS_DELIM(*(pstr + 1)) || IS_QUOTE(*(pstr + 1)))) {
- /* Incrementing pstr here moves us past the backslash so that the line
- below will copy the next character to the new token, no questions asked. */
- pstr++;
+ pdest = slist[cnt];
+
+ /* This for loop is where we process each character. */
+ for (; *pstr && (quote || !IS_DELIM(*pstr));) {
+ if (*pstr == '\"' || *pstr == '\'') {
+ /* It's a quote character, so set or reset the quote variable. */
+ if (quote) {
+ if (quote == *pstr) {
+ quote = 0;
+ } else {
+ /* It's a single quote inside double quotes, or vice versa. Leave it alone. */
+ *pdest++ = *pstr++;
+ }
+ } else {
+ quote = *pstr;
+ }
+ pstr++;
+ } else {
+ /* Handle any backslashes that are escaping delimiters or quotes. */
+ if ((*pstr == '\\') && (IS_DELIM(*(pstr + 1)) || IS_QUOTE(*(pstr + 1)))) {
+ /* Incrementing pstr here moves us past the backslash so that the line
+ below will copy the next character to the new token, no questions asked. */
+ pstr++;
+ }
+ *pdest++ = *pstr++;
+ }
}
- *pdest++ = *pstr++;
- }
- }
- /* Add the trailing \0 to terminate the new string. */
- *pdest = 0;
-
- /* Reallocate the new string to be just the right size. */
- len = strlen(slist[cnt]) + 1;
- slist[cnt] = (char *) REALLOC(slist[cnt], len);
-
- /* Move past any trailing "whitespace." */
- for (; *pstr && IS_DELIM(*pstr); pstr++);
- }
- if (cnt == 0) {
- return NULL;
- } else {
- /* The last element of slist[] should be NULL. */
- slist[cnt] = 0;
- return slist;
- }
+ /* Add the trailing \0 to terminate the new string. */
+ *pdest = 0;
+
+ /* Reallocate the new string to be just the right size. */
+ len = strlen(slist[cnt]) + 1;
+ slist[cnt] = (char *) REALLOC(slist[cnt], len);
+
+ /* Move past any trailing "whitespace." */
+ for (; *pstr && IS_DELIM(*pstr); pstr++);
+ }
+ if (cnt == 0) {
+ return NULL;
+ } else {
+ /* The last element of slist[] should be NULL. */
+ slist[cnt] = 0;
+ return slist;
+ }
}
char **
split_regexp(const char *regexp, const char *str)
{
- USE_VAR(regexp);
- USE_VAR(str);
- return (NULL);
+ USE_VAR(regexp);
+ USE_VAR(str);
+ return (NULL);
}
char *
join(const char *sep, char **slist)
{
- register unsigned long i;
- size_t len, slen;
- char *new_str;
-
- if (sep == NULL) {
- sep = "";
- }
- slen = strlen(sep);
- for (i = len = 0; slist[i]; i++) {
- len += strlen(slist[i]);
- }
- len += slen * (i - 1);
- new_str = (char *) MALLOC(len);
- strcpy(new_str, slist[0]);
- for (i = 1; slist[i]; i++) {
- if (slen) {
- strcat(new_str, sep);
- }
- strcat(new_str, slist[i]);
- }
- return new_str;
+ register unsigned long i;
+ size_t len, slen;
+ char *new_str;
+
+ if (sep == NULL) {
+ sep = "";
+ }
+ slen = strlen(sep);
+ for (i = len = 0; slist[i]; i++) {
+ len += strlen(slist[i]);
+ }
+ len += slen * (i - 1);
+ new_str = (char *) MALLOC(len);
+ strcpy(new_str, slist[0]);
+ for (i = 1; slist[i]; i++) {
+ if (slen) {
+ strcat(new_str, sep);
+ }
+ strcat(new_str, slist[i]);
+ }
+ return new_str;
}
/* Return malloc'd pointer to index-th word in str. "..." counts as 1 word. */
@@ -328,120 +329,119 @@ join(const char *sep, char **slist)
char *
get_word(unsigned long index, const char *str)
{
- char *tmpstr;
- char delim = 0;
- register unsigned long i, j, k;
-
- k = strlen(str) + 1;
- if ((tmpstr = (char *) MALLOC(k)) == NULL) {
- print_error("get_word(%lu, %s): Unable to allocate memory -- %s.\n",
- index, str, strerror(errno));
- return ((char *) NULL);
- }
- *tmpstr = 0;
- for (i = 0, j = 0; j < index && str[i]; j++) {
- for (; isspace(str[i]); i++);
- switch (str[i]) {
- case '\"':
- delim = '\"';
- i++;
- break;
- case '\'':
- delim = '\'';
- i++;
- break;
- default:
- delim = 0;
- }
- for (k = 0; str[i] && !IS_DELIM(str[i]);) {
- if (str[i] == '\\') {
- if (str[i + 1] == '\'' || str[i + 1] == '\"') {
- i++;
- }
- }
- tmpstr[k++] = str[i++];
- }
- switch (str[i]) {
- case '\"':
- case '\'':
- i++;
- break;
- }
- tmpstr[k] = 0;
- }
-
- if (j != index) {
- FREE(tmpstr);
- D_STRINGS(("get_word(%lu, %s) returning NULL.\n", index, str));
- return ((char *) NULL);
- } else {
- tmpstr = (char *) REALLOC(tmpstr, strlen(tmpstr) + 1);
- D_STRINGS(("get_word(%lu, %s) returning \"%s\".\n", index, str, tmpstr));
- return (tmpstr);
- }
+ char *tmpstr;
+ char delim = 0;
+ register unsigned long i, j, k;
+
+ k = strlen(str) + 1;
+ if ((tmpstr = (char *) MALLOC(k)) == NULL) {
+ print_error("get_word(%lu, %s): Unable to allocate memory -- %s.\n", index, str, strerror(errno));
+ return ((char *) NULL);
+ }
+ *tmpstr = 0;
+ for (i = 0, j = 0; j < index && str[i]; j++) {
+ for (; isspace(str[i]); i++);
+ switch (str[i]) {
+ case '\"':
+ delim = '\"';
+ i++;
+ break;
+ case '\'':
+ delim = '\'';
+ i++;
+ break;
+ default:
+ delim = 0;
+ }
+ for (k = 0; str[i] && !IS_DELIM(str[i]);) {
+ if (str[i] == '\\') {
+ if (str[i + 1] == '\'' || str[i + 1] == '\"') {
+ i++;
+ }
+ }
+ tmpstr[k++] = str[i++];
+ }
+ switch (str[i]) {
+ case '\"':
+ case '\'':
+ i++;
+ break;
+ }
+ tmpstr[k] = 0;
+ }
+
+ if (j != index) {
+ FREE(tmpstr);
+ D_STRINGS(("get_word(%lu, %s) returning NULL.\n", index, str));
+ return ((char *) NULL);
+ } else {
+ tmpstr = (char *) REALLOC(tmpstr, strlen(tmpstr) + 1);
+ D_STRINGS(("get_word(%lu, %s) returning \"%s\".\n", index, str, tmpstr));
+ return (tmpstr);
+ }
}
/* Return pointer into str to index-th word in str. "..." counts as 1 word. */
char *
get_pword(unsigned long index, const char *str)
{
- register const char *tmpstr = str;
- register unsigned long j;
-
- if (!str)
- return ((char *) NULL);
- for (; isspace(*tmpstr) && *tmpstr; tmpstr++);
- for (j = 1; j < index && *tmpstr; j++) {
- for (; !isspace(*tmpstr) && *tmpstr; tmpstr++);
+ register const char *tmpstr = str;
+ register unsigned long j;
+
+ if (!str)
+ return ((char *) NULL);
for (; isspace(*tmpstr) && *tmpstr; tmpstr++);
- }
-
- if (*tmpstr == '\"' || *tmpstr == '\'') {
- tmpstr++;
- }
- if (*tmpstr == '\0') {
- D_STRINGS(("get_pword(%lu, %s) returning NULL.\n", index, str));
- return ((char *) NULL);
- } else {
- D_STRINGS(("get_pword(%lu, %s) returning \"%s\"\n", index, str, tmpstr));
- return (char *) tmpstr;
- }
+ for (j = 1; j < index && *tmpstr; j++) {
+ for (; !isspace(*tmpstr) && *tmpstr; tmpstr++);
+ for (; isspace(*tmpstr) && *tmpstr; tmpstr++);
+ }
+
+ if (*tmpstr == '\"' || *tmpstr == '\'') {
+ tmpstr++;
+ }
+ if (*tmpstr == '\0') {
+ D_STRINGS(("get_pword(%lu, %s) returning NULL.\n", index, str));
+ return ((char *) NULL);
+ } else {
+ D_STRINGS(("get_pword(%lu, %s) returning \"%s\"\n", index, str, tmpstr));
+ return (char *) tmpstr;
+ }
}
/* Returns the number of words in str, for use with get_word() and get_pword(). "..." counts as 1 word. */
unsigned long
num_words(const char *str)
{
- register unsigned long cnt = 0;
- char delim = 0;
- register unsigned long i;
-
- for (i = 0; str[i] && IS_DELIM(str[i]); i++);
- for (; str[i]; cnt++) {
- switch (str[i]) {
- case '\"':
- delim = '\"';
- i++;
- break;
- case '\'':
- delim = '\'';
- i++;
- break;
- default:
- delim = 0;
- }
- for (; str[i] && !IS_DELIM(str[i]); i++);
- switch (str[i]) {
- case '\"':
- case '\'':
- i++;
- break;
- }
- for (; str[i] && isspace(str[i]); i++);
- }
-
- D_STRINGS(("num_words() returning %lu\n", cnt));
- return (cnt);
+ register unsigned long cnt = 0;
+ char delim = 0;
+ register unsigned long i;
+
+ for (i = 0; str[i] && IS_DELIM(str[i]); i++);
+ for (; str[i]; cnt++) {
+ switch (str[i]) {
+ case '\"':
+ delim = '\"';
+ i++;
+ break;
+ case '\'':
+ delim = '\'';
+ i++;
+ break;
+ default:
+ delim = 0;
+ }
+ for (; str[i] && !IS_DELIM(str[i]); i++);
+ switch (str[i]) {
+ case '\"':
+ case '\'':
+ i++;
+ break;
+ }
+ for (; str[i] && isspace(str[i]); i++);
+ }
+
+ D_STRINGS(("num_words() returning %lu\n", cnt));
+ return (cnt);
}
/* chomp() removes leading and trailing whitespace from a string */
@@ -449,72 +449,72 @@ char *
chomp(char *s)
{
- register char *front, *back;
+ register char *front, *back;
- ASSERT_RVAL(s != NULL, NULL);
- for (front = s; *front && isspace(*front); front++);
- for (back = s + strlen(s) - 1; *back && isspace(*back) && back > front; back--);
+ ASSERT_RVAL(s != NULL, NULL);
+ for (front = s; *front && isspace(*front); front++);
+ for (back = s + strlen(s) - 1; *back && isspace(*back) && back > front; back--);
- *(++back) = 0;
- if (front != s) {
- memmove(s, front, back - front + 1);
- }
- return (s);
+ *(++back) = 0;
+ if (front != s) {
+ memmove(s, front, back - front + 1);
+ }
+ return (s);
}
char *
strip_whitespace(register char *str)
{
- register unsigned long i, j;
-
- ASSERT_RVAL(str != NULL, NULL);
- if ((j = strlen(str))) {
- for (i = j - 1; isspace(*(str + i)); i--);
- str[j = i + 1] = 0;
- for (i = 0; isspace(*(str + i)); i++);
- j -= i;
- memmove(str, str + i, j + 1);
- }
- return (str);
+ register unsigned long i, j;
+
+ ASSERT_RVAL(str != NULL, NULL);
+ if ((j = strlen(str))) {
+ for (i = j - 1; isspace(*(str + i)); i--);
+ str[j = i + 1] = 0;
+ for (i = 0; isspace(*(str + i)); i++);
+ j -= i;
+ memmove(str, str + i, j + 1);
+ }
+ return (str);
}
char *
downcase_str(char *str)
{
- register char *tmp;
+ register char *tmp;
- for (tmp = str; *tmp; tmp++) {
- *tmp = tolower(*tmp);
- }
- D_STRINGS(("downcase_str() returning %s\n", str));
- return (str);
+ for (tmp = str; *tmp; tmp++) {
+ *tmp = tolower(*tmp);
+ }
+ D_STRINGS(("downcase_str() returning %s\n", str));
+ return (str);
}
char *
upcase_str(char *str)
{
- register char *tmp;
+ register char *tmp;
- for (tmp = str; *tmp; tmp++) {
- *tmp = toupper(*tmp);
- }
- D_STRINGS(("upcase_str() returning %s\n", str));
- return (str);
+ for (tmp = str; *tmp; tmp++) {
+ *tmp = toupper(*tmp);
+ }
+ D_STRINGS(("upcase_str() returning %s\n", str));
+ return (str);
}
#ifndef HAVE_STRCASESTR
char *
strcasestr(const char *haystack, register const char *needle)
{
- register const char *t;
- register size_t len = strlen(needle);
+ register const char *t;
+ register size_t len = strlen(needle);
- for (t = haystack; t && *t; t++) {
- if (!strncasecmp(t, needle, len)) {
- return ((char *) t);
+ for (t = haystack; t && *t; t++) {
+ if (!strncasecmp(t, needle, len)) {
+ return ((char *) t);
+ }
}
- }
- return (NULL);
+ return (NULL);
}
#endif
@@ -522,14 +522,14 @@ strcasestr(const char *haystack, register const char *needle)
char *
strcasechr(const char *haystack, register const char needle)
{
- register const char *t;
+ register const char *t;
- for (t = haystack; t && *t; t++) {
- if (tolower(*t) == tolower(needle)) {
- return ((char *) t);
+ for (t = haystack; t && *t; t++) {
+ if (tolower(*t) == tolower(needle)) {
+ return ((char *) t);
+ }
}
- }
- return (NULL);
+ return (NULL);
}
#endif
@@ -537,14 +537,14 @@ strcasechr(const char *haystack, register const char needle)
char *
strcasepbrk(const char *haystack, register const char *needle)
{
- register const char *t;
+ register const char *t;
- for (t = haystack; t && *t; t++) {
- if (strcasechr(needle, *t)) {
- return ((char *) t);
+ for (t = haystack; t && *t; t++) {
+ if (strcasechr(needle, *t)) {
+ return ((char *) t);
+ }
}
- }
- return (NULL);
+ return (NULL);
}
#endif
@@ -552,13 +552,13 @@ strcasepbrk(const char *haystack, register const char *needle)
char *
strrev(register char *str)
{
- register int i, j;
+ register int i, j;
- i = strlen(str);
- for (j = 0, i--; i > j; i--, j++) {
- SWAP(str[j], str[i]);
- }
- return (str);
+ i = strlen(str);
+ for (j = 0, i--; i > j; i--, j++) {
+ (void) SWAP(str[j], str[i]);
+ }
+ return (str);
}
#endif
@@ -568,26 +568,26 @@ char *
strsep(char **str, register char *sep)
{
- register char *s = *str;
- char *sptr;
-
- D_STRINGS(("strsep(%s, %s) called.\n", *str, sep));
- sptr = s;
- for (; *s && !strchr(sep, *s); s++);
- if (!*s) {
- if (s != sptr) {
- *str = s;
- D_STRINGS(("Reached end of string with token \"%s\" in buffer\n", sptr));
- return (sptr);
- } else {
- D_STRINGS(("Reached end of string\n"));
- return ((char *) NULL);
- }
- }
- *s = 0;
- *str = s + 1;
- D_STRINGS(("Got token \"%s\", *str == \"%s\"\n", sptr, *str));
- return (sptr);
+ register char *s = *str;
+ char *sptr;
+
+ D_STRINGS(("strsep(%s, %s) called.\n", *str, sep));
+ sptr = s;
+ for (; *s && !strchr(sep, *s); s++);
+ if (!*s) {
+ if (s != sptr) {
+ *str = s;
+ D_STRINGS(("Reached end of string with token \"%s\" in buffer\n", sptr));
+ return (sptr);
+ } else {
+ D_STRINGS(("Reached end of string\n"));
+ return ((char *) NULL);
+ }
+ }
+ *s = 0;
+ *str = s + 1;
+ D_STRINGS(("Got token \"%s\", *str == \"%s\"\n", sptr, *str));
+ return (sptr);
}
#endif
@@ -595,154 +595,154 @@ char *
garbage_collect(char *buff, size_t len)
{
- register char *tbuff = buff, *pbuff = buff;
- register unsigned long i, j;
+ register char *tbuff = buff, *pbuff = buff;
+ register unsigned long i, j;
- D_STRINGS(("Garbage collecting on %lu bytes at %10.8p\n", len, buff));
- for (i = 0, j = 0; j < len; j++)
- if (pbuff[j])
- tbuff[i++] = pbuff[j];
- tbuff[i++] = '\0';
- D_STRINGS(("Garbage collecting gives: \n%s\n", buff));
- return ((char *) REALLOC(buff, sizeof(char) * i));
+ D_STRINGS(("Garbage collecting on %lu bytes at %10.8p\n", len, buff));
+ for (i = 0, j = 0; j < len; j++)
+ if (pbuff[j])
+ tbuff[i++] = pbuff[j];
+ tbuff[i++] = '\0';
+ D_STRINGS(("Garbage collecting gives: \n%s\n", buff));
+ return ((char *) REALLOC(buff, sizeof(char) * i));
}
char *
file_garbage_collect(char *buff, size_t len)
{
- register char *tbuff = buff, *pbuff = buff;
- char *tmp1, *tmp2;
- register unsigned long j;
-
- D_STRINGS(("File garbage collecting on %lu bytes at %10.8p\n", len, buff));
- for (j = 0; j < len;) {
- switch (pbuff[j]) {
- case '#':
- for (; !strchr("\r\n", pbuff[j]) && j < len; j++)
- pbuff[j] = '\0'; /* First null out the line up to the CR and/or LF */
- for (; strchr("\r\n", pbuff[j]) && j < len; j++)
- pbuff[j] = '\0'; /* Then null out the CR and/or LF */
- break;
- case '\r':
- case '\n':
- case '\f':
- case ' ':
- case '\t':
- case '\v':
- for (; isspace(pbuff[j]) && j < len; j++)
- pbuff[j] = '\0'; /* Null out the whitespace */
- break;
- default:
- /* Find the end of this line and the occurence of the
- next mid-line comment. */
- tmp1 = strpbrk(pbuff + j, "\r\n");
- tmp2 = strstr(pbuff + j, " #");
-
- /* If either is null, take the non-null one. Otherwise,
- take the lesser of the two. */
- if (!tmp1 || !tmp2) {
- tbuff = ((tmp1) ? (tmp1) : (tmp2));
- } else {
- tbuff = ((tmp1 < tmp2) ? (tmp1) : (tmp2));
- }
-
- /* Now let j catch up so that pbuff+j = tbuff; i.e., let
- pbuff[j] refer to the same character that tbuff does */
- j += tbuff - (pbuff + j);
-
- /* Finally, change whatever is at pbuff[j] to a newline.
- This will accomplish several things at once:
- o It will change a \r to a \n if that's what's there
- o If it's a \n, it'll stay the same. No biggie.
- o If it's a space, it will end the line there and the
- next line will begin with a comment, which is handled
- above. */
- if (j < len)
- pbuff[j++] = '\n';
-
- }
- }
-
- /* Change all occurances of a backslash followed by a newline to nulls
- and null out all whitespace up to the next non-whitespace character.
- This handles support for breaking a string across multiple lines. */
- for (j = 0; j < len; j++) {
- if (pbuff[j] == '\\' && pbuff[j + 1] == '\n') {
- pbuff[j++] = '\0';
- for (; isspace(pbuff[j]) && j < len; j++)
- pbuff[j] = '\0'; /* Null out the whitespace */
- }
- }
-
- /* And the final step, garbage collect the buffer to condense all
- those nulls we just put in. */
- return (garbage_collect(buff, len));
+ register char *tbuff = buff, *pbuff = buff;
+ char *tmp1, *tmp2;
+ register unsigned long j;
+
+ D_STRINGS(("File garbage collecting on %lu bytes at %10.8p\n", len, buff));
+ for (j = 0; j < len;) {
+ switch (pbuff[j]) {
+ case '#':
+ for (; !strchr("\r\n", pbuff[j]) && j < len; j++)
+ pbuff[j] = '\0'; /* First null out the line up to the CR and/or LF */
+ for (; strchr("\r\n", pbuff[j]) && j < len; j++)
+ pbuff[j] = '\0'; /* Then null out the CR and/or LF */
+ break;
+ case '\r':
+ case '\n':
+ case '\f':
+ case ' ':
+ case '\t':
+ case '\v':
+ for (; isspace(pbuff[j]) && j < len; j++)
+ pbuff[j] = '\0'; /* Null out the whitespace */
+ break;
+ default:
+ /* Find the end of this line and the occurence of the
+ next mid-line comment. */
+ tmp1 = strpbrk(pbuff + j, "\r\n");
+ tmp2 = strstr(pbuff + j, " #");
+
+ /* If either is null, take the non-null one. Otherwise,
+ take the lesser of the two. */
+ if (!tmp1 || !tmp2) {
+ tbuff = ((tmp1) ? (tmp1) : (tmp2));
+ } else {
+ tbuff = ((tmp1 < tmp2) ? (tmp1) : (tmp2));
+ }
+
+ /* Now let j catch up so that pbuff+j = tbuff; i.e., let
+ pbuff[j] refer to the same character that tbuff does */
+ j += tbuff - (pbuff + j);
+
+ /* Finally, change whatever is at pbuff[j] to a newline.
+ This will accomplish several things at once:
+ o It will change a \r to a \n if that's what's there
+ o If it's a \n, it'll stay the same. No biggie.
+ o If it's a space, it will end the line there and the
+ next line will begin with a comment, which is handled
+ above. */
+ if (j < len)
+ pbuff[j++] = '\n';
+
+ }
+ }
+
+ /* Change all occurances of a backslash followed by a newline to nulls
+ and null out all whitespace up to the next non-whitespace character.
+ This handles support for breaking a string across multiple lines. */
+ for (j = 0; j < len; j++) {
+ if (pbuff[j] == '\\' && pbuff[j + 1] == '\n') {
+ pbuff[j++] = '\0';
+ for (; isspace(pbuff[j]) && j < len; j++)
+ pbuff[j] = '\0'; /* Null out the whitespace */
+ }
+ }
+
+ /* And the final step, garbage collect the buffer to condense all
+ those nulls we just put in. */
+ return (garbage_collect(buff, len));
}
char *
condense_whitespace(char *s)
{
- register unsigned char gotspc = 0;
- register char *pbuff = s, *pbuff2 = s;
-
- D_STRINGS(("condense_whitespace(%s) called.\n", s));
- for (; *pbuff2; pbuff2++) {
- if (isspace(*pbuff2)) {
- if (!gotspc) {
- *pbuff = ' ';
- gotspc = 1;
- pbuff++;
- }
- } else {
- *pbuff = *pbuff2;
- gotspc = 0;
- pbuff++;
- }
- }
- if ((pbuff >= s) && (isspace(*(pbuff - 1))))
- pbuff--;
- *pbuff = 0;
- D_STRINGS(("condense_whitespace() returning \"%s\".\n", s));
- return (REALLOC(s, strlen(s) + 1));
+ register unsigned char gotspc = 0;
+ register char *pbuff = s, *pbuff2 = s;
+
+ D_STRINGS(("condense_whitespace(%s) called.\n", s));
+ for (; *pbuff2; pbuff2++) {
+ if (isspace(*pbuff2)) {
+ if (!gotspc) {
+ *pbuff = ' ';
+ gotspc = 1;
+ pbuff++;
+ }
+ } else {
+ *pbuff = *pbuff2;
+ gotspc = 0;
+ pbuff++;
+ }
+ }
+ if ((pbuff >= s) && (isspace(*(pbuff - 1))))
+ pbuff--;
+ *pbuff = 0;
+ D_STRINGS(("condense_whitespace() returning \"%s\".\n", s));
+ return ((char *) REALLOC(s, strlen(s) + 1));
}
char *
safe_str(register char *str, unsigned short len)
{
- register unsigned short i;
+ register unsigned short i;
- for (i = 0; i < len; i++) {
- if (iscntrl(str[i])) {
- str[i] = '.';
+ for (i = 0; i < len; i++) {
+ if (iscntrl(str[i])) {
+ str[i] = '.';
+ }
}
- }
- return (str);
+ return (str);
}
void
hex_dump(void *buff, register size_t count)
{
- register unsigned long j, k, l;
- register unsigned char *ptr;
- unsigned char buffr[9];
-
- print_error(" Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII \n");
- print_error("---------+--------+---------+-------------------------+---------\n");
- for (ptr = (unsigned char *) buff, j = 0; j < count; j += 8) {
- print_error(" %8p | %06lu | %07x | ", buff, (unsigned long) count, (unsigned int) j);
- l = ((count - j < 8) ? (count - j) : (8));
- memset(buffr, 0, 9);
- memcpy(buffr, ptr + j, l);
- for (k = 0; k < l; k++) {
- print_error("%02x ", buffr[k]);
- }
- for (; k < 8; k++) {
- print_error(" ");
- }
- print_error("| %-8s\n", safe_str((char *) buffr, l));
- }
+ register unsigned long j, k, l;
+ register unsigned char *ptr;
+ unsigned char buffr[9];
+
+ print_error(" Address | Size | Offset | 00 01 02 03 04 05 06 07 | ASCII \n");
+ print_error("---------+--------+---------+-------------------------+---------\n");
+ for (ptr = (unsigned char *) buff, j = 0; j < count; j += 8) {
+ print_error(" %8p | %06lu | %07x | ", buff, (unsigned long) count, (unsigned int) j);
+ l = ((count - j < 8) ? (count - j) : (8));
+ memset(buffr, 0, 9);
+ memcpy(buffr, ptr + j, l);
+ for (k = 0; k < l; k++) {
+ print_error("%02x ", buffr[k]);
+ }
+ for (; k < 8; k++) {
+ print_error(" ");
+ }
+ print_error("| %-8s\n", safe_str((char *) buffr, l));
+ }
}
diff --git a/src/tok.c b/src/tok.c
index f42620e..0dce086 100644
--- a/src/tok.c
+++ b/src/tok.c
@@ -29,8 +29,18 @@ static const char cvs_ident[] = "$Id$";
#include <libast_internal.h>
-/* Declaration for the spif_tok_t classname variable. */
-SPIF_DECL_CLASSNAME(tok);
+spif_const_class_t SPIF_CLASS_VAR(tok) = {
+ SPIF_DECL_CLASSNAME(tok),
+ (spif_newfunc_t) spif_tok_new,
+ (spif_memberfunc_t) spif_tok_init,
+ (spif_memberfunc_t) spif_tok_done,
+ (spif_memberfunc_t) spif_tok_del,
+ (spif_func_t) spif_tok_show,
+ (spif_func_t) spif_tok_comp,
+ (spif_func_t) spif_tok_dup,
+ (spif_func_t) spif_tok_type
+};
+
spif_tok_t
spif_tok_new(void)
@@ -84,7 +94,7 @@ spif_bool_t
spif_tok_init(spif_tok_t self)
{
spif_str_init(SPIF_STR(self));
- spif_obj_set_classname(SPIF_OBJ(self), SPIF_CLASSNAME_TYPE(tok));
+ spif_obj_set_class(SPIF_OBJ(self), & SPIF_CLASS_VAR(tok));
self->count = 0;
self->token = ((spif_str_t *) (NULL));
self->sep = SPIF_NULL_TYPE(str);
@@ -95,7 +105,7 @@ spif_bool_t
spif_tok_init_from_ptr(spif_tok_t self, spif_charptr_t old)
{
spif_str_init_from_ptr(SPIF_STR(self), old);
- spif_obj_set_classname(SPIF_OBJ(self), SPIF_CLASSNAME_TYPE(tok));
+ spif_obj_set_class(SPIF_OBJ(self), & SPIF_CLASS_VAR(tok));
self->count = 0;
self->token = ((spif_str_t *) (NULL));
self->sep = SPIF_NULL_TYPE(str);
@@ -106,7 +116,7 @@ spif_bool_t
spif_tok_init_from_fp(spif_tok_t self, FILE * fp)
{
spif_str_init_from_fp(SPIF_STR(self), fp);
- spif_obj_set_classname(SPIF_OBJ(self), SPIF_CLASSNAME_TYPE(tok));
+ spif_obj_set_class(SPIF_OBJ(self), & SPIF_CLASS_VAR(tok));
self->count = 0;
self->token = ((spif_str_t *) (NULL));
self->sep = SPIF_NULL_TYPE(str);
@@ -117,7 +127,7 @@ spif_bool_t
spif_tok_init_from_fd(spif_tok_t self, int fd)
{
spif_str_init_from_fd(SPIF_STR(self), fd);
- spif_obj_set_classname(SPIF_OBJ(self), SPIF_CLASSNAME_TYPE(tok));
+ spif_obj_set_class(SPIF_OBJ(self), & SPIF_CLASS_VAR(tok));
self->count = 0;
self->token = ((spif_str_t *) (NULL));
self->sep = SPIF_NULL_TYPE(str);
@@ -243,3 +253,35 @@ spif_tok_show(spif_tok_t self, spif_charptr_t name)
USE_VAR(name);
return TRUE;
}
+
+spif_cmp_t
+spif_tok_comp(spif_tok_t self, spif_tok_t other)
+{
+ return spif_obj_comp(SPIF_OBJ(self), SPIF_OBJ(other));
+}
+
+spif_tok_t
+spif_tok_dup(spif_tok_t self)
+{
+ spif_tok_t tmp;
+ spif_str_t tmp_str;
+ size_t i;
+
+ tmp = spif_tok_new();
+ tmp_str = spif_str_dup(SPIF_STR(self));
+ memcpy(tmp, tmp_str, SPIF_SIZEOF_TYPE(str));
+ tmp->count = self->count;
+ tmp->sep = spif_str_dup(SPIF_STR(self->sep));
+
+ tmp->token = (spif_str_t *) MALLOC(SPIF_SIZEOF_TYPE(str) * tmp->count);
+ for (i = 0; i < tmp->count; i++) {
+ tmp->token[i] = spif_str_dup(SPIF_STR(self->token[i]));
+ }
+ return tmp;
+}
+
+spif_classname_t
+spif_tok_type(spif_tok_t self)
+{
+ return (SPIF_CAST(classname) (self));
+}
diff --git a/test/.cvsignore b/test/.cvsignore
index cdc7533..f00ddf8 100644
--- a/test/.cvsignore
+++ b/test/.cvsignore
@@ -5,4 +5,4 @@ stamp-h*
*.o
.deps
.libs
-libast-test
+libast-*
diff --git a/test/perf.c b/test/perf.c
index cea73e0..bcc8b06 100644
--- a/test/perf.c
+++ b/test/perf.c
@@ -126,10 +126,15 @@ perf_strings(void)
PERF_BEGIN("split() function");
PERF_TEST( slist = split(" ", "Splitting a string on spaces"); );
+ free_array((void **) slist, 0);
PERF_TEST( slist = split(NULL, " a\t \ta a a a a a "); );
+ free_array((void **) slist, 0);
PERF_TEST( slist = split(NULL, " first \"just the second\" third \'fourth and \'\"fifth to\"gether last"); );
+ free_array((void **) slist, 0);
PERF_TEST( slist = split(NULL, "\'don\\\'t\' try this at home \"\" "); );
+ free_array((void **) slist, 0);
PERF_TEST( slist = split(":", "A:B:C:D:::E"); );
+ free_array((void **) slist, 0);
PERF_END();
PERF_ENDED("string");
@@ -140,7 +145,7 @@ int
perf_obj(void)
{
spif_obj_t testobj;
- spif_classname_t cname;
+ spif_class_t cls;
PERF_BEGIN("spif_obj_create_delete");
PERF_TEST( testobj = spif_obj_new(); );
@@ -149,7 +154,7 @@ perf_obj(void)
testobj = spif_obj_new();
PERF_BEGIN("spif_obj_get_classname");
- PERF_TEST( cname = spif_obj_get_classname(testobj); );
+ PERF_TEST( cls = spif_obj_get_class(testobj); );
PERF_END();
spif_obj_del(testobj);
@@ -161,12 +166,10 @@ int
perf_str(void)
{
spif_str_t teststr, test2str;
- spif_classname_t cname;
+ spif_class_t cls;
signed char tmp[] = "this is a test";
signed char buff[4096] = "abcde";
signed char tmp2[] = "string #1\nstring #2";
- FILE *fp;
- int fd, mypipe[2];
spif_charptr_t foo;
PERF_BEGIN("spif_str_new_del");
@@ -176,7 +179,7 @@ perf_str(void)
teststr = spif_str_new();
PERF_BEGIN("spif_obj_get_classname");
- PERF_TEST( cname = spif_obj_get_classname(SPIF_OBJ(teststr)); );
+ PERF_TEST( cls = spif_obj_get_class(SPIF_OBJ(teststr)); );
PERF_END();
spif_str_del(teststr);
@@ -207,14 +210,14 @@ perf_str(void)
PERF_TEST( spif_str_rindex(teststr, '#'); );
PERF_END();
- test2str = spif_str_new_from_ptr("ring");
+ test2str = spif_str_new_from_ptr(SPIF_CAST(charptr) "ring");
PERF_BEGIN("spif_str_find");
PERF_TEST( spif_str_find(teststr, test2str); );
PERF_END();
spif_str_del(test2str);
PERF_BEGIN("spif_str_find_from_ptr");
- PERF_TEST( spif_str_find_from_ptr(teststr, "in"); );
+ PERF_TEST( spif_str_find_from_ptr(teststr, SPIF_CAST(charptr) "in"); );
PERF_END();
spif_str_del(teststr);
@@ -237,19 +240,19 @@ perf_str(void)
PERF_END();
spif_str_del(teststr);
- teststr = spif_str_new_from_ptr("11001001");
+ teststr = spif_str_new_from_ptr(SPIF_CAST(charptr) "11001001");
PERF_BEGIN("spif_str_to_num");
PERF_TEST( spif_str_to_num(teststr, 10); );
PERF_END();
spif_str_del(teststr);
- teststr = spif_str_new_from_ptr("3.1415");
+ teststr = spif_str_new_from_ptr(SPIF_CAST(charptr) "3.1415");
PERF_BEGIN("spif_str_to_float");
PERF_TEST( spif_str_to_float(teststr); );
PERF_END();
spif_str_del(teststr);
- teststr = spif_str_new_from_ptr(" \n \r\f \t testing 1 2 3 \v\r \n");
+ teststr = spif_str_new_from_ptr(SPIF_CAST(charptr) " \n \r\f \t testing 1 2 3 \v\r \n");
PERF_BEGIN("spif_str_trim");
PERF_TEST( spif_str_trim(teststr); );
PERF_END();
@@ -269,7 +272,7 @@ int
perf_tok(void)
{
spif_tok_t testtok, test2tok;
- spif_classname_t cname;
+ spif_class_t cls;
signed char tmp[] = "I \"can\'t\" feel my legs!";
signed char tmp2[] = ":::some:seedy:colon-delimited::data";
signed char tmp3[] = "\"this is one token\" and this \'over here\' is \"another one\"";
diff --git a/test/test.c b/test/test.c
index bbb1570..d6fcaf3 100644
--- a/test/test.c
+++ b/test/test.c
@@ -209,7 +209,7 @@ int
test_obj(void)
{
spif_obj_t testobj;
- spif_classname_t cname;
+ spif_class_t cls;
TEST_BEGIN("spif_obj_new");
testobj = spif_obj_new();
@@ -217,8 +217,8 @@ test_obj(void)
TEST_PASS();
TEST_BEGIN("spif_obj_get_classname");
- cname = spif_obj_get_classname(testobj);
- TEST_FAIL_IF(cname != SPIF_CLASSNAME_TYPE(obj));
+ cls = spif_obj_get_class(testobj);
+ TEST_FAIL_IF(cls != & SPIF_CLASS_VAR(obj));
TEST_PASS();
TEST_BEGIN("spif_obj_del");
@@ -233,7 +233,7 @@ int
test_str(void)
{
spif_str_t teststr, test2str;
- spif_classname_t cname;
+ spif_class_t cls;
signed char tmp[] = "this is a test";
signed char buff[4096] = "abcde";
signed char tmp2[] = "string #1\nstring #2";
@@ -247,8 +247,8 @@ test_str(void)
TEST_PASS();
TEST_BEGIN("spif_obj_get_classname");
- cname = spif_obj_get_classname(SPIF_OBJ(teststr));
- TEST_FAIL_IF(cname != SPIF_CLASSNAME_TYPE(str));
+ cls = spif_obj_get_class(SPIF_OBJ(teststr));
+ TEST_FAIL_IF(cls != & SPIF_CLASS_VAR(str));
TEST_PASS();
TEST_BEGIN("spif_str_del");
@@ -460,7 +460,7 @@ int
test_tok(void)
{
spif_tok_t testtok, test2tok;
- spif_classname_t cname;
+ spif_class_t cls;
signed char tmp[] = "I \"can\'t\" feel my legs!";
signed char tmp2[] = ":::some:seedy:colon-delimited::data";
signed char tmp3[] = "\"this is one token\" and this \'over here\' is \"another one\"";
@@ -473,8 +473,8 @@ test_tok(void)
TEST_PASS();
TEST_BEGIN("spif_obj_get_classname");
- cname = spif_obj_get_classname(SPIF_OBJ(testtok));
- TEST_FAIL_IF(cname != SPIF_CLASSNAME_TYPE(tok));
+ cls = spif_obj_get_class(SPIF_OBJ(testtok));
+ TEST_FAIL_IF(cls != & SPIF_CLASS_VAR(tok));
TEST_PASS();
TEST_BEGIN("spif_tok_del");