Index: libabac/abac_term.c
===================================================================
--- libabac/abac_term.c	(revision 646e57eb457a4e25ff3eb78027c0373b858bdbca)
+++ libabac/abac_term.c	(revision 2e9455f11fea0205b8b4b1306b5d0804cda72e10)
@@ -1,5 +1,4 @@
 /***********************************************************
    abac_term.c
-
  dterm=data term of rt1
  term is a kind of dterm
@@ -12,14 +11,58 @@
 #include <time.h>
 
-#include "abac_internal.h"
 #include "abac_util.h"
+#include "abac_aspect.h"
+#include "abac_verifier.h"
+#include "abac_id.h"
+#include "abac_list.h"
 
 static int debug=0;
+
 extern char *strptime(const char *s, const char *format, struct tm *tm);
+extern int ABAC_IN_PROLOG;
+
+/* termname[dtermtype] */
+static const char *const _termname[] =
+{
+  "badterm",
+  "integer",
+  "urn",
+  "float",
+  "boolean",
+  "string",
+  "time" ,
+  "principal",
+  "anonymous",
+  "this"
+};
+static int _termname_cnt=9;
+
+typedef enum _condtype_t {
+    e_COND_ROLE = 1,
+    e_COND_OSET = 2,
+    e_COND_RANGE = 3
+} abac_condtype_t;
+
+/* condname[condtype] */
+static const char *const _condname[] =
+{
+  "badcondition",
+  "role",
+  "oset",
+  "range"
+};
+static int _condname_cnt=3;
+
+/* itemname[itemtype] */
+static const char *const _itemname[] =
+{
+  "baditem",
+  "min",
+  "max",
+  "target"
+};
+static int _itemname_cnt=3;
 
 /* itemtype is
-     e_ITEM_MIN=1,
-     e_ITEM_MAX=2,
-     e_ITEM_TARGET=3,
  [a..b], [a..], [..b], [a],[a,b],[many a]
 */
@@ -68,5 +111,5 @@
 };
 
-/******************************************************************/
+/****************************************************************/
 char *abac_condtype_string(int i)
 {
@@ -134,5 +177,5 @@
             case e_ITEM_TARGET:
                 if(val)
-                    asprintf(&val,"%s,%s",val,cur->val);
+                    asprintf(&val,"%s,%s",cur->val,val);
                 else val=abac_xstrdup(cur->val);
                 break;
@@ -181,4 +224,14 @@
 
 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;
+}
+
+/* deep copy/same as dup */
+abac_item_t *abac_item_copy(abac_item_t *ptr)
 {
      abac_item_t *nptr=
@@ -288,5 +341,5 @@
 }
 
-/* make a copy */
+/* make a shallow copy */
 abac_condition_t *abac_condition_dup(abac_condition_t *ptr)
 {
@@ -308,4 +361,34 @@
          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;
+}
+
+/* make a deep copy */
+abac_condition_t *abac_condition_copy(abac_condition_t *ptr)
+{
+     abac_condition_t *nptr=
+             (abac_condition_t *)abac_xmalloc(sizeof(abac_condition_t));
+     nptr->condtype=ptr->condtype;
+     nptr->vartype=ptr->vartype;
+     if(ptr->string) {
+         nptr->string=abac_xstrdup(ptr->string);
+     } else {
+         nptr->string=NULL;
+     }
+     if(ptr->of_aspect)
+         nptr->of_aspect=abac_aspect_copy(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_copy(cur);
            abac_list_add(nptr->range_list,nitem); 
          );
@@ -452,27 +535,4 @@
 }
 
-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)
@@ -521,4 +581,10 @@
 {
     if(ptr->type == e_TERM_ANONYMOUS)
+        return 1;
+    return 0;
+}
+int abac_term_is_this(abac_term_t *ptr)
+{
+    if(ptr->type == e_TERM_THIS)
         return 1;
     return 0;
@@ -607,5 +673,5 @@
     strptime(string, "%Y%m%dT%H%M%S", &tm1);
     strftime(buf, sizeof(buf), "time(%Y,%m,%d,%H,%M,%S)", &tm1);
-    return strdup(buf);
+    return abac_xstrdup(buf);
 }
 
@@ -617,7 +683,18 @@
     char* rt=strptime(string, "time(%Y,%m,%d,%H,%M,%S)", &tm1);
     if(rt==NULL)
-        return strdup(string);
+        return abac_xstrdup(string);
     strftime(buf, sizeof(buf), "%Y%m%dT%H%M%S", &tm1);
     return strdup(buf);
+}
+
+static abac_term_t *_abac_term_init()
+{
+    abac_term_t *ptr=abac_xmalloc(sizeof(abac_term_t));
+    ptr->type;
+    ptr->name=NULL;
+    ptr->isnamed=0;
+    ptr->p_name=NULL;
+    ptr->cn=NULL;
+    ptr->constraint=NULL;
 }
 
@@ -652,8 +729,7 @@
          }
      }
-     abac_term_t *ptr=abac_xmalloc(sizeof(abac_term_t));
+     abac_term_t *ptr=_abac_term_init();
      ptr->isnamed=0;
      ptr->type=type;
-     ptr->p_name=NULL;
      /* reformat the term name if it is a time type */
      if((!constraint) && _abac_termtype_is_time_type(type) && isdigit(name[0])) {
@@ -664,5 +740,4 @@
      }
      ptr->constraint=constraint;
-     ptr->cn=NULL;
      return ptr;
 }
@@ -680,8 +755,7 @@
      }
 
-     abac_term_t *ptr=abac_xmalloc(sizeof(abac_term_t));
+     abac_term_t *ptr=_abac_term_init();
      ptr->isnamed=0;
      ptr->type=type;
-     ptr->p_name=NULL;
      /* reformat the term name if it is a time type */
      if((!cptr) && _abac_termtype_is_time_type(type) && isdigit(name[0])) {
@@ -691,6 +765,6 @@
              ptr->name=abac_xstrdup(name);
      }
-     ptr->constraint=(cptr==NULL)?NULL:abac_condition_dup(cptr);
-     ptr->cn=NULL;
+     if(cptr)
+          ptr->constraint=abac_condition_dup(cptr);
      return ptr;
 }
@@ -699,40 +773,49 @@
 abac_term_t *abac_term_named_new(int idtype, char *name)
 {
-     if(debug) {
-         fprintf(stderr,"abac_term_named_new: \n");
-         fprintf(stderr,"  type is %d(%s)\n", idtype, abac_idtype_string(idtype));
-         fprintf(stderr,"  name is (%s)\n", name);
-     }
-     abac_term_t *ptr=abac_xmalloc(sizeof(abac_term_t));
+     DEBUG_PRINTF("abac_term_named_new: \n  type is %d(%s)\n", 
+                              idtype, abac_idtype_string(idtype));
+     DEBUG_PRINTF("  name is (%s)\n", name);
+     abac_term_t *ptr=_abac_term_init();
      ptr->isnamed=1;
      ptr->type=idtype;
      ptr->name=abac_xstrdup(name);
-     ptr->p_name=NULL;
      /* if ABAC_CN, no need to attach p */
      if(!USE("ABAC_CN"))
          asprintf(&ptr->p_name,"p%s",name);
-     ptr->constraint=NULL;
-     ptr->cn=NULL;
      return ptr;
 }
 
-/* seems to be always idtype==e_TERM_PRINCIPAL */
+abac_term_t *abac_term_this_create()
+{
+     DEBUG_PRINTF("abac_term_this_create:\n");
+     abac_term_t *ptr=_abac_term_init();
+     ptr->type=e_TERM_THIS;
+     ptr->name=abac_xstrdup("This");
+     return ptr;
+}
+
+
+/* seems to be always idtype==e_TERM_PRINCIPAL except for ?This*/
 abac_term_t *abac_term_named_create(char *name)
 {
-     if(debug) {
-         fprintf(stderr,"abac_term_named_create: \n");
-         fprintf(stderr,"  name is (%s)\n", name);
-     }
-
-     abac_term_t *ptr=abac_xmalloc(sizeof(abac_term_t));
+     DEBUG_PRINTF("abac_term_named_create: name is (%s)\n",name);
+     abac_term_t *ptr=_abac_term_init();
+     /* special case when it is a ?this */
+     if(strcasecmp(name,"this")==0) {
+        ptr->type=e_TERM_THIS;
+        ptr->name=abac_xstrdup("This");
+        return ptr;
+     }  
+     if(strcasecmp(name,"anonymous")==0) {
+        ptr->type=e_TERM_ANONYMOUS;
+        ptr->name=abac_xstrdup("_");
+        return ptr;
+     }  
      ptr->isnamed=1;
      ptr->type=e_TERM_PRINCIPAL;
      ptr->name=abac_xstrdup(name);
-     ptr->p_name=NULL;
      /* if ABAC_CN, no need to attach p */
      if(!USE("ABAC_CN"))
          asprintf(&ptr->p_name,"p%s",name);
-     ptr->constraint=NULL;
-     ptr->cn=NULL;
      return ptr;
 }
@@ -741,19 +824,12 @@
 abac_term_t *abac_term_id_create(abac_id_t *idptr)
 {
-     if(debug) {
-         fprintf(stderr,"abac_term_id_create: \n");
-         fprintf(stderr,"  name is (%s)\n", abac_id_name(idptr));
-     }
-
-     abac_term_t *ptr=abac_xmalloc(sizeof(abac_term_t));
+     DEBUG_PRINTF("abac_term_named_id_create: name is (%s)\n", abac_id_name(idptr));
+     abac_term_t *ptr=_abac_term_init();
      ptr->isnamed=1;
      ptr->type=abac_id_idtype(idptr);
      ptr->name=abac_xstrdup(abac_id_name(idptr));
-     ptr->p_name=NULL;
      /* if ABAC_CN, no need to attach p */
      if(!USE("ABAC_CN"))
          asprintf(&ptr->p_name,"p%s",ptr->name);
-     ptr->constraint=NULL;
-     ptr->cn=NULL;
      return ptr;
 }
@@ -763,13 +839,31 @@
 {
      assert(ptr);
-     abac_term_t *nptr=abac_xmalloc(sizeof(abac_term_t));
+     abac_term_t *nptr=_abac_term_init();
      nptr->isnamed=ptr->isnamed;
      nptr->type=ptr->type;
      nptr->name=abac_xstrdup(ptr->name);
-     nptr->p_name=(ptr->p_name==NULL)?NULL:abac_xstrdup(ptr->p_name);
+     if(ptr->p_name)
+         nptr->p_name=abac_xstrdup(ptr->p_name);
      if(ptr->constraint!=NULL)
         nptr->constraint=abac_condition_dup(ptr->constraint);
-        else nptr->constraint=NULL;
-     nptr->cn=(ptr->cn)==NULL?NULL:abac_xstrdup(ptr->cn);
+     if(ptr->cn)
+        nptr->cn=abac_xstrdup(ptr->cn);
+     return nptr;
+}
+
+/* a deep copy */
+abac_term_t *abac_term_copy(abac_term_t *ptr)
+{
+     if(ptr == NULL) return NULL;
+     abac_term_t *nptr=_abac_term_init();
+     nptr->isnamed=ptr->isnamed;
+     nptr->type=ptr->type;
+     if(ptr->name)
+         nptr->name=abac_xstrdup(ptr->name);
+     if(ptr->p_name)
+         nptr->p_name=abac_xstrdup(ptr->p_name);
+     if(ptr->constraint!=NULL)
+        nptr->constraint=abac_condition_copy(ptr->constraint);
+     if(ptr->cn)
         nptr->cn=abac_xstrdup(ptr->cn);
      return nptr;
@@ -838,5 +932,5 @@
     if(abac_term_is_time_type(ptr) && !ABAC_IN_PROLOG ) {
        name=abac_time_to_term(name); /* this should be freed */
-       if(debug) fprintf(stderr,"abac_term_typed_string_with_condition: trying to turn the time back\n");
+       DEBUG_PRINTF("abac_term_typed_string_with_condition: trying to turn the time back\n");
        free_name=1;
     }
@@ -849,11 +943,15 @@
            if(abac_term_is_anonymous(ptr)) {
                asprintf(&tmp,"[?]");
+           } else {
+               if(abac_term_is_this(ptr)) {
+                   asprintf(&tmp,"[?This]");
                } else {
                    if(isupper(name[0])) 
                        asprintf(&tmp,"[%s:?%s]", type, name);
                    else asprintf(&tmp,"[%s:%s]", type, name);
+               }
            }
     }
-    if(debug) fprintf(stderr,"abac_term_typed_string_with_condition: (%s)\n",tmp);
+    DEBUG_PRINTF("abac_term_typed_string_with_condition: (%s)\n",tmp);
     if(free_name) free(name);
     return tmp;
@@ -884,12 +982,16 @@
 }
 
-void abac_param_dump(abac_param_list_t *ptr, char *offset)
-{
-    printf("===params===\n");
+abac_param_list_t *abac_param_list_copy(abac_param_list_t *ptr)
+{
+    if(ptr == NULL) return NULL;
+    abac_param_list_t *nptr=abac_xmalloc(sizeof(abac_param_list_t));
+    nptr->list=abac_list_new();
     abac_term_t  *cur;
+    abac_term_t  *ncur;
     abac_list_foreach(ptr->list, cur,
-           abac_term_dump(cur, offset);
+        ncur=abac_term_copy(cur);
+        abac_list_add(nptr->list, ncur);
     );
-    printf("============\n");
+    return nptr;
 }
 
@@ -960,10 +1062,10 @@
                   final=NULL;
                   asprintf(&final,"%s,%s",tmp,s);
-                  if(debug) fprintf(stderr,"typed param so far, %s\n", final);
+                  DEBUG_PRINTF("typed param so far, %s\n", final);
                   free(tmp);
            }
            free(s);
     );
-    if(debug) fprintf(stderr,"typed param so far, %s\n", final);
+    DEBUG_PRINTF("typed param so far, %s\n", final);
     return final;
 }
@@ -988,10 +1090,10 @@
                   final=NULL;
                   asprintf(&final,"%s,%s",tmp,s);
-                  if(debug) fprintf(stderr,"param so far, %s\n", final);
+                  DEBUG_PRINTF("param so far, %s\n", final);
                   free(tmp);
            }
            free(s);
     );
-    if(debug) fprintf(stderr,"param so far, %s\n", final);
+    DEBUG_PRINTF("param so far, %s\n", final);
     return final;
 }
@@ -1034,23 +1136,2 @@
 }
 
-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");
-}
-
