LCOV - code coverage report
Current view: top level - roff/troff - mtsm.cpp (source / functions) Hit Total Coverage
Test: GNU roff Lines: 284 362 78.5 %
Date: 2026-01-16 17:51:41 Functions: 51 66 77.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright 2003-2024 Free Software Foundation, Inc.
       2             :      Written by Gaius Mulley (gaius@glam.ac.uk)
       3             : 
       4             : This file is part of groff, the GNU roff typesetting system.
       5             : 
       6             : groff is free software; you can redistribute it and/or modify it under
       7             : the terms of the GNU General Public License as published by the Free
       8             : Software Foundation, either version 3 of the License, or
       9             : (at your option) any later version.
      10             : 
      11             : groff is distributed in the hope that it will be useful, but WITHOUT ANY
      12             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14             : for more details.
      15             : 
      16             : You should have received a copy of the GNU General Public License
      17             : along with this program.  If not, see <http://www.gnu.org/licenses/>. */
      18             : 
      19             : // mtsm: minimum troff state machine
      20             : 
      21             : #ifdef HAVE_CONFIG_H
      22             : #include <config.h>
      23             : #endif
      24             : 
      25             : extern bool want_html_debugging;
      26             : 
      27             : #include "troff.h"
      28             : #include "hvunits.h"
      29             : #include "stringclass.h"
      30             : #include "mtsm.h"
      31             : #include "env.h"
      32             : 
      33             : #if defined(DEBUGGING)
      34             : static int no_of_statems = 0;
      35             : #endif
      36             : 
      37     2794700 : int_value::int_value()
      38     2794700 : : value(0), is_known(0)
      39             : {
      40     2794700 : }
      41             : 
      42     3979721 : int_value::~int_value()
      43             : {
      44     3979721 : }
      45             : 
      46       10200 : void int_value::diff(FILE *fp, const char *s, int_value compare)
      47             : {
      48       10200 :   if (differs(compare)) {
      49        1363 :     fputs("x X ", fp);
      50        1363 :     fputs(s, fp);
      51        1363 :     fputs(" ", fp);
      52        1363 :     fputs(i_to_a(compare.value), fp);
      53        1363 :     fputs("\n", fp);
      54        1363 :     value = compare.value;
      55        1363 :     is_known = 1;
      56        1363 :     if (want_html_debugging)
      57        1363 :       fflush(fp);
      58             :   }
      59       10200 : }
      60             : 
      61      226391 : void int_value::set(int v)
      62             : {
      63      226391 :   is_known = 1;
      64      226391 :   value = v;
      65      226391 : }
      66             : 
      67      131141 : void int_value::unset()
      68             : {
      69      131141 :   is_known = 0;
      70      131141 : }
      71             : 
      72      128077 : void int_value::set_if_unknown(int v)
      73             : {
      74      128077 :   if (!is_known)
      75      105304 :     set(v);
      76      128077 : }
      77             : 
      78      643402 : int int_value::differs(int_value compare)
      79             : {
      80      643402 :   return compare.is_known
      81      643402 :          && (!is_known || value != compare.value);
      82             : }
      83             : 
      84      558940 : bool_value::bool_value()
      85             : {
      86      558940 : }
      87             : 
      88      598566 : bool_value::~bool_value()
      89             : {
      90      598566 : }
      91             : 
      92        5100 : void bool_value::diff(FILE *fp, const char *s, bool_value compare)
      93             : {
      94        5100 :   if (differs(compare)) {
      95        2331 :     fputs("x X ", fp);
      96        2331 :     fputs(s, fp);
      97        2331 :     fputs("\n", fp);
      98        2331 :     value = compare.value;
      99        2331 :     is_known = 1;
     100        2331 :     if (want_html_debugging)
     101        2331 :       fflush(fp);
     102             :   }
     103        5100 : }
     104             : 
     105     1117880 : units_value::units_value()
     106             : {
     107     1117880 : }
     108             : 
     109     1540621 : units_value::~units_value()
     110             : {
     111     1540621 : }
     112             : 
     113       10200 : void units_value::diff(FILE *fp, const char *s, units_value compare)
     114             : {
     115       10200 :   if (differs(compare)) {
     116         445 :     fputs("x X ", fp);
     117         445 :     fputs(s, fp);
     118         445 :     fputs(" ", fp);
     119         445 :     fputs(i_to_a(compare.value), fp);
     120         445 :     fputs("\n", fp);
     121         445 :     value = compare.value;
     122         445 :     is_known = 1;
     123         445 :     if (want_html_debugging)
     124         445 :       fflush(fp);
     125             :   }
     126       10200 : }
     127             : 
     128      318572 : void units_value::set(hunits v)
     129             : {
     130      318572 :   is_known = 1;
     131      318572 :   value = v.to_units();
     132      318572 : }
     133             : 
     134      343489 : int units_value::differs(units_value compare)
     135             : {
     136      343489 :   return compare.is_known
     137      343489 :          && (!is_known || value != compare.value);
     138             : }
     139             : 
     140      279470 : string_value::string_value()
     141      279470 : : value(string("")), is_known(0)
     142             : {
     143      279470 : }
     144             : 
     145      412928 : string_value::~string_value()
     146             : {
     147      412928 : }
     148             : 
     149        2550 : void string_value::diff(FILE *fp, const char *s, string_value compare)
     150             : {
     151        2550 :   if (differs(compare)) {
     152          52 :     fputs("x X ", fp);
     153          52 :     fputs(s, fp);
     154          52 :     fputs(" ", fp);
     155          52 :     fputs(compare.value.contents(), fp);
     156          52 :     fputs("\n", fp);
     157          52 :     value = compare.value;
     158          52 :     is_known = 1;
     159             :   }
     160        2550 : }
     161             : 
     162      106178 : void string_value::set(string v)
     163             : {
     164      106178 :   is_known = 1;
     165      106178 :   value = v;
     166      106178 : }
     167             : 
     168           0 : void string_value::unset()
     169             : {
     170           0 :   is_known = 0;
     171           0 : }
     172             : 
     173      113645 : int string_value::differs(string_value compare)
     174             : {
     175      113645 :   return compare.is_known
     176      113645 :          && (!is_known || value != compare.value);
     177             : }
     178             : 
     179     1289484 : statem::statem()
     180             : {
     181             : #if defined(DEBUGGING)
     182             :   issue_no = no_of_statems;
     183             :   no_of_statems++;
     184             : #endif
     185      107457 : }
     186             : 
     187     2064156 : statem::statem(statem *copy)
     188             : {
     189             :   int i;
     190      516039 :   for (i = 0; i < LAST_BOOL; i++)
     191      344026 :     bool_values[i] = copy->bool_values[i];
     192      860065 :   for (i = 0; i < LAST_INT; i++)
     193      688052 :     int_values[i] = copy->int_values[i];
     194      860065 :   for (i = 0; i < LAST_UNITS; i++)
     195      688052 :     units_values[i] = copy->units_values[i];
     196      344026 :   for (i = 0; i < LAST_STRING; i++)
     197      172013 :     string_values[i] = copy->string_values[i];
     198             : #if defined(DEBUGGING)
     199             :   issue_no = copy->issue_no;
     200             : #endif
     201      172013 : }
     202             : 
     203     3560796 : statem::~statem()
     204             : {
     205      296733 : }
     206             : 
     207        2550 : void statem::flush(FILE *fp, statem *compare)
     208             : {
     209        2550 :   int_values[MTSM_FI].diff(fp, "devtag:.fi",
     210        2550 :                            compare->int_values[MTSM_FI]);
     211        2550 :   int_values[MTSM_RJ].diff(fp, "devtag:.rj",
     212        2550 :                            compare->int_values[MTSM_RJ]);
     213        2550 :   int_values[MTSM_SP].diff(fp, "devtag:.sp",
     214        2550 :                            compare->int_values[MTSM_SP]);
     215        2550 :   units_values[MTSM_IN].diff(fp, "devtag:.in",
     216        2550 :                              compare->units_values[MTSM_IN]);
     217        2550 :   units_values[MTSM_LL].diff(fp, "devtag:.ll",
     218        2550 :                              compare->units_values[MTSM_LL]);
     219        2550 :   units_values[MTSM_PO].diff(fp, "devtag:.po",
     220        2550 :                              compare->units_values[MTSM_PO]);
     221        2550 :   string_values[MTSM_TA].diff(fp, "devtag:.ta",
     222        5100 :                               compare->string_values[MTSM_TA]);
     223        2550 :   units_values[MTSM_TI].diff(fp, "devtag:.ti",
     224        2550 :                              compare->units_values[MTSM_TI]);
     225        2550 :   int_values[MTSM_CE].diff(fp, "devtag:.ce",
     226        2550 :                            compare->int_values[MTSM_CE]);
     227        2550 :   bool_values[MTSM_EOL].diff(fp, "devtag:.eol",
     228        2550 :                              compare->bool_values[MTSM_EOL]);
     229        2550 :   bool_values[MTSM_BR].diff(fp, "devtag:.br",
     230        2550 :                             compare->bool_values[MTSM_BR]);
     231             : #if defined(DEBUGGING)
     232             :   if (want_html_debugging) {
     233             :     fprintf(stderr, "compared state %d\n", compare->issue_no);
     234             :     fflush(stderr);
     235             :   }
     236             : #endif
     237        2550 : }
     238             : 
     239      107988 : void statem::add_tag(int_value_state t, int v)
     240             : {
     241      107988 :   int_values[t].set(v);
     242      107988 : }
     243             : 
     244      318572 : void statem::add_tag(units_value_state t, hunits v)
     245             : {
     246      318572 :   units_values[t].set(v);
     247      318572 : }
     248             : 
     249        4113 : void statem::add_tag(bool_value_state t)
     250             : {
     251        4113 :   bool_values[t].set(1);
     252        4113 : }
     253             : 
     254           0 : void statem::add_tag(string_value_state t, string v)
     255             : {
     256           0 :   string_values[t].set(v);
     257           0 : }
     258             : 
     259      128077 : void statem::add_tag_if_unknown(int_value_state t, int v)
     260             : {
     261      128077 :   int_values[t].set_if_unknown(v);
     262      128077 : }
     263             : 
     264      119152 : void statem::sub_tag_ce()
     265             : {
     266      119152 :   int_values[MTSM_CE].unset();
     267      119152 : }
     268             : 
     269             : /*
     270             :  *  add_tag_ta - add the tab settings to the minimum troff state machine
     271             :  */
     272             : 
     273      106178 : void statem::add_tag_ta()
     274             : {
     275      106178 :   if (is_writing_html) {
     276      106178 :     string s = string("");
     277      106178 :     hunits d, l;
     278             :     enum tab_type t;
     279     1860616 :     do {
     280     1966794 :       t = curenv->tabs.distance_to_next_tab(l, &d);
     281     1966794 :       l += d;
     282     1966794 :       switch (t) {
     283     1965118 :       case TAB_LEFT:
     284     1965118 :         s += " L ";
     285     1965118 :         s += as_string(l.to_units());
     286     1965118 :         break;
     287           0 :       case TAB_CENTER:
     288           0 :         s += " C ";
     289           0 :         s += as_string(l.to_units());
     290           0 :         break;
     291           0 :       case TAB_RIGHT:
     292           0 :         s += " R ";
     293           0 :         s += as_string(l.to_units());
     294           0 :         break;
     295        1676 :       case TAB_NONE:
     296        1676 :         break;
     297             :       }
     298     1966794 :     } while (t != TAB_NONE && l < curenv->get_line_length());
     299      106178 :     s += '\0';
     300      106178 :     string_values[MTSM_TA].set(s);
     301             :   }
     302      106178 : }
     303             : 
     304       41463 : void statem::update(statem &older, statem *newer, int_value_state t)
     305             : {
     306       41463 :   if (newer->int_values[t].differs(older.int_values[t])
     307       41463 :       && !newer->int_values[t].is_known)
     308         484 :     newer->int_values[t].set(older.int_values[t].value);
     309       41463 : }
     310             : 
     311       41463 : void statem::update(statem &older, statem *newer, units_value_state t)
     312             : {
     313       41463 :   if (newer->units_values[t].differs(older.units_values[t])
     314       41463 :       && !newer->units_values[t].is_known)
     315           0 :     newer->units_values[t].set(older.units_values[t].value);
     316       41463 : }
     317             : 
     318           0 : void statem::update(statem &older, statem *newer, bool_value_state t)
     319             : {
     320           0 :   if (newer->bool_values[t].differs(older.bool_values[t])
     321           0 :       && !newer->bool_values[t].is_known)
     322           0 :     newer->bool_values[t].set(older.bool_values[t].value);
     323           0 : }
     324             : 
     325       13821 : void statem::update(statem &older, statem *newer, string_value_state t)
     326             : {
     327       13821 :   if (newer->string_values[t].differs(older.string_values[t])
     328       13821 :       && !newer->string_values[t].is_known)
     329           0 :     newer->string_values[t].set(older.string_values[t].value);
     330       13821 : }
     331             : 
     332           0 : void statem::merge(statem *newer, statem &older)
     333             : {
     334           0 :   if (0 /* nullptr */ == newer)
     335           0 :     return;
     336           0 :   update(older, newer, MTSM_EOL);
     337           0 :   update(older, newer, MTSM_BR);
     338           0 :   update(older, newer, MTSM_FI);
     339           0 :   update(older, newer, MTSM_LL);
     340           0 :   update(older, newer, MTSM_PO);
     341           0 :   update(older, newer, MTSM_RJ);
     342           0 :   update(older, newer, MTSM_SP);
     343           0 :   update(older, newer, MTSM_TA);
     344           0 :   update(older, newer, MTSM_TI);
     345           0 :   update(older, newer, MTSM_CE);
     346             : }
     347             : 
     348        1279 : mtsm::mtsm()
     349             : {
     350        1279 :   driver = new statem();
     351        1279 : }
     352             : 
     353        1278 : mtsm::~mtsm()
     354             : {
     355        1278 :   delete driver;
     356        1278 : }
     357             : 
     358             : /*
     359             :  *  push_state - push the current troff state and use 'n' as
     360             :  *               the new troff state.
     361             :  */
     362             : 
     363        3535 : void mtsm::push_state(statem *n)
     364             : {
     365        3535 :   if (is_writing_html) {
     366             : #if defined(DEBUGGING)
     367             :     if (want_html_debugging) {
     368             :       fprintf(stderr, "--> state %d pushed\n", n->issue_no);
     369             :       fflush(stderr);
     370             :     }
     371             : #endif
     372        3535 :     stack.push(n);
     373             :   }
     374        3535 : }
     375             : 
     376        3535 : void mtsm::pop_state()
     377             : {
     378        3535 :   if (is_writing_html) {
     379             : #if defined(DEBUGGING)
     380             :     if (want_html_debugging) {
     381             :       fprintf(stderr, "--> state popped\n");
     382             :       fflush(stderr);
     383             :     }
     384             : #endif
     385        3535 :     if (stack.empty())
     386           0 :       fatal("empty state machine stack");
     387        3535 :     stack.pop();
     388             :   }
     389        3535 : }
     390             : 
     391             : /*
     392             :  *  inherit - scan the stack and collects inherited values.
     393             :  */
     394             : 
     395      101770 : void mtsm::inherit(statem *s, int reset_bool)
     396             : {
     397      101770 :   if (!stack.empty()) {
     398       27642 :     statem top = stack.top();
     399       13821 :     if (s->units_values[MTSM_IN].is_known
     400       13821 :         && top.units_values[MTSM_IN].is_known)
     401       13821 :       s->units_values[MTSM_IN].value += top.units_values[MTSM_IN].value;
     402       13821 :     s->update(top, s, MTSM_FI);
     403       13821 :     s->update(top, s, MTSM_LL);
     404       13821 :     s->update(top, s, MTSM_PO);
     405       13821 :     s->update(top, s, MTSM_RJ);
     406       13821 :     s->update(top, s, MTSM_TA);
     407       13821 :     s->update(top, s, MTSM_TI);
     408       13821 :     s->update(top, s, MTSM_CE);
     409       13821 :     if (top.bool_values[MTSM_BR].is_known
     410          74 :         && top.bool_values[MTSM_BR].value) {
     411          74 :       if (reset_bool)
     412           4 :         top.bool_values[MTSM_BR].set(0);
     413          74 :       s->bool_values[MTSM_BR].set(1);
     414             : #if defined(DEBUGGING)
     415             :       if (want_html_debugging)
     416             :         fprintf(stderr, "inherited br from pushed state %d\n",
     417             :                 top.issue_no);
     418             : #endif
     419             :     }
     420       13821 :     if (! s->int_values[MTSM_CE].is_known)
     421       11989 :         s->bool_values[MTSM_BR].unset();
     422       13821 :     if (top.bool_values[MTSM_EOL].is_known
     423         516 :         && top.bool_values[MTSM_EOL].value) {
     424         516 :       if (reset_bool)
     425         258 :         top.bool_values[MTSM_EOL].set(0);
     426         516 :       s->bool_values[MTSM_EOL].set(1);
     427             :     }
     428             :   }
     429      101770 : }
     430             : 
     431       79827 : void mtsm::flush(FILE *fp, statem *s, string tag_list)
     432             : {
     433       79827 :   if (is_writing_html && (s != 0 /* nullptr */)) {
     434        2550 :     inherit(s, 1);
     435        2550 :     driver->flush(fp, s);
     436             :     // Set rj, ce, ti to unknown if they were known and
     437             :     // we have seen an eol or br.  This ensures that these values
     438             :     // are emitted during the next glyph (as they step from n..0
     439             :     // at each newline).
     440        2550 :     if ((driver->bool_values[MTSM_EOL].is_known
     441        2522 :          && driver->bool_values[MTSM_EOL].value)
     442        1582 :         || (driver->bool_values[MTSM_BR].is_known
     443        1560 :             && driver->bool_values[MTSM_BR].value)) {
     444        1875 :       if (driver->units_values[MTSM_TI].is_known)
     445          38 :         driver->units_values[MTSM_TI].is_known = 0;
     446        1875 :       if (driver->int_values[MTSM_RJ].is_known
     447        1875 :           && driver->int_values[MTSM_RJ].value > 0)
     448           0 :         driver->int_values[MTSM_RJ].is_known = 0;
     449        1875 :       if (driver->int_values[MTSM_CE].is_known
     450        1875 :           && driver->int_values[MTSM_CE].value > 0)
     451          61 :         driver->int_values[MTSM_CE].is_known = 0;
     452             :     }
     453             :     // reset the boolean values
     454        2550 :     driver->bool_values[MTSM_BR].set(0);
     455        2550 :     driver->bool_values[MTSM_EOL].set(0);
     456             :     // reset space value
     457        2550 :     driver->int_values[MTSM_SP].set(0);
     458             :     // lastly write out any direct tag entries
     459        2550 :     if (tag_list != string("")) {
     460          24 :       string t = tag_list + '\0';
     461          12 :       fputs(t.contents(), fp);
     462             :     }
     463             :   }
     464       79827 : }
     465             : 
     466             : /*
     467             :  *  display_state - dump out a synopsis of the state to stderr.
     468             :  */
     469             : 
     470           0 : void statem::display_state()
     471             : {
     472           0 :   fprintf(stderr, "\"<state");
     473           0 :   if (bool_values[MTSM_BR].is_known) {
     474           0 :     if (bool_values[MTSM_BR].value)
     475           0 :       fprintf(stderr, " [br]");
     476             :     else
     477           0 :       fprintf(stderr, " [!br]");
     478             :   }
     479           0 :   if (bool_values[MTSM_EOL].is_known) {
     480           0 :     if (bool_values[MTSM_EOL].value)
     481           0 :       fprintf(stderr, " [eol]");
     482             :     else
     483           0 :       fprintf(stderr, " [!eol]");
     484             :   }
     485           0 :   if (int_values[MTSM_SP].is_known) {
     486           0 :     if (int_values[MTSM_SP].value)
     487           0 :       fprintf(stderr, " [sp %d]", int_values[MTSM_SP].value);
     488             :     else
     489           0 :       fprintf(stderr, " [!sp]");
     490             :   }
     491           0 :   fprintf(stderr, ">\"");
     492           0 :   fflush(stderr);
     493           0 : }
     494             : 
     495      389167 : int mtsm::has_changed(int_value_state t, statem *s)
     496             : {
     497      389167 :   return driver->int_values[t].differs(s->int_values[t]);
     498             : }
     499             : 
     500      291826 : int mtsm::has_changed(units_value_state t, statem *s)
     501             : {
     502      291826 :   return driver->units_values[t].differs(s->units_values[t]);
     503             : }
     504             : 
     505      197472 : int mtsm::has_changed(bool_value_state t, statem *s)
     506             : {
     507      197472 :   return driver->bool_values[t].differs(s->bool_values[t]);
     508             : }
     509             : 
     510       97274 : int mtsm::has_changed(string_value_state t, statem *s)
     511             : {
     512       97274 :   return driver->string_values[t].differs(s->string_values[t]);
     513             : }
     514             : 
     515     4974680 : int mtsm::changed(statem *s)
     516             : {
     517     4974680 :   if ((s == 0 /* nullptr */) || !is_writing_html)
     518     4875460 :     return 0 /* nullptr */;
     519       99220 :   s = new statem(s);
     520       99220 :   inherit(s, 0);
     521       99220 :   int result = has_changed(MTSM_EOL, s)
     522       98252 :                || has_changed(MTSM_BR, s)
     523       97345 :                || has_changed(MTSM_FI, s)
     524       97278 :                || has_changed(MTSM_IN, s)
     525       97274 :                || has_changed(MTSM_LL, s)
     526       97274 :                || has_changed(MTSM_PO, s)
     527       97274 :                || has_changed(MTSM_RJ, s)
     528       97274 :                || has_changed(MTSM_SP, s)
     529       97274 :                || has_changed(MTSM_TA, s)
     530      197472 :                || has_changed(MTSM_CE, s);
     531       99220 :   delete s;
     532       99220 :   return result;
     533             : }
     534             : 
     535       11158 : void mtsm::add_tag(FILE *fp, string s)
     536             : {
     537       11158 :   fflush(fp);
     538       11158 :   s += '\0';
     539       11158 :   fputs(s.contents(), fp);
     540       11158 : }
     541             : 
     542             : /*
     543             :  *  state_set class
     544             :  */
     545             : 
     546       53206 : state_set::state_set()
     547       53206 : : boolset(0), intset(0), unitsset(0), stringset(0)
     548             : {
     549       53206 : }
     550             : 
     551       51787 : state_set::~state_set()
     552             : {
     553       51787 : }
     554             : 
     555      575522 : void state_set::incl(bool_value_state b)
     556             : {
     557      575522 :   boolset |= 1 << b;
     558      575522 : }
     559             : 
     560       13531 : void state_set::incl(int_value_state i)
     561             : {
     562       13531 :   intset |= 1 << i;
     563       13531 : }
     564             : 
     565      240750 : void state_set::incl(units_value_state u)
     566             : {
     567      240750 :   unitsset |= 1 << u;
     568      240750 : }
     569             : 
     570       14369 : void state_set::incl(string_value_state s)
     571             : {
     572       14369 :   stringset |= 1 << s;
     573       14369 : }
     574             : 
     575           0 : void state_set::excl(bool_value_state b)
     576             : {
     577           0 :   boolset &= ~(1 << b);
     578           0 : }
     579             : 
     580           0 : void state_set::excl(int_value_state i)
     581             : {
     582           0 :   intset &= ~(1 << i);
     583           0 : }
     584             : 
     585           0 : void state_set::excl(units_value_state u)
     586             : {
     587           0 :   unitsset &= ~(1 << u);
     588           0 : }
     589             : 
     590           0 : void state_set::excl(string_value_state s)
     591             : {
     592           0 :   stringset &= ~(1 << s);
     593           0 : }
     594             : 
     595           0 : int state_set::is_in(bool_value_state b)
     596             : {
     597           0 :   return (boolset & (1 << b)) != 0;
     598             : }
     599             : 
     600           0 : int state_set::is_in(int_value_state i)
     601             : {
     602           0 :   return (intset & (1 << i)) != 0;
     603             : }
     604             : 
     605           0 : int state_set::is_in(units_value_state u)
     606             : {
     607           0 :   return (unitsset & (1 << u)) != 0;
     608             : }
     609             : 
     610           0 : int state_set::is_in(string_value_state s)
     611             : {
     612           0 :   return (stringset & (1 << s)) != 0;
     613             : }
     614             : 
     615           0 : void state_set::add(units_value_state, int n)
     616             : {
     617           0 :   unitsset += n;
     618           0 : }
     619             : 
     620           0 : units state_set::val(units_value_state)
     621             : {
     622           0 :   return unitsset;
     623             : }
     624             : 
     625             : // Local Variables:
     626             : // fill-column: 72
     627             : // mode: C++
     628             : // End:
     629             : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72:

Generated by: LCOV version 1.14