LCOV - code coverage report
Current view: top level - preproc/eqn - limit.cpp (source / functions) Hit Total Coverage
Test: GNU roff Lines: 102 139 73.4 %
Date: 2026-01-16 17:51:41 Functions: 7 8 87.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright 1989-2024 Free Software Foundation, Inc.
       2             :      Written by James Clark (jjc@jclark.com)
       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             : #ifdef HAVE_CONFIG_H
      20             : #include <config.h>
      21             : #endif
      22             : 
      23             : #include "eqn.h"
      24             : #include "pbox.h"
      25             : 
      26             : class limit_box : public box {
      27             : private:
      28             :   box *p;
      29             :   box *from;
      30             :   box *to;
      31             : public:
      32             :   limit_box(box *, box *, box *);
      33             :   ~limit_box();
      34             :   int compute_metrics(int);
      35             :   void output();
      36             :   void debug_print();
      37             :   void diagnose_tab_stop_usage(int);
      38             : };
      39             : 
      40          16 : box *make_limit_box(box *pp, box *qq, box *rr)
      41             : {
      42          16 :   return new limit_box(pp, qq, rr);
      43             : }
      44             : 
      45          16 : limit_box::limit_box(box *pp, box *qq, box *rr)
      46          16 : : p(pp), from(qq), to(rr)
      47             : {
      48          16 :   spacing_type = p->spacing_type;
      49          16 : }
      50             : 
      51          32 : limit_box::~limit_box()
      52             : {
      53          16 :   delete p;
      54          16 :   delete from;
      55          16 :   delete to;
      56          32 : }
      57             : 
      58          16 : int limit_box::compute_metrics(int style)
      59             : {
      60          16 :   printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
      61          16 :   if (!(style <= SCRIPT_STYLE && one_size_reduction_flag))
      62          16 :     set_script_size();
      63          16 :   printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
      64          16 :   int res = 0;
      65          16 :   int mark_uid = -1;
      66          16 :   if (from != 0) {
      67          16 :     res = from->compute_metrics(cramped_style(script_style(style)));
      68          16 :     if (res)
      69           0 :       mark_uid = from->uid;
      70             :   }
      71          16 :   if (to != 0) {
      72          16 :     int r = to->compute_metrics(script_style(style));
      73          16 :     if (res && r)
      74           0 :       error("multiple marks and lineups");
      75             :     else  {
      76          16 :       mark_uid = to->uid;
      77          16 :       res = r;
      78             :     }
      79             :   }
      80          16 :   printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
      81          16 :   int r = p->compute_metrics(style);
      82          16 :   p->compute_subscript_kern();
      83          16 :   if (res && r)
      84           0 :     error("multiple marks and lineups");
      85             :   else {
      86          16 :     mark_uid = p->uid;
      87          16 :     res = r;
      88             :   }
      89          16 :   printf(".nr " LEFT_WIDTH_FORMAT " "
      90             :          "0\\n[" WIDTH_FORMAT "]",
      91          16 :          uid, p->uid);
      92          16 :   if (from != 0)
      93          16 :     printf(">?(\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])",
      94          16 :            p->uid, from->uid);
      95          16 :   if (to != 0)
      96          16 :     printf(">?(-\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])",
      97          16 :            p->uid, to->uid);
      98          16 :   printf("/2\n");
      99          16 :   printf(".nr " WIDTH_FORMAT " "
     100             :          "0\\n[" WIDTH_FORMAT "]",
     101          16 :          uid, p->uid);
     102          16 :   if (from != 0)
     103          16 :     printf(">?(-\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])",
     104          16 :            p->uid, from->uid);
     105          16 :   if (to != 0)
     106          16 :     printf(">?(\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])",
     107          16 :            p->uid, to->uid);
     108          16 :   printf("/2+\\n[" LEFT_WIDTH_FORMAT "]\n", uid);
     109          16 :   printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]", uid, p->uid);
     110          16 :   if (to != 0)
     111          16 :     printf(">?\\n[" WIDTH_FORMAT "]", to->uid);
     112          16 :   if (from != 0)
     113          16 :     printf(">?\\n[" WIDTH_FORMAT "]", from->uid);
     114          16 :   printf("\n");
     115          16 :   if (res)
     116           0 :     printf(".nr " MARK_REG " +(\\n[" LEFT_WIDTH_FORMAT "]"
     117             :            "-(\\n[" WIDTH_FORMAT "]/2))\n",
     118           0 :            uid, mark_uid);
     119          16 :   if (to != 0) {
     120          48 :     printf(".nr " SUP_RAISE_FORMAT " %dM+\\n[" DEPTH_FORMAT
     121             :            "]>?%dM+\\n[" HEIGHT_FORMAT "]\n",
     122          16 :            uid, get_param("big_op_spacing1"), to->uid,
     123          16 :            get_param("big_op_spacing3"), p->uid);
     124          16 :     printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
     125             :            HEIGHT_FORMAT "]+%dM\n",
     126          16 :            uid, uid, to->uid, get_param("big_op_spacing5"));
     127             :   }
     128             :   else
     129           0 :     printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
     130          16 :   if (from != 0) {
     131          48 :     printf(".nr " SUB_LOWER_FORMAT " %dM+\\n[" HEIGHT_FORMAT
     132             :            "]>?%dM+\\n[" DEPTH_FORMAT "]\n",
     133          16 :            uid, get_param("big_op_spacing2"), from->uid,
     134          16 :            get_param("big_op_spacing4"), p->uid);
     135          16 :     printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n["
     136             :            DEPTH_FORMAT "]+%dM\n",
     137          16 :            uid, uid, from->uid, get_param("big_op_spacing5"));
     138             :   }
     139             :   else
     140           0 :     printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
     141          16 :   return res;
     142             : }
     143             : 
     144          16 : void limit_box::output()
     145             : {
     146          16 :   if (output_format == troff) {
     147          16 :     printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
     148          16 :     if (to != 0) {
     149          16 :       printf("\\Z" DELIMITER_CHAR);
     150          16 :       printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
     151          16 :       printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
     152             :              "+(-\\n[" WIDTH_FORMAT "]u+\\n[" SUB_KERN_FORMAT "]u/2u)'",
     153          16 :              uid, to->uid, p->uid);
     154          16 :       to->output();
     155          16 :       printf(DELIMITER_CHAR);
     156             :     }
     157          16 :     if (from != 0) {
     158          16 :       printf("\\Z" DELIMITER_CHAR);
     159          16 :       printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
     160          16 :       printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
     161             :              "+(-\\n[" SUB_KERN_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
     162          16 :              uid, p->uid, from->uid);
     163          16 :       from->output();
     164          16 :       printf(DELIMITER_CHAR);
     165             :     }
     166          16 :     printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
     167          16 :     printf("\\Z" DELIMITER_CHAR);
     168          16 :     printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
     169             :            "-(\\n[" WIDTH_FORMAT "]u/2u)'",
     170          16 :            uid, p->uid);
     171          16 :     p->output();
     172          16 :     printf(DELIMITER_CHAR);
     173          16 :     printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
     174             :   }
     175           0 :   else if (output_format == mathml) {
     176           0 :     if (from != 0 && to != 0) {
     177           0 :       printf("<munderover>");
     178           0 :       p->output();
     179           0 :       from->output();
     180           0 :       to->output();
     181           0 :       printf("</munderover>");
     182             :     }
     183           0 :     else if (from != 0) {
     184           0 :       printf("<munder>");
     185           0 :       p->output();
     186           0 :       from->output();
     187           0 :       printf("</munder>");
     188             :     }
     189           0 :     else if (to != 0) {
     190           0 :       printf("<mover>");
     191           0 :       p->output();
     192           0 :       to->output();
     193           0 :       printf("</mover>");
     194             :     }
     195             :   }
     196          16 : }
     197             : 
     198           0 : void limit_box::debug_print()
     199             : {
     200           0 :   fprintf(stderr, "{ ");
     201           0 :   p->debug_print();
     202           0 :   fprintf(stderr, " }");
     203           0 :   if (from) {
     204           0 :     fprintf(stderr, " from { ");
     205           0 :     from->debug_print();
     206           0 :     fprintf(stderr, " }");
     207             :   }
     208           0 :   if (to) {
     209           0 :     fprintf(stderr, " to { ");
     210           0 :     to->debug_print();
     211           0 :     fprintf(stderr, " }");
     212             :   }
     213           0 : }
     214             : 
     215          16 : void limit_box::diagnose_tab_stop_usage(int level)
     216             : {
     217          16 :   if (to)
     218          16 :     to->diagnose_tab_stop_usage(level + 1);
     219          16 :   if (from)
     220          16 :     from->diagnose_tab_stop_usage(level + 1);
     221          16 :   p->diagnose_tab_stop_usage(level + 1);
     222          16 : }
     223             : 
     224             : // Local Variables:
     225             : // fill-column: 72
     226             : // mode: C++
     227             : // End:
     228             : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72:

Generated by: LCOV version 1.14