LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/ucpp - assert.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 217 0.0 %
Date: 2012-12-17 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          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           0 : void wipe_assertions(void)
     391             : {
     392           0 :         if (assertions_init_done) HTT_kill(&assertions);
     393           0 :         assertions_init_done = 0;
     394           0 : }
     395             : 
     396             : /*
     397             :  * initialize the assertion table
     398             :  */
     399           0 : void init_assertions(void)
     400             : {
     401           0 :         wipe_assertions();
     402           0 :         HTT_init(&assertions, del_assertion);
     403           0 :         assertions_init_done = 1;
     404           0 : }
     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