LCOV - code coverage report
Current view: top level - workdir/unxlngi6.pro/CustomTarget/ucpp/source - assert.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 9 217 4.1 %
Date: 2012-08-25 Functions: 2 14 14.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 268 0.7 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * (c) Thomas Pornin 1999 - 2002
       3                 :            :  *
       4                 :            :  * Redistribution and use in source and binary forms, with or without
       5                 :            :  * modification, are permitted provided that the following conditions
       6                 :            :  * are met:
       7                 :            :  * 1. Redistributions of source code must retain the above copyright
       8                 :            :  *    notice, this list of conditions and the following disclaimer.
       9                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      10                 :            :  *    notice, this list of conditions and the following disclaimer in the
      11                 :            :  *    documentation and/or other materials provided with the distribution.
      12                 :            :  * 4. The name of the authors may not be used to endorse or promote
      13                 :            :  *    products derived from this software without specific prior written
      14                 :            :  *    permission.
      15                 :            :  *
      16                 :            :  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
      17                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      18                 :            :  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      19                 :            :  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
      20                 :            :  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      21                 :            :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
      22                 :            :  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
      23                 :            :  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      24                 :            :  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
      25                 :            :  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
      26                 :            :  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27                 :            :  *
      28                 :            :  */
      29                 :            : 
      30                 :            : #include "tune.h"
      31                 :            : #include <stdio.h>
      32                 :            : #include <string.h>
      33                 :            : #include <stddef.h>
      34                 :            : #include <limits.h>
      35                 :            : #include <time.h>
      36                 :            : #include "ucppi.h"
      37                 :            : #include "mem.h"
      38                 :            : #include "nhash.h"
      39                 :            : 
      40                 :            : /*
      41                 :            :  * Assertion support. Each assertion is indexed by its predicate, and
      42                 :            :  * the list of 'questions' which yield a true answer.
      43                 :            :  */
      44                 :            : 
      45                 :            : static HTT assertions;
      46                 :            : static int assertions_init_done = 0;
      47                 :            : 
      48                 :          0 : static struct assert *new_assertion(void)
      49                 :            : {
      50                 :          0 :         struct assert *a = getmem(sizeof(struct assert));
      51                 :            : 
      52                 :          0 :         a->nbval = 0;
      53                 :          0 :         return a;
      54                 :            : }
      55                 :            : 
      56                 :          0 : static void del_token_fifo(struct token_fifo *tf)
      57                 :            : {
      58                 :            :         size_t i;
      59                 :            : 
      60         [ #  # ]:          0 :         for (i = 0; i < tf->nt; i ++)
      61 [ #  # ][ #  # ]:          0 :                 if (S_TOKEN(tf->t[i].type)) freemem(tf->t[i].name);
      62         [ #  # ]:          0 :         if (tf->nt) freemem(tf->t);
      63                 :          0 : }
      64                 :            : 
      65                 :          0 : static void del_assertion(void *va)
      66                 :            : {
      67                 :          0 :         struct assert *a = va;
      68                 :            :         size_t i;
      69                 :            : 
      70         [ #  # ]:          0 :         for (i = 0; i < a->nbval; i ++) del_token_fifo(a->val + i);
      71         [ #  # ]:          0 :         if (a->nbval) freemem(a->val);
      72                 :          0 :         freemem(a);
      73                 :          0 : }
      74                 :            : 
      75                 :            : /*
      76                 :            :  * print the contents of a token list
      77                 :            :  */
      78                 :          0 : static void print_token_fifo(struct token_fifo *tf)
      79                 :            : {
      80                 :            :         size_t i;
      81                 :            : 
      82         [ #  # ]:          0 :         for (i = 0; i < tf->nt; i ++)
      83 [ #  # ][ #  # ]:          0 :                 if (ttMWS(tf->t[i].type)) fputc(' ', emit_output);
                 [ #  # ]
      84                 :          0 :                 else fputs(token_name(tf->t + i), emit_output);
      85                 :          0 : }
      86                 :            : 
      87                 :            : /*
      88                 :            :  * print all assertions related to a given name
      89                 :            :  */
      90                 :          0 : static void print_assert(void *va)
      91                 :            : {
      92                 :          0 :         struct assert *a = va;
      93                 :            :         size_t i;
      94                 :            : 
      95         [ #  # ]:          0 :         for (i = 0; i < a->nbval; i ++) {
      96                 :          0 :                 fprintf(emit_output, "#assert %s(", HASH_ITEM_NAME(a));
      97                 :          0 :                 print_token_fifo(a->val + i);
      98                 :          0 :                 fprintf(emit_output, ")\n");
      99                 :            :         }
     100                 :          0 : }
     101                 :            : 
     102                 :            : /*
     103                 :            :  * compare two token_fifo, return 0 if they are identical, 1 otherwise.
     104                 :            :  * All whitespace tokens are considered identical, but sequences of
     105                 :            :  * whitespace are not shrinked.
     106                 :            :  */
     107                 :          0 : int cmp_token_list(struct token_fifo *f1, struct token_fifo *f2)
     108                 :            : {
     109                 :            :         size_t i;
     110                 :            : 
     111         [ #  # ]:          0 :         if (f1->nt != f2->nt) return 1;
     112         [ #  # ]:          0 :         for (i = 0; i < f1->nt; i ++) {
     113 [ #  # ][ #  # ]:          0 :                 if (ttMWS(f1->t[i].type) && ttMWS(f2->t[i].type)) continue;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     114         [ #  # ]:          0 :                 if (f1->t[i].type != f2->t[i].type) return 1;
     115         [ #  # ]:          0 :                 if (f1->t[i].type == MACROARG
     116         [ #  # ]:          0 :                         && f1->t[i].line != f2->t[i].line) return 1;
     117 [ #  # ][ #  # ]:          0 :                 if (S_TOKEN(f1->t[i].type)
     118         [ #  # ]:          0 :                         && strcmp(f1->t[i].name, f2->t[i].name)) return 1;
     119                 :            :         }
     120                 :          0 :         return 0;
     121                 :            : }
     122                 :            : 
     123                 :            : /*
     124                 :            :  * for #assert
     125                 :            :  * Assertions are not part of the ISO-C89 standard, but they are sometimes
     126                 :            :  * encountered, for instance in Solaris standard include files.
     127                 :            :  */
     128                 :          0 : int handle_assert(struct lexer_state *ls)
     129                 :            : {
     130                 :          0 :         int ina = 0, ltww;
     131                 :            :         struct token t;
     132                 :          0 :         struct token_fifo *atl = 0;
     133                 :            :         struct assert *a;
     134                 :            :         char *aname;
     135                 :          0 :         int ret = -1;
     136                 :          0 :         long l = ls->line;
     137                 :            :         int nnp;
     138                 :            :         size_t i;
     139                 :            : 
     140         [ #  # ]:          0 :         while (!next_token(ls)) {
     141         [ #  # ]:          0 :                 if (ls->ctok->type == NEWLINE) break;
     142 [ #  # ][ #  # ]:          0 :                 if (ttMWS(ls->ctok->type)) continue;
                 [ #  # ]
     143         [ #  # ]:          0 :                 if (ls->ctok->type == NAME) {
     144         [ #  # ]:          0 :                         if (!(a = HTT_get(&assertions, ls->ctok->name))) {
     145                 :          0 :                                 a = new_assertion();
     146                 :          0 :                                 aname = sdup(ls->ctok->name);
     147                 :          0 :                                 ina = 1;
     148                 :            :                         }
     149                 :          0 :                         goto handle_assert_next;
     150                 :            :                 }
     151                 :          0 :                 error(l, "illegal assertion name for #assert");
     152                 :          0 :                 goto handle_assert_warp_ign;
     153                 :            :         }
     154                 :          0 :         goto handle_assert_trunc;
     155                 :            : 
     156                 :            : handle_assert_next:
     157         [ #  # ]:          0 :         while (!next_token(ls)) {
     158         [ #  # ]:          0 :                 if (ls->ctok->type == NEWLINE) break;
     159 [ #  # ][ #  # ]:          0 :                 if (ttMWS(ls->ctok->type)) continue;
                 [ #  # ]
     160         [ #  # ]:          0 :                 if (ls->ctok->type != LPAR) {
     161                 :          0 :                         error(l, "syntax error in #assert");
     162                 :          0 :                         goto handle_assert_warp_ign;
     163                 :            :                 }
     164                 :          0 :                 goto handle_assert_next2;
     165                 :            :         }
     166                 :          0 :         goto handle_assert_trunc;
     167                 :            : 
     168                 :            : handle_assert_next2:
     169                 :          0 :         atl = getmem(sizeof(struct token_fifo));
     170                 :          0 :         atl->art = atl->nt = 0;
     171 [ #  # ][ #  # ]:          0 :         for (nnp = 1, ltww = 1; nnp && !next_token(ls);) {
     172         [ #  # ]:          0 :                 if (ls->ctok->type == NEWLINE) break;
     173 [ #  # ][ #  # ]:          0 :                 if (ltww && ttMWS(ls->ctok->type)) continue;
         [ #  # ][ #  # ]
     174 [ #  # ][ #  # ]:          0 :                 ltww = ttMWS(ls->ctok->type);
                 [ #  # ]
     175         [ #  # ]:          0 :                 if (ls->ctok->type == LPAR) nnp ++;
     176         [ #  # ]:          0 :                 else if (ls->ctok->type == RPAR) {
     177         [ #  # ]:          0 :                         if (!(-- nnp)) goto handle_assert_next3;
     178                 :            :                 }
     179                 :          0 :                 t.type = ls->ctok->type;
     180 [ #  # ][ #  # ]:          0 :                 if (S_TOKEN(t.type)) t.name = sdup(ls->ctok->name);
     181 [ #  # ][ #  # ]:          0 :                 aol(atl->t, atl->nt, t, TOKEN_LIST_MEMG);
     182                 :            :         }
     183                 :          0 :         goto handle_assert_trunc;
     184                 :            : 
     185                 :            : handle_assert_next3:
     186 [ #  # ][ #  # ]:          0 :         while (!next_token(ls) && ls->ctok->type != NEWLINE) {
     187 [ #  # ][ #  # ]:          0 :                 if (!ttWHI(ls->ctok->type) && (ls->flags & WARN_STANDARD)) {
         [ #  # ][ #  # ]
                 [ #  # ]
     188                 :          0 :                         warning(l, "trailing garbage in #assert");
     189                 :            :                 }
     190                 :            :         }
     191 [ #  # ][ #  # ]:          0 :         if (atl->nt && ttMWS(atl->t[atl->nt - 1].type) && (-- atl->nt) == 0)
         [ #  # ][ #  # ]
                 [ #  # ]
     192                 :          0 :                 freemem(atl->t);
     193         [ #  # ]:          0 :         if (atl->nt == 0) {
     194                 :          0 :                 error(l, "void assertion in #assert");
     195                 :          0 :                 goto handle_assert_error;
     196                 :            :         }
     197 [ #  # ][ #  # ]:          0 :         for (i = 0; i < a->nbval && cmp_token_list(atl, a->val + i); i ++);
     198         [ #  # ]:          0 :         if (i != a->nbval) {
     199                 :            :                 /* we already have it */
     200                 :          0 :                 ret = 0;
     201                 :          0 :                 goto handle_assert_error;
     202                 :            :         }
     203                 :            : 
     204                 :            :         /* This is a new assertion. Let's keep it. */
     205 [ #  # ][ #  # ]:          0 :         aol(a->val, a->nbval, *atl, TOKEN_LIST_MEMG);
     206         [ #  # ]:          0 :         if (ina) {
     207                 :          0 :                 HTT_put(&assertions, a, aname);
     208                 :          0 :                 freemem(aname);
     209                 :            :         }
     210         [ #  # ]:          0 :         if (emit_assertions) {
     211                 :          0 :                 fprintf(emit_output, "#assert %s(", HASH_ITEM_NAME(a));
     212                 :          0 :                 print_token_fifo(atl);
     213                 :          0 :                 fputs(")\n", emit_output);
     214                 :            :         }
     215                 :          0 :         freemem(atl);
     216                 :          0 :         return 0;
     217                 :            : 
     218                 :            : handle_assert_trunc:
     219                 :          0 :         error(l, "unfinished #assert");
     220                 :            : handle_assert_error:
     221         [ #  # ]:          0 :         if (atl) {
     222                 :          0 :                 del_token_fifo(atl);
     223                 :          0 :                 freemem(atl);
     224                 :            :         }
     225         [ #  # ]:          0 :         if (ina) {
     226                 :          0 :                 freemem(aname);
     227                 :          0 :                 freemem(a);
     228                 :            :         }
     229                 :          0 :         return ret;
     230                 :            : handle_assert_warp_ign:
     231 [ #  # ][ #  # ]:          0 :         while (!next_token(ls) && ls->ctok->type != NEWLINE);
     232         [ #  # ]:          0 :         if (ina) {
     233                 :          0 :                 freemem(aname);
     234                 :          0 :                 freemem(a);
     235                 :            :         }
     236                 :          0 :         return ret;
     237                 :            : }
     238                 :            : 
     239                 :            : /*
     240                 :            :  * for #unassert
     241                 :            :  */
     242                 :          0 : int handle_unassert(struct lexer_state *ls)
     243                 :            : {
     244                 :            :         int ltww;
     245                 :            :         struct token t;
     246                 :            :         struct token_fifo atl;
     247                 :            :         struct assert *a;
     248                 :          0 :         int ret = -1;
     249                 :          0 :         long l = ls->line;
     250                 :            :         int nnp;
     251                 :            :         size_t i;
     252                 :            : 
     253                 :          0 :         atl.art = atl.nt = 0;
     254         [ #  # ]:          0 :         while (!next_token(ls)) {
     255         [ #  # ]:          0 :                 if (ls->ctok->type == NEWLINE) break;
     256 [ #  # ][ #  # ]:          0 :                 if (ttMWS(ls->ctok->type)) continue;
                 [ #  # ]
     257         [ #  # ]:          0 :                 if (ls->ctok->type == NAME) {
     258         [ #  # ]:          0 :                         if (!(a = HTT_get(&assertions, ls->ctok->name))) {
     259                 :          0 :                                 ret = 0;
     260                 :          0 :                                 goto handle_unassert_warp;
     261                 :            :                         }
     262                 :          0 :                         goto handle_unassert_next;
     263                 :            :                 }
     264                 :          0 :                 error(l, "illegal assertion name for #unassert");
     265                 :          0 :                 goto handle_unassert_warp;
     266                 :            :         }
     267                 :          0 :         goto handle_unassert_trunc;
     268                 :            : 
     269                 :            : handle_unassert_next:
     270         [ #  # ]:          0 :         while (!next_token(ls)) {
     271         [ #  # ]:          0 :                 if (ls->ctok->type == NEWLINE) break;
     272 [ #  # ][ #  # ]:          0 :                 if (ttMWS(ls->ctok->type)) continue;
                 [ #  # ]
     273         [ #  # ]:          0 :                 if (ls->ctok->type != LPAR) {
     274                 :          0 :                         error(l, "syntax error in #unassert");
     275                 :          0 :                         goto handle_unassert_warp;
     276                 :            :                 }
     277                 :          0 :                 goto handle_unassert_next2;
     278                 :            :         }
     279         [ #  # ]:          0 :         if (emit_assertions)
     280                 :          0 :                 fprintf(emit_output, "#unassert %s\n", HASH_ITEM_NAME(a));
     281                 :          0 :         HTT_del(&assertions, HASH_ITEM_NAME(a));
     282                 :          0 :         return 0;
     283                 :            : 
     284                 :            : handle_unassert_next2:
     285 [ #  # ][ #  # ]:          0 :         for (nnp = 1, ltww = 1; nnp && !next_token(ls);) {
     286         [ #  # ]:          0 :                 if (ls->ctok->type == NEWLINE) break;
     287 [ #  # ][ #  # ]:          0 :                 if (ltww && ttMWS(ls->ctok->type)) continue;
         [ #  # ][ #  # ]
     288 [ #  # ][ #  # ]:          0 :                 ltww = ttMWS(ls->ctok->type);
                 [ #  # ]
     289         [ #  # ]:          0 :                 if (ls->ctok->type == LPAR) nnp ++;
     290         [ #  # ]:          0 :                 else if (ls->ctok->type == RPAR) {
     291         [ #  # ]:          0 :                         if (!(-- nnp)) goto handle_unassert_next3;
     292                 :            :                 }
     293                 :          0 :                 t.type = ls->ctok->type;
     294 [ #  # ][ #  # ]:          0 :                 if (S_TOKEN(t.type)) t.name = sdup(ls->ctok->name);
     295 [ #  # ][ #  # ]:          0 :                 aol(atl.t, atl.nt, t, TOKEN_LIST_MEMG);
     296                 :            :         }
     297                 :          0 :         goto handle_unassert_trunc;
     298                 :            : 
     299                 :            : handle_unassert_next3:
     300 [ #  # ][ #  # ]:          0 :         while (!next_token(ls) && ls->ctok->type != NEWLINE) {
     301 [ #  # ][ #  # ]:          0 :                 if (!ttWHI(ls->ctok->type) && (ls->flags & WARN_STANDARD)) {
         [ #  # ][ #  # ]
                 [ #  # ]
     302                 :          0 :                         warning(l, "trailing garbage in #unassert");
     303                 :            :                 }
     304                 :            :         }
     305 [ #  # ][ #  # ]:          0 :         if (atl.nt && ttMWS(atl.t[atl.nt - 1].type) && (-- atl.nt) == 0)
         [ #  # ][ #  # ]
                 [ #  # ]
     306                 :          0 :                 freemem(atl.t);
     307         [ #  # ]:          0 :         if (atl.nt == 0) {
     308                 :          0 :                 error(l, "void assertion in #unassert");
     309                 :          0 :                 return ret;
     310                 :            :         }
     311 [ #  # ][ #  # ]:          0 :         for (i = 0; i < a->nbval && cmp_token_list(&atl, a->val + i); i ++);
     312         [ #  # ]:          0 :         if (i != a->nbval) {
     313                 :            :                 /* we have it, undefine it */
     314                 :          0 :                 del_token_fifo(a->val + i);
     315         [ #  # ]:          0 :                 if (i < (a->nbval - 1))
     316                 :          0 :                         mmvwo(a->val + i, a->val + i + 1, (a->nbval - i - 1)
     317                 :            :                                 * sizeof(struct token_fifo));
     318         [ #  # ]:          0 :                 if ((-- a->nbval) == 0) freemem(a->val);
     319         [ #  # ]:          0 :                 if (emit_assertions) {
     320                 :          0 :                         fprintf(emit_output, "#unassert %s(",
     321                 :          0 :                                 HASH_ITEM_NAME(a));
     322                 :          0 :                         print_token_fifo(&atl);
     323                 :          0 :                         fputs(")\n", emit_output);
     324                 :            :                 }
     325                 :            :         }
     326                 :          0 :         ret = 0;
     327                 :          0 :         goto handle_unassert_finish;
     328                 :            : 
     329                 :            : handle_unassert_trunc:
     330                 :          0 :         error(l, "unfinished #unassert");
     331                 :            : handle_unassert_finish:
     332         [ #  # ]:          0 :         if (atl.nt) del_token_fifo(&atl);
     333                 :          0 :         return ret;
     334                 :            : handle_unassert_warp:
     335 [ #  # ][ #  # ]:          0 :         while (!next_token(ls) && ls->ctok->type != NEWLINE);
     336                 :          0 :         return ret;
     337                 :            : }
     338                 :            : 
     339                 :            : /*
     340                 :            :  * Add the given assertion (as string).
     341                 :            :  */
     342                 :          0 : int make_assertion(char *aval)
     343                 :            : {
     344                 :            :         struct lexer_state lls;
     345                 :          0 :         size_t n = strlen(aval) + 1;
     346                 :          0 :         char *c = sdup(aval);
     347                 :            :         int ret;
     348                 :            : 
     349                 :          0 :         *(c + n - 1) = '\n';
     350                 :          0 :         init_buf_lexer_state(&lls, 0);
     351                 :          0 :         lls.flags = DEFAULT_LEXER_FLAGS;
     352                 :          0 :         lls.input = 0;
     353                 :          0 :         lls.input_string = (unsigned char *)c;
     354                 :          0 :         lls.pbuf = 0;
     355                 :          0 :         lls.ebuf = n;
     356                 :          0 :         lls.line = -1;
     357                 :          0 :         ret = handle_assert(&lls);
     358                 :          0 :         freemem(c);
     359                 :          0 :         free_lexer_state(&lls);
     360                 :          0 :         return ret;
     361                 :            : }
     362                 :            : 
     363                 :            : /*
     364                 :            :  * Remove the given assertion (as string).
     365                 :            :  */
     366                 :          0 : int destroy_assertion(char *aval)
     367                 :            : {
     368                 :            :         struct lexer_state lls;
     369                 :          0 :         size_t n = strlen(aval) + 1;
     370                 :          0 :         char *c = sdup(aval);
     371                 :            :         int ret;
     372                 :            : 
     373                 :          0 :         *(c + n - 1) = '\n';
     374                 :          0 :         init_buf_lexer_state(&lls, 0);
     375                 :          0 :         lls.flags = DEFAULT_LEXER_FLAGS;
     376                 :          0 :         lls.input = 0;
     377                 :          0 :         lls.input_string = (unsigned char *)c;
     378                 :          0 :         lls.pbuf = 0;
     379                 :          0 :         lls.ebuf = n;
     380                 :          0 :         lls.line = -1;
     381                 :          0 :         ret = handle_unassert(&lls);
     382                 :          0 :         freemem(c);
     383                 :          0 :         free_lexer_state(&lls);
     384                 :          0 :         return ret;
     385                 :            : }
     386                 :            : 
     387                 :            : /*
     388                 :            :  * erase the assertion table
     389                 :            :  */
     390                 :      11956 : void wipe_assertions(void)
     391                 :            : {
     392         [ +  + ]:      11956 :         if (assertions_init_done) HTT_kill(&assertions);
     393                 :      11956 :         assertions_init_done = 0;
     394                 :      11956 : }
     395                 :            : 
     396                 :            : /*
     397                 :            :  * initialize the assertion table
     398                 :            :  */
     399                 :       5978 : void init_assertions(void)
     400                 :            : {
     401                 :       5978 :         wipe_assertions();
     402                 :       5978 :         HTT_init(&assertions, del_assertion);
     403                 :       5978 :         assertions_init_done = 1;
     404                 :       5978 : }
     405                 :            : 
     406                 :            : /*
     407                 :            :  * retrieve an assertion from the hash table
     408                 :            :  */
     409                 :          0 : struct assert *get_assertion(char *name)
     410                 :            : {
     411                 :          0 :         return HTT_get(&assertions, name);
     412                 :            : }
     413                 :            : 
     414                 :            : /*
     415                 :            :  * print already defined assertions
     416                 :            :  */
     417                 :          0 : void print_assertions(void)
     418                 :            : {
     419                 :          0 :         HTT_scan(&assertions, print_assert);
     420                 :          0 : }

Generated by: LCOV version 1.10