coan 4.2.4
|
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*/