1 /*
2  * Copyright (C) 1997-2004, Michael Jennings
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies of the Software, its documentation and marketing & publicity
13  * materials, and acknowledgment shall be given in the documentation, materials
14  * and software packages that this Software was used.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 /**
25  * @file obj.c
26  * LibAST Object Infrastructure -- Generic Objects
27  *
28  * This file contains the basic object class.
29  *
30  * @author Michael Jennings <mej@eterm.org>
31  * $Revision: 1.27 $
32  * $Date: 2004/07/23 21:38:39 $
33  */
34 
35 static const char __attribute__((unused)) cvs_ident[] = "$Id: obj.c,v 1.27 2004/07/23 21:38:39 mej Exp $";
36 
37 #ifdef HAVE_CONFIG_H
38 # include <config.h>
39 #endif
40 
41 #include <libast_internal.h>
42 
43 /* *INDENT-OFF* */
44 /**
45  * The actual class structure for the @c obj type.
46  *
47  * This structure is the actual class for the @c obj type.  All LibAST
48  * objects contain a spif_class_t member called @c cls which points to
49  * a class structure, like this one.  The first structure member is a
50  * pointer to the class name.  Each class uses the same pointer, so
51  * you can compare the pointer values rather than having to compare
52  * strings.  All other members are function pointers which reference
53  * the object-agnostic routines that object supports.  ALL LibAST
54  * objects support at least 8 operations:  new, init, done, del, show,
55  * comp, dup, and type.  Other classes may define other standard
56  * functions.  (This is used for doing interface classes.)
57  *
58  * @see @link DOXGRP_OBJ LibAST Object Infrastructure @endlink
59  * @ingroup DOXGRP_OBJ
60  */
61 static SPIF_CONST_TYPE(class) o_class = {
62     SPIF_DECL_CLASSNAME(obj),
63     (spif_func_t) spif_obj_new,
64     (spif_func_t) spif_obj_init,
65     (spif_func_t) spif_obj_done,
66     (spif_func_t) spif_obj_del,
67     (spif_func_t) spif_obj_show,
68     (spif_func_t) spif_obj_comp,
69     (spif_func_t) spif_obj_dup,
70     (spif_func_t) spif_obj_type
71 };
72 
73 /**
74  * The class instance for the @c obj type.
75  *
76  * This defines the spif_class_t for the @c obj type so that it points
77  * to the spif_const_class_t structure above.  This pointer value is
78  * the very first thing stored in each * instance of an "obj."
79  *
80  * @see @link DOXGRP_OBJ LibAST Object Infrastructure @endlink
81  * @ingroup DOXGRP_OBJ
82  */
83 SPIF_TYPE(class) SPIF_CLASS_VAR(obj) = &o_class;
84 /* *INDENT-ON* */
85 
86 
87 
88 /*@{*/
89 /**
90  * @name Generic Object Member Functions
91  * ---
92  *
93  * These functions are members of the @c obj class.  They can be
94  * called directly or via the macros which dereference the function
95  * pointers in the @c obj class structure.  By convention, functions
96  * are called directly when the object type is known and via macros
97  * when the type is unknown.
98  *
99  * Most of these functions are not intended to actually be called.
100  * Rather, they serve as models for the implementation of standard
101  * methods in other (derived) object types.
102  *
103  * @ingroup DOXGRP_OBJ
104  */
105 
106 /**
107  * Create a new @c obj instance.
108  *
109  * This function creates and returns a new instance of an @c obj.  The
110  * new instance is initialized using the spif_obj_init() function.
111  *
112  * @return A new @c obj instance.
113  *
114  * @see @link DOXGRP_OBJ LibAST Object Infrastructure @endlink
115  */
116 spif_obj_t
spif_obj_new(void)117 spif_obj_new(void)
118 {
119     spif_obj_t self;
120 
121     self = SPIF_ALLOC(obj);
122     if (!spif_obj_init(self)) {
123         SPIF_DEALLOC(self);
124         self = SPIF_NULL_TYPE(obj);
125     }
126     return self;
127 }
128 
129 /**
130  * Delete an @c obj instance.
131  *
132  * This function deletes an instance of an @c obj.  The done method,
133  * spif_obj_done(), is called to free any object resources prior to
134  * deallocation of the object itself.
135  *
136  * @param self The @c obj instance to be deleted.
137  * @return     #TRUE if successful, #FALSE otherwise.
138  *
139  * @see @link DOXGRP_OBJ LibAST Object Infrastructure @endlink
140  * @ingroup DOXGRP_OBJ
141  */
142 spif_bool_t
spif_obj_del(spif_obj_t self)143 spif_obj_del(spif_obj_t self)
144 {
145     spif_bool_t t;
146 
147     ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), FALSE);
148 
149     t = spif_obj_done(self);
150     SPIF_DEALLOC(self);
151     return t;
152 }
153 
154 /**
155  * Initialize an @c obj instance.
156  *
157  * This function initializes the member variables of the @c obj
158  * instance to their appropriate "bootstrap" values.
159  *
160  * @note Though the calling of the parent's initializer is customary
161  * and proper in derived classes, for subtypes of @c obj, this is not
162  * strictly necessary.  All this function does is set the class to
163  * that of an @c obj, which the child must undo anyway (by calling
164  * <tt>spif_obj_set_class(self, SPIF_CLASS_VAR(XXX))</tt>, where
165  * <tt>XXX</tt> is the class name, like below).  Thus, it is
166  * acceptable for direct decendents of @c obj to not call this
167  * function.  However, anything whose parent type is @a not @c obj
168  * MUST call their parent's init function.
169  *
170  * @param self The @c obj instance to be initialized.
171  * @return     #TRUE if successful, #FALSE otherwise.
172  *
173  * @see @link DOXGRP_OBJ LibAST Object Infrastructure @endlink
174  * @ingroup DOXGRP_OBJ
175  */
176 spif_bool_t
spif_obj_init(spif_obj_t self)177 spif_obj_init(spif_obj_t self)
178 {
179     ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), FALSE);
180     spif_obj_set_class(self, SPIF_CLASS_VAR(obj));
181     return TRUE;
182 }
183 
184 /**
185  * Deallocate and reinitialize @c obj resources.
186  *
187  * This function frees up any object resources and re-initializes them
188  * to their "bootstrap" values.
189  *
190  * @param self The @c obj instance to be zeroed and reinitialized.
191  * @return     #TRUE if successful, #FALSE otherwise.
192  *
193  * @see @link DOXGRP_OBJ LibAST Object Infrastructure @endlink
194  * @ingroup DOXGRP_OBJ
195  */
196 spif_bool_t
spif_obj_done(spif_obj_t self)197 spif_obj_done(spif_obj_t self)
198 {
199     ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), FALSE);
200     return TRUE;
201 }
202 
203 /**
204  * Show an object and its contents.
205  *
206  * This function, as it is written here, doesn't do a whole hell of a
207  * lot.  But this standard member function (i.e., all objects must
208  * have one) provides the mechanism for which an object can display
209  * not only itself and its particular values, but those of any parent
210  * class or member object.  Besides the object to be displayed, this
211  * function is passed the variable name for that object (usually a
212  * constant string, like "foo"), a @c str object, possibly NULL, to be
213  * added to and returned, and an indent level, possibly 0, to
214  * represent how many leading spaces should pad the resulting output.
215  * The @c str object returned is either @a buff, or a new @c str if @a
216  * buff was passed as NULL.  Appended to it will be the description of
217  * the object followed by a newline.  This description may include
218  * descriptions of any number of child variables, parent objects, etc.
219  *
220  * Implementing this function properly is key to simplifying the
221  * examination of objects through the use of debugging code.  I @b
222  * highly recommend looking at some examples of how this function
223  * should be implemented.
224  *
225  * The simplest way to display an object is to use the SPIF_SHOW()
226  * macro.  This macro takes the object (@a self) and a file descriptor
227  * (like @c stderr or #LIBAST_DEBUG_FD), calls the object's @c show
228  * method, and prints the resulting string on the given file
229  * descriptor, freeing it afterward.  No muss, no fuss.
230  *
231  * @param self   The @c obj instance.
232  * @param name   The name of the variable passed as @a self.
233  * @param buff   A @c str object, possibly NULL, used as the buffer.
234  * @param indent The number of spaces with which to pad the line.
235  * @return       The @c str object, or a new one if @a buff was NULL,
236  *               describing @a self.
237  *
238  * @see @link DOXGRP_OBJ LibAST Object Infrastructure @endlink, SPIF_SHOW()
239  * @ingroup DOXGRP_OBJ
240  */
241 spif_str_t
spif_obj_show(spif_obj_t self,spif_charptr_t name,spif_str_t buff,size_t indent)242 spif_obj_show(spif_obj_t self, spif_charptr_t name, spif_str_t buff, size_t indent)
243 {
244     spif_char_t tmp[4096];
245 
246     if (SPIF_OBJ_ISNULL(self)) {
247         SPIF_OBJ_SHOW_NULL(obj, name, buff, indent, tmp);
248         return buff;
249     }
250 
251     memset(tmp, ' ', indent);
252     snprintf(SPIF_CAST_C(char *) tmp + indent, sizeof(tmp) - indent,
253              "(spif_obj_t) %s:  %10p \"%s\"\n",
254              name, SPIF_CAST(ptr) self, SPIF_OBJ_CLASSNAME(self));
255     if (SPIF_STR_ISNULL(buff)) {
256         buff = spif_str_new_from_ptr(tmp);
257     } else {
258         spif_str_append_from_ptr(buff, tmp);
259     }
260     return buff;
261 }
262 
263 /**
264  * Compare two objects.
265  *
266  * As with most of the other member functions of the @c obj class,
267  * this one is really just a placeholder.  The @c comp standard member
268  * function is used to compare two objects of a given type.  The
269  * comparison can be implemented in any way, so long as it returns a
270  * consistent spif_cmp_t value.  The simplest way is to compare the
271  * two object variables, as shown below, but often a more sensible
272  * method is warranted.
273  *
274  * @param self  The first @c obj instance.
275  * @param other The second @c obj instance.
276  * @return      A spif_cmp_t value representing the comparison of @a
277  *              self and @a other.
278  *
279  * @see @link DOXGRP_OBJ LibAST Object Infrastructure @endlink, spif_str_comp(), spif_cmp_t, SPIF_CMP_FROM_INT()
280  * @ingroup DOXGRP_OBJ
281  */
282 spif_cmp_t
spif_obj_comp(spif_obj_t self,spif_obj_t other)283 spif_obj_comp(spif_obj_t self, spif_obj_t other)
284 {
285     SPIF_OBJ_COMP_CHECK_NULL(self, other);
286     return SPIF_CMP_FROM_INT(SPIF_CAST(ulong) self - SPIF_CAST(ulong) other);
287 }
288 
289 /**
290  * Duplicate an @c obj and its resources.
291  *
292  * The @c dup standard member function is responsible for returning a
293  * new object instance which contains the exact same value as the
294  * instance supplied to it.  That means that any values are copied
295  * from the original to the duplicate, and any references (pointers
296  * and objects) are duplicated in the new instance, using MALLOC(),
297  * the member object's @c dup function, etc.  The object returned MUST
298  * be independent of the original; i.e., calling @c done or @c del on
299  * the duplicate MUST NOT destroy or affect the original, or any of
300  * its data, in any way.
301  *
302  * @param self The @c obj instance.
303  * @return     An exact duplicate of @a self which is identical to,
304  *             but programmatically independent of, the original.
305  *
306  * @see @link DOXGRP_OBJ LibAST Object Infrastructure @endlink, spif_str_dup()
307  * @ingroup DOXGRP_OBJ
308  */
309 spif_obj_t
spif_obj_dup(spif_obj_t self)310 spif_obj_dup(spif_obj_t self)
311 {
312     spif_obj_t tmp;
313 
314     ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), SPIF_NULL_TYPE(obj));
315     tmp = spif_obj_new();
316     memcpy(tmp, self, SPIF_SIZEOF_TYPE(obj));
317     return tmp;
318 }
319 
320 /**
321  * Obtain the class name of an @c obj.
322  *
323  * The @c type standard member function is responsible for returning
324  * the class name (as a spif_classname_t) of the supplied object.  You
325  * will almost certainly want to implement it exactly as seen here.
326  * If you don't, know why.
327  *
328  * @param self The @c obj instance.
329  * @return     The class name of @a self.
330  *
331  * @see @link DOXGRP_OBJ LibAST Object Infrastructure @endlink
332  * @ingroup DOXGRP_OBJ
333  */
334 spif_classname_t
spif_obj_type(spif_obj_t self)335 spif_obj_type(spif_obj_t self)
336 {
337     ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), SPIF_NULL_TYPE(classname));
338     return SPIF_OBJ_CLASSNAME(self);
339 }
340 
341 /**
342  * Return the class of an object.
343  *
344  * This function returns the class (i.e., spif_class_t) of the
345  * supplied @c obj instance.  Thanks to the Magic and Mystery of
346  * typecasting, any LibAST object can be passed to this function to
347  * obtain its class information, like so:
348  * <tt>spif_obj_get_class(SPIF_OBJ(foo))</tt>  Or, simply use the
349  * SPIF_OBJ_CLASS() macro.
350  *
351  * Keep in mind that this will return the @a entire class.  If you
352  * simply want the class name string, use SPIF_OBJ_CLASSNAME()
353  * instead.
354  *
355  * @param self The @c obj instance.
356  * @return     The object's class, or NULL if @a self is NULL.
357  *
358  * @see @link DOXGRP_OBJ LibAST Object Infrastructure @endlink
359  * @ingroup DOXGRP_OBJ
360  */
361 spif_class_t
spif_obj_get_class(spif_obj_t self)362 spif_obj_get_class(spif_obj_t self)
363 {
364     ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), SPIF_NULL_TYPE(class));
365     return SPIF_OBJ_CLASS(self);
366 }
367 
368 /**
369  * Set an object's class.
370  *
371  * This function sets the class (i.e., spif_class_t) of the supplied
372  * @c obj instance.  Thanks to the Magic and Mystery of typecasting,
373  * any LibAST object can be passed to this function to set its class
374  * information, like so: <tt>spif_obj_set_class(SPIF_OBJ(foo),
375  * SPIF_CLASS_VAR(XXX))</tt>, where <tt>XXX</tt> is the actual type of
376  * the object (like @c str or @c regexp).  Any call to the @c init
377  * member of a parent class MUST be immediately followed by a call to
378  * this function like the one above.  Failure to do so results in
379  * inaccurate class typing information, which kinda defeats the whole
380  * point, ya know?
381  *
382  * @param self The @c obj instance.
383  * @param cls  The @c class for the given instance.
384  * @return     #TRUE if successful, #FALSE otherwise.
385  *
386  * @see @link DOXGRP_OBJ LibAST Object Infrastructure @endlink
387  * @ingroup DOXGRP_OBJ
388  */
389 spif_bool_t
spif_obj_set_class(spif_obj_t self,spif_class_t cls)390 spif_obj_set_class(spif_obj_t self, spif_class_t cls)
391 {
392     ASSERT_RVAL(!SPIF_OBJ_ISNULL(self), FALSE);
393     self->cls = cls;
394     return TRUE;
395 }
396 
397 /*@}*/
398 
399 
400 
401 /**
402  * @defgroup DOXGRP_OBJ LibAST Object Infrastructure
403  *
404  * This group of types, functions, and pre-processor macros implements
405  * a mechanism for defining and utilizing objects in native C.
406  *
407  * C, as you well know, is a procedural language.  It has no native
408  * facilities for doing object-oriented programming.  And thusly was
409  * born C++ -- native object facilities with much of the same C syntax
410  * we all know and love.  But C++ has one very big (and fatal, IMHO)
411  * flaw:  it requires a special compiler.
412  *
413  * That in and of itself is not the end of the world, but it does
414  * create a number of issues in terms of portability, standardization,
415  * speed, and efficiency.  Since C has been around for so much longer,
416  * most C compilers are very stable and reliable, and their
417  * optimization routines often do almost as good a job as writing raw
418  * assembly code (particularly the vendor compilers).  C++ offers none
419  * of these types of advantages, and C++ compiler availability has
420  * historically been sketchy at best.
421  *
422  * There are really 2 possible solutions to this, both accomplishing
423  * the same end result (using the native C compiler to manipulate an
424  * object model and hierarchy) in two similar, but distinct, ways.
425  * Both approaches require the use of some sort of preprocessor.
426  * Option #1 would be to use a dedicated preprocessor, either
427  * something like m4 or a new creation.  This option would probably
428  * allow for cleaner, more native-looking syntax, but it has similar
429  * (and potentially worse) portability problems to those of C++.
430  *
431  * For these reasons, I chose option #2:  a CPP-based (i.e.,
432  * macro-based) object model.  As you might imagine, the syntax and
433  * usage of such a model bears almost no resemblence whatsoever to
434  * that of a native OO language, as it relies heavily on type-casting
435  * and namespace safety measures implemented within the existing C/CPP
436  * structure.  However, the resultant code is native C, which means
437  * you can manipulate data using OO techniques like inheritance,
438  * interface classes, etc., without incurring the speed/portability
439  * penalties of using the C++ compiler.  Plus, you can build libraries
440  * that can be easily linked to both C and C++ programs.
441  *
442  * If you'd like to see a sample program which demonstrates creation
443  * and management of LibAST objects, please look here:
444  * @link obj_example.c @endlink.
445  */
446 
447 /**
448  * @example obj_example.c
449  * Example code for using the LibAST Object Infrastructure
450  *
451  * This is a contrived, but informational, example of using LibAST's
452  * object system.  MORE HERE
453  *
454  * Here's the complete source code:
455  */
456