coan 4.2.4
line_despatch.c
Go to the documentation of this file.
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*/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines