- New claim: CLAIM_Reachable
- Added new switches: -G,--generate-statespace -C,--generate-claims - Claims are now allowed to have no label (they will be generated automatically) - Output summary shows parameter of claims - Internally, new symbols can now be generated by symbolNextFree(prefixsymbol)
This commit is contained in:
		
							parent
							
								
									ccc4c34823
								
							
						
					
					
						commit
						0505aaacd6
					
				
							
								
								
									
										278
									
								
								src/compiler.c
									
									
									
									
									
								
							
							
						
						
									
										278
									
								
								src/compiler.c
									
									
									
									
									
								
							@ -355,15 +355,130 @@ levelTacDeclaration (Tac tc, int isVar)
 | 
			
		||||
      /* declare this variable/constant with the previously derived type list */
 | 
			
		||||
      t = symbolDeclare (tscan->t1.sym, isVar);
 | 
			
		||||
      t->stype = typetl;
 | 
			
		||||
      if (isVar && level == 2)
 | 
			
		||||
      /* local to the role? */
 | 
			
		||||
      if (level == 2)
 | 
			
		||||
	{
 | 
			
		||||
	  /* it is a role variable, so add it to the nicely declared variables */
 | 
			
		||||
	  thisRole->declaredvars = termlistAdd (thisRole->declaredvars, t);
 | 
			
		||||
	  if (isVar)
 | 
			
		||||
	    {
 | 
			
		||||
	      /* it is a role variable, so add it to the nicely declared variables */
 | 
			
		||||
	      thisRole->declaredvars =
 | 
			
		||||
		termlistAdd (thisRole->declaredvars, t);
 | 
			
		||||
	    }
 | 
			
		||||
	  else
 | 
			
		||||
	    {
 | 
			
		||||
	      /* it is a role constant, so add it to the nicely declared constants */
 | 
			
		||||
	      thisRole->declaredconsts =
 | 
			
		||||
		termlistAdd (thisRole->declaredconsts, t);
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
      tscan = tscan->next;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Check whether a claim label already occurs
 | 
			
		||||
int
 | 
			
		||||
isClaimlabelUsed (const System sys, const Term label)
 | 
			
		||||
{
 | 
			
		||||
  Claimlist cl;
 | 
			
		||||
 | 
			
		||||
  if (label == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* we assign this 'occurs' because it is an invalid label */
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
  cl = sys->claimlist;
 | 
			
		||||
  while (cl != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (isTermEqual (cl->label, label))
 | 
			
		||||
	{
 | 
			
		||||
	  return true;
 | 
			
		||||
	}
 | 
			
		||||
      cl = cl->next;
 | 
			
		||||
    }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Generate a fresh claim label
 | 
			
		||||
Term
 | 
			
		||||
generateFreshClaimlabel (const System sys, const Role role, const Term claim)
 | 
			
		||||
{
 | 
			
		||||
  /* Simply use the role as a prefix */
 | 
			
		||||
  return freshTermPrefix (role->nameterm);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Create a claim and add it to the claims list, and add the role event.
 | 
			
		||||
Claimlist
 | 
			
		||||
claimCreate (const System sys, const Protocol protocol, const Role role,
 | 
			
		||||
	     const Term claim, Term label, const Term msg)
 | 
			
		||||
{
 | 
			
		||||
  Claimlist cl;
 | 
			
		||||
  Term labeltuple;
 | 
			
		||||
 | 
			
		||||
  /* check for ignored claim types */
 | 
			
		||||
  if (switches.filterClaim != NULL && switches.filterClaim != claim)
 | 
			
		||||
    {
 | 
			
		||||
      /* abort the construction of the node */
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* generate full unique label */
 | 
			
		||||
  /* is the label empty or used? */
 | 
			
		||||
  if (label == NULL || isClaimlabelUsed (sys, label))
 | 
			
		||||
    {
 | 
			
		||||
      /* simply generate a fresh one */
 | 
			
		||||
      label = generateFreshClaimlabel (sys, role, claim);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  // Assert: label is unique, add claimlist info
 | 
			
		||||
  cl = memAlloc (sizeof (struct claimlist));
 | 
			
		||||
  cl->type = claim;
 | 
			
		||||
  cl->label = label;
 | 
			
		||||
  cl->parameter = msg;
 | 
			
		||||
  cl->protocol = thisProtocol;
 | 
			
		||||
  cl->rolename = role->nameterm;
 | 
			
		||||
  cl->role = role;
 | 
			
		||||
  cl->roledef = NULL;
 | 
			
		||||
  cl->count = 0;
 | 
			
		||||
  cl->complete = 0;
 | 
			
		||||
  cl->timebound = 0;
 | 
			
		||||
  cl->failed = 0;
 | 
			
		||||
  cl->prec = NULL;
 | 
			
		||||
  cl->roles = NULL;
 | 
			
		||||
  cl->alwaystrue = false;
 | 
			
		||||
  cl->warnings = false;
 | 
			
		||||
  cl->next = sys->claimlist;
 | 
			
		||||
  sys->claimlist = cl;
 | 
			
		||||
 | 
			
		||||
  /* add the role event */
 | 
			
		||||
  role->roledef = roledefAdd (role->roledef, CLAIM, label,
 | 
			
		||||
			      role->nameterm, claim, msg, cl);
 | 
			
		||||
 | 
			
		||||
  /* possible special handlers for each claim */
 | 
			
		||||
 | 
			
		||||
  if (claim == CLAIM_Secret)
 | 
			
		||||
    {
 | 
			
		||||
      Termlist claimvars;
 | 
			
		||||
      Termlist readvars;
 | 
			
		||||
 | 
			
		||||
      /* now check whether the claim contains variables that can actually be influenced by the intruder */
 | 
			
		||||
 | 
			
		||||
      claimvars = termlistAddVariables (NULL, msg);
 | 
			
		||||
      readvars = compute_read_variables (thisRole);
 | 
			
		||||
      while (claimvars != NULL)
 | 
			
		||||
	{
 | 
			
		||||
	  if (!inTermlist (readvars, claimvars->term))
 | 
			
		||||
	    {
 | 
			
		||||
	      /* this claimvar does not occur in the reads? */
 | 
			
		||||
	      /* then we should ignore it later */
 | 
			
		||||
	      cl->alwaystrue = true;
 | 
			
		||||
	      cl->warnings = true;
 | 
			
		||||
	    }
 | 
			
		||||
	  claimvars = claimvars->next;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Parse a communication event tc of type event, and add a role definition event for it.
 | 
			
		||||
void
 | 
			
		||||
commEvent (int event, Tac tc)
 | 
			
		||||
{
 | 
			
		||||
@ -382,7 +497,12 @@ commEvent (int event, Tac tc)
 | 
			
		||||
  /* Construct label, if any */
 | 
			
		||||
  if (tc->t1.sym == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      label = NULL;
 | 
			
		||||
      /* right, now this should not be NULL anyway, if so we construct a fresh one.
 | 
			
		||||
       * This can be a weird choice if it is a read or send, because in that case
 | 
			
		||||
       * we cannot chain them anymore and the send-read correspondence is lost.
 | 
			
		||||
       */
 | 
			
		||||
      warning ("Generated fresh label for line %i.", tc->lineno);
 | 
			
		||||
      label = freshTermPrefix (thisRole->nameterm);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
@ -398,21 +518,10 @@ commEvent (int event, Tac tc)
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
	{
 | 
			
		||||
	  /* we already had this label constant */
 | 
			
		||||
	  /* leaves a garbage tuple. dunnoh what to do with it */
 | 
			
		||||
	  label = makeTermTuple (thisProtocol->nameterm, label);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
  /**
 | 
			
		||||
   * We now know the label. Find the corresponding labelinfo bit or make a new one
 | 
			
		||||
   */
 | 
			
		||||
  linfo = label_find (sys->labellist, label);
 | 
			
		||||
  if (linfo == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* Not found, make a new one */
 | 
			
		||||
      linfo = label_create (label, thisProtocol);
 | 
			
		||||
      sys->labellist = list_append (sys->labellist, linfo);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Parse the specific event type
 | 
			
		||||
@ -422,6 +531,17 @@ commEvent (int event, Tac tc)
 | 
			
		||||
    {
 | 
			
		||||
    case READ:
 | 
			
		||||
    case SEND:
 | 
			
		||||
      /**
 | 
			
		||||
       * We know the label. Find the corresponding labelinfo bit or make a new one
 | 
			
		||||
       */
 | 
			
		||||
      linfo = label_find (sys->labellist, label);
 | 
			
		||||
      if (linfo == NULL)
 | 
			
		||||
	{
 | 
			
		||||
	  /* Not found, make a new one */
 | 
			
		||||
	  linfo = label_create (label, thisProtocol);
 | 
			
		||||
	  sys->labellist = list_append (sys->labellist, linfo);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      /* now parse triplet info */
 | 
			
		||||
      if (trip == NULL || trip->next == NULL || trip->next->next == NULL)
 | 
			
		||||
	{
 | 
			
		||||
@ -461,8 +581,13 @@ commEvent (int event, Tac tc)
 | 
			
		||||
	  linfo->readrole = torole;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      /* and make that read/send event */
 | 
			
		||||
      thisRole->roledef = roledefAdd (thisRole->roledef, event, label,
 | 
			
		||||
				      fromrole, torole, msg, cl);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case CLAIM:
 | 
			
		||||
      /* switch can be used to remove all *parsed* claims */
 | 
			
		||||
      if (!switches.removeclaims)
 | 
			
		||||
	{
 | 
			
		||||
	  /* now parse tuple info */
 | 
			
		||||
@ -477,13 +602,6 @@ commEvent (int event, Tac tc)
 | 
			
		||||
	  claim = tupleProject (claimbig, 0);
 | 
			
		||||
	  torole = claim;
 | 
			
		||||
 | 
			
		||||
	  /* check for ignored claim types */
 | 
			
		||||
	  if (switches.filterClaim != NULL && switches.filterClaim != claim)
 | 
			
		||||
	    {
 | 
			
		||||
	      /* abort the construction of the node */
 | 
			
		||||
	      return;
 | 
			
		||||
	    }
 | 
			
		||||
 | 
			
		||||
	  /* check for obvious flaws */
 | 
			
		||||
	  if (claim == NULL)
 | 
			
		||||
	    {
 | 
			
		||||
@ -491,7 +609,7 @@ commEvent (int event, Tac tc)
 | 
			
		||||
	    }
 | 
			
		||||
	  if (!inTermlist (claim->stype, TERM_Claim))
 | 
			
		||||
	    {
 | 
			
		||||
	      printf ("error: unknown claim type ");
 | 
			
		||||
	      printf ("error: claim term is not of claim type ");
 | 
			
		||||
	      termPrint (claim);
 | 
			
		||||
	      errorTac (trip->next->lineno);
 | 
			
		||||
	    }
 | 
			
		||||
@ -514,50 +632,21 @@ commEvent (int event, Tac tc)
 | 
			
		||||
		}
 | 
			
		||||
	    }
 | 
			
		||||
 | 
			
		||||
	  /* store claim in claim list */
 | 
			
		||||
	  // check whether label is unique
 | 
			
		||||
 | 
			
		||||
	  if (label == NULL)
 | 
			
		||||
	  if (isClaimlabelUsed (sys, label))
 | 
			
		||||
	    {
 | 
			
		||||
	      error ("Claim should have label on line %i.",
 | 
			
		||||
		     trip->next->lineno);
 | 
			
		||||
	      warning
 | 
			
		||||
		("Claim label is not unique at line %i, generating fresh label.",
 | 
			
		||||
		 tc->lineno);
 | 
			
		||||
	    }
 | 
			
		||||
	  // First check whether label is unique
 | 
			
		||||
	  cl = sys->claimlist;
 | 
			
		||||
	  while (cl != NULL)
 | 
			
		||||
	    {
 | 
			
		||||
	      if (isTermEqual (cl->label, label))
 | 
			
		||||
		{
 | 
			
		||||
		  /**
 | 
			
		||||
		   *@todo This should not error exit, but automatically generate a fresh claim label.
 | 
			
		||||
		   */
 | 
			
		||||
		  error ("Claim label is not unique at line %i.", tc->lineno);
 | 
			
		||||
		}
 | 
			
		||||
	      cl = cl->next;
 | 
			
		||||
	    }
 | 
			
		||||
	  // Assert: label is unique, add claimlist info
 | 
			
		||||
	  cl = memAlloc (sizeof (struct claimlist));
 | 
			
		||||
	  cl->type = claim;
 | 
			
		||||
	  cl->label = label;
 | 
			
		||||
	  cl->protocol = thisProtocol;
 | 
			
		||||
	  cl->rolename = fromrole;
 | 
			
		||||
	  cl->role = thisRole;
 | 
			
		||||
 | 
			
		||||
	  if (!isTermEqual (fromrole, thisRole->nameterm))
 | 
			
		||||
	    error
 | 
			
		||||
	      ("Claim role does not correspond to execution role at line %i.",
 | 
			
		||||
	       tc->lineno);
 | 
			
		||||
	  cl->roledef = NULL;
 | 
			
		||||
	  cl->count = 0;
 | 
			
		||||
	  cl->complete = 0;
 | 
			
		||||
	  cl->timebound = 0;
 | 
			
		||||
	  cl->failed = 0;
 | 
			
		||||
	  cl->prec = NULL;
 | 
			
		||||
	  cl->roles = NULL;
 | 
			
		||||
	  cl->alwaystrue = false;
 | 
			
		||||
	  cl->warnings = false;
 | 
			
		||||
	  cl->next = sys->claimlist;
 | 
			
		||||
	  sys->claimlist = cl;
 | 
			
		||||
 | 
			
		||||
	  /* handles all claim types differently */
 | 
			
		||||
	  /* handles claim types with different syntactic claims */
 | 
			
		||||
 | 
			
		||||
	  if (claim == CLAIM_Secret)
 | 
			
		||||
	    {
 | 
			
		||||
@ -573,26 +662,6 @@ commEvent (int event, Tac tc)
 | 
			
		||||
		    ("Secrecy claim on line %i should not contain tuples (for Arachne) until it is officially supported.",
 | 
			
		||||
		     trip->next->lineno);
 | 
			
		||||
		}
 | 
			
		||||
	      /* now check whether the claim contains variables that can actually be influenced by the intruder */
 | 
			
		||||
	      {
 | 
			
		||||
		Termlist claimvars;
 | 
			
		||||
		Termlist readvars;
 | 
			
		||||
 | 
			
		||||
		claimvars = termlistAddVariables (NULL, msg);
 | 
			
		||||
		readvars = compute_read_variables (thisRole);
 | 
			
		||||
		while (claimvars != NULL)
 | 
			
		||||
		  {
 | 
			
		||||
		    if (!inTermlist (readvars, claimvars->term))
 | 
			
		||||
		      {
 | 
			
		||||
			/* this claimvar does not occur in the reads? */
 | 
			
		||||
			/* then we should ignore it later */
 | 
			
		||||
			cl->alwaystrue = true;
 | 
			
		||||
			cl->warnings = true;
 | 
			
		||||
		      }
 | 
			
		||||
		    claimvars = claimvars->next;
 | 
			
		||||
		  }
 | 
			
		||||
	      }
 | 
			
		||||
	      break;
 | 
			
		||||
	    }
 | 
			
		||||
	  if (claim == CLAIM_Nisynch)
 | 
			
		||||
	    {
 | 
			
		||||
@ -601,7 +670,6 @@ commEvent (int event, Tac tc)
 | 
			
		||||
		  error ("NISYNCH claim requires no parameters at line %i.",
 | 
			
		||||
			 trip->next->lineno);
 | 
			
		||||
		}
 | 
			
		||||
	      break;
 | 
			
		||||
	    }
 | 
			
		||||
	  if (claim == CLAIM_Niagree)
 | 
			
		||||
	    {
 | 
			
		||||
@ -610,25 +678,14 @@ commEvent (int event, Tac tc)
 | 
			
		||||
		  error ("NIAGREE claim requires no parameters at line %i.",
 | 
			
		||||
			 trip->next->lineno);
 | 
			
		||||
		}
 | 
			
		||||
	      break;
 | 
			
		||||
	    }
 | 
			
		||||
	  if (claim == CLAIM_Empty)
 | 
			
		||||
	    {
 | 
			
		||||
	      break;
 | 
			
		||||
	    }
 | 
			
		||||
 | 
			
		||||
	  /* hmm, no handler yet */
 | 
			
		||||
	  /* create the event */
 | 
			
		||||
 | 
			
		||||
	  printf ("error: No know handler for this claim type: ");
 | 
			
		||||
	  termPrint (claim);
 | 
			
		||||
	  printf (" ");
 | 
			
		||||
	  errorTac (trip->next->lineno);
 | 
			
		||||
	  cl = claimCreate (sys, thisProtocol, thisRole, claim, label, msg);
 | 
			
		||||
	}
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  /* and make that event */
 | 
			
		||||
  thisRole->roledef = roledefAdd (thisRole->roledef, event, label,
 | 
			
		||||
				  fromrole, torole, msg, cl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
@ -663,6 +720,28 @@ normalDeclaration (Tac tc)
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Add all sorts of claims to this role
 | 
			
		||||
void
 | 
			
		||||
claimAddAll (const System sys, const Protocol protocol, const Role role)
 | 
			
		||||
{
 | 
			
		||||
  /* first: secrecy claims for all locally declared things */
 | 
			
		||||
  void addSecrecyList (Termlist tl)
 | 
			
		||||
  {
 | 
			
		||||
    while (tl != NULL)
 | 
			
		||||
      {
 | 
			
		||||
	claimCreate (sys, protocol, role, CLAIM_Secret, NULL, tl->term);
 | 
			
		||||
	tl = tl->next;
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  addSecrecyList (role->declaredconsts);
 | 
			
		||||
  addSecrecyList (role->declaredvars);
 | 
			
		||||
 | 
			
		||||
  /* full non-injective agreement and ni-synch */
 | 
			
		||||
  claimCreate (sys, protocol, role, CLAIM_Niagree, NULL, NULL);
 | 
			
		||||
  claimCreate (sys, protocol, role, CLAIM_Nisynch, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
roleCompile (Term nameterm, Tac tc)
 | 
			
		||||
{
 | 
			
		||||
@ -726,6 +805,19 @@ roleCompile (Term nameterm, Tac tc)
 | 
			
		||||
	tc = tc->next;
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* add any claims according to the switches */
 | 
			
		||||
 | 
			
		||||
  if (switches.addreachableclaim)
 | 
			
		||||
    {
 | 
			
		||||
      claimCreate (sys, thisProtocol, thisRole, CLAIM_Reachable, NULL, NULL);
 | 
			
		||||
    }
 | 
			
		||||
  if (switches.addallclaims)
 | 
			
		||||
    {
 | 
			
		||||
      claimAddAll (sys, thisProtocol, thisRole);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* last bits */
 | 
			
		||||
  compute_role_variables (sys, thisProtocol, thisRole);
 | 
			
		||||
  levelDone ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										103
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								src/main.c
									
									
									
									
									
								
							@ -370,47 +370,104 @@ timersPrint (const System sys)
 | 
			
		||||
  /* Note that if the output is set to empty, the claim output is redirected to stdout (for e.g. processing)
 | 
			
		||||
   */
 | 
			
		||||
  cl_scan = sys->claimlist;
 | 
			
		||||
  anyclaims = 0;
 | 
			
		||||
  anyclaims = false;
 | 
			
		||||
  while (cl_scan != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (!isTermEqual (cl_scan->type, CLAIM_Empty))
 | 
			
		||||
	{
 | 
			
		||||
	  anyclaims = 1;
 | 
			
		||||
	  Protocol protocol;
 | 
			
		||||
	  Term pname;
 | 
			
		||||
	  Term rname;
 | 
			
		||||
	  Termlist labellist;
 | 
			
		||||
 | 
			
		||||
	  anyclaims = true;
 | 
			
		||||
 | 
			
		||||
	  eprintf ("claim\t");
 | 
			
		||||
 | 
			
		||||
	  /* claim label is tuple */
 | 
			
		||||
	  if (realTermTuple (cl_scan->label))
 | 
			
		||||
	  protocol = (Protocol) cl_scan->protocol;
 | 
			
		||||
	  pname = protocol->nameterm;
 | 
			
		||||
	  rname = cl_scan->rolename;
 | 
			
		||||
 | 
			
		||||
	  labellist = tuple_to_termlist (cl_scan->label);
 | 
			
		||||
 | 
			
		||||
	  /* maybe the label contains duplicate info: if so, we remove it here */
 | 
			
		||||
	  {
 | 
			
		||||
	    Termlist tl;
 | 
			
		||||
	    tl = labellist;
 | 
			
		||||
	    while (tl != NULL)
 | 
			
		||||
	      {
 | 
			
		||||
		if (isTermEqual (tl->term, pname)
 | 
			
		||||
		    || isTermEqual (tl->term, rname))
 | 
			
		||||
		  {
 | 
			
		||||
		    tl = termlistDelTerm (tl);
 | 
			
		||||
		    labellist = tl;
 | 
			
		||||
		  }
 | 
			
		||||
		else
 | 
			
		||||
		  {
 | 
			
		||||
		    tl = tl->next;
 | 
			
		||||
		  }
 | 
			
		||||
	      }
 | 
			
		||||
	  }
 | 
			
		||||
 | 
			
		||||
	  termPrint (pname);
 | 
			
		||||
	  eprintf (",");
 | 
			
		||||
	  termPrint (rname);
 | 
			
		||||
	  eprintf ("\t");
 | 
			
		||||
	  /* second print event_label */
 | 
			
		||||
	  termPrint (cl_scan->type);
 | 
			
		||||
 | 
			
		||||
	  eprintf ("_");
 | 
			
		||||
	  if (labellist != NULL)
 | 
			
		||||
	    {
 | 
			
		||||
	      /* modern version: claim label is tuple (protocname, label) */
 | 
			
		||||
	      /* first print protocol.role */
 | 
			
		||||
	      termPrint (TermOp1 (cl_scan->label));
 | 
			
		||||
	      eprintf (",");
 | 
			
		||||
	      termPrint (cl_scan->rolename);
 | 
			
		||||
	      eprintf ("\t");
 | 
			
		||||
	      /* second print event_label */
 | 
			
		||||
	      termPrint (cl_scan->type);
 | 
			
		||||
	      eprintf ("_");
 | 
			
		||||
	      termPrint (TermOp2 (cl_scan->label));
 | 
			
		||||
	      eprintf ("\t");
 | 
			
		||||
	      Termlist tl;
 | 
			
		||||
 | 
			
		||||
	      tl = labellist;
 | 
			
		||||
	      while (tl != NULL)
 | 
			
		||||
		{
 | 
			
		||||
		  termPrint (tl->term);
 | 
			
		||||
		  tl = tl->next;
 | 
			
		||||
		  if (tl != NULL)
 | 
			
		||||
		    {
 | 
			
		||||
		      eprintf (",");
 | 
			
		||||
		    }
 | 
			
		||||
		}
 | 
			
		||||
	      /* clean up */
 | 
			
		||||
	      termlistDelete (labellist);
 | 
			
		||||
	      labellist = NULL;
 | 
			
		||||
	    }
 | 
			
		||||
	  else
 | 
			
		||||
	    {
 | 
			
		||||
	      /* old-fashioned output */
 | 
			
		||||
	      termPrint (cl_scan->type);
 | 
			
		||||
	      eprintf ("\t");
 | 
			
		||||
	      termPrint (cl_scan->rolename);
 | 
			
		||||
	      eprintf (" (");
 | 
			
		||||
	      termPrint (cl_scan->label);
 | 
			
		||||
	      eprintf (")\t");
 | 
			
		||||
	      eprintf ("?");
 | 
			
		||||
	    }
 | 
			
		||||
	  /* add parameter */
 | 
			
		||||
	  eprintf ("\t");
 | 
			
		||||
	  if (cl_scan->parameter != NULL)
 | 
			
		||||
	    {
 | 
			
		||||
	      termPrint (cl_scan->parameter);
 | 
			
		||||
	    }
 | 
			
		||||
	  else
 | 
			
		||||
	    {
 | 
			
		||||
	      eprintf ("-");
 | 
			
		||||
	    }
 | 
			
		||||
 | 
			
		||||
	  /* now report the status */
 | 
			
		||||
	  eprintf ("\t");
 | 
			
		||||
	  eprintf ("attacks: ");
 | 
			
		||||
	  if (cl_scan->count > 0 && cl_scan->failed > 0)
 | 
			
		||||
	    {
 | 
			
		||||
	      /* there is an attack */
 | 
			
		||||
	      eprintf ("yes\t(at least %i)", cl_scan->failed);
 | 
			
		||||
	      eprintf ("yes\t");
 | 
			
		||||
	      /* are these all attacks? */
 | 
			
		||||
	      eprintf ("(");
 | 
			
		||||
	      if (cl_scan->complete)
 | 
			
		||||
		{
 | 
			
		||||
		  eprintf ("exactly");
 | 
			
		||||
		}
 | 
			
		||||
	      else
 | 
			
		||||
		{
 | 
			
		||||
		  eprintf ("at least");
 | 
			
		||||
		}
 | 
			
		||||
	      eprintf (" %i)", cl_scan->failed);
 | 
			
		||||
	    }
 | 
			
		||||
	  else
 | 
			
		||||
	    {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								src/parser.y
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/parser.y
									
									
									
									
									
								
							@ -48,6 +48,7 @@ int yylex(void);
 | 
			
		||||
%type	<tac>	roleref
 | 
			
		||||
 | 
			
		||||
%type	<symb>	label
 | 
			
		||||
%type	<symb>	optlabel
 | 
			
		||||
 | 
			
		||||
%start spdlcomplete
 | 
			
		||||
 | 
			
		||||
@ -142,7 +143,7 @@ event		: READT label '(' termlist ')' ';'
 | 
			
		||||
			t->t2.tac = $4;
 | 
			
		||||
			$$ = t;
 | 
			
		||||
		  }
 | 
			
		||||
		| CLAIMT label '(' termlist ')' ';'
 | 
			
		||||
		| CLAIMT optlabel '(' termlist ')' ';'
 | 
			
		||||
		/* TODO maybe claims should be in the syntax */
 | 
			
		||||
		  {	Tac t = tacCreate(TAC_CLAIM);
 | 
			
		||||
		  	t->t1.sym = $2;
 | 
			
		||||
@ -226,11 +227,17 @@ typeinfoN	: /* empty */
 | 
			
		||||
		  }
 | 
			
		||||
		;
 | 
			
		||||
 | 
			
		||||
/* Previously, the label could be omitted. It is now required. */
 | 
			
		||||
label		: '_' ID
 | 
			
		||||
		  { $$ = $2; }
 | 
			
		||||
		;
 | 
			
		||||
 | 
			
		||||
optlabel        : /* empty */
 | 
			
		||||
                 { $$ = NULL; }
 | 
			
		||||
               | label
 | 
			
		||||
		  { }
 | 
			
		||||
                ;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
term  		: ID
 | 
			
		||||
		  {
 | 
			
		||||
		  	Tac t = tacCreate(TAC_STRING);
 | 
			
		||||
 | 
			
		||||
@ -241,6 +241,7 @@ roleCreate (Term name)
 | 
			
		||||
  r->locals = NULL;
 | 
			
		||||
  r->variables = NULL;
 | 
			
		||||
  r->declaredvars = NULL;
 | 
			
		||||
  r->declaredconsts = NULL;
 | 
			
		||||
  r->initiator = 1;		//! Will be determined later, if a read is the first action (in compiler.c)
 | 
			
		||||
  r->next = NULL;
 | 
			
		||||
  return r;
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,8 @@ struct claimlist
 | 
			
		||||
  Term type;
 | 
			
		||||
  //! The term element for this node.
 | 
			
		||||
  Term label;
 | 
			
		||||
  //! Any parameters
 | 
			
		||||
  Term parameter;
 | 
			
		||||
  //! The pointer to the protocol (not defined typically, because
 | 
			
		||||
  //! at compile time of the claim the protocol structure is not known yet.)
 | 
			
		||||
  void *protocol;
 | 
			
		||||
@ -124,6 +126,8 @@ struct role
 | 
			
		||||
  Termlist locals;
 | 
			
		||||
  //! Local variables for this role.
 | 
			
		||||
  Termlist variables;
 | 
			
		||||
  //! Declared constants for this role
 | 
			
		||||
  Termlist declaredconsts;
 | 
			
		||||
  //! Declared variables for this role
 | 
			
		||||
  Termlist declaredvars;
 | 
			
		||||
  //! Flag for initiator roles
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@ Term CLAIM_Secret;
 | 
			
		||||
Term CLAIM_Nisynch;
 | 
			
		||||
Term CLAIM_Niagree;
 | 
			
		||||
Term CLAIM_Empty;
 | 
			
		||||
Term CLAIM_Reachable;
 | 
			
		||||
 | 
			
		||||
//! Init special terms
 | 
			
		||||
/**
 | 
			
		||||
@ -50,4 +51,5 @@ specialTermInit (const System sys)
 | 
			
		||||
  langcons (CLAIM_Nisynch, "Nisynch", TERM_Claim);
 | 
			
		||||
  langcons (CLAIM_Niagree, "Niagree", TERM_Claim);
 | 
			
		||||
  langcons (CLAIM_Empty, "Empty", TERM_Claim);
 | 
			
		||||
  langcons (CLAIM_Reachable, "Reachable", TERM_Claim);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -18,5 +18,6 @@ extern Term CLAIM_Secret;
 | 
			
		||||
extern Term CLAIM_Nisynch;
 | 
			
		||||
extern Term CLAIM_Niagree;
 | 
			
		||||
extern Term CLAIM_Empty;
 | 
			
		||||
extern Term CLAIM_Reachable;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -75,6 +75,8 @@ switchesInit (int argc, char **argv)
 | 
			
		||||
  switches.switchP = 0;		// multi-purpose parameter
 | 
			
		||||
  switches.experimental = 0;	// experimental stuff defaults to 0, whatever that means.
 | 
			
		||||
  switches.removeclaims = false;	// default: leave claims from spdl file
 | 
			
		||||
  switches.addreachableclaim = false;	// add 'reachable' claims
 | 
			
		||||
  switches.addallclaims = false;	// add all sorts of claims
 | 
			
		||||
 | 
			
		||||
  // Output
 | 
			
		||||
  switches.output = SUMMARY;	// default is to show a summary
 | 
			
		||||
@ -395,6 +397,37 @@ switcher (const int process, int index)
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (detect ('C', "generate-claims", 0))
 | 
			
		||||
    {
 | 
			
		||||
      if (!process)
 | 
			
		||||
	{
 | 
			
		||||
	  helptext ("-C,--generate-claims",
 | 
			
		||||
		    "ignore any existing claims and automatically generate new claims");
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
	{
 | 
			
		||||
	  switches.removeclaims = true;
 | 
			
		||||
	  switches.addallclaims = true;
 | 
			
		||||
	  return index;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (detect ('G', "generate-semibundles", 0))
 | 
			
		||||
    {
 | 
			
		||||
      if (!process)
 | 
			
		||||
	{
 | 
			
		||||
	  helptext ("-G,--generate-statespace",
 | 
			
		||||
		    "ignore any existing claims and add 'reachable' claims to generate the full state space");
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
	{
 | 
			
		||||
	  switches.removeclaims = true;	// remove parsed claims
 | 
			
		||||
	  switches.addreachableclaim = true;	// add reachability claims
 | 
			
		||||
	  switches.prune = 0;	// do not prune anything
 | 
			
		||||
	  return index;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* ==================
 | 
			
		||||
   *  Bounding options
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
@ -54,6 +54,8 @@ struct switchdata
 | 
			
		||||
  int switchP;			//!< A multi-purpose integer parameter, passed to the partial order reduction method selected.
 | 
			
		||||
  int experimental;		//!< Experimental stuff goes here until it moves into main stuff.
 | 
			
		||||
  int removeclaims;		//!< Remove any claims in the spdl file
 | 
			
		||||
  int addreachableclaim;	//!< Adds 'reachable' claims to each role
 | 
			
		||||
  int addallclaims;		//!< Adds all sorts of claims to the roles
 | 
			
		||||
 | 
			
		||||
  // Output
 | 
			
		||||
  int output;			//!< From enum outputs: what should be produced. Default ATTACK.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										54
									
								
								src/symbol.c
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								src/symbol.c
									
									
									
									
									
								
							@ -211,6 +211,60 @@ symbolSysConst (const char *str)
 | 
			
		||||
  return symb;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Generate the first fresh free number symbol, prefixed by a certain symbol's string.
 | 
			
		||||
/**
 | 
			
		||||
 * Note that there is an upper limit to this, to avoid some problems with buffer overflows etc.
 | 
			
		||||
 */
 | 
			
		||||
Symbol
 | 
			
		||||
symbolNextFree (Symbol prefixsymbol)
 | 
			
		||||
{
 | 
			
		||||
  char *prefixstr;
 | 
			
		||||
  int n;
 | 
			
		||||
  int len;
 | 
			
		||||
 | 
			
		||||
  if (prefixsymbol != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      prefixstr = (char *) prefixsymbol->text;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      prefixstr = "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  len = strlen (prefixstr);
 | 
			
		||||
  n = 1;
 | 
			
		||||
  while (n <= 9999)
 | 
			
		||||
    {
 | 
			
		||||
      char buffer[len + 5];	// thus we must enforce a maximum of 9.999 (allowing for storage of \0 )
 | 
			
		||||
      Symbol symb;
 | 
			
		||||
      int slen;
 | 
			
		||||
 | 
			
		||||
      slen = sprintf (buffer, "%s%i", prefixstr, n);
 | 
			
		||||
      symb = lookup (buffer);
 | 
			
		||||
      if (symb == NULL)
 | 
			
		||||
	{
 | 
			
		||||
	  char *newstring;
 | 
			
		||||
	  // Copy the buffer to something that will survive
 | 
			
		||||
	  /**
 | 
			
		||||
	   * Memory leak: although this routine should not be called recursively, it will never de-allocate this memory.
 | 
			
		||||
	   * Thus, some precaution is necessary.
 | 
			
		||||
	   * [x][CC]
 | 
			
		||||
	   */
 | 
			
		||||
	  newstring = (char *) memAlloc (slen + 1);
 | 
			
		||||
	  memcpy (newstring, buffer, slen + 1);
 | 
			
		||||
 | 
			
		||||
	  /* This persistent string can be used to return a fresh symbol */
 | 
			
		||||
 | 
			
		||||
	  return symbolSysConst (newstring);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      // Try next one
 | 
			
		||||
      n++;
 | 
			
		||||
    }
 | 
			
		||||
  error ("We ran out of numbers (%i) when trying to generate a fresh symbol.",
 | 
			
		||||
	 n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Fix all the unset keylevels
 | 
			
		||||
void
 | 
			
		||||
symbol_fix_keylevels (void)
 | 
			
		||||
 | 
			
		||||
@ -44,6 +44,7 @@ void symbolPrint (const Symbol s);
 | 
			
		||||
void symbolPrintAll (void);
 | 
			
		||||
Symbol symbolSysConst (const char *str);
 | 
			
		||||
void symbol_fix_keylevels (void);
 | 
			
		||||
Symbol symbolNextFree (Symbol prefixsymbol);
 | 
			
		||||
 | 
			
		||||
void eprintf (char *fmt, ...);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								src/term.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/term.c
									
									
									
									
									
								
							@ -1336,3 +1336,19 @@ isLeafNameEqual (Term t1, Term t2)
 | 
			
		||||
{
 | 
			
		||||
  return (TermSymb (t1) == TermSymb (t2));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! Generate a fresh term, that does not occur yet, prefixed with the string of the given term.
 | 
			
		||||
Term
 | 
			
		||||
freshTermPrefix (Term prefixterm)
 | 
			
		||||
{
 | 
			
		||||
  Symbol prefixsymbol;
 | 
			
		||||
  Symbol freshsymbol;
 | 
			
		||||
 | 
			
		||||
  prefixsymbol = NULL;
 | 
			
		||||
  if (prefixterm != NULL && realTermLeaf (prefixterm))
 | 
			
		||||
    {
 | 
			
		||||
      prefixsymbol = TermSymb (prefixterm);
 | 
			
		||||
    }
 | 
			
		||||
  freshsymbol = symbolNextFree (prefixsymbol);
 | 
			
		||||
  return makeTermType (GLOBAL, freshsymbol, -1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -196,5 +196,6 @@ float term_constrain_level (const Term term);
 | 
			
		||||
void term_set_keylevels (const Term term);
 | 
			
		||||
void termPrintDiff (Term t1, Term t2);
 | 
			
		||||
int isLeafNameEqual (Term t1, Term t2);
 | 
			
		||||
Term freshTermPrefix (Term prefixterm);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user