ustdlib.c 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853
  1. //###########################################################################
  2. //
  3. // FILE: ustdlib.c
  4. //
  5. // TITLE: Simple standard library functions.
  6. //
  7. //###########################################################################
  8. // $TI Release: F2837xD Support Library v3.05.00.00 $
  9. // $Release Date: Tue Jun 26 03:15:23 CDT 2018 $
  10. // $Copyright:
  11. // Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
  12. //
  13. // Redistribution and use in source and binary forms, with or without
  14. // modification, are permitted provided that the following conditions
  15. // are met:
  16. //
  17. // Redistributions of source code must retain the above copyright
  18. // notice, this list of conditions and the following disclaimer.
  19. //
  20. // Redistributions in binary form must reproduce the above copyright
  21. // notice, this list of conditions and the following disclaimer in the
  22. // documentation and/or other materials provided with the
  23. // distribution.
  24. //
  25. // Neither the name of Texas Instruments Incorporated nor the names of
  26. // its contributors may be used to endorse or promote products derived
  27. // from this software without specific prior written permission.
  28. //
  29. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  30. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  31. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  32. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  33. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  34. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  35. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  36. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  37. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  39. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40. // $
  41. //###########################################################################
  42. //
  43. // Included Files
  44. //
  45. #include <stdint.h>
  46. #include <stdbool.h>
  47. #include "driverlib/debug.h"
  48. #include "utils/ustdlib.h"
  49. //*****************************************************************************
  50. //
  51. //! \addtogroup ustdlib_api
  52. //! @{
  53. //
  54. //*****************************************************************************
  55. //
  56. // Globals
  57. //
  58. //
  59. // A mapping from an integer between 0 and 15 to its ASCII character
  60. // equivalent.
  61. //
  62. static const char * const g_pcHex = "0123456789abcdef";
  63. //
  64. // Functions
  65. //
  66. //*****************************************************************************
  67. //
  68. //! Copies a certain number of characters from one string to another.
  69. //!
  70. //! \param s1 is a pointer to the destination buffer into which characters
  71. //! are to be copied.
  72. //! \param s2 is a pointer to the string from which characters are to be
  73. //! copied.
  74. //! \param n is the number of characters to copy to the destination buffer.
  75. //!
  76. //! This function copies at most \e n characters from the string pointed to
  77. //! by \e s2 into the buffer pointed to by \e s1. If the end of \e s2 is found
  78. //! before \e n characters have been copied, remaining characters in \e s1
  79. //! will be padded with zeroes until \e n characters have been written. Note
  80. //! that the destination string will only be NULL terminated if the number of
  81. //! characters to be copied is greater than the length of \e s2.
  82. //!
  83. //! \return Returns \e s1.
  84. //
  85. //*****************************************************************************
  86. char *
  87. ustrncpy(char * restrict s1, const char * restrict s2, size_t n)
  88. {
  89. size_t count;
  90. //
  91. // Check the arguments.
  92. //
  93. ASSERT(s1);
  94. ASSERT(s2);
  95. //
  96. // Start at the beginning of the source string.
  97. //
  98. count = 0;
  99. //
  100. // Copy the source string until we run out of source characters or
  101. // destination space.
  102. //
  103. while(n && s2[count])
  104. {
  105. s1[count] = s2[count];
  106. count++;
  107. n--;
  108. }
  109. //
  110. // Pad the destination if we are not yet done.
  111. //
  112. while(n)
  113. {
  114. s1[count++] = (char)0;
  115. n--;
  116. }
  117. //
  118. // Pass the destination pointer back to the caller.
  119. //
  120. return(s1);
  121. }
  122. //*****************************************************************************
  123. //
  124. //! A simple vsnprintf function supporting \%c, \%d, \%p, \%s, \%u, \%x, and
  125. //! \%X.
  126. //!
  127. //! \param s points to the buffer where the converted string is stored.
  128. //! \param n is the size of the buffer.
  129. //! \param format is the format string.
  130. //! \param arg is the list of optional arguments, which depend on the
  131. //! contents of the format string.
  132. //!
  133. //! This function is very similar to the C library <tt>vsnprintf()</tt>
  134. //! function. Only the following formatting characters are supported:
  135. //!
  136. //! - \%c to print a character
  137. //! - \%d or \%i to print a decimal value
  138. //! - \%s to print a string
  139. //! - \%u to print an unsigned decimal value
  140. //! - \%x to print a hexadecimal value using lower case letters
  141. //! - \%X to print a hexadecimal value using lower case letters (not upper case
  142. //! letters as would typically be used)
  143. //! - \%p to print a pointer as a hexadecimal value
  144. //! - \%\% to print out a \% character
  145. //!
  146. //! For \%d, \%i, \%p, \%s, \%u, \%x, and \%X, an optional number may reside
  147. //! between the \% and the format character, which specifies the minimum number
  148. //! of characters to use for that value; if preceded by a 0 then the extra
  149. //! characters will be filled with zeros instead of spaces. For example,
  150. //! ``\%8d'' will use eight characters to print the decimal value with spaces
  151. //! added to reach eight; ``\%08d'' will use eight characters as well but will
  152. //! add zeroes instead of spaces.
  153. //!
  154. //! The type of the arguments after \e format must match the requirements of
  155. //! the format string. For example, if an integer was passed where a string
  156. //! was expected, an error of some kind will most likely occur.
  157. //!
  158. //! The \e n parameter limits the number of characters that will be
  159. //! stored in the buffer pointed to by \e s to prevent the possibility of
  160. //! a buffer overflow. The buffer size should be large enough to hold the
  161. //! expected converted output string, including the null termination character.
  162. //!
  163. //! The function will return the number of characters that would be converted
  164. //! as if there were no limit on the buffer size. Therefore it is possible for
  165. //! the function to return a count that is greater than the specified buffer
  166. //! size. If this happens, it means that the output was truncated.
  167. //!
  168. //! \return Returns the number of characters that were to be stored, not
  169. //! including the NULL termination character, regardless of space in the
  170. //! buffer.
  171. //
  172. //*****************************************************************************
  173. int
  174. uvsnprintf(char * restrict s, size_t n, const char * restrict format,
  175. va_list arg)
  176. {
  177. unsigned long ulIdx, ulValue, ulCount, ulBase, ulNeg;
  178. char *pcStr, cFill;
  179. int iConvertCount = 0;
  180. //
  181. // Check the arguments.
  182. //
  183. ASSERT(s);
  184. ASSERT(n);
  185. ASSERT(format);
  186. //
  187. // Adjust buffer size limit to allow one space for null termination.
  188. //
  189. if(n)
  190. {
  191. n--;
  192. }
  193. //
  194. // Initialize the count of characters converted.
  195. //
  196. iConvertCount = 0;
  197. //
  198. // Loop while there are more characters in the format string.
  199. //
  200. while(*format)
  201. {
  202. //
  203. // Find the first non-% character, or the end of the string.
  204. //
  205. for(ulIdx = 0; (format[ulIdx] != '%') && (format[ulIdx] != '\0');
  206. ulIdx++)
  207. {
  208. }
  209. //
  210. // Write this portion of the string to the output buffer. If there are
  211. // more characters to write than there is space in the buffer, then
  212. // only write as much as will fit in the buffer.
  213. //
  214. if(ulIdx > n)
  215. {
  216. ustrncpy(s, format, n);
  217. s += n;
  218. n = 0;
  219. }
  220. else
  221. {
  222. ustrncpy(s, format, ulIdx);
  223. s += ulIdx;
  224. n -= ulIdx;
  225. }
  226. //
  227. // Update the conversion count. This will be the number of characters
  228. // that should have been written, even if there was not room in the
  229. // buffer.
  230. //
  231. iConvertCount += ulIdx;
  232. //
  233. // Skip the portion of the format string that was written.
  234. //
  235. format += ulIdx;
  236. //
  237. // See if the next character is a %.
  238. //
  239. if(*format == '%')
  240. {
  241. //
  242. // Skip the %.
  243. //
  244. format++;
  245. //
  246. // Set the digit count to zero, and the fill character to space
  247. // (that is, to the defaults).
  248. //
  249. ulCount = 0;
  250. cFill = ' ';
  251. //
  252. // It may be necessary to get back here to process more characters.
  253. // Goto's aren't pretty, but effective. I feel extremely dirty for
  254. // using not one but two of the beasts.
  255. //
  256. again:
  257. //
  258. // Determine how to handle the next character.
  259. //
  260. switch(*format++)
  261. {
  262. //
  263. // Handle the digit characters.
  264. //
  265. case '0':
  266. case '1':
  267. case '2':
  268. case '3':
  269. case '4':
  270. case '5':
  271. case '6':
  272. case '7':
  273. case '8':
  274. case '9':
  275. {
  276. //
  277. // If this is a zero, and it is the first digit, then the
  278. // fill character is a zero instead of a space.
  279. //
  280. if((format[-1] == '0') && (ulCount == 0))
  281. {
  282. cFill = '0';
  283. }
  284. //
  285. // Update the digit count.
  286. //
  287. ulCount *= 10;
  288. ulCount += format[-1] - '0';
  289. //
  290. // Get the next character.
  291. //
  292. goto again;
  293. }
  294. //
  295. // Handle the %c command.
  296. //
  297. case 'c':
  298. {
  299. //
  300. // Get the value from the varargs.
  301. //
  302. ulValue = va_arg(arg, unsigned long);
  303. //
  304. // Copy the character to the output buffer, if there is
  305. // room. Update the buffer size remaining.
  306. //
  307. if(n != 0)
  308. {
  309. *s++ = (char)ulValue;
  310. n--;
  311. }
  312. //
  313. // Update the conversion count.
  314. //
  315. iConvertCount++;
  316. //
  317. // This command has been handled.
  318. //
  319. break;
  320. }
  321. //
  322. // Handle the %d and %i commands.
  323. //
  324. case 'd':
  325. case 'i':
  326. {
  327. //
  328. // Get the value from the varargs.
  329. //
  330. ulValue = va_arg(arg, unsigned long);
  331. //
  332. // If the value is negative, make it positive and indicate
  333. // that a minus sign is needed.
  334. //
  335. if((long)ulValue < 0)
  336. {
  337. //
  338. // Make the value positive.
  339. //
  340. ulValue = -(long)ulValue;
  341. //
  342. // Indicate that the value is negative.
  343. //
  344. ulNeg = 1;
  345. }
  346. else
  347. {
  348. //
  349. // Indicate that the value is positive so that a
  350. // negative sign isn't inserted.
  351. //
  352. ulNeg = 0;
  353. }
  354. //
  355. // Set the base to 10.
  356. //
  357. ulBase = 10;
  358. //
  359. // Convert the value to ASCII.
  360. //
  361. goto convert;
  362. }
  363. //
  364. // Handle the %s command.
  365. //
  366. case 's':
  367. {
  368. //
  369. // Get the string pointer from the varargs.
  370. //
  371. pcStr = va_arg(arg, char *);
  372. //
  373. // Determine the length of the string.
  374. //
  375. for(ulIdx = 0; pcStr[ulIdx] != '\0'; ulIdx++)
  376. {
  377. }
  378. //
  379. // Update the convert count to include any padding that
  380. // should be necessary (regardless of whether we have space
  381. // to write it or not).
  382. //
  383. if(ulCount > ulIdx)
  384. {
  385. iConvertCount += (ulCount - ulIdx);
  386. }
  387. //
  388. // Copy the string to the output buffer. Only copy as much
  389. // as will fit in the buffer. Update the output buffer
  390. // pointer and the space remaining.
  391. //
  392. if(ulIdx > n)
  393. {
  394. ustrncpy(s, pcStr, n);
  395. s += n;
  396. n = 0;
  397. }
  398. else
  399. {
  400. ustrncpy(s, pcStr, ulIdx);
  401. s += ulIdx;
  402. n -= ulIdx;
  403. //
  404. // Write any required padding spaces assuming there is
  405. // still space in the buffer.
  406. //
  407. if(ulCount > ulIdx)
  408. {
  409. ulCount -= ulIdx;
  410. if(ulCount > n)
  411. {
  412. ulCount = n;
  413. }
  414. n = -ulCount;
  415. while(ulCount--)
  416. {
  417. *s++ = ' ';
  418. }
  419. }
  420. }
  421. //
  422. // Update the conversion count. This will be the number of
  423. // characters that should have been written, even if there
  424. // was not room in the buffer.
  425. //
  426. iConvertCount += ulIdx;
  427. //
  428. // This command has been handled.
  429. //
  430. break;
  431. }
  432. //
  433. // Handle the %u command.
  434. //
  435. case 'u':
  436. {
  437. //
  438. // Get the value from the varargs.
  439. //
  440. ulValue = va_arg(arg, unsigned long);
  441. //
  442. // Set the base to 10.
  443. //
  444. ulBase = 10;
  445. //
  446. // Indicate that the value is positive so that a minus sign
  447. // isn't inserted.
  448. //
  449. ulNeg = 0;
  450. //
  451. // Convert the value to ASCII.
  452. //
  453. goto convert;
  454. }
  455. //
  456. // Handle the %x and %X commands. Note that they are treated
  457. // identically; that is, %X will use lower case letters for a-f
  458. // instead of the upper case letters is should use. We also
  459. // alias %p to %x.
  460. //
  461. case 'x':
  462. case 'X':
  463. case 'p':
  464. {
  465. //
  466. // Get the value from the varargs.
  467. //
  468. ulValue = va_arg(arg, unsigned long);
  469. //
  470. // Set the base to 16.
  471. //
  472. ulBase = 16;
  473. //
  474. // Indicate that the value is positive so that a minus sign
  475. // isn't inserted.
  476. //
  477. ulNeg = 0;
  478. //
  479. // Determine the number of digits in the string version of
  480. // the value.
  481. //
  482. convert:
  483. for(ulIdx = 1;
  484. (((ulIdx * ulBase) <= ulValue) &&
  485. (((ulIdx * ulBase) / ulBase) == ulIdx));
  486. ulIdx *= ulBase, ulCount--)
  487. {
  488. }
  489. //
  490. // If the value is negative, reduce the count of padding
  491. // characters needed.
  492. //
  493. if(ulNeg)
  494. {
  495. ulCount--;
  496. }
  497. //
  498. // If the value is negative and the value is padded with
  499. // zeros, then place the minus sign before the padding.
  500. //
  501. if(ulNeg && (n != 0) && (cFill == '0'))
  502. {
  503. //
  504. // Place the minus sign in the output buffer.
  505. //
  506. *s++ = '-';
  507. n--;
  508. //
  509. // Update the conversion count.
  510. //
  511. iConvertCount++;
  512. //
  513. // The minus sign has been placed, so turn off the
  514. // negative flag.
  515. //
  516. ulNeg = 0;
  517. }
  518. //
  519. // See if there are more characters in the specified field
  520. // width than there are in the conversion of this value.
  521. //
  522. if((ulCount > 1) && (ulCount < 65536))
  523. {
  524. //
  525. // Loop through the required padding characters.
  526. //
  527. for(ulCount--; ulCount; ulCount--)
  528. {
  529. //
  530. // Copy the character to the output buffer if there
  531. // is room.
  532. //
  533. if(n != 0)
  534. {
  535. *s++ = cFill;
  536. n--;
  537. }
  538. //
  539. // Update the conversion count.
  540. //
  541. iConvertCount++;
  542. }
  543. }
  544. //
  545. // If the value is negative, then place the minus sign
  546. // before the number.
  547. //
  548. if(ulNeg && (n != 0))
  549. {
  550. //
  551. // Place the minus sign in the output buffer.
  552. //
  553. *s++ = '-';
  554. n--;
  555. //
  556. // Update the conversion count.
  557. //
  558. iConvertCount++;
  559. }
  560. //
  561. // Convert the value into a string.
  562. //
  563. for(; ulIdx; ulIdx /= ulBase)
  564. {
  565. //
  566. // Copy the character to the output buffer if there is
  567. // room.
  568. //
  569. if(n != 0)
  570. {
  571. *s++ = g_pcHex[(ulValue / ulIdx) % ulBase];
  572. n--;
  573. }
  574. //
  575. // Update the conversion count.
  576. //
  577. iConvertCount++;
  578. }
  579. //
  580. // This command has been handled.
  581. //
  582. break;
  583. }
  584. //
  585. // Handle the %% command.
  586. //
  587. case '%':
  588. {
  589. //
  590. // Simply write a single %.
  591. //
  592. if(n != 0)
  593. {
  594. *s++ = format[-1];
  595. n--;
  596. }
  597. //
  598. // Update the conversion count.
  599. //
  600. iConvertCount++;
  601. //
  602. // This command has been handled.
  603. //
  604. break;
  605. }
  606. //
  607. // Handle all other commands.
  608. //
  609. default:
  610. {
  611. //
  612. // Indicate an error.
  613. //
  614. if(n >= 5)
  615. {
  616. ustrncpy(s, "ERROR", 5);
  617. s += 5;
  618. n -= 5;
  619. }
  620. else
  621. {
  622. ustrncpy(s, "ERROR", n);
  623. s += n;
  624. n = 0;
  625. }
  626. //
  627. // Update the conversion count.
  628. //
  629. iConvertCount += 5;
  630. //
  631. // This command has been handled.
  632. //
  633. break;
  634. }
  635. }
  636. }
  637. }
  638. //
  639. // Null terminate the string in the buffer.
  640. //
  641. *s = 0;
  642. //
  643. // Return the number of characters in the full converted string.
  644. //
  645. return(iConvertCount);
  646. }
  647. //*****************************************************************************
  648. //
  649. //! A simple sprintf function supporting \%c, \%d, \%p, \%s, \%u, \%x, and \%X.
  650. //!
  651. //! \param s is the buffer where the converted string is stored.
  652. //! \param format is the format string.
  653. //! \param ... are the optional arguments, which depend on the contents of the
  654. //! format string.
  655. //!
  656. //! This function is very similar to the C library <tt>sprintf()</tt> function.
  657. //! Only the following formatting characters are supported:
  658. //!
  659. //! - \%c to print a character
  660. //! - \%d or \%i to print a decimal value
  661. //! - \%s to print a string
  662. //! - \%u to print an unsigned decimal value
  663. //! - \%x to print a hexadecimal value using lower case letters
  664. //! - \%X to print a hexadecimal value using lower case letters (not upper case
  665. //! letters as would typically be used)
  666. //! - \%p to print a pointer as a hexadecimal value
  667. //! - \%\% to print out a \% character
  668. //!
  669. //! For \%d, \%i, \%p, \%s, \%u, \%x, and \%X, an optional number may reside
  670. //! between the \% and the format character, which specifies the minimum number
  671. //! of characters to use for that value; if preceded by a 0 then the extra
  672. //! characters will be filled with zeros instead of spaces. For example,
  673. //! ``\%8d'' will use eight characters to print the decimal value with spaces
  674. //! added to reach eight; ``\%08d'' will use eight characters as well but will
  675. //! add zeros instead of spaces.
  676. //!
  677. //! The type of the arguments after \e format must match the requirements of
  678. //! the format string. For example, if an integer was passed where a string
  679. //! was expected, an error of some kind will most likely occur.
  680. //!
  681. //! The caller must ensure that the buffer \e s is large enough to hold the
  682. //! entire converted string, including the null termination character.
  683. //!
  684. //! \return Returns the count of characters that were written to the output
  685. //! buffer, not including the NULL termination character.
  686. //
  687. //*****************************************************************************
  688. int
  689. usprintf(char * restrict s, const char *format, ...)
  690. {
  691. va_list arg;
  692. int ret;
  693. //
  694. // Start the varargs processing.
  695. //
  696. va_start(arg, format);
  697. //
  698. // Call vsnprintf to perform the conversion. Use a large number for the
  699. // buffer size.
  700. //
  701. ret = uvsnprintf(s, 0xffff, format, arg);
  702. //
  703. // End the varargs processing.
  704. //
  705. va_end(arg);
  706. //
  707. // Return the conversion count.
  708. //
  709. return(ret);
  710. }
  711. //*****************************************************************************
  712. //
  713. //! A simple snprintf function supporting \%c, \%d, \%p, \%s, \%u, \%x, and
  714. //! \%X.
  715. //!
  716. //! \param s is the buffer where the converted string is stored.
  717. //! \param n is the size of the buffer.
  718. //! \param format is the format string.
  719. //! \param ... are the optional arguments, which depend on the contents of the
  720. //! format string.
  721. //!
  722. //! This function is very similar to the C library <tt>sprintf()</tt> function.
  723. //! Only the following formatting characters are supported:
  724. //!
  725. //! - \%c to print a character
  726. //! - \%d or \%i to print a decimal value
  727. //! - \%s to print a string
  728. //! - \%u to print an unsigned decimal value
  729. //! - \%x to print a hexadecimal value using lower case letters
  730. //! - \%X to print a hexadecimal value using lower case letters (not upper case
  731. //! letters as would typically be used)
  732. //! - \%p to print a pointer as a hexadecimal value
  733. //! - \%\% to print out a \% character
  734. //!
  735. //! For \%d, \%i, \%p, \%s, \%u, \%x, and \%X, an optional number may reside
  736. //! between the \% and the format character, which specifies the minimum number
  737. //! of characters to use for that value; if preceded by a 0 then the extra
  738. //! characters will be filled with zeros instead of spaces. For example,
  739. //! ``\%8d'' will use eight characters to print the decimal value with spaces
  740. //! added to reach eight; ``\%08d'' will use eight characters as well but will
  741. //! add zeros instead of spaces.
  742. //!
  743. //! The type of the arguments after \e format must match the requirements of
  744. //! the format string. For example, if an integer was passed where a string
  745. //! was expected, an error of some kind will most likely occur.
  746. //!
  747. //! The function will copy at most \e n - 1 characters into the buffer
  748. //! \e s. One space is reserved in the buffer for the null termination
  749. //! character.
  750. //!
  751. //! The function will return the number of characters that would be converted
  752. //! as if there were no limit on the buffer size. Therefore it is possible for
  753. //! the function to return a count that is greater than the specified buffer
  754. //! size. If this happens, it means that the output was truncated.
  755. //!
  756. //! \return Returns the number of characters that were to be stored, not
  757. //! including the NULL termination character, regardless of space in the
  758. //! buffer.
  759. //
  760. //*****************************************************************************
  761. int
  762. usnprintf(char * restrict s, size_t n, const char * restrict format, ...)
  763. {
  764. va_list arg;
  765. int ret;
  766. //
  767. // Start the varargs processing.
  768. //
  769. va_start(arg, format);
  770. //
  771. // Call vsnprintf to perform the conversion.
  772. //
  773. ret = uvsnprintf(s, n, format, arg);
  774. //
  775. // End the varargs processing.
  776. //
  777. va_end(arg);
  778. //
  779. // Return the conversion count.
  780. //
  781. return(ret);
  782. }
  783. //
  784. // This array contains the number of days in a year at the beginning of each
  785. // month of the year, in a non-leap year.
  786. //
  787. static const time_t g_psDaysToMonth[12] =
  788. {
  789. 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
  790. };
  791. //*****************************************************************************
  792. //
  793. //! Converts from seconds to calendar date and time.
  794. //!
  795. //! \param timer is the number of seconds.
  796. //! \param tm is a pointer to the time structure that is filled in with the
  797. //! broken down date and time.
  798. //!
  799. //! This function converts a number of seconds since midnight GMT on January 1,
  800. //! 1970 (traditional Unix epoch) into the equivalent month, day, year, hours,
  801. //! minutes, and seconds representation.
  802. //!
  803. //! \return None.
  804. //
  805. //*****************************************************************************
  806. void
  807. ulocaltime(time_t timer, struct tm *tm)
  808. {
  809. time_t temp, months;
  810. //
  811. // Extract the number of seconds, converting time to the number of minutes.
  812. //
  813. temp = timer / 60;
  814. tm->tm_sec = timer - (temp * 60);
  815. timer = temp;
  816. //
  817. // Extract the number of minutes, converting time to the number of hours.
  818. //
  819. temp = timer / 60;
  820. tm->tm_min = timer - (temp * 60);
  821. timer = temp;
  822. //
  823. // Extract the number of hours, converting time to the number of days.
  824. //
  825. temp = timer / 24;
  826. tm->tm_hour = timer - (temp * 24);
  827. timer = temp;
  828. //
  829. // Compute the day of the week.
  830. //
  831. tm->tm_wday = (timer + 4) % 7;
  832. //
  833. // Compute the number of leap years that have occurred since 1968, the
  834. // first leap year before 1970. For the beginning of a leap year, cut the
  835. // month loop below at March so that the leap day is classified as February
  836. // 29 followed by March 1, instead of March 1 followed by another March 1.
  837. //
  838. timer += 366 + 365;
  839. temp = timer / ((4 * 365) + 1);
  840. if((timer - (temp * ((4 * 365) + 1))) > (31 + 28))
  841. {
  842. temp++;
  843. months = 12;
  844. }
  845. else
  846. {
  847. months = 2;
  848. }
  849. //
  850. // Extract the year.
  851. //
  852. tm->tm_year = ((timer - temp) / 365) + 68;
  853. timer -= ((tm->tm_year - 68) * 365) + temp;
  854. //
  855. // Extract the month.
  856. //
  857. for(temp = 0; temp < months; temp++)
  858. {
  859. if(g_psDaysToMonth[temp] > timer)
  860. {
  861. break;
  862. }
  863. }
  864. tm->tm_mon = temp - 1;
  865. //
  866. // Extract the day of the month.
  867. //
  868. tm->tm_mday = timer - g_psDaysToMonth[temp - 1] + 1;
  869. }
  870. //*****************************************************************************
  871. //
  872. //! Compares two time structures and determines if one is greater than,
  873. //! less than, or equal to the other.
  874. //!
  875. //! \param t1 is the first time structure to compare.
  876. //! \param t2 is the second time structure to compare.
  877. //!
  878. //! This function compares two time structures and returns a signed number
  879. //! to indicate the result of the comparison. If the time represented by
  880. //! \e t1 is greater than the time represented by \e t2 then a positive
  881. //! number is returned. Likewise if \e t1 is less than \e t2 then a
  882. //! negative number is returned. If the two times are equal then the function
  883. //! returns 0.
  884. //!
  885. //! \return Returns 0 if the two times are equal, +1 if \e t1 is greater
  886. //! than \e t2, and -1 if \e t1 is less than \e t2.
  887. //
  888. //*****************************************************************************
  889. static int
  890. ucmptime(struct tm *t1, struct tm *t2)
  891. {
  892. //
  893. // Compare each field in descending significance to determine if
  894. // greater than, less than, or equal.
  895. //
  896. if(t1->tm_year > t2->tm_year)
  897. {
  898. return(1);
  899. }
  900. else if(t1->tm_year < t2->tm_year)
  901. {
  902. return(-1);
  903. }
  904. else if(t1->tm_mon > t2->tm_mon)
  905. {
  906. return(1);
  907. }
  908. else if(t1->tm_mon < t2->tm_mon)
  909. {
  910. return(-1);
  911. }
  912. else if(t1->tm_mday > t2->tm_mday)
  913. {
  914. return(1);
  915. }
  916. else if(t1->tm_mday < t2->tm_mday)
  917. {
  918. return(-1);
  919. }
  920. else if(t1->tm_hour > t2->tm_hour)
  921. {
  922. return(1);
  923. }
  924. else if(t1->tm_hour < t2->tm_hour)
  925. {
  926. return(-1);
  927. }
  928. else if(t1->tm_min > t2->tm_min)
  929. {
  930. return(1);
  931. }
  932. else if(t1->tm_min < t2->tm_min)
  933. {
  934. return(-1);
  935. }
  936. else if(t1->tm_sec > t2->tm_sec)
  937. {
  938. return(1);
  939. }
  940. else if(t1->tm_sec < t2->tm_sec)
  941. {
  942. return(-1);
  943. }
  944. else
  945. {
  946. //
  947. // Reaching this branch of the conditional means that all of the
  948. // fields are equal, and thus the two times are equal.
  949. //
  950. return(0);
  951. }
  952. }
  953. //*****************************************************************************
  954. //
  955. //! Converts calendar date and time to seconds.
  956. //!
  957. //! \param timeptr is a pointer to the time structure that is filled in with
  958. //! the broken down date and time.
  959. //!
  960. //! This function converts the date and time represented by the \e timeptr
  961. //! structure pointer to the number of seconds since midnight GMT on January 1,
  962. //! 1970 (traditional Unix epoch).
  963. //!
  964. //! \return Returns the calendar time and date as seconds. If the conversion
  965. //! was not possible then the function returns (uint32_t)(-1).
  966. //
  967. //*****************************************************************************
  968. time_t
  969. umktime(struct tm *timeptr)
  970. {
  971. struct tm sTimeGuess;
  972. unsigned long ulTimeGuess = 0x80000000;
  973. unsigned long ulAdjust = 0x40000000;
  974. int iSign;
  975. //
  976. // Seed the binary search with the first guess.
  977. //
  978. ulocaltime(ulTimeGuess, &sTimeGuess);
  979. iSign = ucmptime(timeptr, &sTimeGuess);
  980. //
  981. // While the time is not yet found, execute a binary search.
  982. //
  983. while(iSign && ulAdjust)
  984. {
  985. //
  986. // Adjust the time guess up or down depending on the result of the
  987. // last compare.
  988. //
  989. ulTimeGuess = ((iSign > 0) ? (ulTimeGuess + ulAdjust) :
  990. (ulTimeGuess - ulAdjust));
  991. ulAdjust /= 2;
  992. //
  993. // Compare the new time guess against the time pointed at by the
  994. // function parameters.
  995. //
  996. ulocaltime(ulTimeGuess, &sTimeGuess);
  997. iSign = ucmptime(timeptr, &sTimeGuess);
  998. }
  999. //
  1000. // If the above loop was exited with iSign == 0, that means that the
  1001. // time in seconds was found, so return that value to the caller.
  1002. //
  1003. if(iSign == 0)
  1004. {
  1005. return(ulTimeGuess);
  1006. }
  1007. //
  1008. // Otherwise the time could not be converted so return an error.
  1009. //
  1010. else
  1011. {
  1012. return((unsigned long)-1);
  1013. }
  1014. }
  1015. //*****************************************************************************
  1016. //
  1017. //! Converts a string into its numeric equivalent.
  1018. //!
  1019. //! \param nptr is a pointer to the string containing the integer.
  1020. //! \param endptr is a pointer that will be set to the first character past
  1021. //! the integer in the string.
  1022. //! \param base is the radix to use for the conversion; can be zero to
  1023. //! auto-select the radix or between 2 and 16 to explicitly specify the radix.
  1024. //!
  1025. //! This function is very similar to the C library <tt>strtoul()</tt> function.
  1026. //! It scans a string for the first token (that is, non-white space) and
  1027. //! converts the value at that location in the string into an integer value.
  1028. //!
  1029. //! \return Returns the result of the conversion.
  1030. //
  1031. //*****************************************************************************
  1032. unsigned long
  1033. ustrtoul(const char * restrict nptr, const char ** restrict endptr, int base)
  1034. {
  1035. unsigned long ulRet, ulDigit, ulNeg, ulValid;
  1036. const char *pcPtr;
  1037. //
  1038. // Check the arguments.
  1039. //
  1040. ASSERT(nptr);
  1041. ASSERT((base == 0) || ((base > 1) && (base <= 16)));
  1042. //
  1043. // Initially, the result is zero.
  1044. //
  1045. ulRet = 0;
  1046. ulNeg = 0;
  1047. ulValid = 0;
  1048. //
  1049. // Skip past any leading white space.
  1050. //
  1051. pcPtr = nptr;
  1052. while((*pcPtr == ' ') || (*pcPtr == '\t'))
  1053. {
  1054. pcPtr++;
  1055. }
  1056. //
  1057. // Take a leading + or - from the value.
  1058. //
  1059. if(*pcPtr == '-')
  1060. {
  1061. ulNeg = 1;
  1062. pcPtr++;
  1063. }
  1064. else if(*pcPtr == '+')
  1065. {
  1066. pcPtr++;
  1067. }
  1068. //
  1069. // See if the radix was not specified, or is 16, and the value starts with
  1070. // "0x" or "0X" (to indicate a hex value).
  1071. //
  1072. if(((base == 0) || (base == 16)) && (*pcPtr == '0') &&
  1073. ((pcPtr[1] == 'x') || (pcPtr[1] == 'X')))
  1074. {
  1075. //
  1076. // Skip the leading "0x".
  1077. //
  1078. pcPtr += 2;
  1079. //
  1080. // Set the radix to 16.
  1081. //
  1082. base = 16;
  1083. }
  1084. //
  1085. // See if the radix was not specified.
  1086. //
  1087. if(base == 0)
  1088. {
  1089. //
  1090. // See if the value starts with "0".
  1091. //
  1092. if(*pcPtr == '0')
  1093. {
  1094. //
  1095. // Values that start with "0" are assumed to be radix 8.
  1096. //
  1097. base = 8;
  1098. }
  1099. else
  1100. {
  1101. //
  1102. // Otherwise, the values are assumed to be radix 10.
  1103. //
  1104. base = 10;
  1105. }
  1106. }
  1107. //
  1108. // Loop while there are more valid digits to consume.
  1109. //
  1110. while(1)
  1111. {
  1112. //
  1113. // See if this character is a number.
  1114. //
  1115. if((*pcPtr >= '0') && (*pcPtr <= '9'))
  1116. {
  1117. //
  1118. // Convert the character to its integer equivalent.
  1119. //
  1120. ulDigit = *pcPtr++ - '0';
  1121. }
  1122. //
  1123. // Otherwise, see if this character is an upper case letter.
  1124. //
  1125. else if((*pcPtr >= 'A') && (*pcPtr <= 'Z'))
  1126. {
  1127. //
  1128. // Convert the character to its integer equivalent.
  1129. //
  1130. ulDigit = *pcPtr++ - 'A' + 10;
  1131. }
  1132. //
  1133. // Otherwise, see if this character is a lower case letter.
  1134. //
  1135. else if((*pcPtr >= 'a') && (*pcPtr <= 'z'))
  1136. {
  1137. //
  1138. // Convert the character to its integer equivalent.
  1139. //
  1140. ulDigit = *pcPtr++ - 'a' + 10;
  1141. }
  1142. //
  1143. // Otherwise, this is not a valid character.
  1144. //
  1145. else
  1146. {
  1147. //
  1148. // Stop converting this value.
  1149. //
  1150. break;
  1151. }
  1152. //
  1153. // See if this digit is valid for the chosen radix.
  1154. //
  1155. if(ulDigit >= base)
  1156. {
  1157. //
  1158. // Since this was not a valid digit, move the pointer back to the
  1159. // character that therefore should not have been consumed.
  1160. //
  1161. pcPtr--;
  1162. //
  1163. // Stop converting this value.
  1164. //
  1165. break;
  1166. }
  1167. //
  1168. // Add this digit to the converted value.
  1169. //
  1170. ulRet *= base;
  1171. ulRet += ulDigit;
  1172. //
  1173. // Since a digit has been added, this is now a valid result.
  1174. //
  1175. ulValid = 1;
  1176. }
  1177. //
  1178. // Set the return string pointer to the first character not consumed.
  1179. //
  1180. if(endptr)
  1181. {
  1182. *endptr = ulValid ? pcPtr : nptr;
  1183. }
  1184. //
  1185. // Return the converted value.
  1186. //
  1187. return(ulNeg ? (0 - ulRet) : ulRet);
  1188. }
  1189. //
  1190. // An array of the value of ten raised to the power-of-two exponents. This is
  1191. // used for converting the decimal exponent into the floating-point value of
  1192. // 10^exp.
  1193. //
  1194. static const float g_pfExponents[] =
  1195. {
  1196. 1.0e+01,
  1197. 1.0e+02,
  1198. 1.0e+04,
  1199. 1.0e+08,
  1200. 1.0e+16,
  1201. 1.0e+32,
  1202. };
  1203. //*****************************************************************************
  1204. //
  1205. //! Converts a string into its floating-point equivalent.
  1206. //!
  1207. //! \param nptr is a pointer to the string containing the floating-point
  1208. //! value.
  1209. //! \param endptr is a pointer that will be set to the first character past
  1210. //! the floating-point value in the string.
  1211. //!
  1212. //! This function is very similar to the C library <tt>strtof()</tt> function.
  1213. //! It scans a string for the first token (that is, non-white space) and
  1214. //! converts the value at that location in the string into a floating-point
  1215. //! value.
  1216. //!
  1217. //! \return Returns the result of the conversion.
  1218. //
  1219. //*****************************************************************************
  1220. float
  1221. ustrtof(const char *nptr, const char **endptr)
  1222. {
  1223. unsigned long ulNeg, ulExp, ulExpNeg, ulValid, ulIdx;
  1224. float fRet, fDigit, fExp;
  1225. const char *pcPtr;
  1226. //
  1227. // Check the arguments.
  1228. //
  1229. ASSERT(nptr);
  1230. //
  1231. // Initially, the result is zero.
  1232. //
  1233. fRet = 0;
  1234. ulNeg = 0;
  1235. ulValid = 0;
  1236. //
  1237. // Skip past any leading white space.
  1238. //
  1239. pcPtr = nptr;
  1240. while((*pcPtr == ' ') || (*pcPtr == '\t'))
  1241. {
  1242. pcPtr++;
  1243. }
  1244. //
  1245. // Take a leading + or - from the value.
  1246. //
  1247. if(*pcPtr == '-')
  1248. {
  1249. ulNeg = 1;
  1250. pcPtr++;
  1251. }
  1252. else if(*pcPtr == '+')
  1253. {
  1254. pcPtr++;
  1255. }
  1256. //
  1257. // Loop while there are valid digits to consume.
  1258. //
  1259. while((*pcPtr >= '0') && (*pcPtr <= '9'))
  1260. {
  1261. //
  1262. // Add this digit to the converted value.
  1263. //
  1264. fRet *= 10;
  1265. fRet += *pcPtr++ - '0';
  1266. //
  1267. // Since a digit has been added, this is now a valid result.
  1268. //
  1269. ulValid = 1;
  1270. }
  1271. //
  1272. // See if the next character is a period and the character after that is a
  1273. // digit, indicating the start of the fractional portion of the value.
  1274. //
  1275. if((*pcPtr == '.') && (pcPtr[1] >= '0') && (pcPtr[1] <= '9'))
  1276. {
  1277. //
  1278. // Skip the period.
  1279. //
  1280. pcPtr++;
  1281. //
  1282. // Loop while there are valid fractional digits to consume.
  1283. //
  1284. fDigit = 0.1;
  1285. while((*pcPtr >= '0') && (*pcPtr <= '9'))
  1286. {
  1287. //
  1288. // Add this digit to the converted value.
  1289. //
  1290. fRet += (*pcPtr++ - '0') * fDigit;
  1291. fDigit /= (float)10.0;
  1292. //
  1293. // Since a digit has been added, this is now a valid result.
  1294. //
  1295. ulValid = 1;
  1296. }
  1297. }
  1298. //
  1299. // See if the next character is an "e" and a valid number has been
  1300. // converted, indicating the start of the exponent.
  1301. //
  1302. if(((pcPtr[0] == 'e') || (pcPtr[0] == 'E')) && (ulValid == 1) &&
  1303. (((pcPtr[1] >= '0') && (pcPtr[1] <= '9')) ||
  1304. (((pcPtr[1] == '+') || (pcPtr[1] == '-')) &&
  1305. (pcPtr[2] >= '0') && (pcPtr[2] <= '9'))))
  1306. {
  1307. //
  1308. // Skip the "e".
  1309. //
  1310. pcPtr++;
  1311. //
  1312. // Take a leading + or - from the exponent.
  1313. //
  1314. ulExpNeg = 0;
  1315. if(*pcPtr == '-')
  1316. {
  1317. ulExpNeg = 1;
  1318. pcPtr++;
  1319. }
  1320. else if(*pcPtr == '+')
  1321. {
  1322. pcPtr++;
  1323. }
  1324. //
  1325. // Loop while there are valid digits in the exponent.
  1326. //
  1327. ulExp = 0;
  1328. while((*pcPtr >= '0') && (*pcPtr <= '9'))
  1329. {
  1330. //
  1331. // Add this digit to the converted value.
  1332. //
  1333. ulExp *= 10;
  1334. ulExp += *pcPtr++ - '0';
  1335. }
  1336. //
  1337. // Raise ten to the power of the exponent. Do this via binary
  1338. // decomposition; for each binary bit set in the exponent, multiply the
  1339. // floating-point representation by ten raised to that binary value
  1340. // (extracted from the table above).
  1341. //
  1342. fExp = 1;
  1343. for(ulIdx = 0; ulIdx < 7; ulIdx++)
  1344. {
  1345. if(ulExp & (1 << ulIdx))
  1346. {
  1347. fExp *= g_pfExponents[ulIdx];
  1348. }
  1349. }
  1350. //
  1351. // If the exponent is negative, then the exponent needs to be inverted.
  1352. //
  1353. if(ulExpNeg == 1)
  1354. {
  1355. fExp = 1 / fExp;
  1356. }
  1357. //
  1358. // Multiply the result by the computed exponent value.
  1359. //
  1360. fRet *= fExp;
  1361. }
  1362. //
  1363. // Set the return string pointer to the first character not consumed.
  1364. //
  1365. if(endptr)
  1366. {
  1367. *endptr = ulValid ? pcPtr : nptr;
  1368. }
  1369. //
  1370. // Return the converted value.
  1371. //
  1372. return(ulNeg ? (0 - fRet) : fRet);
  1373. }
  1374. //*****************************************************************************
  1375. //
  1376. //! Returns the length of a null-terminated string.
  1377. //!
  1378. //! \param s is a pointer to the string whose length is to be found.
  1379. //!
  1380. //! This function is very similar to the C library <tt>strlen()</tt> function.
  1381. //! It determines the length of the null-terminated string passed and returns
  1382. //! this to the caller.
  1383. //!
  1384. //! This implementation assumes that single byte character strings are passed
  1385. //! and will return incorrect values if passed some UTF-8 strings.
  1386. //!
  1387. //! \return Returns the length of the string pointed to by \e s.
  1388. //
  1389. //*****************************************************************************
  1390. size_t
  1391. ustrlen(const char *s)
  1392. {
  1393. size_t len;
  1394. //
  1395. // Check the arguments.
  1396. //
  1397. ASSERT(s);
  1398. //
  1399. // Initialize the length.
  1400. //
  1401. len = 0;
  1402. //
  1403. // Step through the string looking for a zero character (marking its end).
  1404. //
  1405. while(s[len])
  1406. {
  1407. //
  1408. // Zero not found so move on to the next character.
  1409. //
  1410. len++;
  1411. }
  1412. return(len);
  1413. }
  1414. //*****************************************************************************
  1415. //
  1416. //! Finds a substring within a string.
  1417. //!
  1418. //! \param s1 is a pointer to the string that will be searched.
  1419. //! \param s2 is a pointer to the substring that is to be found within
  1420. //! \e s1.
  1421. //!
  1422. //! This function is very similar to the C library <tt>strstr()</tt> function.
  1423. //! It scans a string for the first instance of a given substring and returns
  1424. //! a pointer to that substring. If the substring cannot be found, a NULL
  1425. //! pointer is returned.
  1426. //!
  1427. //! \return Returns a pointer to the first occurrence of \e s2 within
  1428. //! \e s1 or NULL if no match is found.
  1429. //
  1430. //*****************************************************************************
  1431. char *
  1432. ustrstr(const char *s1, const char *s2)
  1433. {
  1434. size_t n;
  1435. //
  1436. // Get the length of the string to be found.
  1437. //
  1438. n = ustrlen(s2);
  1439. //
  1440. // Loop while we have not reached the end of the string.
  1441. //
  1442. while(*s1)
  1443. {
  1444. //
  1445. // Check to see if the substring appears at this position.
  1446. //
  1447. if(ustrncmp(s2, s1, n) == 0)
  1448. {
  1449. //
  1450. // It does so return the pointer.
  1451. //
  1452. return((char *)s1);
  1453. }
  1454. //
  1455. // Move to the next position in the string being searched.
  1456. //
  1457. s1++;
  1458. }
  1459. //
  1460. // We reached the end of the string without finding the substring so
  1461. // return NULL.
  1462. //
  1463. return((char *)0);
  1464. }
  1465. //*****************************************************************************
  1466. //
  1467. //! Compares two strings without regard to case.
  1468. //!
  1469. //! \param s1 points to the first string to be compared.
  1470. //! \param s2 points to the second string to be compared.
  1471. //! \param n is the maximum number of characters to compare.
  1472. //!
  1473. //! This function is very similar to the C library <tt>strncasecmp()</tt>
  1474. //! function. It compares at most \e n characters of two strings without
  1475. //! regard to case. The comparison ends if a terminating NULL character is
  1476. //! found in either string before \e n characters are compared. In this case,
  1477. //! the shorter string is deemed the lesser.
  1478. //!
  1479. //! \return Returns 0 if the two strings are equal, -1 if \e s1 is less
  1480. //! than \e s2 and 1 if \e s1 is greater than \e s2.
  1481. //
  1482. //*****************************************************************************
  1483. int
  1484. ustrncasecmp(const char *s1, const char *s2, size_t n)
  1485. {
  1486. char c1, c2;
  1487. //
  1488. // Loop while there are more characters to compare.
  1489. //
  1490. while(n)
  1491. {
  1492. //
  1493. // If we reached a NULL in both strings, they must be equal so
  1494. // we end the comparison and return 0
  1495. //
  1496. if(!*s1 && !*s2)
  1497. {
  1498. return(0);
  1499. }
  1500. //
  1501. // Lower case the characters at the current position before we compare.
  1502. //
  1503. c1 = (((*s1 >= 'A') && (*s1 <= 'Z')) ? (*s1 + ('a' - 'A')) : *s1);
  1504. c2 = (((*s2 >= 'A') && (*s2 <= 'Z')) ? (*s2 + ('a' - 'A')) : *s2);
  1505. //
  1506. // Compare the two characters and, if different, return the relevant
  1507. // return code.
  1508. //
  1509. if(c2 < c1)
  1510. {
  1511. return(1);
  1512. }
  1513. if(c1 < c2)
  1514. {
  1515. return(-1);
  1516. }
  1517. //
  1518. // Move on to the next character.
  1519. //
  1520. s1++;
  1521. s2++;
  1522. n--;
  1523. }
  1524. //
  1525. // If we fall out, the strings must be equal for at least the first n
  1526. // characters so return 0 to indicate this.
  1527. //
  1528. return(0);
  1529. }
  1530. //*****************************************************************************
  1531. //
  1532. //! Compares two strings without regard to case.
  1533. //!
  1534. //! \param s1 points to the first string to be compared.
  1535. //! \param s2 points to the second string to be compared.
  1536. //!
  1537. //! This function is very similar to the C library <tt>strcasecmp()</tt>
  1538. //! function. It compares two strings without regard to case. The comparison
  1539. //! ends if a terminating NULL character is found in either string. In this
  1540. //! case, the int16_ter string is deemed the lesser.
  1541. //!
  1542. //! \return Returns 0 if the two strings are equal, -1 if \e s1 is less
  1543. //! than \e s2 and 1 if \e s1 is greater than \e s2.
  1544. //
  1545. //*****************************************************************************
  1546. int
  1547. ustrcasecmp(const char *s1, const char *s2)
  1548. {
  1549. //
  1550. // Just let ustrncasecmp() handle this.
  1551. //
  1552. return(ustrncasecmp(s1, s2, (size_t)-1));
  1553. }
  1554. //*****************************************************************************
  1555. //
  1556. //! Compares two strings.
  1557. //!
  1558. //! \param s1 points to the first string to be compared.
  1559. //! \param s2 points to the second string to be compared.
  1560. //! \param n is the maximum number of characters to compare.
  1561. //!
  1562. //! This function is very similar to the C library <tt>strncmp()</tt> function.
  1563. //! It compares at most \e n characters of two strings taking case into
  1564. //! account. The comparison ends if a terminating NULL character is found in
  1565. //! either string before \e n characters are compared. In this case, the
  1566. //! int16_ter string is deemed the lesser.
  1567. //!
  1568. //! \return Returns 0 if the two strings are equal, -1 if \e s1 is less
  1569. //! than \e s2 and 1 if \e s1 is greater than \e s2.
  1570. //
  1571. //*****************************************************************************
  1572. int
  1573. ustrncmp(const char *s1, const char *s2, size_t n)
  1574. {
  1575. //
  1576. // Loop while there are more characters.
  1577. //
  1578. while(n)
  1579. {
  1580. //
  1581. // If we reached a NULL in both strings, they must be equal so we end
  1582. // the comparison and return 0
  1583. //
  1584. if(!*s1 && !*s2)
  1585. {
  1586. return(0);
  1587. }
  1588. //
  1589. // Compare the two characters and, if different, return the relevant
  1590. // return code.
  1591. //
  1592. if(*s2 < *s1)
  1593. {
  1594. return(1);
  1595. }
  1596. if(*s1 < *s2)
  1597. {
  1598. return(-1);
  1599. }
  1600. //
  1601. // Move on to the next character.
  1602. //
  1603. s1++;
  1604. s2++;
  1605. n--;
  1606. }
  1607. //
  1608. // If we fall out, the strings must be equal for at least the first n
  1609. // characters so return 0 to indicate this.
  1610. //
  1611. return(0);
  1612. }
  1613. //*****************************************************************************
  1614. //
  1615. //! Compares two strings.
  1616. //!
  1617. //! \param s1 points to the first string to be compared.
  1618. //! \param s2 points to the second string to be compared.
  1619. //!
  1620. //! This function is very similar to the C library <tt>strcmp()</tt>
  1621. //! function. It compares two strings, taking case into account. The
  1622. //! comparison ends if a terminating NULL character is found in either string.
  1623. //! In this case, the int16_ter string is deemed the lesser.
  1624. //!
  1625. //! \return Returns 0 if the two strings are equal, -1 if \e s1 is less
  1626. //! than \e s2 and 1 if \e s1 is greater than \e s2.
  1627. //
  1628. //*****************************************************************************
  1629. int
  1630. ustrcmp(const char *s1, const char *s2)
  1631. {
  1632. //
  1633. // Pass this on to ustrncmp.
  1634. //
  1635. return(ustrncmp(s1, s2, (size_t)-1));
  1636. }
  1637. //
  1638. // Random Number Generator Seed Value
  1639. //
  1640. static unsigned int g_iRandomSeed = 1;
  1641. //*****************************************************************************
  1642. //
  1643. //! Set the random number generator seed.
  1644. //!
  1645. //! \param seed is the new seed value to use for the random number
  1646. //! generator.
  1647. //!
  1648. //! This function is very similar to the C library <tt>srand()</tt> function.
  1649. //! It will set the seed value used in the <tt>urand()</tt> function.
  1650. //!
  1651. //! \return None
  1652. //
  1653. //*****************************************************************************
  1654. void
  1655. usrand(unsigned int seed)
  1656. {
  1657. g_iRandomSeed = seed;
  1658. }
  1659. //*****************************************************************************
  1660. //
  1661. //! Generate a new (pseudo) random number
  1662. //!
  1663. //! This function is very similar to the C library <tt>rand()</tt> function.
  1664. //! It will generate a pseudo-random number sequence based on the seed value.
  1665. //!
  1666. //! \return A pseudo-random number will be returned.
  1667. //
  1668. //*****************************************************************************
  1669. int
  1670. urand(void)
  1671. {
  1672. //
  1673. // Generate a new pseudo-random number with a linear congruence random
  1674. // number generator. This new random number becomes the seed for the next
  1675. // random number.
  1676. //
  1677. g_iRandomSeed = (g_iRandomSeed * 1664525) + 1013904223;
  1678. //
  1679. // Return the new random number.
  1680. //
  1681. return((int)g_iRandomSeed);
  1682. }
  1683. //*****************************************************************************
  1684. //
  1685. // Close the Doxygen group.
  1686. //! @}
  1687. //
  1688. //*****************************************************************************
  1689. //
  1690. // End of file
  1691. //