avstring.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  3. * Copyright (c) 2007 Mans Rullgard
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <stdarg.h>
  22. #include <stdint.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include "avstring.h"
  27. #include "mem.h"
  28. int av_strstart(const char *str, const char *pfx, const char **ptr)
  29. {
  30. while (*pfx && *pfx == *str) {
  31. pfx++;
  32. str++;
  33. }
  34. if (!*pfx && ptr)
  35. *ptr = str;
  36. return !*pfx;
  37. }
  38. int av_stristart(const char *str, const char *pfx, const char **ptr)
  39. {
  40. while (*pfx && toupper((unsigned)*pfx) == toupper((unsigned)*str)) {
  41. pfx++;
  42. str++;
  43. }
  44. if (!*pfx && ptr)
  45. *ptr = str;
  46. return !*pfx;
  47. }
  48. char *av_stristr(const char *s1, const char *s2)
  49. {
  50. if (!*s2)
  51. return (char*)(intptr_t)s1;
  52. do {
  53. if (av_stristart(s1, s2, NULL))
  54. return (char*)(intptr_t)s1;
  55. } while (*s1++);
  56. return NULL;
  57. }
  58. size_t av_strlcpy(char *dst, const char *src, size_t size)
  59. {
  60. size_t len = 0;
  61. while (++len < size && *src)
  62. *dst++ = *src++;
  63. if (len <= size)
  64. *dst = 0;
  65. return len + strlen(src) - 1;
  66. }
  67. size_t av_strlcat(char *dst, const char *src, size_t size)
  68. {
  69. size_t len = strlen(dst);
  70. if (size <= len + 1)
  71. return len + strlen(src);
  72. return len + av_strlcpy(dst + len, src, size - len);
  73. }
  74. size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...)
  75. {
  76. int len = strlen(dst);
  77. va_list vl;
  78. va_start(vl, fmt);
  79. len += vsnprintf(dst + len, size > len ? size - len : 0, fmt, vl);
  80. va_end(vl);
  81. return len;
  82. }
  83. char *av_asprintf(const char *fmt, ...)
  84. {
  85. char *p = NULL;
  86. va_list va;
  87. int len;
  88. va_start(va, fmt);
  89. len = vsnprintf(NULL, 0, fmt, va);
  90. va_end(va);
  91. if (len < 0)
  92. goto end;
  93. p = av_malloc(len + 1);
  94. if (!p)
  95. goto end;
  96. va_start(va, fmt);
  97. len = vsnprintf(p, len + 1, fmt, va);
  98. va_end(va);
  99. if (len < 0)
  100. av_freep(&p);
  101. end:
  102. return p;
  103. }
  104. char *av_d2str(double d)
  105. {
  106. char *str= av_malloc(16);
  107. if(str) snprintf(str, 16, "%f", d);
  108. return str;
  109. }
  110. #define WHITESPACES " \n\t"
  111. char *av_get_token(const char **buf, const char *term)
  112. {
  113. char *out = av_malloc(strlen(*buf) + 1);
  114. char *ret= out, *end= out;
  115. const char *p = *buf;
  116. if (!out) return NULL;
  117. p += strspn(p, WHITESPACES);
  118. while(*p && !strspn(p, term)) {
  119. char c = *p++;
  120. if(c == '\\' && *p){
  121. *out++ = *p++;
  122. end= out;
  123. }else if(c == '\''){
  124. while(*p && *p != '\'')
  125. *out++ = *p++;
  126. if(*p){
  127. p++;
  128. end= out;
  129. }
  130. }else{
  131. *out++ = c;
  132. }
  133. }
  134. do{
  135. *out-- = 0;
  136. }while(out >= end && strspn(out, WHITESPACES));
  137. *buf = p;
  138. return ret;
  139. }
  140. char *av_strtok(char *s, const char *delim, char **saveptr)
  141. {
  142. char *tok;
  143. if (!s && !(s = *saveptr))
  144. return NULL;
  145. /* skip leading delimiters */
  146. s += strspn(s, delim);
  147. /* s now points to the first non delimiter char, or to the end of the string */
  148. if (!*s) {
  149. *saveptr = NULL;
  150. return NULL;
  151. }
  152. tok = s++;
  153. /* skip non delimiters */
  154. s += strcspn(s, delim);
  155. if (*s) {
  156. *s = 0;
  157. *saveptr = s+1;
  158. } else {
  159. *saveptr = NULL;
  160. }
  161. return tok;
  162. }
  163. int av_strcasecmp(const char *a, const char *b)
  164. {
  165. uint8_t c1, c2;
  166. do {
  167. c1 = av_tolower(*a++);
  168. c2 = av_tolower(*b++);
  169. } while (c1 && c1 == c2);
  170. return c1 - c2;
  171. }
  172. int av_strncasecmp(const char *a, const char *b, size_t n)
  173. {
  174. const char *end = a + n;
  175. uint8_t c1, c2;
  176. do {
  177. c1 = av_tolower(*a++);
  178. c2 = av_tolower(*b++);
  179. } while (a < end && c1 && c1 == c2);
  180. return c1 - c2;
  181. }
  182. #ifdef TEST
  183. #include "common.h"
  184. #undef printf
  185. int main(void)
  186. {
  187. int i;
  188. printf("Testing av_get_token()\n");
  189. {
  190. const char *strings[] = {
  191. "''",
  192. "",
  193. ":",
  194. "\\",
  195. "'",
  196. " '' :",
  197. " '' '' :",
  198. "foo '' :",
  199. "'foo'",
  200. "foo ",
  201. " ' foo ' ",
  202. "foo\\",
  203. "foo': blah:blah",
  204. "foo\\: blah:blah",
  205. "foo\'",
  206. "'foo : ' :blahblah",
  207. "\\ :blah",
  208. " foo",
  209. " foo ",
  210. " foo \\ ",
  211. "foo ':blah",
  212. " foo bar : blahblah",
  213. "\\f\\o\\o",
  214. "'foo : \\ \\ ' : blahblah",
  215. "'\\fo\\o:': blahblah",
  216. "\\'fo\\o\\:': foo ' :blahblah"
  217. };
  218. for (i=0; i < FF_ARRAY_ELEMS(strings); i++) {
  219. const char *p= strings[i];
  220. printf("|%s|", p);
  221. printf(" -> |%s|", av_get_token(&p, ":"));
  222. printf(" + |%s|\n", p);
  223. }
  224. }
  225. return 0;
  226. }
  227. #endif /* TEST */