[MPlayer-dev-eng] [PATCH] suboption escaping

Joey Parrish joey at nicewarrior.org
Sun Aug 7 01:59:47 CEST 2005


Hello,

Attached is a patch to allow escaping of suboptions.
The biggest reason for this is that without this patch, I keep wanting
to do this:
  $ mencoder -info "title=Star Trek: The Next Generation"
With this patch, you can say:
  $ mencoder -info "title=Star Trek\\: The Next Generation"
One escape shown above is for the shell, one is for mencoder.

I've also attached a second patch with an alternative implementation.
Please comment on the concept, and then one which patch you prefer.

I'd like to commit this soon.

--Joey

-- 
"Sometimes you just have to bow to the absurd." --Picard
-------------- next part --------------
Index: m_option.c
===================================================================
RCS file: /cvsroot/mplayer/main/m_option.c,v
retrieving revision 1.38
diff -u -r1.38 m_option.c
--- m_option.c	20 Jun 2005 23:07:34 -0000	1.38
+++ m_option.c	6 Aug 2005 23:11:06 -0000
@@ -875,6 +875,7 @@
   char *token;
   char *p;
   char** lst = NULL;
+  int len;
 
   if (param == NULL || strlen(param) == 0)
     return M_OPT_MISSING_PARAM;
@@ -886,13 +887,21 @@
   subopts = opt->p;
 
   token = strtok(p, (char *)&(":"));
+  while (token && (len = strlen(token)) && token[len - 1] == '\\')
+    {
+      // replace an escaped colon.
+      token[len - 1] = ':';
+      token[len] = 1; // to remove the nul for strlen next
+      memmove(&(token[len]), &(token[len + 1]), strlen(&(token[len])));
+      strtok(NULL, (char *)&(":"));
+    }
   while(token)
     {
       int sscanf_ret;
       /* clear out */
       subopt[0] = subparam[0] = 0;
-			    
-      sscanf_ret = sscanf(token, "%[^=]=%[^:]", subopt, subparam);
+
+      sscanf_ret = sscanf(token, "%[^=]=%[^=]", subopt, subparam);
 
       mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "token: '%s', subopt='%s', subparam='%s' (ret: %d)\n", token, subopt, subparam, sscanf_ret);
       switch(sscanf_ret)
@@ -923,6 +932,14 @@
 	  return M_OPT_INVALID;
 	}
       token = strtok(NULL, (char *)&(":"));
+      while (token && (len = strlen(token)) && token[len - 1] == '\\')
+        {
+          // replace an escaped colon.
+          token[len - 1] = ':';
+          token[len] = 1; // to remove the nul for strlen next
+          memmove(&(token[len]), &(token[len + 1]), strlen(&(token[len])));
+          strtok(NULL, (char *)&(":"));
+        }
     }
 
   free(subparam);
-------------- next part --------------
Index: m_option.c
===================================================================
RCS file: /cvsroot/mplayer/main/m_option.c,v
retrieving revision 1.38
diff -u -r1.38 m_option.c
--- m_option.c	20 Jun 2005 23:07:34 -0000	1.38
+++ m_option.c	6 Aug 2005 23:42:16 -0000
@@ -867,6 +867,52 @@
 #undef VAL
 #define VAL(x) (*(char***)(x))
 
+static char *strtokex(char *src, const char *delim, const char escape)
+{
+  static char *ptr = NULL;
+  char *ret;
+  char *tmp;
+  int ignore = 0;
+
+  if (src) ptr = src;
+
+  if (!ptr) return NULL;
+  if (!(*ptr)) return NULL;
+  if (!delim) return NULL;
+
+  ret = ptr;
+  while (*ptr)
+    {
+      if (*ptr == escape)
+        {
+          // move the string down, including the nul.
+          memmove(ptr, ptr + 1, strlen(ptr));
+          // advance past the escaped char, and continue.
+          ptr++;
+          continue;
+        }
+      tmp = (char *)delim;
+      while (*tmp)
+        {
+          if (*ptr == *tmp)
+            {
+              // nullify the delimiter, advance the pointer.
+              *ptr = '\0';
+              ptr++;
+              // if this is not the first char, return it.
+              if (ptr != ret + 1)
+                return ret;
+              // otherwise, we will try to return the first non-delim char.
+              ret = ptr;
+              continue;
+            }
+          tmp++;
+        }
+      ptr++;
+    }
+  return ret;
+}
+
 static int parse_subconf(m_option_t* opt,char *name, char *param, void* dst, int src) {
   char *subparam;
   char *subopt;
@@ -885,14 +931,14 @@
 
   subopts = opt->p;
 
-  token = strtok(p, (char *)&(":"));
+  token = strtokex(p, (char *)&(":"), '\\');
   while(token)
     {
       int sscanf_ret;
       /* clear out */
       subopt[0] = subparam[0] = 0;
-			    
-      sscanf_ret = sscanf(token, "%[^=]=%[^:]", subopt, subparam);
+
+      sscanf_ret = sscanf(token, "%[^=]=%[^=]", subopt, subparam);
 
       mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "token: '%s', subopt='%s', subparam='%s' (ret: %d)\n", token, subopt, subparam, sscanf_ret);
       switch(sscanf_ret)
@@ -922,7 +968,7 @@
 	  mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Invalid subconfig argument! ('%s')\n", token);
 	  return M_OPT_INVALID;
 	}
-      token = strtok(NULL, (char *)&(":"));
+      token = strtokex(NULL, (char *)&(":"), '/');
     }
 
   free(subparam);


More information about the MPlayer-dev-eng mailing list