]> git.sesse.net Git - vlc/blobdiff - src/extras/libc.c
Make Zorglub less unhappy
[vlc] / src / extras / libc.c
index 23ad490ea51288d74744a9a5b9656426b5dd84d4..06d5e27425872431743f7c3b653b28fae5b986cf 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * libc.c: Extra libc function for some systems.
  *****************************************************************************
- * Copyright (C) 2002 VideoLAN
+ * Copyright (C) 2002 the VideoLAN team
  * $Id$
  *
  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
@@ -86,29 +86,20 @@ char *vlc_strndup( const char *string, size_t n )
 #if !defined( HAVE_STRCASECMP ) && !defined( HAVE_STRICMP )
 int vlc_strcasecmp( const char *s1, const char *s2 )
 {
-    int i_delta = 0;
+    int c1, c2;
     if( !s1 || !s2 ) return  -1;
 
-    while( !i_delta && *s1 && *s2 )
+    while( *s1 && *s2 )
     {
-        i_delta = *s1 - *s2;
-
-        if( *s1 >= 'A' && *s1 <= 'Z' )
-        {
-            i_delta -= ('A' - 'a');
-        }
-
-        if( *s2 >= 'A' && *s2 <= 'Z' )
-        {
-            i_delta += ('A' - 'a');
-        }
+        c1 = tolower(*s1);
+        c2 = tolower(*s2);
 
+        if( c1 != c2 ) return (c1 < c2 ? -1 : 1);
         s1++; s2++;
     }
 
-    if( !i_delta && (*s1 || *s2) ) i_delta = *s1 ? 1 : -1;
-
-    return i_delta;
+    if( !*s1 && !*s2 ) return 0;
+    else return (*s1 ? 1 : -1);
 }
 #endif
 
@@ -118,29 +109,20 @@ int vlc_strcasecmp( const char *s1, const char *s2 )
 #if !defined( HAVE_STRNCASECMP ) && !defined( HAVE_STRNICMP )
 int vlc_strncasecmp( const char *s1, const char *s2, size_t n )
 {
-    int i_delta = 0;
+    int c1, c2;
     if( !s1 || !s2 ) return  -1;
 
-    while( n-- && !i_delta && *s1 && *s2 )
+    while( n > 0 && *s1 && *s2 )
     {
-        i_delta = *s1 - *s2;
+        c1 = tolower(*s1);
+        c2 = tolower(*s2);
 
-        if( *s1 >= 'A' && *s1 <= 'Z' )
-        {
-            i_delta -= 'A' - 'a';
-        }
-
-        if( *s2 >= 'A' && *s2 <= 'Z' )
-        {
-            i_delta += 'A' - 'a';
-        }
-
-        s1++; s2++;
+        if( c1 != c2 ) return (c1 < c2 ? -1 : 1);
+        s1++; s2++; n--;
     }
 
-    if( !n && !i_delta && (*s1 || *s2) ) i_delta = *s1 ? 1 : -1;
-
-    return i_delta;
+    if( !n || (!*s1 && !*s2) ) return 0;
+    else return (*s1 ? 1 : -1);
 }
 #endif
 
@@ -339,18 +321,6 @@ int64_t vlc_atoll( const char *nptr )
 }
 #endif
 
-/*****************************************************************************
- * lseek: reposition read/write file offset.
- *****************************************************************************
- * FIXME: this cast sucks!
- *****************************************************************************/
-#if !defined( HAVE_LSEEK )
-off_t vlc_lseek( int fildes, off_t offset, int whence )
-{
-    return SetFilePointer( (HANDLE)fildes, (long)offset, NULL, whence );
-}
-#endif
-
 /*****************************************************************************
  * dgettext: gettext for plugins.
  *****************************************************************************/
@@ -555,3 +525,137 @@ vlc_bool_t vlc_reduce( int *pi_dst_nom, int *pi_dst_den,
 
     return b_exact;
 }
+
+/*************************************************************************
+ * vlc_parse_cmdline: Command line parsing into elements.
+ *
+ * The command line is composed of space/tab separated arguments.
+ * Quotes can be used as argument delimiters and a backslash can be used to
+ * escape a quote.
+ *************************************************************************/
+static void find_end_quote( char **s, char **ppsz_parser, int i_quote )
+{
+    int i_bcount = 0;
+
+    while( **s )
+    {
+        if( **s == '\\' )
+        {
+            **ppsz_parser = **s;
+            (*ppsz_parser)++; (*s)++;
+            i_bcount++;
+        }
+        else if( **s == '"' || **s == '\'' )
+        {
+            /* Preceeded by a number of '\' which we erase. */
+            *ppsz_parser -= i_bcount / 2;
+            if( i_bcount & 1 )
+            {
+                /* '\\' followed by a '"' or '\'' */
+                *ppsz_parser -= 1;
+                **ppsz_parser = **s;
+                (*ppsz_parser)++; (*s)++;
+                i_bcount = 0;
+                continue;
+            }
+
+            if( **s == i_quote )
+            {
+                /* End */
+                return;
+            }
+            else
+            {
+                /* Different quoting */
+                int i_quote = **s;
+                **ppsz_parser = **s;
+                (*ppsz_parser)++; (*s)++;
+                find_end_quote( s, ppsz_parser, i_quote );
+                **ppsz_parser = **s;
+                (*ppsz_parser)++; (*s)++;
+            }
+
+            i_bcount = 0;
+        }
+        else
+        {
+            /* A regular character */
+            **ppsz_parser = **s;
+            (*ppsz_parser)++; (*s)++;
+            i_bcount = 0;
+        }
+    }
+}
+
+char **vlc_parse_cmdline( const char *psz_cmdline, int *i_args )
+{
+    int argc = 0;
+    char **argv = 0;
+    char *s, *psz_parser, *psz_arg, *psz_orig;
+    int i_bcount = 0;
+
+    if( !psz_cmdline ) return 0;
+    psz_orig = strdup( psz_cmdline );
+    psz_arg = psz_parser = s = psz_orig;
+
+    while( *s )
+    {
+        if( *s == '\t' || *s == ' ' )
+        {
+            /* We have a complete argument */
+            *psz_parser = 0;
+            TAB_APPEND( argc, argv, strdup(psz_arg) );
+
+            /* Skip trailing spaces/tabs */
+            do{ s++; } while( *s == '\t' || *s == ' ' );
+
+            /* New argument */
+            psz_arg = psz_parser = s;
+            i_bcount = 0;
+        }
+        else if( *s == '\\' )
+        {
+            *psz_parser++ = *s++;
+            i_bcount++;
+        }
+        else if( *s == '"' || *s == '\'' )
+        {
+            if( ( i_bcount & 1 ) == 0 )
+            {
+                /* Preceeded by an even number of '\', this is half that
+                 * number of '\', plus a quote which we erase. */
+                int i_quote = *s;
+                psz_parser -= i_bcount / 2;
+                s++;
+                find_end_quote( &s, &psz_parser, i_quote );
+                s++;
+            }
+            else
+            {
+                /* Preceeded by an odd number of '\', this is half that
+                 * number of '\' followed by a '"' */
+                psz_parser = psz_parser - i_bcount/2 - 1;
+                *psz_parser++ = '"';
+                s++;
+            }
+            i_bcount = 0;
+        }
+        else
+        {
+            /* A regular character */
+            *psz_parser++ = *s++;
+            i_bcount = 0;
+        }
+    }
+
+    /* Take care of the last arg */
+    if( *psz_arg )
+    {
+        *psz_parser = '\0';
+        TAB_APPEND( argc, argv, strdup(psz_arg) );
+    }
+
+    if( i_args ) *i_args = argc;
+    free( psz_orig );
+    return argv;
+}