Index: libabac/abac_term.c
===================================================================
--- libabac/abac_term.c	(revision d037f549d30de12f67357bdeb76c05f548342399)
+++ libabac/abac_term.c	(revision 440ba2094bb609dfd219413fa918cf7369999c9e)
@@ -18,13 +18,34 @@
 static int debug=0;
 
-/* string will contain either 
-     the range literal (static constraint)
-       or
-     the oset/role prologized string (dynamic constraint)
-   union ptr will only be set if it is a dynamic
-   constraint */
+/* itemtype is
+     e_ITEM_MIN=1,
+     e_ITEM_MAX=2,
+     e_ITEM_TARGET=3,
+ [a..b], [a..], [..b], [a],[a,b],[many a]
+*/
+struct _abac_item_t {
+    int itemtype;
+    char *val;
+};
+
+/* condtype is
+     e_COND_ROLE = 1,
+     e_COND_OSET = 2,
+     e_COND_RANGE = 3
+   vartype is one of termtype 
+   string will contain either 
+       the range literal (static constraint)
+      or
+       the oset/role prologized string (dynamic constraint)
+      it is set if this condition has been pre-processed for codegen
+   of_aspect ptr will only be set only if it is a dynamic
+       constraint 
+   range_list is set only if needed 
+*/
 struct _abac_condition_t {
-    int type;
+    int condtype;
+    int vartype;
     char *string; 
+    abac_list_t *range_list;
     abac_aspect_t *of_aspect;
 };
@@ -33,9 +54,7 @@
    idtype_t/name/p_name pair for the named principal term
 */
-   
 struct _abac_term_t {
     int type;
     char *name;
-    // e_TERM_PRINCIPAL isnamed
     int isnamed;
     char *p_name; 
@@ -49,18 +68,138 @@
 };
 
-
 /******************************************************************/
-char *abac_condtype_name(int i)
+char *abac_condtype_string(int i)
 {
     if(i>_condname_cnt)
-        panic("abac_condtype_name: went out of range on condname");
+        panic("abac_condtype_string: went out of range on condname");
     return (char *) _condname[i];
 }
-
-abac_condition_t *abac_condition_new(int type,char* condstr,abac_aspect_t *cptr)
+char *abac_termtype_string(int i)
+{
+    if(i>_termname_cnt)
+        panic("abac_termtype_string: went out of range on termname");
+    return (char *) _termname[i];
+}
+
+int abac_verify_term_type(char *type) {
+    int i;
+
+    if (type == NULL)
+        panic("abac_verify_term_type: fail with NULL type\n");
+
+    for (i = 1; i <= _termname_cnt ; i++)
+        if(strcmp(type,_termname[i])==0)
+            return i;
+
+    panic("abac_verify_term_type: fail with unfounded type\n");
+}
+
+int abac_verify_item_type(char *type) {
+    int i;
+
+    if (type == NULL)
+        panic("abac_verify_item_type: fail with NULL type\n");
+
+    for (i = 1; i <= _itemname_cnt ; i++)
+        if(strcmp(type,_itemname[i])==0)
+            return i;
+    panic("abac_verify_item_type: fail with unfounded type\n");
+}
+
+char *abac_range_string(abac_list_t *ptr)
+{
+    assert(ptr);
+    char *tmp=NULL;
+    char *min=NULL;
+    char *max=NULL;
+    char *val=NULL;
+    int type;
+
+    abac_item_t *cur;
+    assert(ptr);
+    abac_list_foreach(ptr, cur,
+        type=cur->itemtype;
+        switch (type) {
+            case e_ITEM_MIN:
+                min=abac_xstrdup(cur->val);
+                break;
+            case e_ITEM_MAX:
+                max=abac_xstrdup(cur->val);
+                break;
+            case e_ITEM_TARGET:
+                if(val)
+                    asprintf(&val,"%s,%s",val,cur->val);
+                else val=abac_xstrdup(cur->val);
+                break;
+        }
+    );
+    if(max && min) {
+         asprintf(&tmp,"[%s..%s]",min,max);
+         free(max);
+         free(min);
+         return tmp;
+    }
+    if(max) {
+         asprintf(&tmp,"[..%s]",max);
+         free(max);
+         return tmp;
+    }
+    if(min) {
+         asprintf(&tmp,"[%s..]",min);
+         free(min);
+         return tmp;
+    }
+    if(val) {
+         asprintf(&tmp,"[%s]",val);
+         free(val);
+         return tmp;
+    }
+    return NULL;
+}
+/******************************************************************/
+abac_item_t *abac_item_new(char *itype, char *val)
+{
+     abac_item_t *nptr=
+             (abac_item_t *)abac_xmalloc(sizeof(abac_item_t));
+     nptr->itemtype=abac_verify_item_type(itype);
+     nptr->val=abac_xstrdup(val);
+     return nptr;
+}
+
+void abac_item_free(abac_item_t *ptr)
+{
+     assert(ptr);
+     assert(ptr->val);
+     free(ptr->val);
+     free(ptr);
+}
+
+abac_item_t *abac_item_dup(abac_item_t *ptr)
+{
+     abac_item_t *nptr=
+             (abac_item_t *)abac_xmalloc(sizeof(abac_item_t));
+     nptr->itemtype=ptr->itemtype;
+     nptr->val=abac_xstrdup(ptr->val);
+     return nptr;
+}
+
+int abac_item_type(abac_item_t *ptr)
+{
+    return ptr->itemtype;
+}
+
+char *abac_item_val(abac_item_t *ptr)
+{
+    return ptr->val;
+}
+
+/******************************************************************/
+static abac_condition_t *_abac_condition_new(int type, int vtype,
+char* condstr,void *cptr)
 {
      if(debug) {
          printf("   abac_condition_new: \n");
-         printf("     type is %d(%s)\n", type, abac_condtype_name(type));
+         printf("     condtype is %d(%s)\n", type, abac_condtype_string(type));
+         printf("     vtype is %d(%s)\n", vtype, abac_termtype_string(type));
          printf("     condstr is (%s)\n", condstr);
          if(cptr) printf("     yes on cptr\n");
@@ -69,8 +208,14 @@
      abac_condition_t *ptr=
              (abac_condition_t *)abac_xmalloc(sizeof(abac_condition_t));
-     ptr->type=type;
+     ptr->condtype=type;
+     ptr->vartype=vtype;
      ptr->string=abac_xstrdup(condstr);
-     if(cptr) ptr->of_aspect=abac_aspect_dup(cptr);
-         else ptr->of_aspect=NULL;
+     ptr->of_aspect=NULL;
+     ptr->range_list=NULL;
+     if(type==e_COND_RANGE) {
+          ptr->range_list=(abac_list_t *)cptr;
+          } else {
+             if(cptr) ptr->of_aspect=abac_aspect_dup((abac_aspect_t *)cptr);
+     }
      return ptr;
 }
@@ -78,5 +223,5 @@
 void abac_condition_free(abac_condition_t *ptr)
 {
-     switch(ptr->type) {
+     switch(ptr->condtype) {
         case e_COND_OSET:
         case e_COND_ROLE:
@@ -88,19 +233,40 @@
      }
      if(ptr->string) free(ptr->string);
+     if(ptr->range_list != NULL) {
+         abac_item_t *cur;
+         abac_list_foreach(ptr->range_list, cur,
+           abac_item_free(cur);
+         );
+         abac_list_free(ptr->range_list);
+     }
      free(ptr);
 }
 
-abac_condition_t *abac_condition_from_string(char *string)
-{
-     assert(string);
+abac_aspect_t *abac_condition_of_aspect(abac_condition_t *ptr)
+{
+   return ptr->of_aspect;
+}
+
+int abac_condition_is_range(abac_condition_t *ptr)
+{
+   if(ptr->condtype==e_COND_RANGE)
+      return 1;
+      else return 0;
+}
+
+/* called from backend, intended as stub for range constraint */
+abac_condition_t *abac_condition_create(char *vtype)
+{
      abac_condition_t *nptr=
              (abac_condition_t *)abac_xmalloc(sizeof(abac_condition_t));
-     nptr->type=e_COND_RANGE;
-     nptr->string=abac_xstrdup(string);
+     nptr->condtype=e_COND_RANGE;
+     nptr->vartype=abac_verify_term_type(vtype);
+     nptr->string=NULL;
+     nptr->range_list=NULL;
      nptr->of_aspect=NULL;
      return nptr;
 }
 
-abac_condition_t *abac_condition_from_aspect(abac_aspect_t *ptr)
+abac_condition_t *abac_condition_create_from_aspect(abac_aspect_t *ptr)
 {
      assert(ptr);
@@ -108,7 +274,9 @@
              (abac_condition_t *)abac_xmalloc(sizeof(abac_condition_t));
      if(abac_aspect_is_role(ptr))
-         nptr->type=e_COND_ROLE;
-         else nptr->type=e_COND_OSET;
+         nptr->condtype=e_COND_ROLE;
+         else nptr->condtype=e_COND_OSET;
+     nptr->vartype=e_TERM_PRINCIPAL;
      nptr->string=NULL;
+     nptr->range_list=NULL;
      nptr->of_aspect=abac_aspect_dup(ptr);
      return nptr;
@@ -120,5 +288,6 @@
      abac_condition_t *nptr=
              (abac_condition_t *)abac_xmalloc(sizeof(abac_condition_t));
-     nptr->type=ptr->type;
+     nptr->condtype=ptr->condtype;
+     nptr->vartype=ptr->vartype;
      if(ptr->string)
          nptr->string=abac_xstrdup(ptr->string);
@@ -127,17 +296,59 @@
          nptr->of_aspect=abac_aspect_dup(ptr->of_aspect);
          else nptr->of_aspect=NULL;
+
+     if(ptr->range_list!=NULL) {
+         nptr->range_list=abac_list_new();
+         abac_item_t *cur;
+         abac_item_t *nitem;
+         abac_list_foreach(ptr->range_list, cur,
+           nitem=abac_item_dup(cur);
+           abac_list_add(nptr->range_list,nitem); 
+         );
+         } else {
+             nptr->range_list=NULL;
+     }
      return nptr;
 }
 
+int abac_condition_vartype(abac_condition_t *ptr)
+{
+    return ptr->vartype;
+}
+
+abac_list_t *abac_condition_range_list(abac_condition_t *ptr)
+{
+     assert(ptr);
+     return ptr->range_list;
+}
+
+
+int abac_condition_add_range_item(abac_condition_t *ptr, char *vtype, char* itype, char* val)
+{
+    if(ptr->vartype != abac_verify_term_type(vtype))
+       panic("abac_condition_add_range_item: attempt to add range item that does not match with the constraint's type\n");
+    abac_item_t *nitem=abac_item_new(itype,val);
+    if(ptr->range_list==NULL)
+       ptr->range_list=abac_list_new();
+    abac_list_add(ptr->range_list,nitem);
+}
+
 char *abac_condition_string(abac_condition_t *ptr)
 {
      char *string=NULL;
-     switch(ptr->type) {
+     switch(ptr->condtype) {
         case e_COND_OSET:
         case e_COND_ROLE:
             string=abac_aspect_string_with_condition(ptr->of_aspect);
+            return string;
             break;
         case e_COND_RANGE:
-            string=abac_xstrdup(ptr->string);
+            if(ptr->string != NULL) {
+                string=abac_xstrdup(ptr->string);
+                return string;
+            }
+            if(ptr->range_list != NULL) {
+                string=abac_range_string(ptr->range_list);
+                return string;
+            }
             break;
      }
@@ -148,11 +359,19 @@
 {
      char *string=NULL;
-     switch(ptr->type) {
+     switch(ptr->condtype) {
         case e_COND_OSET:
         case e_COND_ROLE:
             string=abac_aspect_typed_string_with_condition(ptr->of_aspect);
+            return string;
             break;
         case e_COND_RANGE:
-            string=abac_xstrdup(ptr->string);
+            if(ptr->string != NULL) {
+                string=abac_xstrdup(ptr->string);
+                return string;
+            }
+            if(ptr->range_list != NULL) {
+                string=abac_range_string(ptr->range_list);
+                return string;
+            }
             break;
      }
@@ -160,5 +379,52 @@
 }
 
+int abac_condition_set_range_string(abac_condition_t *ptr)
+{
+   char *string= abac_range_string(ptr->range_list);
+   ptr->string=string;
+   return 1;
+}
+
+int abac_condition_set_aspect_string(abac_condition_t *ptr, char *str)
+{
+   ptr->string=abac_xstrdup(str);
+   return 1;
+}
+
+int abac_condition_set_aspect_ptr(abac_condition_t *ptr, abac_aspect_t *aptr)
+{
+   ptr->of_aspect=abac_aspect_dup(aptr);
+   return 1;
+}
+
+void abac_condition_dump(abac_condition_t *ptr, char *offset)
+{
+   printf("...constraint...\n");
+   printf("%s condtype: %d(%s)\n",
+                offset, ptr->condtype,abac_condtype_string(ptr->condtype));
+   printf("%s vartype: %d(%s)\n",
+                offset, ptr->vartype,abac_termtype_string(ptr->vartype));
+   if(ptr->string)
+       printf("%s string: %s\n", offset, ptr->string);
+       else printf("%s string: --\n", offset);
+   if(ptr->range_list)
+       printf("%s range_list: %s\n",
+                     offset, abac_range_string(ptr->range_list));
+       else printf("%s range_list: --\n", offset);
+   if(ptr->of_aspect) {
+       char *tmp=NULL;
+       asprintf(&tmp,"  %s",offset);
+       abac_aspect_dump(ptr->of_aspect,tmp);
+       free(tmp);
+       } else printf("%s of_aspect: --\n", offset);
+   printf("................\n");
+}
+
 /******************************************************************/
+int abac_term_isvar(abac_term_t *term)
+{
+    if(isupper(term->name[0])) return 1;
+       else return 0;
+} 
 
 int abac_term_isnamed(abac_term_t *term)
@@ -184,11 +450,4 @@
 {
     return term->constraint;
-}
-
-char *abac_termtype_string(int i)
-{
-    if(i>_termname_cnt)
-        panic("abac_termtype_string: went out of range on termname");
-    return (char *) _termname[i];
 }
 
@@ -253,13 +512,25 @@
 }
 
-int abac_term_verify_term_type(char *type) {
-    int i;
-
-    if (type == NULL)
-        return 0;
-
-    for (i = 1; i <= _termname_cnt ; i++)
-        if(strcmp(type,_termname[i])==0)
-            return i;
+bool abac_term_is_alpha(abac_term_t *term)
+{
+    if(term->type == e_TERM_URN ||
+          term->type == e_TERM_STRING ||
+              term->type == e_TERM_BOOLEAN)
+        return 1;
+    return 0;
+}
+
+bool abac_term_is_numeric(abac_term_t *term)
+{
+    if(term->type == e_TERM_INTEGER ||
+          term->type == e_TERM_FLOAT)
+        return 1;
+    return 0;
+}
+
+bool abac_term_is_time(abac_term_t *term)
+{
+    if(term->type == e_TERM_TIME)
+        return 1;
     return 0;
 }
@@ -275,6 +546,6 @@
 }
 
-/* called from yy */
-abac_term_t *abac_term_new(int type, char *name, char *cond, abac_aspect_t *cptr)
+/* called from yy, cptr is either abac_aspect_t or abac_list_t */
+abac_term_t *abac_term_new(int type, char *name, int isrange, char *cond, void *cptr)
 {
      if(debug) {
@@ -285,17 +556,22 @@
              printf("  cond is %s\n", cond);
              else printf("  no cond \n");
-         if(cptr)
-             printf("  cptr is (%s)\n", abac_aspect_string_with_condition(cptr));
-             else printf("  there is no cptr\n");
+         printf("  isrange is %d\n", isrange);
+         if(cptr) {
+             if(isrange) printf("  cptr is (%s)\n", 
+                                    abac_range_string((abac_list_t *)cptr));
+                else
+                   printf("  cptr is (%s)\n", 
+                          abac_aspect_string_with_condition((abac_aspect_t *)cptr));
+         }    else printf("  there is no cptr\n");
      }
      abac_condition_t *constraint=NULL;
-     if (cond) {
-         if(type==e_TERM_PRINCIPAL) {
-             constraint=abac_condition_new(e_COND_ROLE,cond,cptr);
-             } else {
-                 if(cptr == NULL)
-                    constraint=abac_condition_new(e_COND_RANGE,cond,NULL);
-                    else
-                        constraint=abac_condition_new(e_COND_OSET,cond,cptr);
+     if (cptr) {
+         if(isrange) {
+           constraint=_abac_condition_new(e_COND_RANGE,type,cond,cptr);
+           } else {
+             if(type==e_TERM_PRINCIPAL)
+               constraint=_abac_condition_new(e_COND_ROLE,type,cond,cptr);
+               else
+                 constraint=_abac_condition_new(e_COND_OSET,type,cond,cptr);
          }
      }
@@ -414,4 +690,10 @@
 abac_term_t *abac_term_add_constraint(abac_term_t *ptr, abac_condition_t *cond)
 {
+    /* make sure the types are matching */
+    if(abac_condition_vartype(cond) != abac_term_type(ptr)) {
+        panic("abac_term_add_constraint: mismatched constraint type with the dataterm\n");
+        return NULL;
+    }
+    
     if(ptr->constraint) {
         abac_condition_free(ptr->constraint);
@@ -467,4 +749,20 @@
 
 /********************************************************************/
+abac_list_t *abac_param_list(abac_param_list_t *ptr)
+{
+    assert(ptr);
+    return ptr->list;
+}
+
+void abac_param_dump(abac_param_list_t *ptr, char *offset)
+{
+    printf("===params===\n");
+    abac_term_t  *cur;
+    abac_list_foreach(ptr->list, cur,
+           abac_term_dump(cur, offset);
+    );
+    printf("============\n");
+}
+
 abac_param_list_t *abac_param_list_new(abac_term_t *term)
 {
@@ -595,4 +893,5 @@
 }
 
+
 void abac_terms_free(abac_term_t **terms)
 {
@@ -605,2 +904,24 @@
     free(terms);
 }
+
+void abac_term_dump(abac_term_t *ptr, char *offset)
+{
+    printf("--- term---\n");
+    printf("%s type : %s\n",offset, abac_term_type_name(ptr));
+    printf("%s name : %s\n",offset, abac_term_name(ptr));
+    printf("%s isnamed: %d\n",offset,ptr->isnamed);
+    if(ptr->p_name)
+        printf("%s p_name: %s\n",offset,ptr->p_name);
+        else printf("%s p_name: --\n",offset);
+    if(ptr->cn)
+        printf("%s cn: %s\n",offset,ptr->cn);
+        else printf("%s cn: --\n",offset);
+    if(ptr->constraint) {
+        char *tmp=NULL;
+        asprintf(&tmp,"  %s", offset);
+        abac_condition_dump(ptr->constraint,offset);
+        free(tmp);
+        } else printf("%s constraint: --\n",offset);
+    printf("-----------\n");
+}
+
