bookloupe/pending.c
author ali <ali@juiblex.co.uk>
Wed Oct 02 23:51:18 2013 +0100 (2013-10-02)
changeset 94 466f43a12118
parent 93 9fb13a5dde3b
permissions -rw-r--r--
Fix bug #11: Test for balanced "slanted" UTF-8 quotation marks 8220/8221
     1 #include <stdlib.h>
     2 #include <string.h>
     3 #include <glib.h>
     4 #include <bl/bl.h>
     5 #include "bookloupe.h"
     6 #include "pending.h"
     7 
     8 /*
     9  * print_pending:
    10  *
    11  * If we are in a state of unbalanced quotes, and this line
    12  * doesn't begin with a quote, output the stored error message.
    13  * If the -p switch was used, print the warning even if the
    14  * new para starts with quotes.
    15  */
    16 void print_pending(const char *aline,const char *parastart,
    17   struct pending *pending)
    18 {
    19     if (aline)
    20 	while (g_unichar_isspace(g_utf8_get_char(aline)))
    21 	    aline=g_utf8_next_char(aline);
    22     if (pending->illustration.warning_text)
    23     {
    24 	if (aline)
    25 	{
    26 	    if (pswit[ECHO_SWITCH] && !pending->illustration.queried_line)
    27 		pending->illustration.queried_line=g_strdup(parastart);
    28 	}
    29 	else
    30 	{
    31 	    if (!pswit[OVERVIEW_SWITCH])
    32 	    {
    33 		if (pending->illustration.queried_line)
    34 		    g_print("\n%s\n",pending->illustration.queried_line);
    35 		g_print("%s\n",pending->illustration.warning_text);
    36 	    }
    37 	    else
    38 		cnt_brack++;
    39 	    g_free(pending->illustration.warning_text);
    40 	    pending->illustration.warning_text=NULL;
    41 	    g_free(pending->illustration.queried_line);
    42 	    pending->illustration.queried_line=NULL;
    43 	}
    44     }
    45     if (pending->quote)
    46     {
    47 	if (!pending->continuing_quote || !aline ||
    48 	  !g_str_has_prefix(aline,pending->continuing_quote))
    49 	{
    50 	    if (!pswit[OVERVIEW_SWITCH])
    51 	    {
    52 		if (pswit[ECHO_SWITCH])
    53 		    g_print("\n%s\n",parastart);
    54 		g_print("%s\n",pending->quote);
    55 	    }
    56 	    else
    57 		cnt_quote++;
    58 	}
    59 	g_free(pending->quote);
    60 	pending->quote=NULL;
    61     }
    62     g_free(pending->continuing_quote);
    63     pending->continuing_quote=NULL;
    64     if (pending->rbrack)
    65     {
    66 	if (!pswit[OVERVIEW_SWITCH])
    67 	{
    68 	    if (pswit[ECHO_SWITCH])
    69 		g_print("\n%s\n",parastart);
    70 	    g_print("%s\n",pending->rbrack);
    71 	}
    72 	else
    73 	    cnt_brack++;
    74 	g_free(pending->rbrack);
    75 	pending->rbrack=NULL;
    76     }
    77     if (pending->sbrack)
    78     {
    79 	if (!pswit[OVERVIEW_SWITCH])
    80 	{
    81 	    if (pswit[ECHO_SWITCH])
    82 		g_print("\n%s\n",parastart);
    83 	    g_print("%s\n",pending->sbrack);
    84 	}
    85 	else
    86 	    cnt_brack++;
    87 	g_free(pending->sbrack);
    88 	pending->sbrack=NULL;
    89     }
    90     if (pending->cbrack)
    91     {
    92 	if (!pswit[OVERVIEW_SWITCH])
    93 	{
    94 	    if (pswit[ECHO_SWITCH])
    95 		g_print("\n%s\n",parastart);
    96 	    g_print("%s\n",pending->cbrack);
    97 	}
    98 	else
    99 	    cnt_brack++;
   100 	g_free(pending->cbrack);
   101 	pending->cbrack=NULL;
   102     }
   103     if (pending->unders)
   104     {
   105 	if (!pswit[OVERVIEW_SWITCH])
   106 	{
   107 	    if (pswit[ECHO_SWITCH])
   108 		g_print("\n%s\n",parastart);
   109 	    g_print("%s\n",pending->unders);
   110 	}
   111 	else
   112 	    cnt_brack++;
   113 	g_free(pending->unders);
   114 	pending->unders=NULL;
   115     }
   116 }
   117 
   118 void reset_pending(struct pending *pending)
   119 {
   120     memset(pending,0,sizeof(*pending));
   121 }
   122 
   123 /*
   124  * check_for_mismatched_quotes:
   125  *
   126  * At end of paragraph, check for mismatched quotes.
   127  *
   128  * We don't want to report an error immediately, since it is a
   129  * common convention to omit the quotes at end of paragraph if
   130  * the next paragraph is a continuation of the same speaker.
   131  * Where this is the case, the next para should begin with a
   132  * quote, so we store the warning message and only display it
   133  * at the top of the next iteration if the new para doesn't
   134  * start with a quote.
   135  * The -p switch overrides this default, and warns of unclosed
   136  * quotes on _every_ paragraph, whether the next begins with a
   137  * quote or not.
   138  */
   139 void check_for_mismatched_quotes(struct counters *counters,
   140   struct pending *pending)
   141 {
   142     gboolean all_single;
   143     gunichar c;
   144     int difference;
   145     const char *quote_type;
   146     GString *str;
   147     if (counters->open_quotes)
   148     {
   149 	str=g_string_new(NULL);
   150 	counters->open_quotes=g_slist_reverse(counters->open_quotes);
   151 	all_single=TRUE;
   152 	while(counters->open_quotes)
   153 	{
   154 	    c=GPOINTER_TO_INT(counters->open_quotes->data);
   155 	    if (!CHAR_IS_SQUOTE(c))
   156 		all_single=FALSE;
   157 	    g_string_append_unichar(str,c);
   158 	    counters->open_quotes=g_slist_delete_link(counters->open_quotes,
   159 	      counters->open_quotes);
   160 	}
   161 	pending->continuing_quote=g_string_free(str,FALSE);
   162 	if (all_single)
   163 	    quote_type="singlequotes?";
   164 	else
   165 	    quote_type="quotes";
   166 	pending->quote=g_strdup_printf("    Line %ld - Mismatched %s",linecnt,
   167 	  quote_type);
   168     }
   169     difference=matching_difference(counters,COUNTER_ILLUSTRATION);
   170     if (difference)
   171     {
   172 	if (difference<0 && pending->illustration.warning_text)
   173 	{
   174 	    difference++;
   175 	    g_free(pending->illustration.queried_line);
   176 	    pending->illustration.queried_line=NULL;
   177 	    g_free(pending->illustration.warning_text);
   178 	    pending->illustration.warning_text=NULL;
   179 	}
   180 	if (difference<0)
   181 	{
   182 	    increment_matching(counters,CHAR_OPEN_SBRACK,FALSE);
   183 	    difference++;
   184 	}
   185 	if (difference)
   186 	{
   187 	    if (pending->illustration.warning_text)
   188 	    {
   189 		if (!pswit[OVERVIEW_SWITCH])
   190 		{
   191 		    if (pending->illustration.queried_line)
   192 			g_print("\n%s\n",pending->illustration.queried_line);
   193 		    g_print("%s\n",pending->illustration.warning_text);
   194 		}
   195 		else
   196 		    cnt_brack++;
   197 		g_free(pending->illustration.warning_text);
   198 	    }
   199 	    pending->illustration.warning_text=g_strdup_printf(
   200 	      "    Line %ld - Mismatched illustration tag?",linecnt);
   201 	    g_free(pending->illustration.queried_line);
   202 	    pending->illustration.queried_line=NULL;
   203 	}
   204     }
   205     if (matching_difference(counters,CHAR_OPEN_RBRACK))
   206 	pending->rbrack=
   207 	  g_strdup_printf("    Line %ld - Mismatched round brackets?",linecnt);
   208     if (matching_difference(counters,CHAR_OPEN_SBRACK))
   209 	pending->sbrack=
   210 	  g_strdup_printf("    Line %ld - Mismatched square brackets?",linecnt);
   211     if (matching_difference(counters,CHAR_OPEN_CBRACK))
   212 	pending->cbrack=
   213 	  g_strdup_printf("    Line %ld - Mismatched curly brackets?",linecnt);
   214     if (counters->c_unders%2)
   215 	pending->unders=
   216 	  g_strdup_printf("    Line %ld - Mismatched underscores?",linecnt);
   217 }