Browse Source

Add objects

Andrew Young 8 years ago
parent
commit
16e006c904
9 changed files with 466 additions and 22 deletions
  1. 1 0
      .gitignore
  2. 1 1
      src/Makefile.am
  3. 224 0
      src/object.c
  4. 68 0
      src/object.h
  5. 9 5
      tests/Makefile.am
  6. 133 0
      tests/check_objects.c
  7. 20 0
      tests/check_org-merge-driver.c
  8. 9 0
      tests/check_org-merge-driver.h
  9. 1 16
      tests/check_parser.c

+ 1 - 0
.gitignore

@@ -17,3 +17,4 @@ stamp-h1
 
 # temporary emacs files
 *~
+#*#

+ 1 - 1
src/Makefile.am

@@ -5,7 +5,7 @@ BUILT_SOURCES = org_parser.h org_lexer.h
 AM_YFLAGS = -d
 AM_LFLAGS = 
 
-org_merge_driver_SOURCES = org_parser.y org_lexer.l main.c
+org_merge_driver_SOURCES = org_parser.y org_lexer.l main.c object.c
 
 org_lexer.h: org_lexer.l
 	lex $^

+ 224 - 0
src/object.c

@@ -0,0 +1,224 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "object.h"
+#include "object.r"
+
+static void *
+Object_ctor (void * _self, va_list * app)
+{
+  return _self;
+}
+
+static void *
+Object_dtor (void * _self)
+{
+  return _self;
+}
+
+static int
+Object_differ (const void * _self, const void * b)
+{
+  return _self != b;
+}
+
+static int
+Object_puto (const void * _self, FILE * fp)
+{	
+  const struct Class * class = classOf(_self);
+
+  return fprintf(fp, "%s at %p\n", class -> name, _self);
+}
+
+const void *
+classOf (const void * _self)
+{	
+  const struct Object * self = _self;
+
+  assert(self && self -> class);
+  return self -> class;
+}
+
+size_t
+sizeOf (const void * _self)
+{
+  const struct Class * class = classOf(_self);
+  return class -> size;
+}
+
+/*
+ *	Class
+ */
+
+static void *
+Class_ctor (void * _self, va_list * app)
+{
+  struct Class * self = _self;
+  const size_t offset = offsetof(struct Class, ctor);
+
+  self -> name = va_arg(* app, char *);
+  self -> super = va_arg(* app, struct Class *);
+  self -> size = va_arg(* app, size_t);
+
+  assert(self -> super);
+
+  memcpy((char *) self + offset, (char *) self -> super
+	 + offset, sizeOf(self -> super) - offset);
+  {
+    typedef void (* voidf) ();	/* generic function pointer */
+    voidf selector;
+
+    while ((selector = va_arg(*app, voidf)))
+      {
+	voidf method = va_arg(*app, voidf);
+
+	if (selector == (voidf) ctor)
+	  * (voidf *) & self -> ctor = method;
+	else if (selector == (voidf) dtor)
+	  * (voidf *) & self -> dtor = method;
+	else if (selector == (voidf) differ)
+	  * (voidf *) & self -> differ = method;
+	else if (selector == (voidf) puto)
+	  * (voidf *) & self -> puto = method;
+      }
+
+    return self;
+  }
+}
+
+static void *
+Class_dtor (void * _self)
+{
+  struct Class * self = _self;
+
+  fprintf(stderr, "%s: cannot destroy class\n", self->name);
+  return 0;
+}
+
+const void *
+super (const void * _self)
+{	const struct Class * self = _self;
+
+  assert(self && self -> super);
+  return self -> super;
+}
+
+/*
+ *	initialization
+ */
+
+static const struct Class object [] = {
+  { { object + 1 },
+    "Object", object, sizeof(struct Object),
+    Object_ctor, Object_dtor, Object_differ, Object_puto
+  },
+  { { object + 1 },
+    "Class", object, sizeof(struct Class),
+    Class_ctor, Class_dtor, Object_differ, Object_puto
+  }
+};
+
+const void * Object = object;
+const void * Class = object + 1;
+
+/*
+ *	object management and selectors
+ */
+
+void *
+new (const void * _class, ...)
+{	
+  const struct Class * class = _class;
+  struct Object * object;
+  va_list ap;
+
+  assert(class && class -> size);
+  object = calloc(1, class -> size);
+  assert(object);
+  object -> class = class;
+  va_start(ap, _class);
+  object = ctor(object, & ap);
+  va_end(ap);
+  return object;
+}
+
+void
+delete (void * _self)
+{
+  if (_self)
+    free(dtor(_self));
+}
+
+void *
+ctor (void * _self, va_list * app)
+{	
+  const struct Class * class = classOf(_self);
+
+  assert(class -> ctor);
+  return class -> ctor(_self, app);
+}
+
+void *
+super_ctor (const void * _class,
+		   void * _self, va_list * app)
+{	
+  const struct Class * superclass = super(_class);
+
+  assert(_self && superclass -> ctor);
+  return superclass -> ctor(_self, app);
+}
+
+void *
+dtor (void * _self)
+{	
+  const struct Class * class = classOf(_self);
+
+  assert(class -> dtor);
+  return class -> dtor(_self);
+}
+
+void *
+super_dtor (const void * _class, void * _self)
+{	
+  const struct Class * superclass = super(_class);
+
+  assert(_self && superclass -> dtor);
+  return superclass -> dtor(_self);
+}
+
+int
+differ (const void * _self, const void * b)
+{	
+  const struct Class * class = classOf(_self);
+
+  assert(class -> differ);
+  return class -> differ(_self, b);
+}
+
+int
+super_differ (const void * _class, const void * _self, const void * b)
+{	
+  const struct Class * superclass = super(_class);
+
+  assert(_self && superclass -> differ);
+  return superclass -> differ(_self, b);
+}
+
+int
+puto (const void * _self, FILE * fp)
+{	
+  const struct Class * class = classOf(_self);
+
+  assert(class -> puto);
+  return class -> puto(_self, fp);
+}
+
+int
+super_puto (const void * _class, const void * _self, FILE * fp)
+{	
+  const struct Class * superclass = super(_class);
+
+  assert(_self && superclass -> puto);
+  return superclass -> puto(_self, fp);
+}

+ 68 - 0
src/object.h

@@ -0,0 +1,68 @@
+/**
+ */
+#ifndef	OBJECT_H
+#define	OBJECT_H
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+
+/**
+ * @class Object
+ * @brief The base object from which all objects inherit.
+ */
+extern const void * Object;		/* new(Object); */
+
+/**
+ * @class Object
+ * @fn Object *new(void *Object);
+ * @brief Create an new Object.
+ * @param Object The object class.
+ * @return An Object pointer.
+ */
+void * new (const void * class, ...);
+
+/**
+ * @brief Delete any object.
+ * @param self A pointer to the instance to be deleted.
+ */
+void delete (void * self);
+
+/**
+ * @brief Return the class sof any object.
+ * @param self The object.
+ * @return A pointer to the class
+ */
+const void * classOf (const void * self);
+
+/**
+ * @brief
+size_t sizeOf (const void * self);
+
+void * ctor (void * self, va_list * app);
+void * dtor (void * self);
+int differ (const void * self, const void * b);
+int puto (const void * self, FILE * fp);
+
+/* new(Class, "name", super, size, sel, meth, ... 0); */
+/**
+ * @class Class
+ * @brief The base object from which all classes inherit
+ */
+extern const void * Class;
+
+/**
+ * @fn Class * new(void* Class, char *name, void *super, size_t size, meth, voidf *fnc, ... 0)
+ * @brief Create a new Class.
+ * @param Class Pointer to Class.
+ * @param name The name of the class.
+ * @param super The class which this class inherits from.  Should be Class for those that do not inherit from user defined classes.
+ * @param size The size of class structure.
+ * @param meth A pointer to a method to be overidden.
+ * @param fnc The new function.
+ * @return A pointer to a new class.
+ */
+
+const void * super (const void * self);	/* class' superclass */
+
+#endif

+ 9 - 5
tests/Makefile.am

@@ -1,8 +1,12 @@
 ## Process this file with automake to produce Makefile.in
-TESTS = check_parser
-check_PROGRAMS = check_parser
+TESTS = check_org-merge-driver
+check_PROGRAMS = check_org-merge-driver
 
 ## Check Parser
-check_parser_SOURCES = check_parser.c
-check_parser_CFLAGS = @CHECK_CFLAGS@
-check_parser_LDADD = @CHECK_LIBS@
+check_org_merge_driver_SOURCES = \
+	check_org-merge-driver.c \
+	check_objects.c \
+	check_parser.c
+
+check_org_merge_driver_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/src 
+check_org_merge_driver_LDADD = @CHECK_LIBS@

+ 133 - 0
tests/check_objects.c

@@ -0,0 +1,133 @@
+#include <stdlib.h>
+#include <check.h>
+#include "object.c"
+
+static int state=0;
+
+static void *
+Empty_ctor (void * _self, va_list * app)
+{
+  state+=1;
+  return _self;
+}
+
+static void *
+Empty_dtor (void * _self)
+{
+  state+=1;
+  return _self;
+}
+
+START_TEST (new_object_call_constructor)
+{
+  struct Empty
+  {
+    const struct Object _;
+  };
+  struct EmptyClass
+  {
+    const struct Class _;
+  };
+  void * EmptyClass = new(Class, "EmptyClass",
+			  Class, sizeof(struct EmptyClass),
+			  0);
+  void * Empty = new(EmptyClass, "Empty",
+		     Object, sizeof(struct Empty),
+		     ctor, Empty_ctor,
+		     0);
+  state = 0;
+  void *e = new(Empty);
+  fail_if(state != 1);
+  delete(e);
+}
+END_TEST
+
+START_TEST (delete_object_call_destructor)
+{
+  struct Empty
+  {
+    const struct Object _;
+  };
+  struct EmptyClass
+  {
+    const struct Class _;
+  };
+  void * EmptyClass = new(Class, "EmptyClass",
+			  Class, sizeof(struct EmptyClass),
+			  0);
+  void * Empty = new(EmptyClass, "Empty",
+		     Object, sizeof(struct Empty),
+		     ctor, Empty_dtor,
+		     0);
+  state = 0;
+  void *e = new(Empty);
+  delete(e);
+  fail_if(state != 1);
+}
+END_TEST
+
+START_TEST(delete_class_stop_from_destroying)
+{
+  struct Empty
+  {
+    const struct Object _;
+  };
+  struct EmptyClass
+  {
+    const struct Class _;
+  };
+  void * EmptyClass = new(Class, "EmptyClass",
+			  Class, sizeof(struct EmptyClass),
+			  0);
+  delete (EmptyClass);
+  /* should fail if the test was deleted */
+  void * Empty = new(EmptyClass, "Empty",
+		     Object, sizeof(struct Empty),
+		     dtor, Empty_dtor,
+		     0);
+  fail_if (Empty==0);
+}
+END_TEST
+
+START_TEST(differ_different_classes_differ)
+{
+  void * AClass = new(Class, "AClass",
+		      Class, sizeof(struct Class),
+		      0);
+  void * BClass = new(Class, "BClass",
+		      Class, sizeof(struct Class),
+		      0);
+  void * A = new(AClass, "A",
+		 Object, sizeof(struct Object),
+		 0);
+  void * B = new(BClass, "B",
+		 Object, sizeof(struct Object),
+		 0);
+
+  fail_unless (differ (A, B));
+}
+END_TEST
+
+START_TEST(differ_same_classes_do_not_differ)
+{
+  void * A = new(Class, "A",
+		 Class, sizeof(struct Class),
+		 0);
+  fail_if (differ (A, A));
+}
+END_TEST
+
+Suite *
+make_object_suite (void)
+{
+  Suite *s = suite_create ("Object");
+  /* Core test case */
+  TCase *tc_core = tcase_create ("Core");
+  tcase_add_test (tc_core, new_object_call_constructor);
+  tcase_add_test (tc_core, delete_object_call_destructor);
+  tcase_add_test (tc_core, delete_class_stop_from_destroying);
+  tcase_add_test (tc_core, differ_different_classes_differ);
+  tcase_add_test (tc_core, differ_same_classes_do_not_differ);
+  suite_add_tcase (s, tc_core);
+  return s;
+}

+ 20 - 0
tests/check_org-merge-driver.c

@@ -0,0 +1,20 @@
+#include "check_org-merge-driver.h"
+#include <check.h>
+#include <stdlib.h>
+
+int
+main (void)
+{
+  int number_failed;
+
+  SRunner *sr = srunner_create (make_parser_suite ());
+  srunner_add_suite (sr, make_object_suite());
+
+  srunner_run_all (sr, CK_NORMAL);
+  number_failed = srunner_ntests_failed (sr);
+  srunner_free (sr);
+
+  return (number_failed == 0) 
+    ? EXIT_SUCCESS
+    : EXIT_FAILURE;
+}

+ 9 - 0
tests/check_org-merge-driver.h

@@ -0,0 +1,9 @@
+#ifndef CHECK_ORG_MERGE_DRIVER_H
+#define CHECK_ORG_MERGE_DRIVER_H
+
+#include <check.h>
+ 
+Suite * make_parser_suite (void);
+Suite * make_object_suite (void);
+
+#endif

+ 1 - 16
tests/check_parser.c

@@ -8,7 +8,7 @@ START_TEST (parser_check)
 END_TEST
 
 Suite *
-parser_suite (void)
+make_parser_suite (void)
 {
   Suite *s = suite_create ("Parsing");
   /* Core test case */
@@ -17,18 +17,3 @@ parser_suite (void)
   suite_add_tcase (s, tc_core);
   return s;
 }
-
-int
-main (void)
-{
-  int number_failed;
-  Suite *s = parser_suite ();
-  SRunner *sr = srunner_create (s);
-  srunner_run_all (sr, CK_NORMAL);
-  number_failed = srunner_ntests_failed (sr);
-  srunner_free (sr);
-
-  return (number_failed == 0) 
-    ? EXIT_SUCCESS 
-    : EXIT_FAILURE;
-}