Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers fnet_stdlib.c Source File

fnet_stdlib.c

Go to the documentation of this file.
00001 /**************************************************************************
00002 *
00003 * Copyright (c) 2017, Arm Limited and affiliates.
00004 * Copyright 2011-2016 by Andrey Butok. FNET Community.
00005 * Copyright 2008-2010 by Freescale Semiconductor, Inc.
00006 * Copyright 2003 by Motorola SPS.
00007 *
00008 ***************************************************************************
00009 *
00010 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00011 *  not use this file except in compliance with the License.
00012 *  You may obtain a copy of the License at
00013 *
00014 *  http://www.apache.org/licenses/LICENSE-2.0
00015 *
00016 *  Unless required by applicable law or agreed to in writing, software
00017 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00018 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00019 *  See the License for the specific language governing permissions and
00020 *  limitations under the License.
00021 *
00022 **********************************************************************/
00023 /*!
00024 *
00025 * @file fnet_stdlib.c
00026 *
00027 * @brief Standard functions implementation.
00028 *
00029 ***************************************************************************/
00030 
00031 #include "fnet.h"
00032 
00033 static fnet_uint32_t fnet_rand_value;  /* Used by fnet_rand()*/
00034 
00035 #if !FNET_CFG_OVERLOAD_MEMCPY
00036 /************************************************************************
00037 * DESCRIPTION:
00038 *************************************************************************/
00039 #if 0
00040 /* Slowest && Smallest */
00041 void fnet_memcpy( FNET_COMP_PACKED_VAR void *dest, FNET_COMP_PACKED_VAR const void *src, fnet_size_t n )
00042 {
00043     const fnet_uint8_t  *p = (fnet_uint8_t *)src;
00044     fnet_uint8_t        *q = (fnet_uint8_t *)dest;
00045 
00046     for (n++; --n; )
00047     {
00048         *q++ = *p++;
00049     }
00050 }
00051 #elif 0 /* Faster. */
00052 void fnet_memcpy (FNET_COMP_PACKED_VAR void *dest, FNET_COMP_PACKED_VAR const void *src, fnet_size_t n)
00053 {
00054     fnet_size_t                         longs;
00055     fnet_size_t                         bytes;
00056     FNET_COMP_PACKED_VAR fnet_uint32_t  *dpl = (fnet_uint32_t *)dest;
00057     FNET_COMP_PACKED_VAR fnet_uint32_t  *spl = (fnet_uint32_t *)src;
00058     fnet_uint8_t                        *dpb, *spb;
00059 
00060     bytes = (n & 0x3);
00061     longs = ((n - bytes) >> 2);
00062 
00063     for (longs++; --longs;)
00064     {
00065         *dpl++ = *spl++;
00066     }
00067 
00068     dpb = (fnet_uint8_t *)dpl;
00069     spb = (fnet_uint8_t *)spl;
00070 
00071     for (bytes++; --bytes;)
00072     {
00073         *dpb++ = *spb++;
00074     }
00075 }
00076 #else /* Fastest & Biggest. */
00077 void fnet_memcpy(FNET_COMP_PACKED_VAR void *to_ptr, FNET_COMP_PACKED_VAR const void *from_ptr, fnet_size_t number_of_bytes)
00078 {
00079     const fnet_uint8_t                          *from8_ptr = (const fnet_uint8_t *) from_ptr;
00080     fnet_uint8_t                                *to8_ptr = (fnet_uint8_t *) to_ptr;
00081     FNET_COMP_PACKED_VAR const fnet_uint16_t    *from16_ptr = (const fnet_uint16_t *) from_ptr;
00082     FNET_COMP_PACKED_VAR fnet_uint16_t          *to16_ptr = (fnet_uint16_t *) to_ptr;
00083     FNET_COMP_PACKED_VAR const fnet_uint32_t    *from32_ptr = (const fnet_uint32_t *) from_ptr;
00084     FNET_COMP_PACKED_VAR fnet_uint32_t          *to32_ptr = (fnet_uint32_t *) to_ptr;
00085     fnet_index_t                                loops;
00086 
00087     /*
00088     * The copying is optimized to avoid alignment problems, and attempts
00089     *               to copy 32bit numbers optimally.
00090     */
00091     if (number_of_bytes > 3u)
00092     {
00093         /* Try to align source on word */
00094         if (((uintptr_t)from_ptr & 1u) != 0u)
00095         {
00096             from8_ptr = (const fnet_uint8_t *) from_ptr;
00097             to8_ptr = (fnet_uint8_t *) to_ptr;
00098 
00099             *to8_ptr++ = *from8_ptr++;
00100 
00101             from_ptr = from8_ptr;
00102             to_ptr = to8_ptr;
00103             --number_of_bytes;
00104         }
00105 
00106         /* Try to align source on longword */
00107         if ((((uintptr_t)from_ptr) & 2u) != 0u)
00108         {
00109             from16_ptr = (const fnet_uint16_t *) from_ptr;
00110             to16_ptr = (fnet_uint16_t *) to_ptr;
00111 
00112             *to16_ptr++ = *from16_ptr++;
00113 
00114             from_ptr = from16_ptr;
00115             to_ptr = to16_ptr;
00116             number_of_bytes -= 2u;
00117         }
00118 
00119         from32_ptr = (const fnet_uint32_t *) from_ptr;
00120         to32_ptr = (fnet_uint32_t *) to_ptr;
00121 
00122         /*
00123         ** To increase performance a bit, we will copy 64 bytes (16 * longwords) sequentially
00124         ** This gets less instruction cycles.
00125         */
00126         for (loops = (number_of_bytes >> 6u); loops > 0u; loops--)
00127         {
00128             /* copy 16 longwords */
00129             *to32_ptr++ = *from32_ptr++;
00130             *to32_ptr++ = *from32_ptr++;
00131             *to32_ptr++ = *from32_ptr++;
00132             *to32_ptr++ = *from32_ptr++;
00133             *to32_ptr++ = *from32_ptr++;
00134             *to32_ptr++ = *from32_ptr++;
00135             *to32_ptr++ = *from32_ptr++;
00136             *to32_ptr++ = *from32_ptr++;
00137             *to32_ptr++ = *from32_ptr++;
00138             *to32_ptr++ = *from32_ptr++;
00139             *to32_ptr++ = *from32_ptr++;
00140             *to32_ptr++ = *from32_ptr++;
00141             *to32_ptr++ = *from32_ptr++;
00142             *to32_ptr++ = *from32_ptr++;
00143             *to32_ptr++ = *from32_ptr++;
00144             *to32_ptr++ = *from32_ptr++;
00145         }
00146 
00147         /* Now, write the rest of bytes */
00148         for (loops = ((number_of_bytes >> 2) & 0xFu); loops > 0u; loops--)
00149         {
00150             *to32_ptr++ = *from32_ptr++;
00151         }
00152 
00153         from_ptr = from32_ptr;
00154         to_ptr = to32_ptr;
00155     }
00156 
00157     /* Copy all remaining bytes */
00158     if ((number_of_bytes & 2u) != 0u)
00159     {
00160         from16_ptr = (const fnet_uint16_t *) from_ptr;
00161         to16_ptr = (fnet_uint16_t *) to_ptr;
00162 
00163         *to16_ptr++ = *from16_ptr++;
00164 
00165         from_ptr = from16_ptr;
00166         to_ptr = to16_ptr;
00167     }
00168 
00169     if ((number_of_bytes & 1u) != 0u)
00170     {
00171         * (fnet_uint8_t *) to_ptr = * (const fnet_uint8_t *) from_ptr;
00172     }
00173 }
00174 #endif
00175 
00176 #endif
00177 
00178 /************************************************************************
00179 * DESCRIPTION: Copy function to other location.
00180 *              Used for relocate function from Flash to RAM
00181 *
00182 *************************************************************************/
00183 void *fnet_memcpy_func(void *to_buf_ptr, const void *from_func_ptr, fnet_size_t to_buf_size)
00184 {
00185 
00186     fnet_memcpy(to_buf_ptr, (void *)FNET_CPU_INSTRUCTION_TO_ADDR(from_func_ptr), to_buf_size);
00187 
00188     return (void *)FNET_CPU_ADDR_TO_INSTRUCTION(to_buf_ptr);
00189 }
00190 
00191 /************************************************************************
00192 * DESCRIPTION:
00193 *************************************************************************/
00194 void fnet_memset( void *dest, fnet_uint8_t value, fnet_size_t n )
00195 {
00196     /* Not optimized */
00197     fnet_uint8_t *sp = (fnet_uint8_t *)dest;
00198 
00199     while(n)
00200     {
00201         *sp++ = (fnet_uint8_t)value;
00202         n--;
00203     }
00204 }
00205 
00206 /************************************************************************
00207 * DESCRIPTION: Same as "fnet_memset( void *s, 0, unsigned n )"
00208 *************************************************************************/
00209 void fnet_memset_zero( void *dest, fnet_size_t n )
00210 {
00211     /* Not optimized */
00212     fnet_uint8_t *sp = (fnet_uint8_t *)dest;
00213 
00214     while(n)
00215     {
00216         *sp++ = 0u;
00217         n--;
00218     }
00219 }
00220 
00221 /************************************************************************
00222 * DESCRIPTION: Compare two memory regions and return zero if they are identical,
00223 *              non-zero otherwise.  If count is zero, return zero.
00224 *************************************************************************/
00225 fnet_int32_t fnet_memcmp(const void *src1, const void *src2, fnet_size_t count )
00226 {
00227     const fnet_uint8_t *p1 = (const fnet_uint8_t *)src1;
00228     const fnet_uint8_t *p2 = (const fnet_uint8_t *)src2;
00229 
00230     while(count)
00231     {
00232         if(*p1++ != *p2++)
00233         {
00234             return 1;
00235         }
00236         count--;
00237     }
00238 
00239     return (0);
00240 }
00241 
00242 /************************************************************************
00243 * DESCRIPTION:
00244 *************************************************************************/
00245 fnet_int32_t fnet_strcmp( const fnet_char_t *str1, const fnet_char_t *str2 )
00246 {
00247     /* No checks for 0 */
00248     const fnet_char_t *s1p = str1;
00249     const fnet_char_t *s2p = str2;
00250 
00251     while(*s2p != '\0')
00252     {
00253         if(*s1p != *s2p)
00254         {
00255             break;
00256         }
00257 
00258         ++s1p;
00259         ++s2p;
00260     }
00261 
00262     return (fnet_int32_t)(*s1p - *s2p);
00263 }
00264 
00265 /************************************************************************
00266 * DESCRIPTION: Calculates the length of a string.
00267 *************************************************************************/
00268 fnet_size_t fnet_strlen (const fnet_char_t *str)
00269 {
00270     const fnet_char_t  *s = str;
00271     fnet_size_t         len = 0U;
00272 
00273     if (s == 0)
00274     {
00275         return 0U;
00276     }
00277 
00278     while (*s++ != '\0')
00279     {
00280         ++len;
00281     }
00282 
00283     return len;
00284 }
00285 
00286 /************************************************************************
00287 * DESCRIPTION:
00288 *************************************************************************/
00289 void fnet_strcat (fnet_char_t *dest, const fnet_char_t *src)
00290 {
00291     fnet_char_t        *dp;
00292     const fnet_char_t  *sp = src;
00293 
00294     if ((dest != 0) && (src != 0))
00295     {
00296         dp = &dest[fnet_strlen(dest)];
00297 
00298         while (*sp != '\0')
00299         {
00300             *dp++ = *sp++;
00301         }
00302         *dp = '\0';
00303     }
00304 }
00305 
00306 /************************************************************************
00307 * DESCRIPTION:
00308 *************************************************************************/
00309 void fnet_strncat (fnet_char_t *dest, const fnet_char_t *src, fnet_size_t n)
00310 {
00311     fnet_char_t        *dp;
00312     const fnet_char_t  *sp = src;
00313 
00314     if ((dest != 0) && (src != 0) && (n > 0U))
00315     {
00316         dp = &dest[fnet_strlen(dest)];
00317 
00318         while((*sp != '\0') && (n > 0u))
00319         {
00320             *dp++ = *sp++;
00321             n--;
00322         }
00323         *dp = '\0';
00324     }
00325 }
00326 
00327 /************************************************************************
00328 * DESCRIPTION:
00329 *************************************************************************/
00330 void fnet_strcpy (fnet_char_t *dest, const fnet_char_t *src)
00331 {
00332     fnet_char_t        *dp = dest;
00333     const fnet_char_t  *sp = src;
00334 
00335     if ((dest != 0) && (src != 0))
00336     {
00337         while (*sp != '\0')
00338         {
00339             *dp++ = *sp++;
00340         }
00341         *dp = '\0';
00342     }
00343 }
00344 
00345 /************************************************************************
00346 * DESCRIPTION:
00347 *************************************************************************/
00348 void fnet_strncpy( fnet_char_t *dest, const fnet_char_t *src, fnet_size_t n )
00349 {
00350     fnet_char_t        *dp = dest;
00351     const fnet_char_t  *sp = src;
00352 
00353     if((dest != 0) && (src != 0) && (n > 0u))
00354     {
00355         while((*sp != '\0') && (n-- > 0u))
00356         {
00357             *dp++ = *sp++;
00358         }
00359 
00360         *dp = '\0';
00361     }
00362 }
00363 
00364 /************************************************************************
00365 * DESCRIPTION: The function fnet_strrchr() returns a pointer to the last
00366 * occurrence of chr in str, or NULL if no match is found.
00367 *************************************************************************/
00368 fnet_char_t *fnet_strrchr(const fnet_char_t *str, fnet_char_t chr )
00369 {
00370     const fnet_char_t  *p = str;
00371     const fnet_char_t  *q = 0;
00372     fnet_char_t        c = chr;
00373     fnet_char_t        ch = *p++;
00374 
00375     while(ch)
00376     {
00377         if(ch == c)
00378         {
00379             q = p - 1;
00380         }
00381 
00382         ch = *p++;
00383     }
00384 
00385     if(q)
00386     {
00387         return (fnet_char_t *)(q);
00388     }
00389 
00390     return (c ? FNET_NULL : (fnet_char_t *)(p - 1));
00391 }
00392 /************************************************************************
00393 * DESCRIPTION: The function fnet_strchr() returns a pointer to the first
00394 * occurence of chr in str, or 0 if chr is not found.
00395 *************************************************************************/
00396 fnet_char_t *fnet_strchr( const fnet_char_t *str, fnet_char_t chr )
00397 {
00398     const fnet_char_t   *p = str;
00399     fnet_char_t         c = chr;
00400     fnet_char_t         ch = *p++;
00401 
00402     while(ch)
00403     {
00404         if(ch == c)
00405         {
00406             return (fnet_char_t *)(p - 1);
00407         }
00408 
00409         ch = *p++;
00410     }
00411 
00412     return (fnet_char_t *)(c ? FNET_NULL : (p - 1));
00413 }
00414 
00415 /************************************************************************
00416 * DESCRIPTION: The function fnet_strstr() returns a pointer to the first
00417 * occurrence of substr in str, or 0 if no match is found.
00418 * If the length of pat is zero, then fnet_strstr() will
00419 * simply return str.
00420 *************************************************************************/
00421 fnet_char_t *fnet_strstr( const fnet_char_t *str, const fnet_char_t *substr )
00422 {
00423     const fnet_char_t  *s1 = str;
00424     const fnet_char_t  *p1 = substr;
00425     fnet_uint8_t        firstc, c1, c2;
00426 
00427     if((substr == 0) || (!((firstc = *p1++) != 0u)) )
00428     {
00429         return (fnet_char_t *)(str);
00430     }
00431 
00432     c1 = *s1++;
00433 
00434     while(c1)
00435     {
00436         if(c1 == firstc)
00437         {
00438             const fnet_char_t *s2 = s1;
00439             const fnet_char_t *p2 = p1;
00440 
00441             while(((c1 = *s2++) == (c2 = *p2++)) && c1)
00442             {}
00443 
00444             if(!c2)
00445             {
00446                 return ((fnet_char_t *)(s1 - 1));
00447             }
00448         }
00449 
00450         c1 = *s1++;
00451     }
00452 
00453     return (0);
00454 }
00455 
00456 /************************************************************************
00457 * DESCRIPTION: The fnet_strncmp() function compares at most count characters
00458 * of str1 and str2.
00459 *************************************************************************/
00460 fnet_int32_t fnet_strncmp( const fnet_char_t *str1, const fnet_char_t *str2, fnet_size_t n )
00461 {
00462     const fnet_char_t  *p1 = str1;
00463     const fnet_char_t  *p2 = str2;
00464     fnet_uint8_t        c1, c2;
00465 
00466     n++;
00467 
00468     while(--n)
00469     {
00470         if((c1 = *p1++) != (c2 = *p2++))
00471         {
00472             return (fnet_int32_t)(c1 - c2);
00473         }
00474         else if(!c1)
00475         {
00476             break;
00477         }
00478         else
00479         {}
00480     }
00481 
00482     return (0);
00483 }
00484 
00485 /************************************************************************
00486 * DESCRIPTION:
00487 *************************************************************************/
00488 fnet_uint32_t fnet_strtoul (const fnet_char_t *str, fnet_char_t **ptr, fnet_size_t base)
00489 {
00490     fnet_uint32_t   rvalue;
00491     fnet_bool_t     err;
00492     fnet_bool_t     neg;
00493     fnet_char_t     c;
00494     fnet_char_t     *endp;
00495     fnet_char_t     *startp;
00496 
00497     rvalue = 0u;
00498     err = FNET_FALSE;
00499     neg = FNET_FALSE;
00500 
00501     /* Check for invalid arguments */
00502     if ((str == 0) || (base == 1u) || (base > 36u))
00503     {
00504         if (ptr != 0)
00505         {
00506             *ptr = (fnet_char_t *)str;
00507         }
00508         return 0u;
00509     }
00510 
00511     /* Skip leading white spaces */
00512     for (startp = (fnet_char_t *)str; ((*startp == ' ') || (*startp == '\t')) ; ++startp)
00513     {}
00514 
00515     /* Check for notations */
00516     switch (startp[0])
00517     {
00518         case '0':
00519             if ((startp[1] == 'x') || (startp[1] == 'X'))
00520             {
00521                 if ((base == 0u) || (base == 16u))
00522                 {
00523                     base = 16u;
00524                     startp = &startp[2];
00525                 }
00526             }
00527             break;
00528         case '-':
00529             neg = FNET_TRUE;
00530             startp = &startp[1];
00531             break;
00532         default:
00533             break;
00534     }
00535 
00536     if (base == 0u)
00537     {
00538         base = 10u;
00539     }
00540 
00541     /* Check for invalid chars in str */
00542     for ( endp = startp; (err == FNET_FALSE) && ((c = (*endp)) != '\0') && (!((*endp == ' ') || (*endp == '\t'))); ++endp)
00543     {
00544         /* Check for 0..9,Aa-Zz */
00545         if (!(((c >= '0') && (c <= '9')) ||
00546               ((c >= 'A') && (c <= 'Z')) ||
00547               ((c >= 'a') && (c <= 'z'))))
00548         {
00549             err = FNET_TRUE;
00550         }
00551         else
00552         {
00553             /* Convert fnet_char_t to num in 0..36 */
00554             if ((c >= '0') && (c <= '9')) /* Is digit.*/
00555             {
00556                 c = c - '0';
00557             }
00558             else
00559             {
00560                 if ((c >= 'A') && (c <= 'Z')) /* Is upper.*/
00561                 {
00562                     c = c - 'A' + 10u;
00563                 }
00564                 else
00565                 {
00566                     c = c - 'a' + 10u;
00567                 }
00568             }
00569 
00570             /* check c against base */
00571             if ((fnet_size_t)c >= base)
00572             {
00573                 err = FNET_TRUE;
00574             }
00575             else
00576             {
00577                 if (neg)
00578                 {
00579                     rvalue = (rvalue * base) - (fnet_uint32_t)c;
00580                 }
00581                 else
00582                 {
00583                     rvalue = (rvalue * base) + (fnet_uint32_t)c;
00584                 }
00585             }
00586         }
00587     }
00588 
00589     /* Upon exit, endp points to the character at which valid info */
00590     /* STOPS.  No chars including and beyond endp are used.        */
00591 
00592     if (ptr != 0)
00593     {
00594         *ptr = endp;
00595     }
00596 
00597     if (err)
00598     {
00599         if (ptr != 0)
00600         {
00601             *ptr = (fnet_char_t *)str;
00602         }
00603         return 0u;
00604     }
00605     else
00606     {
00607         return rvalue;
00608     }
00609 }
00610 
00611 /************************************************************************
00612 * DESCRIPTION: This function converts an uppercase letter to the corresponding
00613 * lowercase letter.
00614 *************************************************************************/
00615 fnet_char_t fnet_tolower( fnet_char_t to_lower )
00616 {
00617     if((to_lower >= 'A') && (to_lower <= 'Z'))
00618     {
00619         return (fnet_uint8_t)(to_lower + 0x20u);
00620     }
00621 
00622     return to_lower;
00623 }
00624 
00625 /************************************************************************
00626 * DESCRIPTION: The fnet_strcasecmp() function compares the two strings s1
00627 * and s2, ignoring the case of the characters. It returns an
00628 * integer less than, equal to, or greater than zero if s1 is found,
00629 * respectively, to be less than, to match, or be greater than s2.
00630 *************************************************************************/
00631 fnet_int32_t fnet_strcasecmp( const fnet_char_t *str1, const fnet_char_t *str2 )
00632 {
00633     fnet_uint8_t c1, c2;
00634 
00635     while(1)
00636     {
00637         c1 = fnet_tolower(*str1++);
00638         c2 = fnet_tolower(*str2++);
00639 
00640         if(c1 < c2)
00641         {
00642             return -1;
00643         }
00644 
00645         if(c1 > c2)
00646         {
00647             return 1;
00648         }
00649 
00650         if(c1 == 0u)
00651         {
00652             return 0;
00653         }
00654     }
00655 }
00656 
00657 /************************************************************************
00658 * DESCRIPTION:
00659 *************************************************************************/
00660 fnet_int32_t fnet_strcmp_splitter( const fnet_char_t *in_str, const fnet_char_t *name, fnet_char_t splitter)
00661 {
00662     fnet_int32_t result;
00663 
00664     /* No checks for 0 */
00665     const fnet_char_t *s1p = in_str;
00666     const fnet_char_t *s2p = name;
00667 
00668     while (*s1p == ' ')
00669     {
00670         s1p++;      /* Strip leading spaces */
00671     }
00672     while (*s1p == splitter)
00673     {
00674         s1p++;  /* Strip heading slash */
00675     }
00676 
00677     while((*s2p != '\0') && (*s1p == *s2p))
00678     {
00679         ++s1p;
00680         ++s2p;
00681 
00682         if (*s1p == splitter)
00683         {
00684             break; /* next element */
00685         }
00686     }
00687 
00688     if(*s1p == splitter)
00689     {
00690         result = 0;
00691     }
00692     else
00693     {
00694         result = (fnet_int32_t )(*s1p - *s2p);
00695     }
00696 
00697     return result;
00698 }
00699 
00700 /************************************************************************
00701 * DESCRIPTION: Breaks a string into a sequence of tokens.
00702 *************************************************************************/
00703 fnet_char_t *fnet_strtok_r(fnet_char_t *str, const fnet_char_t *delimiter, fnet_char_t **last)
00704 {
00705     const fnet_char_t  *spanp;
00706     fnet_char_t        c;
00707     fnet_char_t        sc;
00708     fnet_char_t        *tok;
00709 
00710     if ((str == FNET_NULL) && ((str = *last) == FNET_NULL))
00711     {
00712         return (FNET_NULL);
00713     }
00714 
00715     /*
00716      * Skip leading delimiters.
00717      */
00718 CONT:
00719     c = (*str++);
00720     spanp = delimiter;
00721     while( (sc = (*spanp++)) != 0u)
00722     {
00723         if (c == sc)
00724         {
00725             goto CONT;
00726         }
00727     }
00728 
00729     if (c == 0u) /* No non-delimiter characters */
00730     {
00731         *last = FNET_NULL;
00732         return (FNET_NULL);
00733     }
00734     tok = str - 1;
00735 
00736     /*
00737      * Scan token.
00738      */
00739     for (;;)
00740     {
00741         c = (*str++);
00742         spanp = delimiter;
00743         do
00744         {
00745             if ((sc = (*spanp++)) == c)
00746             {
00747                 if (c == 0u)
00748                 {
00749                     str = FNET_NULL;
00750                 }
00751                 else
00752                 {
00753                     str[-1] = 0u;
00754                 }
00755                 *last = str;
00756                 return (tok);
00757             }
00758         }
00759         while (sc != 0u);
00760     }
00761     /* Not reached.*/
00762 }
00763 
00764 /************************************************************************
00765 * DESCRIPTION: Generates a pseudo-random number.
00766 *************************************************************************/
00767 fnet_uint32_t fnet_rand(void)
00768 {
00769     fnet_rand_value = fnet_rand_value * 1103515245u + 12345u;
00770     return((fnet_uint32_t)(fnet_rand_value >> 16u) % (FNET_RAND_MAX + 1u));
00771 }
00772 
00773 /************************************************************************
00774 * DESCRIPTION: Initializes the pseudo-random number generator.
00775 *************************************************************************/
00776 void fnet_srand(fnet_uint32_t seed)
00777 {
00778     fnet_rand_value += seed;
00779 }