Index: libabac/abac_pl_gen.c
===================================================================
--- libabac/abac_pl_gen.c	(revision 718ad9243faff3a00dea5c5c5b2ef6fe89caedbe)
+++ libabac/abac_pl_gen.c	(revision 718ad9243faff3a00dea5c5c5b2ef6fe89caedbe)
@@ -0,0 +1,335 @@
+
+
+/***********************************************************************/
+/* clause generation called from parser to generate credential clauses */
+/***********************************************************************/
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "abac_set.h"
+#include "abac_util.h"
+#include "abac_pl.h"
+
+#include "uthash.h"
+
+// index to generate C1,C2..
+static int cred_count=0;
+extern char* abac_yyfptr;
+extern int abac_cnt_yy_id_certs();
+extern void abac_free_yy_id_certs();
+extern char *abac_string_yy_id_certs();
+char *abac_role_principal_cn(abac_role_t *role);
+char *abac_type_clauses=NULL;
+
+/***********************************************************************/
+static int _get_next_cred_idx()
+{
+    cred_count++;
+    return cred_count;
+}
+
+/* remember to free the returned string */
+static char *_compose_cred_list()
+{
+    int i=cred_count;;
+    if(cred_count==0) return "";
+
+    char *clist=(char *)abac_xmalloc(sizeof(char)*(cred_count)*3);
+    strcpy(clist,"C1");
+    if (cred_count==1) return clist;
+
+    i=1;
+    while(i!=cred_count) {
+        i++;
+        sprintf(clist,"%s,C%d",clist,i);
+    }
+    return clist;
+}
+
+
+/* generate role(p_name, r_name, param..) */
+static char* generate_pl_head_role_string(abac_role_t *role)
+{
+     char *tmp=NULL;
+     char *principalname=abac_role_principal_cn(role);
+     char *rolename=abac_role_role_name(role);
+     char *param_string=NULL;
+     int cnt=0;
+
+     /* can not be a linked role */
+     abac_param_list_t *role_params=abac_role_role_params(role);
+     if(role_params) {
+        param_string=abac_param_list_string(role_params);
+     }
+
+     if (param_string != NULL) {
+         cnt=asprintf(&tmp,"role(%s,%s,%s)", principalname, rolename, param_string);
+         free(param_string);
+         } else {
+             cnt=asprintf(&tmp,"role(%s,%s)", principalname, rolename);
+     }
+     if(cnt>0)
+        return tmp;
+        else
+           return NULL;
+}
+
+/* generate role(p_name, r_name, param..) with isMember call ?? */
+static char* generate_pl_tail_role_string(abac_role_t *role)
+{
+     char *tmp;
+     char *principalname=abac_role_principal_cn(role);
+     char *rolename=abac_role_role_name(role);
+     char *linkedname=abac_role_linked_role(role);
+
+     char *param_string=NULL;
+     char *linked_param_string=NULL;
+     int cnt=0;
+
+     abac_param_list_t *role_params=abac_role_role_params(role);
+     if(role_params) {
+        param_string=abac_param_list_string(role_params);
+     }
+
+     abac_param_list_t *linked_role_params=abac_role_linked_role_params(role);
+     if(linked_role_params) {
+        linked_param_string=abac_param_list_string(linked_role_params);
+     }
+
+     /* b.r.r */
+     if(linkedname!=NULL && rolename!=NULL && principalname!=NULL ) {
+         int fst=_get_next_cred_idx();
+         int snd=_get_next_cred_idx();
+         if(linked_param_string !=NULL) {
+             if (param_string != NULL) {
+                 cnt=asprintf(&tmp,"isMember(Y,role(%s,%s,%s),C%d),isMember(X,role(Y,%s,%s),C%d)",
+                            principalname,
+                            linkedname,linked_param_string,fst,
+                            rolename,param_string,snd);
+                 free(param_string);
+                 } else {
+                     cnt=asprintf(&tmp,"isMember(Y,role(%s,%s,%s),C%d),isMember(X,role(Y,%s),C%d)",
+                            principalname,
+                            linkedname,linked_param_string,fst,
+                            rolename,snd);
+             }
+             free(linked_param_string);
+             } else {
+                 if (role_params != NULL) {
+                     cnt=asprintf(&tmp,"isMember(Y,role(%s,%s),C%d),isMember(X,role(Y,%s,%s),C%d)",
+                            principalname,
+                            linkedname,fst,
+                            rolename,param_string,snd);
+                     free(param_string);
+                     } else {
+                         cnt=asprintf(&tmp,"isMember(Y,role(%s,%s),C%d),isMember(X,role(Y,%s),C%d)",
+                            principalname,
+                            linkedname,fst,
+                            rolename,snd);
+               }
+         }
+         if(cnt>0)
+             return tmp;
+             else
+                 return NULL;
+     } 
+     /* b.r */
+     if(linkedname==NULL && rolename!=NULL && principalname!=NULL ) {
+         int fst=_get_next_cred_idx();
+         if(param_string != NULL) {
+             cnt=asprintf(&tmp,"isMember(X,role(%s,%s,%s),C%d)",
+                          principalname, rolename, param_string, fst);
+             free(param_string);
+             } else {
+                 cnt=asprintf(&tmp,"isMember(X,role(%s,%s),C%d)",
+                          principalname, rolename, fst);
+         }
+         if(cnt>0)
+             return tmp;
+             else
+                 return NULL;
+     } 
+     /* b */
+     if(linkedname==NULL && rolename==NULL && principalname!=NULL ) {
+         tmp=abac_xstrdup(principalname);
+         return tmp;
+     } 
+
+     return tmp;
+}
+
+
+static char *generate_pl_rule_clause(char *head_role_string, abac_role_t *tail_role)
+{
+    char *tmp=NULL;
+    char* tail_role_string=NULL;
+    char* rolename=abac_role_role_name(tail_role);
+
+    if(rolename == NULL) {
+        /* A.R <- B */
+        tail_role_string=generate_pl_tail_role_string(tail_role);
+        if(tail_role_string != NULL) {
+            if(abac_type_clauses==NULL) {
+                asprintf(&tmp, "isMember(%s,%s,['%s'])",
+                         tail_role_string,head_role_string,abac_yyfptr);
+                } else {
+                    asprintf(&tmp, "isMember(%s,%s,['%s']) :- %s",
+                         tail_role_string,head_role_string,abac_yyfptr,
+                         abac_type_clauses);
+                    free(abac_type_clauses);
+                    abac_type_clauses=NULL;
+            }
+            } else { 
+                goto error;
+        }
+        } else {
+             /* A.R <- B.R */
+             /* A.R <- B.R.R */
+             tail_role_string=generate_pl_tail_role_string(tail_role);
+             if (cred_count==0) {
+                 if(abac_type_clauses==NULL) { 
+                     asprintf(&tmp,"isMember(X,%s,['%s']):-%s",
+                           head_role_string, abac_yyfptr, tail_role_string);
+                     } else {
+                         asprintf(&tmp,"isMember(X,%s,['%s']):-%s, %s",
+                                 head_role_string, abac_yyfptr,
+                                 tail_role_string, abac_type_clauses);
+                         free(abac_type_clauses);
+                         abac_type_clauses=NULL;
+                 }
+                 } else {
+                     char *tmp_cred_list=_compose_cred_list();
+                     if(abac_type_clauses == NULL) {
+                         asprintf(&tmp,"isMember(X,%s,L):-%s, appendL([['%s'],%s],L)", 
+                                  head_role_string, tail_role_string,
+                                  abac_yyfptr, tmp_cred_list);
+                         } else {
+                             asprintf(&tmp,"isMember(X,%s,L):-%s, appendL([['%s'],%s],L), %s", 
+                                  head_role_string, tail_role_string,
+                                  abac_yyfptr, tmp_cred_list, abac_type_clauses);
+                             free(abac_type_clauses);
+                             abac_type_clauses=NULL;
+                     }
+                     free(tmp_cred_list);
+                     cred_count=0;
+             }
+    }
+    if(tail_role_string) free(tail_role_string);
+    return tmp;
+
+error:
+    if(tail_role_string) free(tail_role_string);
+    return NULL;
+}
+
+static char *_add_string(char *dstr, char *nstr)
+{
+    if(strlen(dstr)==0) {
+        dstr=abac_xstrdup(nstr);
+        return dstr;
+        } else { 
+            int len = strlen(dstr)+strlen(nstr)+2;
+            char *tmp=abac_xmalloc(len*sizeof(char));
+            sprintf(tmp,"%s,%s", dstr,nstr);
+            free(dstr);
+            return tmp;
+    }
+    return NULL;
+}
+
+static char *generate_pl_intersecting_clause(char *head_role_string,
+                                                     abac_role_t *tail_role)
+{
+    char *tmp=NULL;
+    char* tail_role_string=NULL;
+    abac_list_t *list=abac_role_prereqs(tail_role);
+    /* A.R <- B.R & C.R.R */
+
+    if (list != NULL) {
+        abac_role_t *cur;
+        abac_list_foreach(list, cur,
+            char *ntmp=generate_pl_tail_role_string(cur);
+            if(tail_role_string==NULL)
+                 asprintf(&tail_role_string,"%s",ntmp);
+                 else
+                    asprintf(&tail_role_string,"%s, %s",tail_role_string,ntmp);
+            free(ntmp);
+        );
+    }
+
+    if (cred_count==0) {
+        if(abac_type_clauses ==NULL) {
+            asprintf(&tmp,"isMember(X,%s,['%s']):-%s",
+                   head_role_string, abac_yyfptr, tail_role_string);
+            } else {
+                asprintf(&tmp,"isMember(X,%s,['%s']):-%s, %s",
+                       head_role_string, abac_yyfptr, tail_role_string,
+                       abac_type_clauses);
+                free(abac_type_clauses);
+                abac_type_clauses=NULL;
+        }
+        } else {
+            char *tmp_cred_list=_compose_cred_list();
+            if(abac_type_clauses ==NULL) {
+                asprintf(&tmp,"isMember(X,%s,L):-%s, appendL([['%s'],%s],L)", 
+                                head_role_string, tail_role_string,
+                                abac_yyfptr, tmp_cred_list);
+                } else {
+                    asprintf(&tmp,"isMember(X,%s,L):-%s, appendL([['%s'],%s],L), %s", 
+                                head_role_string, tail_role_string,
+                                abac_yyfptr, tmp_cred_list,abac_type_clauses);
+                    free(abac_type_clauses);
+                    abac_type_clauses=NULL;
+            }
+            free(tmp_cred_list);
+            cred_count=0;
+    }
+    if(tail_role_string) free(tail_role_string);
+    return tmp;
+}
+
+/* generate the yap isMember rule clause for the credential stmt */
+abac_list_t *generate_pl_clauses(abac_role_t *head_role, abac_role_t *tail_role)
+{
+   char *tmp=NULL;
+   abac_list_t *clauses=abac_list_new();
+
+   int cnt=abac_cnt_yy_id_certs();
+   if(cnt > 0) { /* string it up */
+       abac_type_clauses=abac_string_yy_id_certs();
+       abac_free_yy_id_certs();
+   }
+
+/* generate head's role string */
+    char *head_role_string=generate_pl_head_role_string(head_role);
+    if(head_role_string == NULL)
+        goto error;
+
+/* tail side */
+    if(abac_role_is_intersection(tail_role)) {
+       tmp=generate_pl_intersecting_clause(head_role_string, tail_role);
+       } else {
+           tmp=generate_pl_rule_clause(head_role_string, tail_role);
+    }
+    if(tmp==NULL)
+        goto error;
+    abac_list_add(clauses,tmp);
+    return clauses;
+
+error:
+    if(head_role_string) free(head_role_string);
+    return clauses;
+}
+
+/* generate the yap isType rule clause for the type,
+   isType(Acme, keyid); */
+char *generate_pl_type_clause(char *principalname, int type)
+{
+    char *tmp=NULL;
+    char *typeid= abac_keyid_type(type);
+    int cnt=asprintf(&tmp,"isType(%s,%s)",
+                                principalname, typeid);
+    return tmp;
+}
+
