coan 4.2.4
|
00001 /*************************************************************************** 00002 * Copyright (C) 2004, 2006 Symbian Software Ltd. * 00003 * All rights reserved. * 00004 * Copyright (C) 2002, 2003 Tony Finch <dot@dotat.at>. * 00005 * All rights reserved. * 00006 * Copyright (C) 1985, 1993 The Regents of the University of California. * 00007 * All rights reserved. * 00008 * * 00009 * Contributed by Mike Kinghan, imk@strudl.org, derived from the code * 00010 * of Tony Finch * 00011 * * 00012 * Redistribution and use in source and binary forms, with or without * 00013 * modification, are permitted provided that the following conditions * 00014 * are met: * 00015 * * 00016 * Redistributions of source code must retain the above copyright * 00017 * notice, this list of conditions and the following disclaimer. * 00018 * * 00019 * Redistributions in binary form must reproduce the above copyright * 00020 * notice, this list of conditions and the following disclaimer in the * 00021 * documentation and/or other materials provided with the distribution. * 00022 * * 00023 * Neither the name of Symbian Software Ltd. nor the names of its * 00024 * contributors may be used to endorse or promote products derived from * 00025 * this software without specific prior written permission. * 00026 * * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 00028 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * 00029 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * 00030 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * 00031 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 00032 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 00033 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * 00034 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * 00035 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,* 00036 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * 00037 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * 00038 * DAMAGE. * 00039 * * 00040 **************************************************************************/ 00041 00042 #include "line_despatch.h" 00043 #include "report.h" 00044 #include "args.h" 00045 #include "line_edit.h" 00046 #include "io.h" 00047 00055 00057 #define LINE_UNSIMPLIFIED (GET_PUBLIC(line_edit,ops_cut) == false && GET_PUBLIC(line_edit,parens_deleted) == 0) 00058 00059 /* Helpers **********************************************************/ 00060 00061 00064 static void 00065 printline_fast(void) 00066 { 00067 fputs(GET_PUBLIC(io,line_start),GET_PUBLIC(io,output)); 00068 } 00069 00073 static void 00074 printline_cut(void) 00075 { 00076 discard_policy_t discard_policy = GET_PUBLIC(args,discard_policy); 00077 unsigned extension_lines = GET_PUBLIC(io,extension_lines); 00078 char *cp = LINE_START; 00079 char last_written = ' '; 00080 SET_PUBLIC(line_despatch,lines_changed) += extension_lines + 1; 00081 for ( ; *cp != '\n'; ++cp) { 00082 assert(*cp); 00083 if (!DELETEABLE(*cp)) { 00084 if (*cp == ' ') {} 00085 else if (*cp == '\\' && cp[1] == '\n') { 00086 *cp = cp[1] = ' '; 00087 ++cp; 00088 } 00089 else if (isspace(*cp)) { 00090 *cp = ' '; 00091 } 00092 else if (!isspace(last_written)) { 00093 fputc(' ',GET_PUBLIC(io,output)); 00094 last_written = ' '; 00095 } 00096 fputc(*cp,GET_PUBLIC(io,output)); 00097 } 00098 else if (!DELETEABLE(last_written)) { 00099 last_written = *cp; 00100 } 00101 } 00102 fputc('\n',GET_PUBLIC(io,output)); 00103 if (discard_policy == DISCARD_BLANK) { 00104 for ( ; extension_lines; --extension_lines) { 00105 putc('\n', GET_PUBLIC(io,output)); 00106 } 00107 } 00108 else if (discard_policy == DISCARD_COMMENT) { 00109 for ( ; extension_lines; --extension_lines) { 00110 fputs("//coan <\n", GET_PUBLIC(io,output)); 00111 } 00112 } 00113 } 00114 00122 static void 00123 printline_restore_all_paren(void) 00124 { 00125 restore_all_paren(); 00126 printline_fast(); 00127 } 00128 00137 static void 00138 printline_slow(void) 00139 { 00140 if (GET_PUBLIC(line_edit,ops_cut)) { 00141 printline_cut(); 00142 } else { 00143 printline_restore_all_paren(); 00144 } 00145 } 00146 00152 static void 00153 printline(void) 00154 { 00155 if (LINE_UNSIMPLIFIED) { 00156 printline_fast(); 00157 } else { 00158 printline_slow(); 00159 } 00160 } 00161 00164 static void 00165 printline_commented_out(void) 00166 { 00167 if (LINE_UNSIMPLIFIED) { 00168 unsigned extension_lines = GET_PUBLIC(io,extension_lines); 00169 ++SET_PUBLIC(line_despatch,lines_changed); 00170 if (!extension_lines) { 00171 fputs("//coan < ",GET_PUBLIC(io,output)); 00172 printline_fast(); 00173 } 00174 else { 00175 char const *linestart = LINE_START; 00176 char const *newline; 00177 SET_PUBLIC(line_despatch,lines_changed) += extension_lines; 00178 for ( ;(newline = strchr(linestart,'\n')) != NULL; ) { 00179 size_t written; 00180 fputs("//coan < ",GET_PUBLIC(io,output)); 00181 written = fwrite(linestart,1,newline - linestart,GET_PUBLIC(io,output)); 00182 assert(written == newline - linestart); 00183 fputc('\n',GET_PUBLIC(io,output)); 00184 linestart = newline + 1; 00185 } 00186 } 00187 } else { 00188 fputs("//coan < ",GET_PUBLIC(io,output)); 00189 printline_slow(); 00190 } 00191 } 00192 00196 static void 00197 flushline_dummy(bool keep,const char *insert_text) {} 00198 00199 00218 static void 00219 flushline_live(bool keep, char const *insert_text) 00220 { 00221 if (insert_text) { 00222 /* Replacing a contradictory input line with a 00223 * diagnostic comment or #error*/ 00224 fputs(insert_text,GET_PUBLIC(io,output)); 00225 --SET_PUBLIC(line_despatch,lines_inactive); 00226 ++SET_PUBLIC(line_despatch,lines_changed); 00227 return; 00228 } 00229 if (keep ^ GET_PUBLIC(args,complement)) { 00230 printline(); 00231 } else { 00232 unsigned extension_lines = GET_PUBLIC(io,extension_lines); 00233 discard_policy_t discard_policy = GET_PUBLIC(args,discard_policy); 00234 if (discard_policy == DISCARD_BLANK) { 00235 SET_PUBLIC(line_despatch,lines_changed) += extension_lines + 1; 00236 putc('\n', GET_PUBLIC(io,output)); 00237 for ( ; extension_lines; --extension_lines) { 00238 putc('\n', GET_PUBLIC(io,output)); 00239 } 00240 } else if (discard_policy == DISCARD_DROP) { 00241 SET_PUBLIC(line_despatch,lines_inactive) += extension_lines + 1; 00242 } else { 00243 printline_commented_out(); 00244 } 00245 } 00246 } 00247 00252 00254 STATE_DEF(line_despatch) 00255 { 00257 INCLUDE_PUBLIC(line_despatch); 00263 void (*flushline)(bool,const char *); 00265 size_t drop_run; 00266 } 00267 STATE_T(line_despatch); 00268 00273 00274 IMPLEMENT(line_despatch,STATIC_INITABLE); 00275 00276 USE_STATIC_INITIALISER(line_despatch) = { { 0, 0 }, flushline_live, false }; 00279 /* API **************************************************************/ 00280 00281 void 00282 line_despatch_no_op(void) 00283 { 00284 SET_STATE(line_despatch,flushline) = flushline_dummy; 00285 } 00286 00287 void 00288 print(void) 00289 { 00290 if (GET_PUBLIC(args,line_directives)) { 00291 if (GET_STATE(line_despatch,drop_run)) { 00292 int line_num = GET_PUBLIC(io,line_num); 00293 size_t extension_lines = GET_PUBLIC(io,extension_lines); 00294 if (extension_lines) { 00295 --line_num; 00296 } 00297 printf("#line %d\n",line_num); 00298 --SET_PUBLIC(line_despatch,lines_inactive); 00299 ++SET_PUBLIC(line_despatch,lines_changed); 00300 } 00301 SET_STATE(line_despatch,drop_run) = 0; 00302 } 00303 GET_STATE(line_despatch,flushline)(true,NULL); 00304 00305 } 00306 00307 void 00308 drop(void) 00309 { 00310 GET_STATE(line_despatch,flushline)(false,NULL); 00311 if (GET_PUBLIC(args,line_directives)) { 00312 ++SET_STATE(line_despatch,drop_run); 00313 } 00314 } 00315 00316 void 00317 substitute(const char *replacement) 00318 { 00319 GET_STATE(line_despatch,flushline)(false,replacement); 00320 } 00321 00322 /* EOF*/