Object Layer
The Object Layer implements the containers for So-o classes and instances and all the functions needed by the Object class.
The data types are defined in the file OL.h. All the code is in the file OL.c.
- #include "list.h"
- #include "alist.h"
So-o uses simple lists and associative lists.
The files list.h and alist.h declare the data types list and alist and the functions to manage them.
The code is in the files list.c and alist.c.
It's compiled in the library libso-o.a.
- typedef char *property;
- typedef char *message;
- typedef union _value {
- int i;
- long l;
- float f;
- double d;
- void *p;
- } value;
- typedef value (*method)();
- #define METHOD(f) (value (*)())f
- typedef struct _selector {
- message msg;
- method func;
- } selector;
- typedef struct _attribute {
- property name;
- value value;
- } attribute;
A property or a message is a character string terminated by a '\0'.
The data type value is a union which is used to contain all the different values a method can return.
Sending a message always returns a type value.
To assign the value returned by a message or pass it to another function, access the appropriate member of the union.
A method is a pointer to a function with a return type value.
The macron METHOD is used to cast a function which implements a message.
A selector associates a message to a method. An attribute is a property with a value.
- #define CLASS 'C'
- #define INSTANCE 'I'
- typedef struct _class {
- char type;
- const char *name;
- unsigned int revision;
- struct _class *superclass;
- list c_properties;
- list i_properties;
- alist c_messages;
- alist i_messages;
- alist attributes;
- } *class;
- typedef struct _instance {
- char type;
- class class;
- alist attributes;
- } *instance;
A class has a name and a revision number. It inherits its behavior from a superclass, except the Object class. It has properties. It implements class messages. The instances of a class have properties. They implement instance messages. The properties of a class which have a value are its attributes.
An instance belongs to a class. The properties of an instance which have a value are its attributes.
The field type is used by the interface to determine whether the object which receives a message is a class or an instance.
A class has the type CLASS. An instance has the type INSTANCE.
The Object class is the only class with a NULL superclass.
All the other classes inherit, at least, from the class Object.
All lists can be NULL.
The rest of the file OL.h declares all the functions of the Object Layer.
The functions which start with class_ deal with a class.
The functions which start with object_ deal with an instance.
IMPORTANT: In principle, all the functions of the Object Layer are private. Only the functions of the class Object and the functions of the interface of So-o can call them.
- #define CNAMEMAXLEN 64
- #define CNAMEREGEXP "^[:alpha:]?[[:alnum:]_-]{0,62}[:alnum:]?$"
CNAMEMAXLEN specifies the maximum length of a class name.
CNAMEREGEXP defines the regular expression used to validate a class name.
- class class_alloc( void ) {
- return (class)calloc( 1, sizeof ( struct _class ));
- }
class_alloc allocates the space necessary to hold a class and returns it.
- class class_init( class self, const char *cname, class superclass, unsigned int rev, property *c_props, property *i_props, selector *c_msgs, selector *i_msgs ) {
- static regex_t regexp;
- regcomp(®exp, CNAMEREGEXP, REG_EXTENDED | REG_NOSUB);
- if ( regexec(®exp, cname, 0, 0, 0) != 0 )
- return 0;
- extern class Object;
- self->type = CLASS;
- self->name = cname;
- self->revision = rev;
- self->superclass = strcmp("Object", cname) != 0 ? (superclass ? superclass : Object) : 0;
- if ( c_msgs )
- class_set_class_messages(self, c_msgs);
- if ( i_msgs )
- class_set_instance_messages(self, i_msgs);
- if ( c_props )
- class_set_class_properties(self, c_props);
- if ( i_props )
- class_set_instance_properties(self, i_props);
- return self;
- }
class_init initializes the definition of the class self.
name speficies the name of the class. name is validated with the regular expression CNAMEREGEXP.
superclass is the global reference of the superclass of the new class.
If superclass is 0, the new class inherits by default from the Object class defined by the global variable Object.
IMPORTANT: superclass must contain the address of the definiton of a constructed class.
rev gives the revision number of the class. rev is an int > 0 which can be used to differentiate successive versions of the class.
class_properties and instance_properties list the properties of the class and instances of the class.
A property is a string terminated by a '\0'.
A list of properties is an array terminated by a NULL pointer.
A NULL array defines an empty list.
class_messages and instance_messages are associative lists of messages and methods of the class and instances of the class.
A message is a string terminated by a '\0'.
A method is a function pointer cast with the macro METHOD defined in OL.h.
A selector associates a method to a message.
A list of messages and methods is an array terminated by two NULL pointers.
A NULL array defines an empty list.
- class class_new( const char *name, class superclass, unsigned revision, property *class_properties, property *instance_properties, selector *class_messages, selector *instance_messages ) {
- return class_init( class_alloc(), name, superclass, revision, class_properties, instance_properties, class_messages, instance_messages );
- }
class_new allocates the space necessary for the definition of a class, initializes it and returns it.
- void class_free( class self ) {
- if (self->c_properties)
- list_free( self->c_properties );
- if (self->i_properties)
- list_free( self->i_properties );
- if (self->c_messages)
- alist_free( self->c_messages );
- if (self->i_messages)
- alist_free( self->i_messages );
- if (self->attributes)
- alist_free( self->attributes );
- free( self );
- }
class_free frees the space allocated by self,
i.e. all the lists allocated by the class and the container of the class.
IMPORTANT: class_free doesn't free the space which might be allocated for the values of the attributes of the class.
- char *class_tostring( class self ) {
- static char s[CNAMEMAXLEN+7+1];
- sprintf(s, "class(%s)", self->name);
- return s;
- }
class_tostring returns a string representation of self, i.e. the word class followed by the name of the class between parenthesis.
IMPORTANT: The string is formatted in a static area. It must be used before this method is called again.
- instance class_make(class self) {
- return object_new( self );
- }
class_make returns of new instance of self.
- instance object_alloc( void ) {
- return (instance)calloc( 1, sizeof ( struct _instance ));
- }
object_alloc allocates the space necessary to hold an instance and returns it.
- instance object_init( instance self, class c ) {
- self->type = INSTANCE;
- self->class = c;
- return self;
- }
object_init initializes the definition of the instance self.
c is the global reference of the class of self.
- instance object_new( class c ) {
- return object_init(object_alloc(), c);
- }
object_new allocates the space necessary for the definition of an instance, initializes it and returns it.
- void object_free( instance self ) {
- if (self->attributes)
- alist_free( self->attributes );
- free( self );
- }
object_free frees the space allocated by self,
i.e. the list of attributes allocated by the instance and the container of the instance.
IMPORTANT: object_free doesn't free the space which might be allocated for the values of the attributes of the instance.
- instance object_copy(instance self) {
- instance newself = object_new(object_class(self));
- if (self->attributes)
- newself->attributes = alist_copy(self->attributes);
- return newself;
- }
object_copy returns a copy of self.
IMPORTANT: object_copy doesn't duplicate the space which might be allocated for the values of the attributes of the instance; self and its copy have independent lists of attributes which share the same values.
- char *object_tostring( instance self ) {
- static char s[CNAMEMAXLEN+8+1];
- sprintf(s, "object(%s)", self->class->name);
- return s;
- }
object_tostring returns a string representation of self, i.e. the word object followed by the name of the instance between parenthesis.
IMPORTANT: The string is formatted in a static area. It must be used before this method is called again.
The rest of the code implements all the functions of the Object Layer which are needed by the Object class.
- class_name
- Returns the name of a class.
- class_revision
- Returns the revision number of a class.
- class_superclass
- Returns the superclass of a class.
- class_class_properties
- Returns the class properties defined by a class.
- class_instance_properties
- Returns the instance properties defined by a class.
- class_class_messages
- Returns the class messages defined by a class.
- class_instance_messages
- Returns the instance messages defined by a class.
- class_set_class_properties
- Initializes the class properties of a class.
- class_set_instance_properties
- Initializes the instance properties of a class.
- class_set_class_messages
- Initializes the class messages of a class.
- class_set_instance_messages
- Initializes the instance messages of a class.
- class_add_class_message
- Adds a class message to a class.
- class_remove_class_message
- Removes a class message from a class.
- class_add_instance_message
- Adds an instance message to a class.
- class_remove_instance_message
- Removes an instance message from a class.
- class_add_class_property
- Adds a class property to a class.
- class_remove_class_property
- Removes a class property from a class.
- class_add_instance_property
- Adds an instance property to a class.
- class_remove_instance_property
- Removes an instance property from a class.
- class_attributes
- Returns the values of the properties of a class.
- class_set_attributes
- Initializes the values of the properties of a class.
- class_is_kind_of
- Checks if a class is a subclass of another class.
- class_get
- Returns the value of a property of a class.
- class_set
- Modifies the value of a property of a class.
- object_class
- Returns the class of an instance.
- object_superclass
- Returns the superclass of an instance.
- object_assume
- Changes the class of an instance.
- object_attributes
- Returns the values of the properties of an instance.
- object_set_attributes
- Initializes the values of the properties of an instance.
- object_get
- Returns the value of a property of an instance.
- object_set
- Initializes the value of a property of an instance.
- class_find_class_property
- Checks if a class property of a class exists.
- class_find_instance_property
- Checks if an instance property of a class exists.
- class_find_class_method_class
- Returns the class which implements a class message.
- class_find_class_method
- Returns the function which implements a class message.
- class_find_instance_method_class
- Returns the class which implements an instance message.
- class_find_instance_method
- Returns the function which implements an instance message.
- class_send_message
- Executes a class message.
- class_super_send_message
- Executes a class message inherited from a superclass.
- object_send_message
- Executes an instance message.
- object_super_send_message
- Executes an instance message inherited from a superclass.
Comments