strfunc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. /*
  2. 从rotpV3平台拷贝过来的函数,考虑到cpu特性和应用,没有全部拷贝过来,只拷贝了常用的几个函数
  3. ** Description: 字符串相关的工具函数
  4. **
  5. */
  6. #include <stdarg.h>
  7. #include <ctype.h>
  8. #include "stdio.h"
  9. #include "string.h"
  10. #include "macro_common.h"
  11. /*lint -save -e713 -e715 -e732 -e737 -e415 -e661 -e530*/
  12. static void dopr (char *buffer, size_t maxlen, const char *format,
  13. va_list args);
  14. static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
  15. const char *value, int flags, int min, int max);
  16. static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
  17. long value, int base, int min, int max, int flags);
  18. static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
  19. /*
  20. * dopr(): poor man's version of doprintf
  21. */
  22. /* format read states */
  23. #define DP_S_DEFAULT 0
  24. #define DP_S_FLAGS 1
  25. #define DP_S_MIN 2
  26. #define DP_S_DOT 3
  27. #define DP_S_MAX 4
  28. #define DP_S_MOD 5
  29. #define DP_S_CONV 6
  30. #define DP_S_DONE 7
  31. /* format flags - Bits */
  32. #define DP_F_MINUS (1 << 0)
  33. #define DP_F_PLUS (1 << 1)
  34. #define DP_F_SPACE (1 << 2)
  35. #define DP_F_NUM (1 << 3)
  36. #define DP_F_ZERO (1 << 4)
  37. #define DP_F_UP (1 << 5)
  38. #define DP_F_UNSIGNED (1 << 6)
  39. /* Conversion Flags */
  40. #define DP_C_SHORT 1
  41. #define DP_C_LONG 2
  42. #define char_to_int(p) (p - '0')
  43. #define chisdigit(ch) (((ch)>='0')&&((ch)<='9'))
  44. static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
  45. {
  46. char ch;
  47. long value;
  48. char *strvalue;
  49. int min;
  50. int max;
  51. int state;
  52. int flags;
  53. int cflags;
  54. size_t currlen;
  55. state = DP_S_DEFAULT;
  56. currlen = flags = cflags = min = 0;
  57. max = -1;
  58. ch = *format++;
  59. while (state != DP_S_DONE)
  60. {
  61. if ((ch == '\0') || (currlen >= maxlen))
  62. {
  63. state = DP_S_DONE;
  64. }
  65. switch(state)
  66. {
  67. case DP_S_DEFAULT:
  68. if (ch == '%')
  69. {
  70. state = DP_S_FLAGS;
  71. }
  72. else
  73. {
  74. dopr_outch (buffer, &currlen, maxlen, ch);
  75. }
  76. ch = *format++;
  77. break;
  78. case DP_S_FLAGS:
  79. switch (ch)
  80. {
  81. case '-':
  82. flags |= DP_F_MINUS;
  83. ch = *format++;
  84. break;
  85. case '+':
  86. flags |= DP_F_PLUS;
  87. ch = *format++;
  88. break;
  89. case ' ':
  90. flags |= DP_F_SPACE;
  91. ch = *format++;
  92. break;
  93. case '#':
  94. flags |= DP_F_NUM;
  95. ch = *format++;
  96. break;
  97. case '0':
  98. flags |= DP_F_ZERO;
  99. ch = *format++;
  100. break;
  101. default:
  102. state = DP_S_MIN;
  103. break;
  104. }
  105. break;
  106. case DP_S_MIN:
  107. if(chisdigit(ch))
  108. {
  109. min = 10*min + char_to_int (ch);
  110. ch = *format++;
  111. }
  112. else if (ch == '*')
  113. {
  114. min = va_arg (args, int);
  115. ch = *format++;
  116. state = DP_S_DOT;
  117. }
  118. else
  119. {
  120. state = DP_S_DOT;
  121. }
  122. break;
  123. case DP_S_DOT:
  124. if (ch == '.')
  125. {
  126. state = DP_S_MAX;
  127. ch = *format++;
  128. }
  129. else
  130. {
  131. state = DP_S_MOD;
  132. }
  133. break;
  134. case DP_S_MAX:
  135. if (chisdigit((int) ch))
  136. {
  137. if (max < 0)
  138. {
  139. max = 0;
  140. }
  141. max = 10*max + char_to_int (ch);
  142. ch = *format++;
  143. }
  144. else if(ch == '*')
  145. {
  146. max = va_arg (args, int);
  147. ch = *format++;
  148. state = DP_S_MOD;
  149. }
  150. else
  151. {
  152. state = DP_S_MOD;
  153. }
  154. break;
  155. case DP_S_MOD:
  156. /* Currently, we don't support Long Long, bummer */
  157. switch (ch)
  158. {
  159. case 'h':
  160. cflags = DP_C_SHORT;
  161. ch = *format++;
  162. break;
  163. case 'l':
  164. cflags = DP_C_LONG;
  165. ch = *format++;
  166. break;
  167. default:
  168. break;
  169. }
  170. state = DP_S_CONV;
  171. break;
  172. case DP_S_CONV:
  173. switch (ch)
  174. {
  175. case 'd':
  176. case 'i':
  177. if (cflags == DP_C_SHORT)
  178. {
  179. #if ( defined(OTP_COMPILER) && OTP_COMPILER == TORNADO_2_2 )
  180. value = va_arg (args, int);
  181. #else
  182. value = va_arg (args, int);
  183. #endif
  184. }
  185. else if (cflags == DP_C_LONG)
  186. {
  187. value = va_arg (args, long int);
  188. }
  189. else
  190. {
  191. value = va_arg (args, int);
  192. }
  193. fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
  194. break;
  195. case 'o':
  196. flags |= DP_F_UNSIGNED;
  197. if (cflags == DP_C_SHORT)
  198. {
  199. #if ( defined(OTP_COMPILER) && OTP_COMPILER == TORNADO_2_2 )
  200. value = va_arg (args, int);
  201. #else
  202. value = va_arg (args, unsigned int);
  203. #endif
  204. }
  205. else if (cflags == DP_C_LONG)
  206. {
  207. value = va_arg (args, unsigned long int);
  208. }
  209. else
  210. {
  211. value = va_arg (args, unsigned int);
  212. }
  213. fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
  214. break;
  215. case 'u':
  216. flags |= DP_F_UNSIGNED;
  217. if (cflags == DP_C_SHORT)
  218. {
  219. #if ( defined(OTP_COMPILER) && OTP_COMPILER == TORNADO_2_2 )
  220. value = va_arg (args, int);
  221. #else
  222. value = va_arg (args, unsigned int);
  223. #endif
  224. }
  225. else if (cflags == DP_C_LONG)
  226. {
  227. value = va_arg (args, unsigned long int);
  228. }
  229. else
  230. {
  231. value = va_arg (args, unsigned int);
  232. }
  233. fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
  234. break;
  235. /*lint -save -e616 -e825*/
  236. case 'X':
  237. flags |= DP_F_UP;
  238. case 'x':
  239. flags |= DP_F_UNSIGNED;
  240. if (cflags == DP_C_SHORT)
  241. {
  242. #if ( defined(OTP_COMPILER) && OTP_COMPILER == TORNADO_2_2 )
  243. value = va_arg (args, int);
  244. #else
  245. value = va_arg (args, unsigned int);
  246. #endif
  247. }
  248. else if (cflags == DP_C_LONG)
  249. {
  250. value = va_arg (args, unsigned long int);
  251. }
  252. else
  253. {
  254. value = va_arg (args, unsigned int);
  255. }
  256. fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
  257. break;
  258. /*lint -restore*/
  259. case 'c':
  260. dopr_outch (buffer, &currlen, maxlen,(char) va_arg (args, int));
  261. break;
  262. case 's':
  263. strvalue = va_arg (args, char *);
  264. if (max < 0)
  265. {
  266. max = maxlen; /* ie, no max */
  267. }
  268. fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
  269. break;
  270. case 'p':
  271. strvalue = va_arg (args, void *);
  272. fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
  273. break;
  274. case 'n':
  275. if (cflags == DP_C_SHORT)
  276. {
  277. short int *num;
  278. num = va_arg (args, short int *);
  279. *num = currlen;
  280. }
  281. else if (cflags == DP_C_LONG)
  282. {
  283. long int *num;
  284. num = va_arg (args, long int *);
  285. *num = currlen;
  286. }
  287. else
  288. {
  289. int *num;
  290. num = va_arg (args, int *);
  291. *num = currlen;
  292. }
  293. break;
  294. case '%':
  295. dopr_outch (buffer, &currlen, maxlen, ch);
  296. break;
  297. case 'w':
  298. /* not supported yet, treat as next char */
  299. ch = *format++;
  300. break;
  301. default:
  302. /* Unknown, skip */
  303. break;
  304. }
  305. ch = *format++;
  306. state = DP_S_DEFAULT;
  307. flags = cflags = min = 0;
  308. max = -1;
  309. break;
  310. case DP_S_DONE:
  311. break;
  312. default: /* hmm? */
  313. break; /* some picky compilers need this */
  314. }
  315. }
  316. if (currlen < maxlen - 1)
  317. {
  318. buffer[currlen] = '\0';
  319. }
  320. else
  321. {
  322. buffer[maxlen - 1] = '\0';
  323. }
  324. }
  325. static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
  326. const char *value, int flags, int min, int max)
  327. {
  328. int padlen; /* amount to pad */
  329. int cnt = 0;
  330. if (value == 0)
  331. value = "<NULL>";
  332. /*lint -save -e64*/
  333. padlen = min - strlen(value);
  334. /*lint -restore*/
  335. if (padlen < 0)
  336. padlen = 0;
  337. if (flags & DP_F_MINUS)
  338. padlen = -padlen; /* Left Justify */
  339. while ((padlen > 0) && (cnt < max)) {
  340. dopr_outch (buffer, currlen, maxlen, ' ');
  341. --padlen;
  342. ++cnt;
  343. }
  344. while (*value && (cnt < max)) {
  345. dopr_outch (buffer, currlen, maxlen, *value++);
  346. ++cnt;
  347. }
  348. while ((padlen < 0) && (cnt < max)) {
  349. dopr_outch (buffer, currlen, maxlen, ' ');
  350. ++padlen;
  351. ++cnt;
  352. }
  353. }
  354. /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
  355. static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
  356. long value, int base, int min, int max, int flags)
  357. {
  358. char signvalue = 0;
  359. unsigned long uvalue;
  360. char convert[20];
  361. int place = 0;
  362. int spadlen = 0; /* amount to space pad */
  363. int zpadlen = 0; /* amount to zero pad */
  364. char *chars = ((flags & DP_F_UP)
  365. ? "0123456789ABCDEF"
  366. : "0123456789abcdef");
  367. if (max < 0)
  368. max = 0;
  369. uvalue = value;
  370. if (!(flags & DP_F_UNSIGNED)) {
  371. if (value < 0) {
  372. signvalue = '-';
  373. uvalue = -value;
  374. } else if (flags & DP_F_PLUS) { /* Do a sign (+/i) */
  375. signvalue = '+';
  376. } else if (flags & DP_F_SPACE) {
  377. signvalue = ' ';
  378. }
  379. }
  380. do {
  381. convert[place++] = chars[uvalue % (unsigned) base];
  382. uvalue = (uvalue / (unsigned)base );
  383. } while(uvalue && (place < 20));
  384. if (place == 20)
  385. place--;
  386. convert[place] = 0;
  387. zpadlen = max - place;
  388. spadlen = (min - MAX (max, place)) - (signvalue ? 1 : 0);
  389. if (zpadlen < 0)
  390. zpadlen = 0;
  391. if (spadlen < 0)
  392. spadlen = 0;
  393. if (flags & DP_F_ZERO) {
  394. zpadlen = MAX(zpadlen, spadlen);
  395. spadlen = 0;
  396. }
  397. if (flags & DP_F_MINUS)
  398. spadlen = -spadlen; /* Left Justifty */
  399. /* Spaces */
  400. while (spadlen > 0) {
  401. dopr_outch (buffer, currlen, maxlen, ' ');
  402. --spadlen;
  403. }
  404. /* Sign */
  405. if (signvalue)
  406. dopr_outch (buffer, currlen, maxlen, signvalue);
  407. /* Zeros */
  408. if (zpadlen > 0) {
  409. while (zpadlen > 0) {
  410. dopr_outch (buffer, currlen, maxlen, '0');
  411. --zpadlen;
  412. }
  413. }
  414. /* Digits */
  415. while (place > 0)
  416. dopr_outch (buffer, currlen, maxlen, convert[--place]);
  417. /* Left Justified spaces */
  418. while (spadlen < 0) {
  419. dopr_outch (buffer, currlen, maxlen, ' ');
  420. ++spadlen;
  421. }
  422. }
  423. static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
  424. {
  425. if (*currlen < maxlen)
  426. buffer[(*currlen)++] = c;
  427. }
  428. /*
  429. 王炯从snprintf.c拷贝过来
  430. */
  431. unsigned int otp_vsnprintf (char *str, size_t count, const char *fmt, va_list args)
  432. {
  433. if(count==0)
  434. {
  435. return 0;
  436. }
  437. str[0] = 0;
  438. dopr(str, count, fmt, args);
  439. /*lint -save -e64*/
  440. return(strlen(str));
  441. /*lint -restore*/
  442. }
  443. /*
  444. 王炯从snprintf.c拷贝过来
  445. 向str中打印字符串,最多只打印count-1个字符。
  446. 如果打印了count-1个字符,则第count个字符为'\0'。
  447. */
  448. unsigned int otp_snprintf (char *str, unsigned int count, const char *fmt, ...)
  449. {
  450. int len;
  451. va_list ap;
  452. if(count==0 || !str )
  453. {
  454. return 0;
  455. }
  456. va_start(ap, fmt);
  457. len = otp_vsnprintf(str, count, fmt, ap);
  458. va_end(ap);
  459. return len;
  460. }
  461. /*
  462. 把输入的字符串转换成小写。
  463. 该函数会转换str中的所有大写字母为小写,非大写字母保持不变。
  464. 遇到'\0'会结束转换,达到了缓冲区长度count也会结束转换
  465. 输入参数:
  466. str, 需要转换的字符串指针,
  467. count, str的缓冲区长度。
  468. 返回
  469. str的值
  470. */
  471. char * otp_strtolower (char *str, int count)
  472. {
  473. int i=0;
  474. if( !str )
  475. {
  476. return str;
  477. }
  478. while( i<count && str[i]!='\0' )
  479. {
  480. str[i]= (char)tolower(str[i]);
  481. i++;
  482. }
  483. return str;
  484. }
  485. /*
  486. 把输入的字符串转换成大写。
  487. 该函数会转换str中的所有小写字母为大写,非小写字母保持不变。
  488. 遇到'\0'会结束转换,达到了缓冲区长度count也会结束转换
  489. 输入参数:
  490. str, 需要转换的字符串指针,
  491. count, str的缓冲区长度。
  492. 返回
  493. str的值
  494. */
  495. char * otp_strtoupper (char *str, int count)
  496. {
  497. int i=0;
  498. if( !str )
  499. {
  500. return str;
  501. }
  502. while( i<count && str[i]!='\0' )
  503. {
  504. str[i]= (char)toupper(str[i]);
  505. i++;
  506. }
  507. return str;
  508. }
  509. /*lint -restore*/