coan 4.2.4
contradiction.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004, 2006 Symbian Software Ltd.                        *
00003  *   All rights reserved.                                                  *
00004  *   Copyright (C) 2007-2011 Mike Kinghan, imk@strudl.org                  *
00005  *   All rights reserved.                                                  *
00006  *                                                                         *
00007  *   Contributed originally by Mike Kinghan, imk@strudl.org                *
00008  *                                                                         *
00009  *   Redistribution and use in source and binary forms, with or without    *
00010  *   modification, are permitted provided that the following conditions    *
00011  *   are met:                                                              *
00012  *                                                                         *
00013  *   Redistributions of source code must retain the above copyright        *
00014  *   notice, this list of conditions and the following disclaimer.         *
00015  *                                                                         *
00016  *   Redistributions in binary form must reproduce the above copyright     *
00017  *   notice, this list of conditions and the following disclaimer in the   *
00018  *   documentation and/or other materials provided with the distribution.  *
00019  *                                                                         *
00020  *   Neither the name of Symbian Software Ltd. nor the names of its        *
00021  *   contributors may be used to endorse or promote products derived from  *
00022  *   this software without specific prior written permission.              *
00023  *                                                                         *
00024  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   *
00025  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     *
00026  *   LIMITED TO, THE IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS    *
00027  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE        *
00028  *   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,   *
00029  *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  *
00030  *   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS *
00031  *   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    *
00032  *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,*
00033  *   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF *
00034  *   THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH  *
00035  *   DAMAGE.                                                               *
00036  *                                                                         *
00037  **************************************************************************/
00038 
00039 #include "contradiction.h"
00040 #include "report.h"
00041 #include "line_despatch.h"
00042 #include "io.h"
00043 #include "if_control.h"
00044 #include <stdlib.h>
00045 #include <assert.h>
00046 
00054 
00056 STATE_DEF(contradiction)
00057 {
00059     INCLUDE_PUBLIC(contradiction);
00064     char *   contradiction_insert_prefix;
00073     int                 contradiction_insert_reason;
00080     bool                had_warnings;
00084     heap_str err_msg_buf[2];
00085 }
00086 STATE_T(contradiction);
00091 
00092 IMPLEMENT(contradiction,STATIC_INITABLE)
00093 
00094 USE_STATIC_INITIALISER(contradiction) = {
00095     { NULL },
00096     "//",
00097     GRIPE_COMMENTED_CONTRADICTION
00098 };
00099 
00104 
00109 #define CONTRADICTION_PENDING\
00110         (GET_STATE(contradiction,err_msg_buf)[ERR_MSG_BUF] != 0)
00111 
00113 enum {
00114     ERR_MSG_BUF,        
00115     OUT_MSG_BUF         
00116 };
00117 
00118 
00119 /* Helpers ****************************************************************/
00120 
00144 static void
00145 compose_contradiction_insert_format(heap_str *buf, const char *sub_format)
00146 {
00147     int buflen = 0;
00148     int startoff = 0;
00149     format_output(buf,&buflen,&startoff,
00150                   "%serror : inserted by coan: %s at %s(%d)\n",
00151                   GET_STATE(contradiction,contradiction_insert_prefix),
00152                   sub_format,
00153                   GET_PUBLIC(io,filename),
00154                   GET_PUBLIC(io,line_num));
00155 }
00156 
00171 static void
00172 forget_pending_contradiction(void)
00173 {
00174     release((void **)&GET_STATE(contradiction,err_msg_buf)[OUT_MSG_BUF]);
00175     release((void **)&GET_STATE(contradiction,err_msg_buf)[ERR_MSG_BUF]);
00176     SET_PUBLIC(contradiction,last_contradictory_undef) = NULL;
00177 }
00178 
00189 static void
00190 insert_pending_contradiction(void)
00191 {
00192     assert(GET_STATE(contradiction,err_msg_buf)[ERR_MSG_BUF]);
00193     report(GET_STATE(contradiction,contradiction_insert_reason),
00194            &GET_STATE(contradiction,err_msg_buf)[ERR_MSG_BUF],NULL);
00195     if (GET_STATE(contradiction,contradiction_insert_prefix)) {
00196         substitute(GET_STATE(contradiction,err_msg_buf)[OUT_MSG_BUF]);
00197         if (GET_STATE(contradiction,contradiction_insert_reason) ==
00198                 GRIPE_ERRORED_CONTRADICTION) {
00199             set_exit_flags(EVENT_SUMMARY_ERRORED_LINES,true);
00200             if (is_unconditional_line()) {
00201                 set_exit_flags(EVENT_SUMMARY_ERROR_OUTPUT,true);
00202                 report(GRIPE_UNCONDITIONAL_ERROR_INPUT,NULL,
00203                        "An unconditional #error directive was output");
00204             }
00205         }
00206     }
00207     forget_pending_contradiction();
00208 }
00209 
00213 /* API **************************************************************/
00214 
00227 void
00228 insert_contradiction(char const *sub_format)
00229 {
00230     save_contradiction(sub_format);
00231     insert_pending_contradiction();
00232 }
00233 
00234 
00235 void
00236 contradiction_policy(contradiction_policy_t p)
00237 {
00238     switch(p) {
00239     case CONTRADICTION_DELETE:
00240         SET_STATE(contradiction,contradiction_insert_prefix) = NULL;
00241         SET_STATE(contradiction,contradiction_insert_reason) =
00242             GRIPE_DELETED_CONTRADICTION;
00243         break;
00244     case CONTRADICTION_COMMENT:
00245         SET_STATE(contradiction,contradiction_insert_prefix) = "//";
00246         SET_STATE(contradiction,contradiction_insert_reason) =
00247             GRIPE_COMMENTED_CONTRADICTION;
00248         break;
00249     case CONTRADICTION_ERROR:
00250         SET_STATE(contradiction,contradiction_insert_prefix) = "#";
00251         SET_STATE(contradiction,contradiction_insert_reason) =
00252             GRIPE_ERRORED_CONTRADICTION;
00253         break;
00254     default:
00255         assert(false);
00256     }
00257 }
00258 
00259 void
00260 flush_contradiction(void)
00261 {
00262     if (GET_STATE(contradiction,err_msg_buf)[ERR_MSG_BUF]) {
00263         insert_pending_contradiction();
00264     }
00265 }
00266 
00267 void
00268 forget_contradiction(void)
00269 {
00270     if (GET_STATE(contradiction,err_msg_buf)[OUT_MSG_BUF]) {
00271         if (!GET_STATE(contradiction,had_warnings)) {
00272             set_exit_flags(MSGCLASS_WARNING,false);
00273         }
00274         forget_pending_contradiction();
00275     }
00276 }
00277 
00278 void
00279 save_contradiction(char const *sub_format)
00280 {
00281     size_t linelen = line_len(GET_PUBLIC(io,line_start));
00282     size_t extension_lines = GET_PUBLIC(io,extension_lines);
00283     assert(GET_STATE(contradiction,err_msg_buf)[ERR_MSG_BUF] == 0);
00284     if (extension_lines) {
00285         /* Ensure no embedded newlines or tabs in the error message buffer*/
00286         flatten_line(GET_PUBLIC(io,line_start));
00287     }
00288     SET_STATE(contradiction,had_warnings) = get_exit_flags(MSGCLASS_WARNING) != 0;
00289     report(GET_STATE(contradiction,contradiction_insert_reason),
00290            &GET_STATE(contradiction,err_msg_buf)[ERR_MSG_BUF],
00291            sub_format,
00292            linelen,
00293            GET_PUBLIC(io,line_start));
00294     if (GET_STATE(contradiction,contradiction_insert_prefix)) {
00295         heap_str contradiction_insert_format = NULL;
00296         int buflen = 0;
00297         int startoff;
00298         compose_contradiction_insert_format(&contradiction_insert_format,
00299                                             sub_format);
00300         assert(GET_STATE(contradiction,err_msg_buf)[OUT_MSG_BUF] == 0);
00301         format_output(&GET_STATE(contradiction,err_msg_buf)[OUT_MSG_BUF],
00302                         &buflen,&startoff,
00303                         contradiction_insert_format,
00304                         linelen,
00305                         GET_PUBLIC(io,line_start),
00306                         GET_PUBLIC(io,filename),
00307                         GET_PUBLIC(io,line_num));
00308         free(contradiction_insert_format);
00309     }
00310 }
00311 
00312 /* EOF*/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines