libc.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:19k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * libc.c: Extra libc function for some systems.
  3.  *****************************************************************************
  4.  * Copyright (C) 2002 VideoLAN
  5.  * $Id: libc.c 9292 2004-11-12 10:44:50Z gbazin $
  6.  *
  7.  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
  8.  *          Samuel Hocevar <sam@zoy.org>
  9.  *          Gildas Bazin <gbazin@videolan.org>
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  24.  *****************************************************************************/
  25. #include <string.h>                                              /* strdup() */
  26. #include <stdlib.h>
  27. #include <ctype.h>
  28. #include <vlc/vlc.h>
  29. #undef iconv_t
  30. #undef iconv_open
  31. #undef iconv
  32. #undef iconv_close
  33. #if defined(HAVE_ICONV)
  34. #   include <iconv.h>
  35. #endif
  36. /*****************************************************************************
  37.  * getenv: just in case, but it should never be called
  38.  *****************************************************************************/
  39. #if !defined( HAVE_GETENV )
  40. char *vlc_getenv( const char *name )
  41. {
  42.     return NULL;
  43. }
  44. #endif
  45. /*****************************************************************************
  46.  * strdup: returns a malloc'd copy of a string
  47.  *****************************************************************************/
  48. #if !defined( HAVE_STRDUP )
  49. char *vlc_strdup( const char *string )
  50. {
  51.     return strndup( string, strlen( string ) );
  52. }
  53. #endif
  54. /*****************************************************************************
  55.  * strndup: returns a malloc'd copy of at most n bytes of string
  56.  * Does anyone know whether or not it will be present in Jaguar?
  57.  *****************************************************************************/
  58. #if !defined( HAVE_STRNDUP )
  59. char *vlc_strndup( const char *string, size_t n )
  60. {
  61.     char *psz;
  62.     size_t len = strlen( string );
  63.     len = __MIN( len, n );
  64.     psz = (char*)malloc( len + 1 );
  65.     if( psz != NULL )
  66.     {
  67.         memcpy( (void*)psz, (const void*)string, len );
  68.         psz[ len ] = 0;
  69.     }
  70.     return psz;
  71. }
  72. #endif
  73. /*****************************************************************************
  74.  * strcasecmp: compare two strings ignoring case
  75.  *****************************************************************************/
  76. #if !defined( HAVE_STRCASECMP ) && !defined( HAVE_STRICMP )
  77. int vlc_strcasecmp( const char *s1, const char *s2 )
  78. {
  79.     int i_delta = 0;
  80.     if( !s1 || !s2 ) return  -1;
  81.     while( !i_delta && *s1 && *s2 )
  82.     {
  83.         i_delta = *s1 - *s2;
  84.         if( *s1 >= 'A' && *s1 <= 'Z' )
  85.         {
  86.             i_delta -= ('A' - 'a');
  87.         }
  88.         if( *s2 >= 'A' && *s2 <= 'Z' )
  89.         {
  90.             i_delta += ('A' - 'a');
  91.         }
  92.         s1++; s2++;
  93.     }
  94.     if( !i_delta && (*s1 || *s2) ) i_delta = *s1 ? 1 : -1;
  95.     return i_delta;
  96. }
  97. #endif
  98. /*****************************************************************************
  99.  * strncasecmp: compare n chars from two strings ignoring case
  100.  *****************************************************************************/
  101. #if !defined( HAVE_STRNCASECMP ) && !defined( HAVE_STRNICMP )
  102. int vlc_strncasecmp( const char *s1, const char *s2, size_t n )
  103. {
  104.     int i_delta = 0;
  105.     if( !s1 || !s2 ) return  -1;
  106.     while( n-- && !i_delta && *s1 && *s2 )
  107.     {
  108.         i_delta = *s1 - *s2;
  109.         if( *s1 >= 'A' && *s1 <= 'Z' )
  110.         {
  111.             i_delta -= 'A' - 'a';
  112.         }
  113.         if( *s2 >= 'A' && *s2 <= 'Z' )
  114.         {
  115.             i_delta += 'A' - 'a';
  116.         }
  117.         s1++; s2++;
  118.     }
  119.     if( !n && !i_delta && (*s1 || *s2) ) i_delta = *s1 ? 1 : -1;
  120.     return i_delta;
  121. }
  122. #endif
  123. /******************************************************************************
  124.  * strcasestr: find a substring (little) in another substring (big)
  125.  * Case sensitive. Return NULL if not found, return big if little == null
  126.  *****************************************************************************/
  127. #if !defined( HAVE_STRCASESTR ) && !defined( HAVE_STRISTR )
  128. char * vlc_strcasestr( const char *psz_big, const char *psz_little )
  129. {
  130.     char *p_pos = (char *)psz_big;
  131.     if( !psz_big || !psz_little || !*psz_little ) return p_pos;
  132.  
  133.     while( *p_pos ) 
  134.     {
  135.         if( toupper( *p_pos ) == toupper( *psz_little ) )
  136.         {
  137.             char * psz_cur1 = p_pos + 1;
  138.             char * psz_cur2 = (char *)psz_little + 1;
  139.             while( *psz_cur1 && *psz_cur2 &&
  140.                    toupper( *psz_cur1 ) == toupper( *psz_cur2 ) )
  141.             {
  142.                 psz_cur1++;
  143.                 psz_cur2++;
  144.             }
  145.             if( !*psz_cur2 ) return p_pos;
  146.         }
  147.         p_pos++;
  148.     }
  149.     return NULL;
  150. }
  151. #endif
  152. /*****************************************************************************
  153.  * vasprintf:
  154.  *****************************************************************************/
  155. #if !defined(HAVE_VASPRINTF) || defined(SYS_DARWIN) || defined(SYS_BEOS)
  156. int vlc_vasprintf(char **strp, const char *fmt, va_list ap)
  157. {
  158.     /* Guess we need no more than 100 bytes. */
  159.     int     i_size = 100;
  160.     char    *p = malloc( i_size );
  161.     int     n;
  162.     if( p == NULL )
  163.     {
  164.         *strp = NULL;
  165.         return -1;
  166.     }
  167.     for( ;; )
  168.     {
  169.         /* Try to print in the allocated space. */
  170.         n = vsnprintf( p, i_size, fmt, ap );
  171.         /* If that worked, return the string. */
  172.         if (n > -1 && n < i_size)
  173.         {
  174.             *strp = p;
  175.             return strlen( p );
  176.         }
  177.         /* Else try again with more space. */
  178.         if (n > -1)    /* glibc 2.1 */
  179.         {
  180.            i_size = n+1; /* precisely what is needed */
  181.         }
  182.         else           /* glibc 2.0 */
  183.         {
  184.            i_size *= 2;  /* twice the old size */
  185.         }
  186.         if( (p = realloc( p, i_size ) ) == NULL)
  187.         {
  188.             *strp = NULL;
  189.             return -1;
  190.         }
  191.     }
  192. }
  193. #endif
  194. /*****************************************************************************
  195.  * asprintf:
  196.  *****************************************************************************/
  197. #if !defined(HAVE_ASPRINTF) || defined(SYS_DARWIN) || defined(SYS_BEOS)
  198. int vlc_asprintf( char **strp, const char *fmt, ... )
  199. {
  200.     va_list args;
  201.     int i_ret;
  202.     va_start( args, fmt );
  203.     i_ret = vasprintf( strp, fmt, args );
  204.     va_end( args );
  205.     return i_ret;
  206. }
  207. #endif
  208. /*****************************************************************************
  209.  * atof: convert a string to a double.
  210.  *****************************************************************************/
  211. #if !defined( HAVE_ATOF )
  212. double vlc_atof( const char *nptr )
  213. {
  214.     double f_result;
  215.     wchar_t *psz_tmp;
  216.     int i_len = strlen( nptr ) + 1;
  217.     psz_tmp = malloc( i_len * sizeof(wchar_t) );
  218.     MultiByteToWideChar( CP_ACP, 0, nptr, -1, psz_tmp, i_len );
  219.     f_result = wcstod( psz_tmp, NULL );
  220.     free( psz_tmp );
  221.     return f_result;
  222. }
  223. #endif
  224. /*****************************************************************************
  225.  * strtoll: convert a string to a 64 bits int.
  226.  *****************************************************************************/
  227. #if !defined( HAVE_STRTOLL )
  228. int64_t vlc_strtoll( const char *nptr, char **endptr, int base )
  229. {
  230.     int64_t i_value = 0;
  231.     int sign = 1, newbase = base ? base : 10;
  232.     while( isspace(*nptr) ) nptr++;
  233.     if( *nptr == '-' )
  234.     {
  235.         sign = -1;
  236.         nptr++;
  237.     }
  238.     /* Try to detect base */
  239.     if( *nptr == '0' )
  240.     {
  241.         newbase = 8;
  242.         nptr++;
  243.         if( *nptr == 'x' )
  244.         {
  245.             newbase = 16;
  246.             nptr++;
  247.         }
  248.     }
  249.     if( base && newbase != base )
  250.     {
  251.         if( endptr ) *endptr = (char *)nptr;
  252.         return i_value;
  253.     }
  254.     switch( newbase )
  255.     {
  256.         case 10:
  257.             while( *nptr >= '0' && *nptr <= '9' )
  258.             {
  259.                 i_value *= 10;
  260.                 i_value += ( *nptr++ - '0' );
  261.             }
  262.             if( endptr ) *endptr = (char *)nptr;
  263.             break;
  264.         case 16:
  265.             while( (*nptr >= '0' && *nptr <= '9') ||
  266.                    (*nptr >= 'a' && *nptr <= 'f') ||
  267.                    (*nptr >= 'A' && *nptr <= 'F') )
  268.             {
  269.                 int i_valc = 0;
  270.                 if(*nptr >= '0' && *nptr <= '9') i_valc = *nptr - '0';
  271.                 else if(*nptr >= 'a' && *nptr <= 'f') i_valc = *nptr - 'a' +10;
  272.                 else if(*nptr >= 'A' && *nptr <= 'F') i_valc = *nptr - 'A' +10;
  273.                 i_value *= 16;
  274.                 i_value += i_valc;
  275.                 nptr++;
  276.             }
  277.             if( endptr ) *endptr = (char *)nptr;
  278.             break;
  279.         default:
  280.             i_value = strtol( nptr, endptr, newbase );
  281.             break;
  282.     }
  283.     return i_value * sign;
  284. }
  285. #endif
  286. /*****************************************************************************
  287.  * atoll: convert a string to a 64 bits int.
  288.  *****************************************************************************/
  289. #if !defined( HAVE_ATOLL )
  290. int64_t vlc_atoll( const char *nptr )
  291. {
  292.     return strtoll( nptr, (char **)NULL, 10 );
  293. }
  294. #endif
  295. /*****************************************************************************
  296.  * lseek: reposition read/write file offset.
  297.  *****************************************************************************
  298.  * FIXME: this cast sucks!
  299.  *****************************************************************************/
  300. #if !defined( HAVE_LSEEK )
  301. off_t vlc_lseek( int fildes, off_t offset, int whence )
  302. {
  303.     return SetFilePointer( (HANDLE)fildes, (long)offset, NULL, whence );
  304. }
  305. #endif
  306. /*****************************************************************************
  307.  * dgettext: gettext for plugins.
  308.  *****************************************************************************/
  309. char *vlc_dgettext( const char *package, const char *msgid )
  310. {
  311. #if defined( ENABLE_NLS ) 
  312.      && ( defined(HAVE_GETTEXT) || defined(HAVE_INCLUDED_GETTEXT) )
  313.     return dgettext( package, msgid );
  314. #else
  315.     return (char *)msgid;
  316. #endif
  317. }
  318. /*****************************************************************************
  319.  * count_utf8_string: returns the number of characters in the string.
  320.  *****************************************************************************/
  321. static int count_utf8_string( const char *psz_string )
  322. {
  323.     int i = 0, i_count = 0;
  324.     while( psz_string[ i ] != 0 )
  325.     {
  326.         if( ((unsigned char *)psz_string)[ i ] <  0x80UL ) i_count++;
  327.         i++;
  328.     }
  329.     return i_count;
  330. }
  331. /*****************************************************************************
  332.  * wraptext: inserts n at convenient places to wrap the text.
  333.  *           Returns the modified string in a new buffer.
  334.  *****************************************************************************/
  335. char *vlc_wraptext( const char *psz_text, int i_line, vlc_bool_t b_utf8 )
  336. {
  337.     int i_len;
  338.     char *psz_line, *psz_new_text;
  339.     psz_line = psz_new_text = strdup( psz_text );
  340.     if( b_utf8 )
  341.         i_len = count_utf8_string( psz_text );
  342.     else
  343.         i_len = strlen( psz_text );
  344.     while( i_len > i_line )
  345.     {
  346.         /* Look if there is a newline somewhere. */
  347.         char *psz_parser = psz_line;
  348.         int i_count = 0;
  349.         while( i_count <= i_line && *psz_parser != 'n' )
  350.         {
  351.             if( b_utf8 )
  352.             {
  353.                 while( *((unsigned char *)psz_parser) >= 0x80UL ) psz_parser++;
  354.             }
  355.             psz_parser++;
  356.             i_count++;
  357.         }
  358.         if( *psz_parser == 'n' )
  359.         {
  360.             i_len -= (i_count + 1);
  361.             psz_line = psz_parser + 1;
  362.             continue;
  363.         }
  364.         /* Find the furthest space. */
  365.         while( psz_parser > psz_line && *psz_parser != ' ' )
  366.         {
  367.             if( b_utf8 )
  368.             {
  369.                 while( *((unsigned char *)psz_parser) >= 0x80UL ) psz_parser--;
  370.             }
  371.             psz_parser--;
  372.             i_count--;
  373.         }
  374.         if( *psz_parser == ' ' )
  375.         {
  376.             *psz_parser = 'n';
  377.             i_len -= (i_count + 1);
  378.             psz_line = psz_parser + 1;
  379.             continue;
  380.         }
  381.         /* Wrapping has failed. Find the first space or newline */
  382.         while( i_count < i_len && *psz_parser != ' ' && *psz_parser != 'n' )
  383.         {
  384.             if( b_utf8 )
  385.             {
  386.                 while( *((unsigned char *)psz_parser) >= 0x80UL ) psz_parser++;
  387.             }
  388.             psz_parser++;
  389.             i_count++;
  390.         }
  391.         if( i_count < i_len ) *psz_parser = 'n';
  392.         i_len -= (i_count + 1);
  393.         psz_line = psz_parser + 1;
  394.     }
  395.     return psz_new_text;
  396. }
  397. /*****************************************************************************
  398.  * iconv wrapper
  399.  *****************************************************************************/
  400. vlc_iconv_t vlc_iconv_open( const char *tocode, const char *fromcode )
  401. {
  402. #if defined(HAVE_ICONV)
  403.     return iconv_open( tocode, fromcode );
  404. #else
  405.     return NULL;
  406. #endif
  407. }
  408. size_t vlc_iconv( vlc_iconv_t cd, char **inbuf, size_t *inbytesleft,
  409.                   char **outbuf, size_t *outbytesleft )
  410. {
  411. #if defined(HAVE_ICONV)
  412.     return iconv( cd, inbuf, inbytesleft, outbuf, outbytesleft );
  413. #else
  414.     int i_bytes = __MIN(*inbytesleft, *outbytesleft);
  415.     if( !inbuf || !outbuf || !i_bytes ) return (size_t)(-1);
  416.     memcpy( *outbuf, *inbuf, i_bytes );
  417.     inbuf += i_bytes;
  418.     outbuf += i_bytes;
  419.     inbytesleft -= i_bytes;
  420.     outbytesleft -= i_bytes;
  421.     return i_bytes;
  422. #endif
  423. }
  424. int vlc_iconv_close( vlc_iconv_t cd )
  425. {
  426. #if defined(HAVE_ICONV)
  427.     return iconv_close( cd );
  428. #else
  429.     return 0;
  430. #endif
  431. }
  432. /*****************************************************************************
  433.  * reduce a fraction
  434.  *   (adapted from libavcodec, author Michael Niedermayer <michaelni@gmx.at>)
  435.  *****************************************************************************/
  436. vlc_bool_t vlc_reduce( int *pi_dst_nom, int *pi_dst_den,
  437.                        int64_t i_nom, int64_t i_den, int64_t i_max )
  438. {
  439.     vlc_bool_t b_exact = 1, b_sign = 0;
  440.     int64_t i_gcd;
  441.     if( i_den == 0 )
  442.     {
  443.         *pi_dst_nom = 0;
  444.         *pi_dst_den = 1;
  445.         return 1;
  446.     }
  447.     if( i_den < 0 )
  448.     {
  449.         i_den = - i_den;
  450.         i_nom = - i_nom;
  451.     }
  452.     if( i_nom < 0 )
  453.     {
  454.         i_nom = - i_nom;
  455.         b_sign = 1;
  456.     }
  457.     i_gcd = GCD( i_nom, i_den );
  458.     i_nom /= i_gcd;
  459.     i_den /= i_gcd;
  460.     if( i_max == 0 ) i_max = I64C(0xFFFFFFFF);
  461.     if( i_nom > i_max || i_den > i_max )
  462.     {
  463.         int i_a0_num = 0, i_a0_den = 1, i_a1_num = 1, i_a1_den = 0;
  464.         b_exact = 0;
  465.         for( ; ; )
  466.         {
  467.             int64_t i_x = i_nom / i_den;
  468.             int64_t i_a2n = i_x * i_a1_num + i_a0_num;
  469.             int64_t i_a2d = i_x * i_a1_den + i_a0_den;
  470.             if( i_a2n > i_max || i_a2d > i_max ) break;
  471.             i_nom %= i_den;
  472.             i_a0_num = i_a1_num; i_a0_den = i_a1_den;
  473.             i_a1_num = i_a2n; i_a1_den = i_a2d;
  474.             if( i_nom == 0 ) break;
  475.             i_x = i_nom; i_nom = i_den; i_den = i_x;
  476.         }
  477.         i_nom = i_a1_num;
  478.         i_den = i_a1_den;
  479.     }
  480.     if( b_sign ) i_nom = - i_nom;
  481.     *pi_dst_nom = i_nom;
  482.     *pi_dst_den = i_den;
  483.     return b_exact;
  484. }
  485. /*************************************************************************
  486.  * vlc_parse_cmdline: Command line parsing into elements.
  487.  *
  488.  * The command line is composed of space/tab separated arguments.
  489.  * Quotes can be used as argument delimiters and a backslash can be used to
  490.  * escape a quote.
  491.  *************************************************************************/
  492. static void find_end_quote( char **s, char **ppsz_parser, int i_quote )
  493. {
  494.     int i_bcount = 0;
  495.     while( **s )
  496.     {
  497.         if( **s == '\' )
  498.         {
  499.             **ppsz_parser = **s;
  500.             (*ppsz_parser)++; (*s)++;
  501.             i_bcount++;
  502.         }
  503.         else if( **s == '"' || **s == ''' )
  504.         {
  505.             /* Preceeded by a number of '' which we erase. */
  506.             *ppsz_parser -= i_bcount / 2;
  507.             if( i_bcount & 1 )
  508.             {
  509.                 /* '\' followed by a '"' or ''' */
  510.                 *ppsz_parser -= 1;
  511.                 **ppsz_parser = **s;
  512.                 (*ppsz_parser)++; (*s)++;
  513.                 i_bcount = 0;
  514.                 continue;
  515.             }
  516.             if( **s == i_quote )
  517.             {
  518.                 /* End */
  519.                 return;
  520.             }
  521.             else
  522.             {
  523.                 /* Different quoting */
  524.                 int i_quote = **s;
  525.                 **ppsz_parser = **s;
  526.                 (*ppsz_parser)++; (*s)++;
  527.                 find_end_quote( s, ppsz_parser, i_quote );
  528.                 **ppsz_parser = **s;
  529.                 (*ppsz_parser)++; (*s)++;
  530.             }
  531.             i_bcount = 0;
  532.         }
  533.         else
  534.         {
  535.             /* A regular character */
  536.             **ppsz_parser = **s;
  537.             (*ppsz_parser)++; (*s)++;
  538.             i_bcount = 0;
  539.         }
  540.     }
  541. }
  542. char **vlc_parse_cmdline( const char *psz_cmdline, int *i_args )
  543. {
  544.     int argc = 0;
  545.     char **argv = 0;
  546.     char *s, *psz_parser, *psz_arg, *psz_orig;
  547.     int i_bcount = 0;
  548.     if( !psz_cmdline ) return 0;
  549.     psz_orig = strdup( psz_cmdline );
  550.     psz_arg = psz_parser = s = psz_orig;
  551.     while( *s )
  552.     {
  553.         if( *s == 't' || *s == ' ' )
  554.         {
  555.             /* We have a complete argument */
  556.             *psz_parser = 0;
  557.             TAB_APPEND( argc, argv, strdup(psz_arg) );
  558.             /* Skip trailing spaces/tabs */
  559.             do{ s++; } while( *s == 't' || *s == ' ' );
  560.             /* New argument */
  561.             psz_arg = psz_parser = s;
  562.             i_bcount = 0;
  563.         }
  564.         else if( *s == '\' )
  565.         {
  566.             *psz_parser++ = *s++;
  567.             i_bcount++;
  568.         }
  569.         else if( *s == '"' || *s == ''' )
  570.         {
  571.             if( ( i_bcount & 1 ) == 0 )
  572.             {
  573.                 /* Preceeded by an even number of '', this is half that
  574.                  * number of '', plus a quote which we erase. */
  575.                 int i_quote = *s;
  576.                 psz_parser -= i_bcount / 2;
  577.                 s++;
  578.                 find_end_quote( &s, &psz_parser, i_quote );
  579.                 s++;
  580.             }
  581.             else
  582.             {
  583.                 /* Preceeded by an odd number of '', this is half that
  584.                  * number of '' followed by a '"' */
  585.                 psz_parser = psz_parser - i_bcount/2 - 1;
  586.                 *psz_parser++ = '"';
  587.                 s++;
  588.             }
  589.             i_bcount = 0;
  590.         }
  591.         else
  592.         {
  593.             /* A regular character */
  594.             *psz_parser++ = *s++;
  595.             i_bcount = 0;
  596.         }
  597.     }
  598.     /* Take care of the last arg */
  599.     if( *psz_arg )
  600.     {
  601.         *psz_parser = '';
  602.         TAB_APPEND( argc, argv, strdup(psz_arg) );
  603.     }
  604.     if( i_args ) *i_args = argc;
  605.     free( psz_orig );
  606.     return argv;
  607. }