LCOV - code coverage report
Current view: top level - source/trotLib - trotDecoding.c (source / functions) Hit Total Coverage
Test: trot.info Lines: 281 281 100.0 %
Date: 2014-03-07 Functions: 6 6 100.0 %
Branches: 178 178 100.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            : Copyright (c) 2010-2014 Jeremiah Martell
       3                 :            : All rights reserved.
       4                 :            : 
       5                 :            : Redistribution and use in source and binary forms, with or without modification,
       6                 :            : are permitted provided that the following conditions are met:
       7                 :            : 
       8                 :            :     - Redistributions of source code must retain the above copyright notice,
       9                 :            :       this list of conditions and the following disclaimer.
      10                 :            :     - Redistributions in binary form must reproduce the above copyright notice,
      11                 :            :       this list of conditions and the following disclaimer in the documentation
      12                 :            :       and/or other materials provided with the distribution.
      13                 :            :     - Neither the name of Jeremiah Martell nor the name of GeekHorse nor the
      14                 :            :       name of Trot nor the names of its contributors may be used to endorse or
      15                 :            :       promote products derived from this software without specific prior written
      16                 :            :       permission.
      17                 :            : 
      18                 :            : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
      19                 :            : ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      20                 :            : WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      21                 :            : DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
      22                 :            : ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      23                 :            : (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      24                 :            : LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
      25                 :            : ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      26                 :            : (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      27                 :            : SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      28                 :            : */
      29                 :            : 
      30                 :            : /******************************************************************************/
      31                 :            : /*!
      32                 :            :         \file
      33                 :            :         Decodes textual format to trot list.
      34                 :            : */
      35                 :            : #define TROT_FILE_NUMBER 5
      36                 :            : 
      37                 :            : /******************************************************************************/
      38                 :            : #include "trot.h"
      39                 :            : #include "trotInternal.h"
      40                 :            : 
      41                 :            : /******************************************************************************/
      42                 :            : static TROT_RC skipWhitespace( TrotList *lCharacters, TROT_INT charactersCount, TROT_INT *index, s32 mustBeOne );
      43                 :            : static TROT_RC getWord( TrotList *lCharacters, TROT_INT charactersCount, TROT_INT *index, TrotList **lWord_A );
      44                 :            : static TROT_RC wordToNumber( TrotList *lWord, TROT_INT *number );
      45                 :            : static TROT_RC splitList( TrotList *listToSplit, TROT_INT separator, TrotList **lPartList_A );
      46                 :            : static TROT_RC getReferenceList( TrotList *lTop, TrotList *lPartList, TrotList **lReference_A );
      47                 :            : 
      48                 :            : /******************************************************************************/
      49                 :            : /*!
      50                 :            :         \brief Decodes a list of characters into a list.
      51                 :            :         \param[in] lCharacters Characters to decode.
      52                 :            :         \param[out] lDecodedList_A On success, the decoded list.
      53                 :            :         \return TROT_RC
      54                 :            : 
      55                 :            :         lCharacters is not modified.
      56                 :            :         lDecodedList_A is created, and caller is responsible for freeing.
      57                 :            : */
      58                 :      17433 : TROT_RC trotDecode( TrotList *lCharacters, TrotList **lDecodedList_A )
      59                 :            : {
      60                 :            :         /* DATA */
      61                 :      17433 :         TROT_RC rc = TROT_RC_SUCCESS;
      62                 :            : 
      63                 :      17433 :         TROT_INT charactersCount = 0;
      64                 :      17433 :         TROT_INT index = 1;
      65                 :            : 
      66                 :      17433 :         TrotList *lTop = NULL;
      67                 :      17433 :         TrotList *lCurrent = NULL;
      68                 :      17433 :         TrotList *lChild = NULL;
      69                 :            : 
      70                 :      17433 :         TrotList *lWord = NULL;
      71                 :      17433 :         TROT_INT ch = 0;
      72                 :            : 
      73                 :      17433 :         TROT_INT number = 0;
      74                 :            : 
      75                 :      17433 :         TrotList *lStack = NULL;
      76                 :      17433 :         TROT_INT stackCount = 0;
      77                 :            : 
      78                 :      17433 :         TrotList *lPartList = NULL;
      79                 :            : 
      80                 :            : 
      81                 :            :         /* PRECOND */
      82         [ +  + ]:      17433 :         ERR_IF( lCharacters == NULL, TROT_RC_ERROR_PRECOND );
      83         [ +  + ]:      17432 :         ERR_IF( lDecodedList_A == NULL, TROT_RC_ERROR_PRECOND );
      84         [ +  + ]:      17431 :         ERR_IF( (*lDecodedList_A) != NULL, TROT_RC_ERROR_PRECOND );
      85                 :            : 
      86                 :            : 
      87                 :            :         /* CODE */
      88                 :            :         /* get count of characters */
      89                 :      17430 :         rc = trotListGetCount( lCharacters, &charactersCount );
      90                 :            :         PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
      91                 :            : 
      92                 :            :         /* create "top" list */
      93                 :      17430 :         rc = trotListInit( &lTop );
      94         [ +  + ]:      17430 :         ERR_IF_PASSTHROUGH;
      95                 :            : 
      96                 :            :         /* create current list */
      97                 :      17254 :         rc = trotListTwin( lTop, &lCurrent );
      98         [ +  + ]:      17254 :         ERR_IF_PASSTHROUGH;
      99                 :            : 
     100                 :            :         /* create our stack */
     101                 :      17232 :         rc = trotListInit( &lStack );
     102         [ +  + ]:      17232 :         ERR_IF_PASSTHROUGH;
     103                 :            : 
     104                 :            : 
     105                 :            :         /* skip whitespace */
     106                 :      17056 :         rc = skipWhitespace( lCharacters, charactersCount, &index, 0 );
     107         [ +  + ]:      17056 :         ERR_IF_PASSTHROUGH;
     108                 :            : 
     109                 :            : 
     110                 :            :         /* get first character */
     111                 :      17055 :         rc = trotListGetInt( lCharacters, index, &ch );
     112         [ +  + ]:      17055 :         ERR_IF_PASSTHROUGH;
     113                 :            : 
     114                 :            :         /* must be [ */
     115         [ +  + ]:      17053 :         ERR_IF_1( ch != '[', TROT_RC_ERROR_DECODE, ch );
     116                 :            : 
     117                 :            :         /* skip past [ */
     118                 :      17051 :         index += 1;
     119                 :            : 
     120                 :            : 
     121                 :            :         /* decode rest of characters */
     122                 :            :         while ( 1 )
     123                 :            :         {
     124                 :            :                 /* skip whitespace */
     125                 :     546637 :                 rc = skipWhitespace( lCharacters, charactersCount, &index, 1 );
     126         [ +  + ]:     546637 :                 ERR_IF_PASSTHROUGH;
     127                 :            :                 
     128                 :            :                 /* get next character */
     129                 :     546617 :                 rc = trotListGetInt( lCharacters, index, &ch );
     130         [ +  + ]:     546617 :                 ERR_IF_PASSTHROUGH;
     131                 :            : 
     132                 :            :                 /* if double quote, decode text format */
     133         [ +  + ]:     546614 :                 if ( ch == '\"' )
     134                 :            :                 {
     135                 :            :                         /* skip double quote */
     136                 :      10398 :                         index += 1;
     137                 :            : 
     138                 :            :                         /* go through text */
     139                 :            :                         while ( 1 )
     140                 :            :                         {
     141                 :            :                                 /* get character */
     142                 :      29100 :                                 rc = trotListGetInt( lCharacters, index, &ch );
     143         [ +  + ]:      29100 :                                 ERR_IF_PASSTHROUGH;
     144                 :            : 
     145                 :            :                                 /* if double quote, we're at end of text format */
     146         [ +  + ]:      29099 :                                 if ( ch == '\"' )
     147                 :            :                                 {
     148                 :            :                                         /* skip double quote */
     149                 :      10369 :                                         index += 1;
     150                 :            : 
     151                 :      10369 :                                         break;
     152                 :            :                                 }
     153                 :            : 
     154                 :            :                                 /* add to lCurrent */
     155                 :      18730 :                                 rc = trotListAppendInt( lCurrent, ch );
     156         [ +  + ]:      18730 :                                 ERR_IF_PASSTHROUGH;
     157                 :            : 
     158                 :            :                                 /* increment */
     159                 :      18702 :                                 index += 1;
     160                 :      29071 :                         }
     161                 :            :                 }
     162                 :            :                 /* if left bracket, create new child list and "go down" into it */
     163         [ +  + ]:     536216 :                 else if ( ch == '[' )
     164                 :            :                 {
     165                 :            :                         /* skip bracket */
     166                 :      75391 :                         index += 1;
     167                 :            : 
     168                 :            :                         /* create new list */
     169                 :      75391 :                         trotListFree( &lChild );
     170                 :      75391 :                         rc = trotListInit( &lChild );
     171         [ +  + ]:      75391 :                         ERR_IF_PASSTHROUGH;
     172                 :            : 
     173                 :            :                         /* add new list to current list */
     174                 :      74607 :                         rc = trotListAppendList( lCurrent, lChild );
     175         [ +  + ]:      74607 :                         ERR_IF_PASSTHROUGH;
     176                 :            : 
     177                 :            :                         /* push current list */
     178                 :      74485 :                         rc = trotListAppendList( lStack, lCurrent );
     179         [ +  + ]:      74485 :                         ERR_IF_PASSTHROUGH;
     180                 :            : 
     181                 :            :                         /* switchup lCurrent and lChild ... "go down" */
     182                 :      74191 :                         trotListFree( &lCurrent );
     183                 :      74191 :                         lCurrent = lChild;
     184                 :      74191 :                         lChild = NULL;
     185                 :            :                 }
     186                 :            :                 /* if right bracket, "go up" to parent */
     187         [ +  + ]:     460825 :                 else if ( ch == ']' )
     188                 :            :                 {
     189                 :            :                         /* skip bracket */
     190                 :      82053 :                         index += 1;
     191                 :            : 
     192                 :            :                         /* is stack empty? */
     193                 :      82053 :                         rc = trotListGetCount( lStack, &stackCount );
     194                 :            :                         PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     195                 :            : 
     196         [ +  + ]:      82053 :                         if ( stackCount == 0 )
     197                 :            :                         {
     198                 :       8872 :                                 break;
     199                 :            :                         }
     200                 :            : 
     201                 :            :                         /* pop off stack ... "go up" */
     202                 :      73181 :                         trotListFree( &lCurrent );
     203                 :      73181 :                         rc = trotListRemoveList( lStack, -1, &lCurrent );
     204                 :            :                         PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     205                 :            :                 }
     206                 :            :                 /* if tilde, set tag */
     207         [ +  + ]:     378772 :                 else if ( ch == '~' )
     208                 :            :                 {
     209                 :            :                         /* skip tilde */
     210                 :      22225 :                         index += 1;
     211                 :            : 
     212                 :            :                         /* get word */
     213                 :      22225 :                         trotListFree( &lWord );
     214                 :      22225 :                         rc = getWord( lCharacters, charactersCount, &index, &lWord );
     215         [ +  + ]:      22225 :                         ERR_IF_PASSTHROUGH;
     216                 :            : 
     217                 :            :                         /* word to number */
     218                 :      21845 :                         rc = wordToNumber( lWord, &number );
     219         [ +  + ]:      21845 :                         ERR_IF_PASSTHROUGH;
     220                 :            : 
     221                 :            :                         /* set tag */
     222                 :      21839 :                         rc = trotListSetTag( lCurrent, number );
     223         [ +  + ]:      21839 :                         ERR_IF_PASSTHROUGH;
     224                 :            :                 }
     225                 :            :                 /* if backtick, set user tag */
     226         [ +  + ]:     356547 :                 else if ( ch == '`' )
     227                 :            :                 {
     228                 :            :                         /* skip backtick */
     229                 :      20832 :                         index += 1;
     230                 :            : 
     231                 :            :                         /* get word */
     232                 :      20832 :                         trotListFree( &lWord );
     233                 :      20832 :                         rc = getWord( lCharacters, charactersCount, &index, &lWord );
     234         [ +  + ]:      20832 :                         ERR_IF_PASSTHROUGH;
     235                 :            : 
     236                 :            :                         /* word to number */
     237                 :      20532 :                         rc = wordToNumber( lWord, &number );
     238         [ +  + ]:      20532 :                         ERR_IF_PASSTHROUGH;
     239                 :            : 
     240                 :            :                         /* set user tag */
     241                 :      20527 :                         rc = trotListSetUserTag( lCurrent, number );
     242                 :            :                         PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     243                 :            :                 }
     244                 :            :                 /* if @, read in reference, and twin a previously-seen list */
     245         [ +  + ]:     335715 :                 else if ( ch == '@' )
     246                 :            :                 {
     247                 :            :                         /* get word */
     248                 :     145510 :                         trotListFree( &lWord );
     249                 :     145510 :                         rc = getWord( lCharacters, charactersCount, &index, &lWord );
     250         [ +  + ]:     145510 :                         ERR_IF_PASSTHROUGH;
     251                 :            : 
     252                 :            :                         /* split */
     253                 :     144567 :                         trotListFree( &lPartList );
     254                 :     144567 :                         rc = splitList( lWord, '.', &lPartList );
     255         [ +  + ]:     144567 :                         ERR_IF_PASSTHROUGH;
     256                 :            : 
     257                 :            :                         /* get reference */
     258                 :     142153 :                         trotListFree( &lChild );
     259                 :     142153 :                         rc = getReferenceList( lTop, lPartList, &lChild );
     260         [ +  + ]:     142153 :                         ERR_IF_PASSTHROUGH;
     261                 :            : 
     262                 :            :                         /* add to current */
     263                 :     141875 :                         rc = trotListAppendList( lCurrent, lChild );
     264         [ +  + ]:     141875 :                         ERR_IF_PASSTHROUGH;
     265                 :            :                 }
     266                 :            :                 /* else, must be number */
     267                 :            :                 else
     268                 :            :                 {
     269                 :            :                         /* get word */
     270                 :     190205 :                         trotListFree( &lWord );
     271                 :     190205 :                         rc = getWord( lCharacters, charactersCount, &index, &lWord );
     272         [ +  + ]:     190205 :                         ERR_IF_PASSTHROUGH;
     273                 :            : 
     274                 :            :                         /* word to number */
     275                 :     188164 :                         rc = wordToNumber( lWord, &number );
     276         [ +  + ]:     188164 :                         ERR_IF_PASSTHROUGH;
     277                 :            : 
     278                 :            :                         /* add number to current list */
     279                 :     188144 :                         rc = trotListAppendInt( lCurrent, number );
     280         [ +  + ]:     188144 :                         ERR_IF_PASSTHROUGH;
     281                 :            :                 }
     282                 :     529586 :         }
     283                 :            : 
     284                 :            :         /* skip whitespace */
     285                 :       8872 :         rc = skipWhitespace( lCharacters, charactersCount, &index, 0 );
     286         [ +  + ]:       8872 :         ERR_IF_PASSTHROUGH;
     287                 :            : 
     288                 :            :         /* we must be at end of characters */
     289         [ +  + ]:       8871 :         ERR_IF( index != (charactersCount + 1), TROT_RC_ERROR_DECODE );
     290                 :            : 
     291                 :            : 
     292                 :            :         /* give back */
     293                 :       8869 :         (*lDecodedList_A) = lTop;
     294                 :       8869 :         lTop = NULL;
     295                 :            : 
     296                 :            : 
     297                 :            :         /* CLEANUP */
     298                 :            :         cleanup:
     299                 :            : 
     300                 :      17433 :         trotListFree( &lTop );
     301                 :      17433 :         trotListFree( &lCurrent );
     302                 :      17433 :         trotListFree( &lWord );
     303                 :      17433 :         trotListFree( &lStack );
     304                 :      17433 :         trotListFree( &lPartList );
     305                 :      17433 :         trotListFree( &lChild );
     306                 :            : 
     307                 :      17433 :         return rc;
     308                 :            : }
     309                 :            : 
     310                 :            : /******************************************************************************/
     311                 :            : /*!
     312                 :            :         \brief Skips whitespace characters.
     313                 :            :         \param[in] lCharacters List of characters.
     314                 :            :         \param[in] charactersCount Count of characters.
     315                 :            :         \param[in,out] index Current index into lCharacters.
     316                 :            :         \param[in] mustBeOne Whether there must be at least 1 whitespace character.
     317                 :            :         \return TROT_RC
     318                 :            : 
     319                 :            :         index will be incremented to first non-whitespace character, or 1 past end of list.
     320                 :            : */
     321                 :     572565 : static TROT_RC skipWhitespace( TrotList *lCharacters, TROT_INT charactersCount, TROT_INT *index, s32 mustBeOne )
     322                 :            : {
     323                 :            :         /* DATA */
     324                 :     572565 :         TROT_RC rc = TROT_RC_SUCCESS;
     325                 :            : 
     326                 :     572565 :         TROT_INT ch = 0;
     327                 :            : 
     328                 :            : 
     329                 :            :         /* PRECOND */
     330                 :            :         PARANOID_ERR_IF( lCharacters == NULL );
     331                 :            :         PARANOID_ERR_IF( index == NULL );
     332                 :            : 
     333                 :            : 
     334                 :            :         /* CODE */
     335         [ +  + ]:     572565 :         if ( mustBeOne )
     336                 :            :         {
     337                 :     546637 :                 rc = trotListGetInt( lCharacters, (*index), &ch );
     338         [ +  + ]:     546637 :                 ERR_IF_PASSTHROUGH;
     339                 :            : 
     340         [ +  + ]:     546633 :                 ERR_IF( ! trotUnicodeIsWhitespace( ch ), TROT_RC_ERROR_DECODE );
     341                 :            : 
     342                 :     546622 :                 (*index) += 1;
     343                 :            :         }
     344                 :            : 
     345         [ +  + ]:     574223 :         while ( (*index) <= charactersCount )
     346                 :            :         {
     347                 :     565349 :                 rc = trotListGetInt( lCharacters, (*index), &ch );
     348         [ +  + ]:     565349 :                 ERR_IF_PASSTHROUGH;
     349                 :            : 
     350         [ +  + ]:     565342 :                 if ( ! trotUnicodeIsWhitespace( ch ) )
     351                 :            :                 {
     352                 :     563669 :                         break;
     353                 :            :                 }
     354                 :            : 
     355                 :       1673 :                 (*index) += 1;
     356                 :            :         }
     357                 :            : 
     358                 :            : 
     359                 :            :         /* CLEANUP */
     360                 :            :         cleanup:
     361                 :            : 
     362                 :     572565 :         return rc;
     363                 :            : }
     364                 :            : 
     365                 :            : /******************************************************************************/
     366                 :            : /*!
     367                 :            :         \brief Gets the next word in lCharacters.
     368                 :            :         \param[in] lCharacters List of characters.
     369                 :            :         \param[in] charactersCount Count of characters.
     370                 :            :         \param[in,out] index Current index into lCharacters.
     371                 :            :         \param[out] lWord_A The next word.
     372                 :            :         \return TROT_RC
     373                 :            : 
     374                 :            :         index will be incremented.
     375                 :            :         lWord_A will be created. Caller is responsible for freeing.
     376                 :            : */
     377                 :     378772 : static TROT_RC getWord( TrotList *lCharacters, TROT_INT charactersCount, TROT_INT *index, TrotList **lWord_A )
     378                 :            : {
     379                 :            :         /* DATA */
     380                 :     378772 :         TROT_RC rc = TROT_RC_SUCCESS;
     381                 :            : 
     382                 :     378772 :         TrotList *newLWord = NULL;
     383                 :     378772 :         TROT_INT ch = 0;
     384                 :            : 
     385                 :            : 
     386                 :            :         /* PRECOND */
     387                 :            :         PARANOID_ERR_IF( lCharacters == NULL );
     388                 :            :         PARANOID_ERR_IF( index == NULL );
     389                 :            :         PARANOID_ERR_IF( lWord_A == NULL );
     390                 :            :         PARANOID_ERR_IF( (*lWord_A) != NULL );
     391                 :            : 
     392                 :            : 
     393                 :            :         /* CODE */
     394                 :     378772 :         rc = trotListInit( &newLWord );
     395         [ +  + ]:     378772 :         ERR_IF_PASSTHROUGH;
     396                 :            : 
     397         [ +  + ]:    1075190 :         while ( (*index) <= charactersCount )
     398                 :            :         {
     399                 :    1075189 :                 rc = trotListGetInt( lCharacters, (*index), &ch );
     400         [ +  + ]:    1075189 :                 ERR_IF_PASSTHROUGH;
     401                 :            : 
     402         [ +  + ]:    1075185 :                 if ( trotUnicodeIsWhitespace( ch ) )
     403                 :            :                 {
     404                 :     375107 :                         break;
     405                 :            :                 }
     406                 :            : 
     407                 :     700078 :                 rc = trotListAppendInt( newLWord, ch );
     408         [ +  + ]:     700078 :                 ERR_IF_PASSTHROUGH;
     409                 :            : 
     410                 :     699346 :                 (*index) += 1;
     411                 :            :         }
     412                 :            : 
     413                 :            : 
     414                 :            :         /* give back */
     415                 :     375108 :         (*lWord_A) = newLWord;
     416                 :     375108 :         newLWord = NULL;
     417                 :            : 
     418                 :            : 
     419                 :            :         /* CLEANUP */
     420                 :            :         cleanup:
     421                 :            : 
     422                 :     378772 :         trotListFree( &newLWord );
     423                 :            : 
     424                 :     378772 :         return rc;
     425                 :            : }
     426                 :            : 
     427                 :            : /******************************************************************************/
     428                 :            : /*!
     429                 :            :         \brief Converts a word into a number.
     430                 :            :         \param[in] lWord The list to convert
     431                 :            :         \param[out] number On success, the number.
     432                 :            :         \return TROT_RC
     433                 :            : 
     434                 :            :         lWord must not contain lists, only ints.
     435                 :            : 
     436                 :            :         Example:
     437                 :            :         If lWord is ["123"] number would be 123.
     438                 :            : */
     439                 :     291485 : static TROT_RC wordToNumber( TrotList *lWord, TROT_INT *number )
     440                 :            : {
     441                 :            :         /* DATA */
     442                 :     291485 :         TROT_RC rc = TROT_RC_SUCCESS;
     443                 :            : 
     444                 :     291485 :         TROT_INT index = 0;
     445                 :     291485 :         TROT_INT count = 0;
     446                 :            : 
     447                 :     291485 :         TROT_INT character = 0;
     448                 :     291485 :         TROT_INT newNumber = 0;
     449                 :            : 
     450                 :     291485 :         TROT_INT i = 0;
     451                 :            : 
     452                 :            : 
     453                 :            :         /* PRECOND */
     454                 :            :         PARANOID_ERR_IF( lWord == NULL );
     455                 :            :         PARANOID_ERR_IF( number == NULL );
     456                 :            : 
     457                 :            : 
     458                 :            :         /* CODE */
     459                 :            :         /* get count */
     460                 :     291485 :         rc = trotListGetCount( lWord, &count );
     461                 :            :         PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     462                 :            : 
     463                 :            :         /* get first character */
     464                 :     291485 :         rc = trotListGetInt( lWord, 1, &character );
     465         [ +  + ]:     291485 :         ERR_IF_PASSTHROUGH;
     466                 :            : 
     467                 :            :         /* make sure it's a good format */
     468                 :     291480 :         index = 1;
     469         [ +  + ]:     291480 :         if ( character == '-' )
     470                 :            :         {
     471                 :         26 :                 index += 1;
     472                 :            :         }
     473                 :            : 
     474                 :     291480 :         rc = trotListGetInt( lWord, index, &character );
     475         [ +  + ]:     291480 :         ERR_IF_PASSTHROUGH;
     476                 :            : 
     477 [ +  + ][ +  + ]:     291479 :         ERR_IF_1( ( ! ( character >= '0' && character <= '9' ) ), TROT_RC_ERROR_DECODE, character );
     478                 :            : 
     479 [ +  + ][ +  + ]:     291470 :         ERR_IF_1( character == '0' && count != 1, TROT_RC_ERROR_DECODE, count );
     480                 :            : 
     481                 :     291467 :         index += 1;
     482                 :            : 
     483         [ +  + ]:     490946 :         while ( index <= count )
     484                 :            :         {
     485                 :     199487 :                 rc = trotListGetInt( lWord, index, &character );
     486                 :            :                 PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     487                 :            : 
     488 [ +  + ][ +  + ]:     199487 :                 ERR_IF_1( ( ! ( character >= '0' && character <= '9' ) ), TROT_RC_ERROR_DECODE, character );
     489                 :            : 
     490                 :     199479 :                 index += 1;
     491                 :            :         }
     492                 :            : 
     493                 :            :         /* make sure number can fit into our TROT_INT */
     494                 :     291459 :         index = 1;
     495                 :            : 
     496                 :     291459 :         rc = trotListGetInt( lWord, index, &character );
     497                 :            :         PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     498                 :            : 
     499         [ +  + ]:     291459 :         if ( character == '-' )
     500                 :            :         {
     501         [ +  + ]:         23 :                 ERR_IF_1( count > TROT_INT_MIN_STRING_LENGTH, TROT_RC_ERROR_DECODE, count );
     502                 :            : 
     503         [ +  + ]:         22 :                 if ( count == TROT_INT_MIN_STRING_LENGTH )
     504                 :            :                 {
     505                 :         12 :                         index += 1;
     506                 :         12 :                         i = 1; /* to skip the '-' at the beginning of TROT_INT_MIN */
     507                 :            : 
     508         [ +  + ]:         92 :                         while ( index <= count )
     509                 :            :                         {       
     510                 :         74 :                                 rc = trotListGetInt( lWord, index, &character );
     511                 :            :                                 PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     512                 :            : 
     513         [ +  + ]:         74 :                                 ERR_IF ( character > TROT_INT_MIN_STRING[ i ], TROT_RC_ERROR_DECODE );
     514                 :            : 
     515         [ +  + ]:         70 :                                 if ( character < TROT_INT_MIN_STRING[ i ] )
     516                 :            :                                 {
     517                 :          6 :                                         break;
     518                 :            :                                 }
     519                 :            : 
     520                 :         64 :                                 index += 1;
     521                 :         64 :                                 i += 1;
     522                 :            :                         }
     523                 :            :                 }
     524                 :            :         }
     525                 :            :         else
     526                 :            :         {
     527         [ +  + ]:     291436 :                 ERR_IF_1( count > TROT_INT_MAX_STRING_LENGTH, TROT_RC_ERROR_DECODE, count );
     528                 :            : 
     529         [ +  + ]:     291435 :                 if ( count == TROT_INT_MAX_STRING_LENGTH )
     530                 :            :                 {
     531                 :         12 :                         i = 0;
     532                 :            : 
     533         [ +  + ]:         76 :                         while ( index <= count )
     534                 :            :                         {       
     535                 :         74 :                                 rc = trotListGetInt( lWord, index, &character );
     536                 :            :                                 PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     537                 :            : 
     538         [ +  + ]:         74 :                                 ERR_IF_1( character > TROT_INT_MAX_STRING[ i ], TROT_RC_ERROR_DECODE, character );
     539                 :            : 
     540         [ +  + ]:         70 :                                 if ( character < TROT_INT_MAX_STRING[ i ] )
     541                 :            :                                 {
     542                 :          6 :                                         break;
     543                 :            :                                 }
     544                 :            : 
     545                 :         64 :                                 index += 1;
     546                 :         64 :                                 i += 1;
     547                 :            :                         }
     548                 :            :                 }
     549                 :            :         }
     550                 :            : 
     551                 :            :         /* get our number started */
     552                 :     291449 :         index = 1;
     553                 :            : 
     554                 :     291449 :         rc = trotListGetInt( lWord, index, &character );
     555                 :            :         PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     556                 :            : 
     557                 :            :         /* if negative, get real first number */
     558         [ +  + ]:     291449 :         if ( character == '-' )
     559                 :            :         {
     560                 :         18 :                 index += 1;
     561                 :            : 
     562                 :         18 :                 rc = trotListGetInt( lWord, index, &character );
     563                 :            :                 PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     564                 :            : 
     565                 :         18 :                 newNumber = character - '0';
     566                 :         18 :                 newNumber *= -1;
     567                 :            : 
     568                 :            :                 /* build rest of number */
     569                 :         18 :                 index += 1;
     570                 :            : 
     571         [ +  + ]:        100 :                 while ( index <= count )
     572                 :            :                 {
     573                 :         82 :                         rc = trotListGetInt( lWord, index, &character );
     574                 :            :                         PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     575                 :            :         
     576                 :         82 :                         newNumber *= 10;
     577                 :         82 :                         newNumber -= character - '0';
     578                 :            :         
     579                 :         82 :                         index += 1;
     580                 :            :                 }
     581                 :            :         }
     582                 :            :         else
     583                 :            :         {
     584                 :     291431 :                 newNumber = character - '0';
     585                 :            : 
     586                 :            :                 /* build rest of number */
     587                 :     291431 :                 index += 1;
     588                 :            : 
     589         [ +  + ]:     490736 :                 while ( index <= count )
     590                 :            :                 {
     591                 :     199305 :                         rc = trotListGetInt( lWord, index, &character );
     592                 :            :                         PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     593                 :            :         
     594                 :     199305 :                         newNumber *= 10;
     595                 :     199305 :                         newNumber += character - '0';
     596                 :            :         
     597                 :     199305 :                         index += 1;
     598                 :            :                 }
     599                 :            :         }
     600                 :            : 
     601                 :            :         /* give back */
     602                 :     291449 :         (*number) = newNumber;
     603                 :            : 
     604                 :            : 
     605                 :            :         /* CLEANUP */
     606                 :            :         cleanup:
     607                 :            : 
     608                 :     291485 :         return rc;
     609                 :            : }
     610                 :            : 
     611                 :            : /******************************************************************************/
     612                 :            : /*!
     613                 :            :         \brief Creates a new list of parts that were separated out of l.
     614                 :            :         \param[in] listToSplit List that contains parts.
     615                 :            :         \param[in] separator Separating character
     616                 :            :         \param[out] lPartList_A On success, contains the parts.
     617                 :            :         \return TROT_RC
     618                 :            : 
     619                 :            :         listToSplit is not modified.
     620                 :            :         listToSplit must only contain characters, not lists.
     621                 :            : 
     622                 :            :         lPartList_A is created, and caller is responsible for freeing.
     623                 :            : 
     624                 :            :         Example:
     625                 :            :         IN:
     626                 :            :                 listToSplit = ["abc.def.ghi"]
     627                 :            :                 separator = '.'
     628                 :            :         OUT:
     629                 :            :                 listToSplit = ["abc.def.ghi"]
     630                 :            :                 lPartList_A will be [["abc"]["def"]["ghi"]]
     631                 :            : */
     632                 :     144567 : static TROT_RC splitList( TrotList *listToSplit, TROT_INT separator, TrotList **lPartList_A )
     633                 :            : {
     634                 :            :         /* DATA */
     635                 :     144567 :         TROT_RC rc = TROT_RC_SUCCESS;
     636                 :            : 
     637                 :     144567 :         TROT_INT count = 0;
     638                 :     144567 :         TROT_INT index = 0;
     639                 :     144567 :         TROT_INT character = 0;
     640                 :            : 
     641                 :     144567 :         TrotList *newLPartList = NULL;
     642                 :     144567 :         TrotList *lPart = NULL;
     643                 :            : 
     644                 :            : 
     645                 :            :         /* PRECOND */
     646                 :            :         PARANOID_ERR_IF( listToSplit == NULL );
     647                 :            :         PARANOID_ERR_IF( lPartList_A == NULL );
     648                 :            :         PARANOID_ERR_IF( (*lPartList_A) != NULL );
     649                 :            : 
     650                 :            : 
     651                 :            :         /* CODE */
     652                 :            :         /* create giveback */
     653                 :     144567 :         rc = trotListInit( &newLPartList );
     654         [ +  + ]:     144567 :         ERR_IF_PASSTHROUGH;
     655                 :            : 
     656                 :     143815 :         rc = trotListInit( &lPart );
     657         [ +  + ]:     143815 :         ERR_IF_PASSTHROUGH;
     658                 :            : 
     659                 :     143063 :         rc = trotListAppendList( newLPartList, lPart );
     660         [ +  + ]:     143063 :         ERR_IF_PASSTHROUGH;
     661                 :            : 
     662                 :            :         /* get count */
     663                 :     142781 :         rc = trotListGetCount( listToSplit, &count );
     664                 :            :         PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     665                 :            : 
     666                 :            :         /* foreach character */
     667                 :     142781 :         index = 1;
     668         [ +  + ]:     407590 :         while ( index <= count )
     669                 :            :         {
     670                 :            :                 /* get next character */
     671                 :     265437 :                 rc = trotListGetInt( listToSplit, index, &character );
     672                 :            :                 PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     673                 :            : 
     674                 :            :                 /* if separator */
     675         [ +  + ]:     265437 :                 if ( character == separator )
     676                 :            :                 {
     677                 :      61507 :                         trotListFree( &lPart );
     678                 :            : 
     679                 :      61507 :                         rc = trotListInit( &lPart );
     680         [ +  + ]:      61507 :                         ERR_IF_PASSTHROUGH;
     681                 :            : 
     682                 :      61187 :                         rc = trotListAppendList( newLPartList, lPart );
     683         [ +  + ]:      61187 :                         ERR_IF_PASSTHROUGH;
     684                 :            :                 }
     685                 :            :                 /* else add to current part */
     686                 :            :                 else
     687                 :            :                 {
     688                 :     203930 :                         rc = trotListAppendInt( lPart, character );
     689         [ +  + ]:     203930 :                         ERR_IF_PASSTHROUGH;
     690                 :            :                 }
     691                 :            : 
     692                 :            :                 /* increment index */
     693                 :     264809 :                 index += 1;
     694                 :            :         }
     695                 :            : 
     696                 :            :         /* give back */
     697                 :     142153 :         (*lPartList_A) = newLPartList;
     698                 :     142153 :         newLPartList = NULL;
     699                 :            : 
     700                 :            : 
     701                 :            :         /* CLEANUP */
     702                 :            :         cleanup:
     703                 :            : 
     704                 :     144567 :         trotListFree( &newLPartList );
     705                 :     144567 :         trotListFree( &lPart );
     706                 :            : 
     707                 :     144567 :         return rc;
     708                 :            : }
     709                 :            : 
     710                 :            : /******************************************************************************/
     711                 :            : /*!
     712                 :            :         \brief Takes a textual-reference and retrieves the correct list out of lTop
     713                 :            :         \param[in] lTop The top list.
     714                 :            :         \param[in] lPartList List that contains the parts of the textual-reference
     715                 :            :         \param[out] lReference_A On success, the list that the textual-reference
     716                 :            :                 specified
     717                 :            :         \return TROT_RC
     718                 :            : 
     719                 :            :         Example:
     720                 :            :         If lTop is [ 85 [ 86 ] [ [ 87 ] ] ]
     721                 :            :         and lPartList is [ [ "@" ] [ "3" ] [ "1" ] ]
     722                 :            :         then lReference_A would the the list that's [ 87 ].
     723                 :            : */
     724                 :     142153 : static TROT_RC getReferenceList( TrotList *lTop, TrotList *lPartList, TrotList **lReference_A )
     725                 :            : {
     726                 :            :         /* DATA */
     727                 :     142153 :         TROT_RC rc = TROT_RC_SUCCESS;
     728                 :            : 
     729                 :     142153 :         TROT_INT partListCount = 0;
     730                 :     142153 :         TROT_INT partListIndex = 0;
     731                 :            : 
     732                 :     142153 :         TrotList *lPart = NULL;
     733                 :     142153 :         TROT_INT partNumber = 0;
     734                 :     142153 :         TROT_INT partCount = 0;
     735                 :            : 
     736                 :     142153 :         TrotList *lParent = NULL;
     737                 :     142153 :         TrotList *lChild = NULL;
     738                 :            : 
     739                 :            : 
     740                 :            :         /* PRECOND */
     741                 :            :         PARANOID_ERR_IF( lTop == NULL );
     742                 :            :         PARANOID_ERR_IF( lPartList == NULL );
     743                 :            :         PARANOID_ERR_IF( lReference_A == NULL );
     744                 :            :         PARANOID_ERR_IF( (*lReference_A) != NULL );
     745                 :            : 
     746                 :            : 
     747                 :            :         /* CODE */
     748                 :            :         /* get partListCount */
     749                 :     142153 :         rc = trotListGetCount( lPartList, &partListCount );
     750                 :            :         PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     751                 :            : 
     752                 :            :         /* get first part */
     753                 :     142153 :         rc = trotListGetList( lPartList, 1, &lPart );
     754         [ +  + ]:     142153 :         ERR_IF_PASSTHROUGH;
     755                 :            : 
     756                 :            :         /* first part must be '@'
     757                 :            :            we already know it starts with '@', so just make sure there's nothing
     758                 :            :            else in the part */
     759                 :     142059 :         rc = trotListGetCount( lPart, &partCount );
     760                 :            :         PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
     761                 :            : 
     762         [ +  + ]:     142059 :         ERR_IF_1( partCount != 1, TROT_RC_ERROR_DECODE, partCount );
     763                 :            : 
     764                 :            :         /* start parent */
     765                 :     142056 :         rc = trotListTwin( lTop, &lParent );
     766         [ +  + ]:     142056 :         ERR_IF_PASSTHROUGH;
     767                 :            : 
     768                 :            :         /* for each part, starting at 2 */
     769                 :     141962 :         partListIndex = 2;
     770         [ +  + ]:     202859 :         while ( partListIndex <= partListCount )
     771                 :            :         {
     772                 :            :                 /* get part */
     773                 :      60984 :                 trotListFree( &lPart );
     774                 :      60984 :                 rc = trotListGetList( lPartList, partListIndex, &lPart );
     775         [ +  + ]:      60984 :                 ERR_IF_PASSTHROUGH;
     776                 :            : 
     777                 :            :                 /* part into number */
     778                 :      60944 :                 rc = wordToNumber( lPart, &partNumber );
     779         [ +  + ]:      60944 :                 ERR_IF_PASSTHROUGH;
     780                 :            : 
     781                 :            :                 /* must be positive */
     782         [ +  + ]:      60939 :                 ERR_IF_1( partNumber <= 0, TROT_RC_ERROR_DECODE, partNumber );
     783                 :            : 
     784                 :            :                 /* get child of parent */
     785                 :      60937 :                 trotListFree( &lChild );
     786                 :      60937 :                 rc = trotListGetList( lParent, partNumber, &lChild );
     787         [ +  + ]:      60937 :                 ERR_IF_PASSTHROUGH;
     788                 :            : 
     789                 :            :                 /* switchup parent and child, "go down" */
     790                 :      60897 :                 trotListFree( &lParent );
     791                 :      60897 :                 lParent = lChild;
     792                 :      60897 :                 lChild = NULL;
     793                 :            : 
     794                 :            :                 /* increment */
     795                 :      60897 :                 partListIndex += 1;
     796                 :            :         }
     797                 :            : 
     798                 :            : 
     799                 :            :         /* give back */
     800                 :     141875 :         (*lReference_A) = lParent;
     801                 :     141875 :         lParent = NULL;
     802                 :            : 
     803                 :            : 
     804                 :            :         /* CLEANUP */
     805                 :            :         cleanup:
     806                 :            : 
     807                 :     142153 :         trotListFree( &lPart );
     808                 :     142153 :         trotListFree( &lParent );
     809                 :     142153 :         trotListFree( &lChild );
     810                 :            : 
     811                 :     142153 :         return rc;
     812                 :            : }
     813                 :            : 

Generated by: LCOV version 1.9