[Aptitude-svn-commit] r3701 - in branches/aptitude-0.3/aptitude: . src/generic

Daniel Burrows dburrows at costa.debian.org
Wed Aug 3 06:12:38 UTC 2005


Author: dburrows
Date: Wed Aug  3 06:12:32 2005
New Revision: 3701

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/generic/matchers.cc
   branches/aptitude-0.3/aptitude/src/generic/matchers.h
Log:
Add core support for nesting matchers in other syntactic constructs.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Wed Aug  3 06:12:32 2005
@@ -1,3 +1,12 @@
+2005-08-02  Daniel Burrows  <dburrows at debian.org>
+
+	* src/generic/matchers.cc, src/generic/matchers.h:
+
+	  Make the parser more generic: you can pass in a set of
+	  characters that should terminate the match if they are
+	  encountered at the top syntactic level.  The loader will use
+	  this (but doesn't yet) to safely split its arguments.
+
 2005-07-27  Daniel Burrows  <dburrows at debian.org>
 
 	* src/generic/matchers.cc, src/generic/matchers.h:

Modified: branches/aptitude-0.3/aptitude/src/generic/matchers.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/matchers.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/matchers.cc	Wed Aug  3 06:12:32 2005
@@ -1515,6 +1515,7 @@
 
 pkg_matcher *parse_condition_list(string::const_iterator &start,
 				  const string::const_iterator &end,
+				  const char *terminators,
 				  bool match_descriptions);
 
 // Returns a substring up to the first metacharacter, including escaped
@@ -1522,7 +1523,8 @@
 //
 // Advances loc to the first character of 's' following the escaped string.
 std::string parse_substr(string::const_iterator &start,
-			 const string::const_iterator &end)
+			 const string::const_iterator &end,
+			 const char *terminators)
 {
   std::string rval="";
   bool done=false;
@@ -1534,7 +1536,8 @@
 	    *start != ')' &&
 	    *start != '!' &&
 	    *start != '~' &&
-	    *start != '|')
+	    *start != '|' &&
+	    strchr(terminators, *start) == NULL)
 	{
 	  rval += *start;
 	  ++start;
@@ -1555,8 +1558,10 @@
 	      start += 2;
 	    }
 	  else
-	    done=true;
+	    done = true;
 	}
+      else
+	done = true;
     } while(!done);
 
   return rval;
@@ -1564,6 +1569,7 @@
 
 pkg_matcher *parse_atom(string::const_iterator &start,
 			const string::const_iterator &end,
+			const char *terminators,
 			bool search_descriptions)
 {
   std::string substr;
@@ -1571,19 +1577,21 @@
   while(start != end && isspace(*start))
     ++start;
 
-  while(start != end && *start != '|' && *start != ')')
+  while(start != end && *start != '|' && *start != ')' &&
+	strchr(terminators, *start) == NULL)
     {
       if(*start == '!')
 	{
 	  ++start;
-	  return new pkg_not_matcher(parse_atom(start, end,
+	  return new pkg_not_matcher(parse_atom(start, end, terminators,
 						search_descriptions));
 	}
       else if(*start == '(')
-	// Recur into the list
+	// Recur into the list, losing the extra terminators (they are
+	// treated normally until the closing paren)
 	{
 	  ++start;
-	  auto_ptr<pkg_matcher> lst(parse_condition_list(start, end,
+	  auto_ptr<pkg_matcher> lst(parse_condition_list(start, end, "",
 							 search_descriptions));
 
 	  if(!(start != end && *start == ')'))
@@ -1650,6 +1658,7 @@
 		  {
 		    auto_ptr<pkg_matcher> m(parse_atom(start,
 						       end,
+						       terminators,
 						       search_descriptions));
 		    
 		    switch(search_flag)
@@ -1668,7 +1677,8 @@
 
 		    string::const_iterator nextstart = start;
 
-		    while(nextstart != end && isalpha(*nextstart))
+		    while(nextstart != end && isalpha(*nextstart) &&
+			  strchr(terminators, *nextstart) == NULL)
 		      ++nextstart;
 
 		    if(nextstart != end && *nextstart == ':')
@@ -1690,7 +1700,7 @@
 			  }
 		      }
 
-		    auto_ptr<pkg_matcher> m(parse_atom(start, end,
+		    auto_ptr<pkg_matcher> m(parse_atom(start, end, terminators,
 						       search_descriptions));
 
 		    switch(search_flag)
@@ -1708,7 +1718,7 @@
 		      }
 		  }
 		default:
-		  substr=parse_substr(start, end);
+		  substr=parse_substr(start, end, terminators);
 		  switch(search_flag)
 		    {
 		    case 'a':
@@ -1816,10 +1826,11 @@
       else
 	{
 	  if(!search_descriptions)
-	    return new pkg_name_matcher(parse_substr(start, end));
+	    return new pkg_name_matcher(parse_substr(start, end,
+						     terminators));
 	  else
 	    {
-	      substr=parse_substr(start, end);
+	      substr=parse_substr(start, end, terminators);
 	      auto_ptr<pkg_matcher> name(new pkg_name_matcher(substr));
 	      auto_ptr<pkg_matcher> desc(new pkg_description_matcher(substr));
 
@@ -1835,27 +1846,30 @@
 
 pkg_matcher *parse_and_group(string::const_iterator &start,
 			     const string::const_iterator &end,
+			     const char *terminators,
 			     bool search_descriptions)
 {
   auto_ptr<pkg_matcher> rval(NULL);
   while(start != end && isspace(*start))
     ++start;
 
-  while(start != end && *start != '|' && *start != ')')
+  while(start != end && *start != '|' && *start != ')' &&
+	strchr(terminators, *start) == NULL)
     {
-      auto_ptr<pkg_matcher> atom(parse_atom(start, end,
+      auto_ptr<pkg_matcher> atom(parse_atom(start, end, terminators,
 					    search_descriptions));
 
-      if(rval.get()==NULL)
+      if(rval.get() == NULL)
 	rval = atom;
       else
 	rval = auto_ptr<pkg_matcher>(new pkg_and_matcher(rval.release(), atom.release()));
 
-      while(start != end && isspace(*start))
+      while(start != end && isspace(*start) &&
+	    strchr(terminators, *start) == NULL)
 	++start;
     }
 
-  if(rval.get()==NULL)
+  if(rval.get() == NULL)
     throw CompilationException(_("Unexpected empty expression"));
 
   return rval.release();
@@ -1863,20 +1877,21 @@
 
 pkg_matcher *parse_condition_list(string::const_iterator &start,
 				  const string::const_iterator &end,
+				  const char *terminators,
 				  bool search_descriptions)
 {
-  auto_ptr<pkg_matcher> grp(parse_and_group(start, end,
+  auto_ptr<pkg_matcher> grp(parse_and_group(start, end, terminators,
 					    search_descriptions));
 
-  while(start != end && isspace(*start))
+  while(start != end && isspace(*start) && strchr(terminators, *start) == NULL)
     ++start;
 
-  while(start != end && *start != ')')
+  while(start != end && *start != ')' && strchr(terminators, *start) == NULL)
     {
       if(start != end && *start == '|')
 	{
 	  ++start;
-	  auto_ptr<pkg_matcher> grp2(parse_condition_list(start, end,
+	  auto_ptr<pkg_matcher> grp2(parse_condition_list(start, end, terminators,
 							  search_descriptions));
 
 	  return new pkg_or_matcher(grp.release(), grp2.release());
@@ -1896,12 +1911,13 @@
 
 pkg_matcher *parse_pattern(string::const_iterator &start,
 			   const string::const_iterator &end,
+			   const char *terminators,
 			   bool search_descriptions,
 			   bool flag_errors,
 			   bool require_full_parse)
 {
   // Just filter blank strings out immediately.
-  while(start != end && isspace(*start))
+  while(start != end && isspace(*start) && strchr(terminators, *start) == NULL)
     ++start;
 
   if(start == end)
@@ -1909,7 +1925,7 @@
 
   try
     {
-      auto_ptr<pkg_matcher> rval(parse_condition_list(start, end,
+      auto_ptr<pkg_matcher> rval(parse_condition_list(start, end, terminators,
 						      search_descriptions));
 
       if(require_full_parse && start != end)

Modified: branches/aptitude-0.3/aptitude/src/generic/matchers.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/matchers.h	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/matchers.h	Wed Aug  3 06:12:32 2005
@@ -60,14 +60,19 @@
 };
 
 /** Parse the given pattern, returning a matcher.  start will be
- *  modified to point to the first unparsable location.
+ *  modified to point to the first unparsable location.  The parse
+ *  will terminate when a closing parenthesis or an element of
+ *  terminators is encountered at the top syntax level.
  *
  *  \param start the beginning of the range to parse
  *  \param end the end of the range to parse
+ *  \param terminators a set of characters whose presence at the top
+ *                     syntactic level should cause the parse to
+ *                     terminate.
  *  \param search_descriptions if \b true, then strings without an
  *                     explicit pattern escape will be used to search
  *                     both names and descriptions rather than
- *                     names alone
+ *                     names alone.
  *  \param flag_errors if \b true, then error messages will be generated
  *                     for incorrect patterns.
  *  \param require_full_parse if \b true, then an error will be signalled
@@ -78,16 +83,19 @@
  */
 pkg_matcher *parse_pattern(std::string::const_iterator &start,
 			   const std::string::const_iterator &end,
+			   const char *terminators="",
 			   bool search_descriptions=false,
 			   bool flag_errors=true,
 			   bool require_full_parse=true);
 
 inline pkg_matcher *parse_pattern(const std::string &s,
+				  const char *terminators="",
 				  bool search_descriptions = false,
 				  bool flag_errors = true)
 {
   std::string::const_iterator start = s.begin();
-  return parse_pattern(start, s.end(), search_descriptions, flag_errors,
+  return parse_pattern(start, s.end(), terminators,
+		       search_descriptions, flag_errors,
 		       true);
 }
 



More information about the Aptitude-svn-commit mailing list