LCOV - code coverage report
Current view: top level - src/flisp - print.c (source / functions) Hit Total Coverage
Test: [build process] commit ef510b1f346f4c9f9d86eaceace5ca54961a1dbc Lines: 207 501 41.3 %
Date: 2022-07-17 01:01:28 Functions: 19 26 73.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 139 524 26.5 %

           Branch data     Line data    Source code
       1                 :            : extern void *memrchr(const void *s, int c, size_t n);
       2                 :            : 
       3                 :        600 : static void outc(fl_context_t *fl_ctx, char c, ios_t *f)
       4                 :            : {
       5                 :        600 :     ios_putc(c, f);
       6         [ -  + ]:        600 :     if (c == '\n')
       7                 :          0 :         fl_ctx->HPOS = 0;
       8                 :            :     else
       9                 :        600 :         fl_ctx->HPOS++;
      10                 :        600 : }
      11                 :    1769974 : static void outs(fl_context_t *fl_ctx, const char *s, ios_t *f)
      12                 :            : {
      13                 :    1769974 :     ios_puts(s, f);
      14                 :    1769974 :     fl_ctx->HPOS += u8_strwidth(s);
      15                 :    1769974 : }
      16                 :          0 : static void outsn(fl_context_t *fl_ctx, const char *s, ios_t *f, size_t n)
      17                 :            : {
      18                 :          0 :     ios_write(f, s, n);
      19                 :          0 :     fl_ctx->HPOS += u8_strwidth(s);
      20                 :          0 : }
      21                 :          0 : static int outindent(fl_context_t *fl_ctx, int n, ios_t *f)
      22                 :            : {
      23                 :            :     // move back to left margin if we get too indented
      24         [ #  # ]:          0 :     if (n > fl_ctx->SCR_WIDTH-12)
      25                 :          0 :         n = 2;
      26                 :          0 :     int n0 = n;
      27                 :          0 :     ios_putc('\n', f);
      28                 :          0 :     fl_ctx->VPOS++;
      29                 :          0 :     fl_ctx->HPOS = n;
      30         [ #  # ]:          0 :     while (n >= 8) {
      31                 :          0 :         ios_putc('\t', f);
      32                 :          0 :         n -= 8;
      33                 :            :     }
      34         [ #  # ]:          0 :     while (n) {
      35                 :          0 :         ios_putc(' ', f);
      36                 :          0 :         n--;
      37                 :            :     }
      38                 :          0 :     return n0;
      39                 :            : }
      40                 :            : 
      41                 :          0 : void fl_print_chr(fl_context_t *fl_ctx, char c, ios_t *f)
      42                 :            : {
      43                 :          0 :     outc(fl_ctx, c, f);
      44                 :          0 : }
      45                 :            : 
      46                 :          0 : void fl_print_str(fl_context_t *fl_ctx, const char *s, ios_t *f)
      47                 :            : {
      48                 :          0 :     outs(fl_ctx, s, f);
      49                 :          0 : }
      50                 :            : 
      51                 :    2436440 : void print_traverse(fl_context_t *fl_ctx, value_t v)
      52                 :            : {
      53                 :            :     value_t *bp;
      54         [ +  + ]:    2436860 :     while (iscons(v)) {
      55         [ -  + ]:        432 :         if (ismarked(fl_ctx, v)) {
      56                 :          0 :             bp = (value_t*)ptrhash_bp(&fl_ctx->printconses, (void*)v);
      57         [ #  # ]:          0 :             if (*bp == (value_t)HT_NOTFOUND)
      58                 :          0 :                 *bp = fixnum(fl_ctx->printlabel++);
      59                 :          0 :             return;
      60                 :            :         }
      61                 :        432 :         mark_cons(fl_ctx, v);
      62                 :        432 :         print_traverse(fl_ctx, car_(v));
      63                 :        432 :         v = cdr_(v);
      64                 :            :     }
      65   [ +  +  +  -  :    2436440 :     if (!ismanaged(fl_ctx, v) || issymbol(v))
                   -  + ]
      66                 :     186178 :         return;
      67         [ -  + ]:    2250260 :     if (ismarked(fl_ctx, v)) {
      68                 :          0 :         bp = (value_t*)ptrhash_bp(&fl_ctx->printconses, (void*)v);
      69         [ #  # ]:          0 :         if (*bp == (value_t)HT_NOTFOUND)
      70                 :          0 :             *bp = fixnum(fl_ctx->printlabel++);
      71                 :          0 :         return;
      72                 :            :     }
      73         [ -  + ]:    2250260 :     if (isvector(v)) {
      74         [ #  # ]:          0 :         if (vector_size(v) > 0)
      75                 :          0 :             mark_cons(fl_ctx, v);
      76                 :            :         unsigned int i;
      77         [ #  # ]:          0 :         for(i=0; i < vector_size(v); i++)
      78                 :          0 :             print_traverse(fl_ctx, vector_elt(v,i));
      79                 :            :     }
      80         [ +  + ]:    2250260 :     else if (iscprim(v)) {
      81                 :    1583964 :         mark_cons(fl_ctx, v);
      82                 :            :     }
      83   [ -  +  -  - ]:     666288 :     else if (isclosure(v)) {
      84                 :          0 :         mark_cons(fl_ctx, v);
      85                 :          0 :         function_t *f = (function_t*)ptr(v);
      86                 :          0 :         print_traverse(fl_ctx, f->bcode);
      87                 :          0 :         print_traverse(fl_ctx, f->vals);
      88                 :          0 :         print_traverse(fl_ctx, f->env);
      89                 :            :     }
      90                 :            :     else {
      91         [ -  + ]:     666288 :         assert(iscvalue(v));
      92                 :     666288 :         cvalue_t *cv = (cvalue_t*)ptr(v);
      93                 :            :         // don't consider shared references to ""
      94   [ +  +  +  + ]:     666288 :         if (!cv_isstr(fl_ctx, cv) || cv_len(cv)!=0)
      95                 :     653398 :             mark_cons(fl_ctx, v);
      96                 :     666288 :         fltype_t *t = cv_class(cv);
      97   [ -  +  -  - ]:     666288 :         if (t->vtable != NULL && t->vtable->print_traverse != NULL)
      98                 :          0 :             t->vtable->print_traverse(fl_ctx, v);
      99                 :            :     }
     100                 :            : }
     101                 :            : 
     102                 :          0 : static void print_symbol_name(fl_context_t *fl_ctx, ios_t *f, char *name)
     103                 :            : {
     104                 :          0 :     int i, escape=0, charescape=0;
     105                 :            : 
     106         [ #  # ]:          0 :     if ((name[0] == '\0') ||
     107   [ #  #  #  # ]:          0 :         (name[0] == '.' && name[1] == '\0') ||
     108   [ #  #  #  # ]:          0 :         (name[0] == '#') ||
     109                 :          0 :         isnumtok(fl_ctx, name, NULL))
     110                 :          0 :         escape = 1;
     111                 :          0 :     i=0;
     112         [ #  # ]:          0 :     while (name[i]) {
     113         [ #  # ]:          0 :         if (!symchar(name[i])) {
     114                 :          0 :             escape = 1;
     115   [ #  #  #  # ]:          0 :             if (name[i]=='|' || name[i]=='\\') {
     116                 :          0 :                 charescape = 1;
     117                 :          0 :                 break;
     118                 :            :             }
     119                 :            :         }
     120                 :          0 :         i++;
     121                 :            :     }
     122         [ #  # ]:          0 :     if (escape) {
     123         [ #  # ]:          0 :         if (charescape) {
     124                 :          0 :             outc(fl_ctx, '|', f);
     125                 :          0 :             i=0;
     126         [ #  # ]:          0 :             while (name[i]) {
     127   [ #  #  #  # ]:          0 :                 if (name[i]=='|' || name[i]=='\\')
     128                 :          0 :                     outc(fl_ctx, '\\', f);
     129                 :          0 :                 outc(fl_ctx, name[i], f);
     130                 :          0 :                 i++;
     131                 :            :             }
     132                 :          0 :             outc(fl_ctx, '|', f);
     133                 :            :         }
     134                 :            :         else {
     135                 :          0 :             outc(fl_ctx, '|', f);
     136                 :          0 :             outs(fl_ctx, name, f);
     137                 :          0 :             outc(fl_ctx, '|', f);
     138                 :            :         }
     139                 :            :     }
     140                 :            :     else {
     141                 :          0 :         outs(fl_ctx, name, f);
     142                 :            :     }
     143                 :          0 : }
     144                 :            : 
     145                 :            : /*
     146                 :            :   The following implements a simple pretty-printing algorithm. This is
     147                 :            :   an unlimited-width approach that doesn't require an extra pass.
     148                 :            :   It uses some heuristics to guess whether an expression is "small",
     149                 :            :   and avoids wrapping symbols across lines. The result is high
     150                 :            :   performance and nice output for typical code. Quality is poor for
     151                 :            :   pathological or deeply-nested expressions, but those are difficult
     152                 :            :   to print anyway.
     153                 :            : */
     154                 :            : #define SMALL_STR_LEN 20
     155                 :        600 : static inline int tinyp(fl_context_t *fl_ctx, value_t v)
     156                 :            : {
     157         [ +  + ]:        600 :     if (issymbol(v))
     158                 :        408 :         return (u8_strwidth(symbol_name(fl_ctx, v)) < SMALL_STR_LEN);
     159         [ -  + ]:        192 :     if (fl_isstring(fl_ctx, v))
     160                 :          0 :         return (cv_len((cvalue_t*)ptr(v)) < SMALL_STR_LEN);
     161   [ +  -  -  +  :        384 :     return (isfixnum(v) || isbuiltin(v) || v==fl_ctx->F || v==fl_ctx->T || v==fl_ctx->NIL ||
          -  -  +  -  +  
                -  +  - ]
     162         [ -  + ]:        192 :             v == fl_ctx->FL_EOF);
     163                 :            : }
     164                 :            : 
     165                 :        384 : static int smallp(fl_context_t *fl_ctx, value_t v)
     166                 :            : {
     167         [ +  + ]:        384 :     if (tinyp(fl_ctx, v)) return 1;
     168         [ -  + ]:         96 :     if (fl_isnumber(fl_ctx, v)) return 1;
     169         [ +  + ]:         96 :     if (iscons(v)) {
     170   [ +  -  +  - ]:         72 :         if (tinyp(fl_ctx, car_(v)) && (tinyp(fl_ctx, cdr_(v)) ||
     171   [ +  -  +  + ]:         72 :                                (iscons(cdr_(v)) && tinyp(fl_ctx, car_(cdr_(v))) &&
     172         [ +  - ]:         48 :                                 cdr_(cdr_(v))==fl_ctx->NIL)))
     173                 :         48 :             return 1;
     174                 :         24 :         return 0;
     175                 :            :     }
     176         [ -  + ]:         24 :     if (isvector(v)) {
     177                 :          0 :         size_t s = vector_size(v);
     178   [ #  #  #  #  :          0 :         return (s == 0 || (tinyp(fl_ctx, vector_elt(v,0)) &&
                   #  # ]
     179   [ #  #  #  # ]:          0 :                            (s == 1 || (s == 2 &&
     180                 :          0 :                                        tinyp(fl_ctx, vector_elt(v,1))))));
     181                 :            :     }
     182                 :         24 :     return 0;
     183                 :            : }
     184                 :            : 
     185                 :        168 : static int specialindent(fl_context_t *fl_ctx, value_t head)
     186                 :            : {
     187                 :            :     // indent these forms 2 spaces, not lined up with the first argument
     188   [ +  -  +  -  :        168 :     if (head == fl_ctx->LAMBDA || head == fl_ctx->TRYCATCH || head == fl_ctx->definesym ||
                   +  - ]
     189   [ +  -  -  + ]:        168 :         head == fl_ctx->defmacrosym || head == fl_ctx->forsym)
     190                 :          0 :         return 2;
     191                 :        168 :     return -1;
     192                 :            : }
     193                 :            : 
     194                 :          0 : static int lengthestimate(fl_context_t *fl_ctx, value_t v)
     195                 :            : {
     196                 :            :     // get the width of an expression if we can do so cheaply
     197         [ #  # ]:          0 :     if (issymbol(v))
     198                 :          0 :         return u8_strwidth(symbol_name(fl_ctx, v));
     199                 :          0 :     return -1;
     200                 :            : }
     201                 :            : 
     202                 :        168 : static int allsmallp(fl_context_t *fl_ctx, value_t v)
     203                 :            : {
     204                 :        168 :     int n = 1;
     205         [ +  + ]:        504 :     while (iscons(v)) {
     206         [ +  + ]:        384 :         if (!smallp(fl_ctx, car_(v)))
     207                 :         48 :             return 0;
     208                 :        336 :         v = cdr_(v);
     209                 :        336 :         n++;
     210         [ -  + ]:        336 :         if (n > 25)
     211                 :          0 :             return n;
     212                 :            :     }
     213                 :        120 :     return n;
     214                 :            : }
     215                 :            : 
     216                 :        168 : static int indentafter3(fl_context_t *fl_ctx, value_t head, value_t v)
     217                 :            : {
     218                 :            :     // for certain X always indent (X a b c) after b
     219   [ -  +  -  - ]:        168 :     return ((head == fl_ctx->forsym) && !allsmallp(fl_ctx, cdr_(v)));
     220                 :            : }
     221                 :            : 
     222                 :        168 : static int indentafter2(fl_context_t *fl_ctx, value_t head, value_t v)
     223                 :            : {
     224                 :            :     // for certain X always indent (X a b) after a
     225   [ +  -  -  +  :        168 :     return ((head == fl_ctx->definesym || head == fl_ctx->defmacrosym) &&
                   -  - ]
     226                 :          0 :             !allsmallp(fl_ctx, cdr_(v)));
     227                 :            : }
     228                 :            : 
     229                 :        168 : static int indentevery(fl_context_t *fl_ctx, value_t v)
     230                 :            : {
     231                 :            :     // indent before every subform of a special form, unless every
     232                 :            :     // subform is "small"
     233                 :        168 :     value_t c = car_(v);
     234   [ +  -  -  + ]:        168 :     if (c == fl_ctx->LAMBDA || c == fl_ctx->setqsym)
     235                 :          0 :         return 0;
     236         [ -  + ]:        168 :     if (c == fl_ctx->IF) // TODO: others
     237                 :          0 :         return !allsmallp(fl_ctx, cdr_(v));
     238                 :        168 :     return 0;
     239                 :            : }
     240                 :            : 
     241                 :        168 : static int blockindent(fl_context_t *fl_ctx, value_t v)
     242                 :            : {
     243                 :            :     // in this case we switch to block indent mode, where the head
     244                 :            :     // is no longer considered special:
     245                 :            :     // (a b c d e
     246                 :            :     //  f g h i j)
     247                 :        168 :     return (allsmallp(fl_ctx, v) > 9);
     248                 :            : }
     249                 :            : 
     250                 :        168 : static void print_pair(fl_context_t *fl_ctx, ios_t *f, value_t v)
     251                 :            : {
     252                 :            :     value_t cd;
     253                 :        168 :     char *op = NULL;
     254   [ +  -  +  +  :        240 :     if (iscons(cdr_(v)) && cdr_(cdr_(v)) == fl_ctx->NIL &&
                   +  - ]
     255                 :         72 :         !ptrhash_has(&fl_ctx->printconses, (void*)cdr_(v)) &&
     256         [ -  + ]:         72 :         (((car_(v) == fl_ctx->QUOTE)     && (op = "'"))  ||
     257         [ -  + ]:         72 :          ((car_(v) == fl_ctx->BACKQUOTE) && (op = "`"))  ||
     258         [ -  + ]:         72 :          ((car_(v) == fl_ctx->COMMA)     && (op = ","))  ||
     259         [ -  + ]:         72 :          ((car_(v) == fl_ctx->COMMAAT)   && (op = ",@")) ||
     260         [ -  + ]:         72 :          ((car_(v) == fl_ctx->COMMADOT)  && (op = ",.")))) {
     261                 :            :         // special prefix syntax
     262                 :          0 :         unmark_cons(fl_ctx, v);
     263                 :          0 :         unmark_cons(fl_ctx, cdr_(v));
     264                 :          0 :         outs(fl_ctx, op, f);
     265                 :          0 :         fl_print_child(fl_ctx, f, car_(cdr_(v)));
     266                 :          0 :         return;
     267                 :            :     }
     268                 :        168 :     int startpos = fl_ctx->HPOS;
     269                 :        168 :     outc(fl_ctx, '(', f);
     270                 :        168 :     int newindent=fl_ctx->HPOS, blk=blockindent(fl_ctx, v);
     271                 :        168 :     int lastv, n=0, si, ind=0, est, always=0, nextsmall, thistiny;
     272         [ +  - ]:        168 :     if (!blk) always = indentevery(fl_ctx, v);
     273                 :        168 :     value_t head = car_(v);
     274                 :        168 :     int after3 = indentafter3(fl_ctx, head, v);
     275                 :        168 :     int after2 = indentafter2(fl_ctx, head, v);
     276                 :        168 :     int n_unindented = 1;
     277                 :            :     while (1) {
     278                 :        432 :         cd = cdr_(v);
     279   [ -  +  -  -  :        432 :         if (fl_ctx->print_length >= 0 && n >= fl_ctx->print_length && cd!=fl_ctx->NIL) {
                   -  - ]
     280                 :          0 :             outsn(fl_ctx, "...)", f, 4);
     281                 :          0 :             break;
     282                 :            :         }
     283                 :        432 :         lastv = fl_ctx->VPOS;
     284                 :        432 :         unmark_cons(fl_ctx, v);
     285                 :        432 :         fl_print_child(fl_ctx, f, car_(v));
     286   [ +  +  -  + ]:        432 :         if (!iscons(cd) || ptrhash_has(&fl_ctx->printconses, (void*)cd)) {
     287         [ -  + ]:        168 :             if (cd != fl_ctx->NIL) {
     288                 :          0 :                 outsn(fl_ctx, " . ", f, 3);
     289                 :          0 :                 fl_print_child(fl_ctx, f, cd);
     290                 :            :             }
     291                 :        168 :             outc(fl_ctx, ')', f);
     292                 :        168 :             break;
     293                 :            :         }
     294                 :            : 
     295         [ -  + ]:        264 :         if (!fl_ctx->print_pretty ||
     296   [ #  #  #  # ]:          0 :             ((head == fl_ctx->LAMBDA) && n == 0)) {
     297                 :            :             // never break line before lambda-list
     298                 :        264 :             ind = 0;
     299                 :            :         }
     300                 :            :         else {
     301                 :          0 :             est = lengthestimate(fl_ctx, car_(cd));
     302                 :          0 :             nextsmall = smallp(fl_ctx, car_(cd));
     303                 :          0 :             thistiny = tinyp(fl_ctx, car_(v));
     304                 :          0 :             ind = (((fl_ctx->VPOS > lastv) ||
     305   [ #  #  #  #  :          0 :                     (fl_ctx->HPOS>fl_ctx->SCR_WIDTH/2 && !nextsmall && !thistiny && n>0)) ||
             #  #  #  # ]
     306                 :            : 
     307   [ #  #  #  # ]:          0 :                    (fl_ctx->HPOS > fl_ctx->SCR_WIDTH-4) ||
     308                 :            : 
     309         [ #  # ]:          0 :                    (est!=-1 && (fl_ctx->HPOS+est > fl_ctx->SCR_WIDTH-2)) ||
     310                 :            : 
     311   [ #  #  #  #  :          0 :                    ((head == fl_ctx->LAMBDA) && !nextsmall) ||
                   #  # ]
     312                 :            : 
     313   [ #  #  #  # ]:          0 :                    (n > 0 && always) ||
     314                 :            : 
     315   [ #  #  #  # ]:          0 :                    (n == 2 && after3) ||
     316   [ #  #  #  # ]:          0 :                    (n == 1 && after2) ||
     317                 :            : 
     318   [ #  #  #  #  :          0 :                    (n_unindented >= 3 && !nextsmall) ||
                   #  # ]
     319                 :            : 
     320         [ #  # ]:          0 :                    (n == 0 && !smallp(fl_ctx, head)));
     321                 :            :         }
     322                 :            : 
     323         [ -  + ]:        264 :         if (ind) {
     324                 :          0 :             newindent = outindent(fl_ctx, newindent, f);
     325                 :          0 :             n_unindented = 1;
     326                 :            :         }
     327                 :            :         else {
     328                 :        264 :             n_unindented++;
     329                 :        264 :             outc(fl_ctx, ' ', f);
     330         [ +  + ]:        264 :             if (n==0) {
     331                 :            :                 // set indent level after printing head
     332                 :        168 :                 si = specialindent(fl_ctx, head);
     333         [ -  + ]:        168 :                 if (si != -1)
     334                 :          0 :                     newindent = startpos + si;
     335         [ +  - ]:        168 :                 else if (!blk)
     336                 :        168 :                     newindent = fl_ctx->HPOS;
     337                 :            :             }
     338                 :            :         }
     339                 :        264 :         n++;
     340                 :        264 :         v = cd;
     341                 :            :     }
     342                 :            : }
     343                 :            : 
     344                 :            : static void cvalue_print(fl_context_t *fl_ctx, ios_t *f, value_t v);
     345                 :            : 
     346                 :    2250420 : static int print_circle_prefix(fl_context_t *fl_ctx, ios_t *f, value_t v)
     347                 :            : {
     348                 :            :     value_t label;
     349                 :            :     char buf[64];
     350                 :            :     char *str;
     351         [ -  + ]:    2250420 :     if ((label=(value_t)ptrhash_get(&fl_ctx->printconses, (void*)v)) !=
     352                 :            :         (value_t)HT_NOTFOUND) {
     353         [ #  # ]:          0 :         if (!ismarked(fl_ctx, v)) {
     354                 :            :             //fl_ctx->HPOS+=ios_printf(f, "#%ld#", numval(label));
     355                 :          0 :             outc(fl_ctx, '#', f);
     356                 :          0 :             str = uint2str(buf, sizeof(buf)-1, numval(label), 10);
     357                 :          0 :             outs(fl_ctx, str, f);
     358                 :          0 :             outc(fl_ctx, '#', f);
     359                 :          0 :             return 1;
     360                 :            :         }
     361                 :            :         //fl_ctx->HPOS+=ios_printf(f, "#%ld=", numval(label));
     362                 :          0 :         outc(fl_ctx, '#', f);
     363                 :          0 :         str = uint2str(buf, sizeof(buf)-1, numval(label), 10);
     364                 :          0 :         outs(fl_ctx, str, f);
     365                 :          0 :         outc(fl_ctx, '=', f);
     366                 :            :     }
     367   [ +  -  +  - ]:    2250420 :     if (ismanaged(fl_ctx, v))
     368                 :    2250420 :         unmark_cons(fl_ctx, v);
     369                 :    2250420 :     return 0;
     370                 :            : }
     371                 :            : 
     372                 :    2436440 : void fl_print_child(fl_context_t *fl_ctx, ios_t *f, value_t v)
     373                 :            : {
     374                 :            :     char *name, *str;
     375                 :            :     char buf[64];
     376   [ -  +  -  - ]:    2436440 :     if (fl_ctx->print_level >= 0 && fl_ctx->P_LEVEL >= fl_ctx->print_level &&
     377   [ #  #  #  #  :          0 :         (iscons(v) || isvector(v) || isclosure(v))) {
             #  #  #  # ]
     378                 :          0 :         outc(fl_ctx, '#', f);
     379                 :          0 :         return;
     380                 :            :     }
     381                 :    2436440 :     fl_ctx->P_LEVEL++;
     382                 :            : 
     383   [ +  +  -  +  :    2436440 :     switch (tag(v)) {
                   +  - ]
     384                 :      61106 :     case TAG_NUM :
     385                 :            :     case TAG_NUM1: //fl_ctx->HPOS+=ios_printf(f, "%ld", numval(v)); break;
     386                 :      61106 :         str = uint2str(&buf[1], sizeof(buf)-1, labs(numval(v)), 10);
     387         [ -  + ]:      61106 :         if (numval(v)<0)
     388                 :          0 :             *(--str) = '-';
     389                 :      61106 :         outs(fl_ctx, str, f);
     390                 :      61106 :         break;
     391                 :     124904 :     case TAG_SYM:
     392                 :     124904 :         name = symbol_name(fl_ctx, v);
     393         [ +  - ]:     124904 :         if (fl_ctx->print_princ)
     394                 :     124904 :             outs(fl_ctx, name, f);
     395   [ #  #  #  # ]:          0 :         else if (ismanaged(fl_ctx, v)) {
     396                 :          0 :             outsn(fl_ctx, "#:", f, 2);
     397                 :          0 :             outs(fl_ctx, name, f);
     398                 :            :         }
     399                 :            :         else
     400                 :          0 :             print_symbol_name(fl_ctx, f, name);
     401                 :     124904 :         break;
     402                 :          0 :     case TAG_FUNCTION:
     403         [ #  # ]:          0 :         if (v == fl_ctx->T) {
     404                 :          0 :             outsn(fl_ctx, "#t", f, 2);
     405                 :            :         }
     406         [ #  # ]:          0 :         else if (v == fl_ctx->F) {
     407                 :          0 :             outsn(fl_ctx, "#f", f, 2);
     408                 :            :         }
     409         [ #  # ]:          0 :         else if (v == fl_ctx->NIL) {
     410                 :          0 :             outsn(fl_ctx, "()", f, 2);
     411                 :            :         }
     412         [ #  # ]:          0 :         else if (v == fl_ctx->FL_EOF) {
     413                 :          0 :             outsn(fl_ctx, "#<eof>", f, 6);
     414                 :            :         }
     415   [ #  #  #  # ]:          0 :         else if (isbuiltin(v)) {
     416         [ #  # ]:          0 :             if (!fl_ctx->print_princ)
     417                 :          0 :                 outsn(fl_ctx, "#.", f, 2);
     418                 :          0 :             outs(fl_ctx, builtin_names[uintval(v)], f);
     419                 :            :         }
     420                 :            :         else {
     421   [ #  #  #  # ]:          0 :             assert(isclosure(v));
     422         [ #  # ]:          0 :             if (!fl_ctx->print_princ) {
     423         [ #  # ]:          0 :                 if (print_circle_prefix(fl_ctx, f, v)) break;
     424                 :          0 :                 function_t *fn = (function_t*)ptr(v);
     425                 :          0 :                 outs(fl_ctx, "#fn(", f);
     426                 :          0 :                 char *data = (char*)cvalue_data(fn->bcode);
     427                 :          0 :                 size_t i, sz = cvalue_len(fn->bcode);
     428         [ #  # ]:          0 :                 for(i=0; i < sz; i++) data[i] += 48;
     429                 :          0 :                 fl_print_child(fl_ctx, f, fn->bcode);
     430         [ #  # ]:          0 :                 for(i=0; i < sz; i++) data[i] -= 48;
     431                 :          0 :                 outc(fl_ctx, ' ', f);
     432                 :          0 :                 fl_print_child(fl_ctx, f, fn->vals);
     433         [ #  # ]:          0 :                 if (fn->env != fl_ctx->NIL) {
     434                 :          0 :                     outc(fl_ctx, ' ', f);
     435                 :          0 :                     fl_print_child(fl_ctx, f, fn->env);
     436                 :            :                 }
     437         [ #  # ]:          0 :                 if (fn->name != fl_ctx->LAMBDA) {
     438                 :          0 :                     outc(fl_ctx, ' ', f);
     439                 :          0 :                     fl_print_child(fl_ctx, f, fn->name);
     440                 :            :                 }
     441                 :          0 :                 outc(fl_ctx, ')', f);
     442                 :            :             }
     443                 :            :             else {
     444                 :          0 :                 outs(fl_ctx, "#<function>", f);
     445                 :            :             }
     446                 :            :         }
     447                 :          0 :         break;
     448                 :    2250260 :     case TAG_CVALUE:
     449                 :            :     case TAG_CPRIM:
     450         [ -  + ]:    2250260 :         if (v == UNBOUND) { outs(fl_ctx, "#<undefined>", f); break; }
     451                 :            :         JL_FALLTHROUGH;
     452                 :            :     case TAG_VECTOR:
     453                 :            :     case TAG_CONS:
     454         [ -  + ]:    2250420 :         if (print_circle_prefix(fl_ctx, f, v)) break;
     455         [ -  + ]:    2250420 :         if (isvector(v)) {
     456                 :          0 :             outc(fl_ctx, '[', f);
     457                 :          0 :             int newindent = fl_ctx->HPOS, est;
     458                 :          0 :             int i, sz = vector_size(v);
     459         [ #  # ]:          0 :             for(i=0; i < sz; i++) {
     460   [ #  #  #  #  :          0 :                 if (fl_ctx->print_length >= 0 && i >= fl_ctx->print_length && i < sz-1) {
                   #  # ]
     461                 :          0 :                     outsn(fl_ctx, "...", f, 3);
     462                 :          0 :                     break;
     463                 :            :                 }
     464                 :          0 :                 fl_print_child(fl_ctx, f, vector_elt(v,i));
     465         [ #  # ]:          0 :                 if (i < sz-1) {
     466         [ #  # ]:          0 :                     if (!fl_ctx->print_pretty) {
     467                 :          0 :                         outc(fl_ctx, ' ', f);
     468                 :            :                     }
     469                 :            :                     else {
     470                 :          0 :                         est = lengthestimate(fl_ctx, vector_elt(v,i+1));
     471   [ #  #  #  # ]:          0 :                         if (fl_ctx->HPOS > fl_ctx->SCR_WIDTH-4 ||
     472         [ #  # ]:          0 :                             (est!=-1 && (fl_ctx->HPOS+est > fl_ctx->SCR_WIDTH-2)) ||
     473   [ #  #  #  # ]:          0 :                             (fl_ctx->HPOS > fl_ctx->SCR_WIDTH/2 &&
     474         [ #  # ]:          0 :                              !smallp(fl_ctx, vector_elt(v,i+1)) &&
     475                 :          0 :                              !tinyp(fl_ctx, vector_elt(v,i))))
     476                 :          0 :                             newindent = outindent(fl_ctx, newindent, f);
     477                 :            :                         else
     478                 :          0 :                             outc(fl_ctx, ' ', f);
     479                 :            :                     }
     480                 :            :                 }
     481                 :            :             }
     482                 :          0 :             outc(fl_ctx, ']', f);
     483                 :          0 :             break;
     484                 :            :         }
     485   [ +  +  +  + ]:    2250420 :         if (iscvalue(v) || iscprim(v))
     486                 :    2250260 :             cvalue_print(fl_ctx, f, v);
     487                 :            :         else
     488                 :        168 :             print_pair(fl_ctx, f, v);
     489                 :    2250420 :         break;
     490                 :            :     }
     491                 :    2436440 :     fl_ctx->P_LEVEL--;
     492                 :            : }
     493                 :            : 
     494                 :          0 : static void print_string(fl_context_t *fl_ctx, ios_t *f, char *str, size_t sz)
     495                 :            : {
     496                 :            :     char buf[512];
     497                 :          0 :     size_t i = 0;
     498                 :            :     uint8_t c;
     499                 :            :     static const char hexdig[] = "0123456789abcdef";
     500                 :            : 
     501                 :          0 :     outc(fl_ctx, '"', f);
     502         [ #  # ]:          0 :     if (!u8_isvalid(str, sz)) {
     503                 :            :         // alternate print algorithm that preserves data if it's not UTF-8
     504         [ #  # ]:          0 :         for(i=0; i < sz; i++) {
     505                 :          0 :             c = str[i];
     506         [ #  # ]:          0 :             if (c == '\\')
     507                 :          0 :                 outsn(fl_ctx, "\\\\", f, 2);
     508         [ #  # ]:          0 :             else if (c == '"')
     509                 :          0 :                 outsn(fl_ctx, "\\\"", f, 2);
     510   [ #  #  #  # ]:          0 :             else if (c >= 32 && c < 0x7f)
     511                 :          0 :                 outc(fl_ctx, c, f);
     512                 :            :             else {
     513                 :          0 :                 outsn(fl_ctx, "\\x", f, 2);
     514                 :          0 :                 outc(fl_ctx, hexdig[c>>4], f);
     515                 :          0 :                 outc(fl_ctx, hexdig[c&0xf], f);
     516                 :            :             }
     517                 :            :         }
     518                 :            :     }
     519                 :            :     else {
     520         [ #  # ]:          0 :         while (i < sz) {
     521                 :          0 :             size_t n = u8_escape(buf, sizeof(buf), str, &i, sz, 1, 0);
     522                 :          0 :             outsn(fl_ctx, buf, f, n-1);
     523                 :            :         }
     524                 :            :     }
     525                 :          0 :     outc(fl_ctx, '"', f);
     526                 :          0 : }
     527                 :            : 
     528                 :            : static numerictype_t sym_to_numtype(fl_context_t *fl_ctx, value_t type);
     529                 :            : #ifndef _OS_WINDOWS_
     530                 :            : #define __USE_GNU
     531                 :            : #include <dlfcn.h>
     532                 :            : #undef __USE_GNU
     533                 :            : #endif
     534                 :            : 
     535                 :            : #define sign_bit(r) ((*(int64_t*)&(r)) & BIT63)
     536                 :            : #define DFINITE(d) (((*(int64_t*)&(d))&0x7ff0000000000000LL)!=0x7ff0000000000000LL)
     537                 :            : 
     538                 :            : // 'weak' means we don't need to accurately reproduce the type, so
     539                 :            : // for example #int32(0) can be printed as just 0. this is used
     540                 :            : // printing in a context where a type is already implied, e.g. inside
     541                 :            : // an array.
     542                 :    2250260 : static void cvalue_printdata(fl_context_t *fl_ctx, ios_t *f, void *data,
     543                 :            :                              size_t len, value_t type, int weak)
     544                 :            : {
     545         [ -  + ]:    2250260 :     if (type == fl_ctx->bytesym) {
     546                 :          0 :         unsigned char ch = *(unsigned char*)data;
     547         [ #  # ]:          0 :         if (fl_ctx->print_princ)
     548                 :          0 :             outc(fl_ctx, ch, f);
     549         [ #  # ]:          0 :         else if (weak)
     550                 :          0 :             fl_ctx->HPOS+=ios_printf(f, "0x%hhx", ch);
     551                 :            :         else
     552                 :          0 :             fl_ctx->HPOS+=ios_printf(f, "#byte(0x%hhx)", ch);
     553                 :            :     }
     554         [ +  + ]:    2250260 :     else if (type == fl_ctx->wcharsym) {
     555                 :    1583964 :         uint32_t wc = *(uint32_t*)data;
     556                 :            :         char seq[8];
     557                 :    1583964 :         size_t nb = u8_toutf8(seq, sizeof(seq), &wc, 1);
     558                 :    1583964 :         seq[nb] = '\0';
     559         [ +  - ]:    1583964 :         if (fl_ctx->print_princ) {
     560                 :            :             // TODO: better multibyte handling
     561                 :    1583964 :             outs(fl_ctx, seq, f);
     562                 :            :         }
     563                 :            :         else {
     564                 :          0 :             outsn(fl_ctx, "#\\", f, 2);
     565         [ #  # ]:          0 :             if      (wc == 0x00) outsn(fl_ctx, "nul", f, 3);
     566         [ #  # ]:          0 :             else if (wc == 0x07) outsn(fl_ctx, "alarm", f, 5);
     567         [ #  # ]:          0 :             else if (wc == 0x08) outsn(fl_ctx, "backspace", f, 9);
     568         [ #  # ]:          0 :             else if (wc == 0x09) outsn(fl_ctx, "tab", f, 3);
     569         [ #  # ]:          0 :             else if (wc == 0x0A) outsn(fl_ctx, "linefeed", f, 8);
     570                 :            :             //else if (wc == 0x0A) outsn(fl_ctx, "newline", f, 7);
     571         [ #  # ]:          0 :             else if (wc == 0x0B) outsn(fl_ctx, "vtab", f, 4);
     572         [ #  # ]:          0 :             else if (wc == 0x0C) outsn(fl_ctx, "page", f, 4);
     573         [ #  # ]:          0 :             else if (wc == 0x0D) outsn(fl_ctx, "return", f, 6);
     574         [ #  # ]:          0 :             else if (wc == 0x1B) outsn(fl_ctx, "esc", f, 3);
     575         [ #  # ]:          0 :             else if (wc == 0x20) outsn(fl_ctx, "space", f, 5);
     576         [ #  # ]:          0 :             else if (wc == 0x7F) outsn(fl_ctx, "delete", f, 6);
     577         [ #  # ]:          0 :             else if (iswprint(wc)) outs(fl_ctx, seq, f);
     578                 :          0 :             else fl_ctx->HPOS+=ios_printf(f, "x%04x", (int)wc);
     579                 :            :         }
     580                 :            :     }
     581   [ +  -  -  + ]:     666288 :     else if (type == fl_ctx->floatsym || type == fl_ctx->doublesym) {
     582                 :            :         char buf[64];
     583                 :            :         double d;
     584         [ #  # ]:          0 :         if (type == fl_ctx->floatsym) { d = (double)*(float*)data; }
     585                 :          0 :         else { d = *(double*)data; }
     586         [ #  # ]:          0 :         if (!DFINITE(d)) {
     587                 :            :             char *rep;
     588         [ #  # ]:          0 :             if (d != d)
     589         [ #  # ]:          0 :                 rep = (char*)(sign_bit(d) ? "-nan.0" : "+nan.0");
     590                 :            :             else
     591         [ #  # ]:          0 :                 rep = (char*)(sign_bit(d) ? "-inf.0" : "+inf.0");
     592   [ #  #  #  #  :          0 :             if (type == fl_ctx->floatsym && !fl_ctx->print_princ && !weak)
                   #  # ]
     593                 :          0 :                 fl_ctx->HPOS+=ios_printf(f, "#%s(%s)", symbol_name(fl_ctx, type), rep);
     594                 :            :             else
     595                 :          0 :                 outs(fl_ctx, rep, f);
     596                 :            :         }
     597         [ #  # ]:          0 :         else if (d == 0) {
     598         [ #  # ]:          0 :             if (sign_bit(d))
     599                 :          0 :                 outsn(fl_ctx, "-0.0", f, 4);
     600                 :            :             else
     601                 :          0 :                 outsn(fl_ctx, "0.0", f, 3);
     602   [ #  #  #  #  :          0 :             if (type == fl_ctx->floatsym && !fl_ctx->print_princ && !weak)
                   #  # ]
     603                 :          0 :                 outc(fl_ctx, 'f', f);
     604                 :            :         }
     605                 :            :         else {
     606         [ #  # ]:          0 :             double ad = d < 0 ? -d : d;
     607   [ #  #  #  #  :          0 :             if ((long)d == d && ad < 1e6 && ad >= 1e-4) {
                   #  # ]
     608                 :          0 :                 snprintf(buf, sizeof(buf), "%g", d);
     609                 :            :             }
     610                 :            :             else {
     611         [ #  # ]:          0 :                 if (type == fl_ctx->floatsym)
     612                 :          0 :                     snprintf(buf, sizeof(buf), "%.8g", d);
     613                 :            :                 else
     614                 :          0 :                     snprintf(buf, sizeof(buf), "%.16g", d);
     615                 :            :             }
     616                 :          0 :             int hasdec = (strpbrk(buf, ".eE") != NULL);
     617                 :          0 :             outs(fl_ctx, buf, f);
     618         [ #  # ]:          0 :             if (!hasdec) outsn(fl_ctx, ".0", f, 2);
     619   [ #  #  #  #  :          0 :             if (type == fl_ctx->floatsym && !fl_ctx->print_princ && !weak)
                   #  # ]
     620                 :          0 :                 outc(fl_ctx, 'f', f);
     621                 :            :         }
     622                 :            :     }
     623         [ +  - ]:     666288 :     else if (type == fl_ctx->uint64sym
     624                 :            : #ifdef _P64
     625         [ -  + ]:     666288 :              || type == fl_ctx->sizesym
     626                 :            : #endif
     627                 :          0 :              ) {
     628                 :          0 :         uint64_t ui64 = *(uint64_t*)data;
     629   [ #  #  #  # ]:          0 :         if (weak || fl_ctx->print_princ)
     630                 :          0 :             fl_ctx->HPOS += ios_printf(f, "%llu", ui64);
     631                 :            :         else
     632                 :          0 :             fl_ctx->HPOS += ios_printf(f, "#%s(%llu)", symbol_name(fl_ctx, type), ui64);
     633                 :            :     }
     634         [ +  + ]:     666288 :     else if (issymbol(type)) {
     635                 :            :         // handle other integer prims. we know it's smaller than uint64
     636                 :            :         // at this point, so int64 is big enough to capture everything.
     637                 :         24 :         numerictype_t nt = sym_to_numtype(fl_ctx, type);
     638         [ +  - ]:         24 :         if (nt == N_NUMTYPES) {
     639                 :            :             // These states should be context independent.
     640                 :            :             static size_t (*volatile jl_static_print)(ios_t*, void*) = NULL;
     641                 :            :             static volatile int init = 0;
     642                 :            :             // XXX: use uv_once
     643         [ +  + ]:         24 :             if (init == 0) {
     644                 :            : #if defined(RTLD_SELF)
     645                 :            :                 jl_static_print = (size_t (*)(ios_t*, void*))
     646                 :            :                     (uintptr_t)dlsym(RTLD_SELF, "ijl_static_show");
     647                 :            : #elif defined(RTLD_DEFAULT)
     648                 :          4 :                 jl_static_print = (size_t (*)(ios_t*, void*))
     649                 :          4 :                     (uintptr_t)dlsym(RTLD_DEFAULT, "ijl_static_show");
     650                 :            : #elif defined(_OS_WINDOWS_)
     651                 :            :                 HMODULE handle;
     652                 :            :                 if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
     653                 :            :                                        GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
     654                 :            :                                        (LPCWSTR)(&cvalue_printdata),
     655                 :            :                                        &handle)) {
     656                 :            :                     jl_static_print = (size_t (*)(ios_t*, void*))
     657                 :            :                         (uintptr_t)GetProcAddress(handle, "ijl_static_show");
     658                 :            :                 }
     659                 :            : #endif
     660                 :          4 :                 init = 1;
     661                 :            :             }
     662   [ +  -  +  - ]:         24 :             if (jl_static_print != NULL && fl_ctx->jl_sym == type) {
     663                 :         24 :                 fl_ctx->HPOS += ios_printf(f, "#<julia: ");
     664                 :         24 :                 fl_ctx->HPOS += jl_static_print(f, *(void**)data);
     665                 :         24 :                 fl_ctx->HPOS += ios_printf(f, ">");
     666                 :            :             }
     667                 :            :             else
     668                 :          0 :                 fl_ctx->HPOS += ios_printf(f, "#<%s>", symbol_name(fl_ctx, type));
     669                 :            :         }
     670                 :            :         else {
     671                 :          0 :             int64_t i64 = conv_to_int64(data, nt);
     672   [ #  #  #  # ]:          0 :             if (weak || fl_ctx->print_princ)
     673                 :          0 :                 fl_ctx->HPOS += ios_printf(f, "%lld", i64);
     674                 :            :             else
     675                 :          0 :                 fl_ctx->HPOS += ios_printf(f, "#%s(%lld)", symbol_name(fl_ctx, type), i64);
     676                 :            :         }
     677                 :            :     }
     678         [ +  - ]:     666264 :     else if (iscons(type)) {
     679         [ +  - ]:     666264 :         if (car_(type) == fl_ctx->arraysym) {
     680                 :     666264 :             value_t eltype = car(fl_ctx, cdr_(type));
     681                 :            :             size_t cnt, elsize;
     682         [ -  + ]:     666264 :             if (iscons(cdr_(cdr_(type)))) {
     683                 :          0 :                 cnt = tosize(fl_ctx, car_(cdr_(cdr_(type))), "length");
     684         [ #  # ]:          0 :                 elsize = cnt ? len/cnt : 0;
     685                 :            :             }
     686                 :            :             else {
     687                 :            :                 // incomplete array type
     688                 :            :                 int junk;
     689                 :     666264 :                 elsize = ctype_sizeof(fl_ctx, eltype, &junk);
     690         [ +  - ]:     666264 :                 cnt = elsize ? len/elsize : 0;
     691                 :            :             }
     692         [ +  - ]:     666264 :             if (eltype == fl_ctx->bytesym) {
     693         [ +  - ]:     666264 :                 if (fl_ctx->print_princ) {
     694                 :     666264 :                     ios_write(f, (char*)data, len);
     695                 :            :                     /*
     696                 :            :                     char *nl = memrchr(data, '\n', len);
     697                 :            :                     if (nl)
     698                 :            :                         fl_ctx->HPOS = u8_strwidth(nl+1);
     699                 :            :                     else
     700                 :            :                         fl_ctx->HPOS += u8_strwidth(data);
     701                 :            :                     */
     702                 :            :                 }
     703                 :            :                 else {
     704                 :          0 :                     print_string(fl_ctx, f, (char*)data, len);
     705                 :            :                 }
     706                 :     666264 :                 return;
     707                 :            :             }
     708                 :          0 :             else if (eltype == fl_ctx->wcharsym) {
     709                 :            :                 // TODO wchar
     710                 :            :             }
     711                 :            :             else {
     712                 :            :             }
     713                 :            :             size_t i;
     714         [ #  # ]:          0 :             if (!weak) {
     715         [ #  # ]:          0 :                 if (eltype == fl_ctx->uint8sym) {
     716                 :          0 :                     outsn(fl_ctx, "#vu8(", f, 5);
     717                 :            :                 }
     718                 :            :                 else {
     719                 :          0 :                     outsn(fl_ctx, "#array(", f, 7);
     720                 :          0 :                     fl_print_child(fl_ctx, f, eltype);
     721         [ #  # ]:          0 :                     if (cnt > 0)
     722                 :          0 :                         outc(fl_ctx, ' ', f);
     723                 :            :                 }
     724                 :            :             }
     725                 :            :             else {
     726                 :          0 :                 outc(fl_ctx, '[', f);
     727                 :            :             }
     728         [ #  # ]:          0 :             for(i=0; i < cnt; i++) {
     729         [ #  # ]:          0 :                 if (i > 0)
     730                 :          0 :                     outc(fl_ctx, ' ', f);
     731                 :          0 :                 cvalue_printdata(fl_ctx, f, data, elsize, eltype, 1);
     732                 :          0 :                 data = (char *)data + elsize;
     733                 :            :             }
     734         [ #  # ]:          0 :             if (!weak)
     735                 :          0 :                 outc(fl_ctx, ')', f);
     736                 :            :             else
     737                 :          0 :                 outc(fl_ctx, ']', f);
     738                 :            :         }
     739                 :            :     }
     740                 :            : }
     741                 :            : 
     742                 :    2250260 : static void cvalue_print(fl_context_t *fl_ctx, ios_t *f, value_t v)
     743                 :            : {
     744                 :    2250260 :     cvalue_t *cv = (cvalue_t*)ptr(v);
     745         [ +  + ]:    2250260 :     void *data = cptr(v);
     746                 :            :     value_t label;
     747                 :            : 
     748         [ -  + ]:    2250260 :     if (cv_class(cv) == fl_ctx->builtintype) {
     749                 :          0 :         void *fptr = *(void**)data;
     750                 :          0 :         label = (value_t)ptrhash_get(&fl_ctx->reverse_dlsym_lookup_table, cv);
     751         [ #  # ]:          0 :         if (label == (value_t)HT_NOTFOUND) {
     752                 :          0 :             fl_ctx->HPOS += ios_printf(f, "#<builtin @0x%08zx>", (size_t)fptr);
     753                 :            :         }
     754                 :            :         else {
     755         [ #  # ]:          0 :             if (fl_ctx->print_princ) {
     756                 :          0 :                 outs(fl_ctx, symbol_name(fl_ctx, label), f);
     757                 :            :             }
     758                 :            :             else {
     759                 :          0 :                 outsn(fl_ctx, "#fn(", f, 4);
     760                 :          0 :                 outs(fl_ctx, symbol_name(fl_ctx, label), f);
     761                 :          0 :                 outc(fl_ctx, ')', f);
     762                 :            :             }
     763                 :            :         }
     764                 :            :     }
     765         [ -  + ]:    2250260 :     else if (cv_class(cv)->vtable != NULL &&
     766         [ #  # ]:          0 :              cv_class(cv)->vtable->print != NULL) {
     767                 :          0 :         cv_class(cv)->vtable->print(fl_ctx, v, f);
     768                 :            :     }
     769                 :            :     else {
     770                 :    2250260 :         value_t type = cv_type(cv);
     771         [ +  + ]:    2250260 :         size_t len = iscprim(v) ? cv_class(cv)->size : cv_len(cv);
     772                 :    2250260 :         cvalue_printdata(fl_ctx, f, data, len, type, 0);
     773                 :            :     }
     774                 :    2250260 : }
     775                 :            : 
     776                 :     115360 : static void set_print_width(fl_context_t *fl_ctx)
     777                 :            : {
     778                 :     115360 :     value_t pw = symbol_value(fl_ctx->printwidthsym);
     779         [ -  + ]:     115360 :     if (!isfixnum(pw)) return;
     780                 :     115360 :     fl_ctx->SCR_WIDTH = numval(pw);
     781                 :            : }
     782                 :            : 
     783                 :    2436000 : void fl_print(fl_context_t *fl_ctx, ios_t *f, value_t v)
     784                 :            : {
     785                 :    2436000 :     fl_ctx->print_pretty = (symbol_value(fl_ctx->printprettysym) != fl_ctx->F);
     786         [ +  + ]:    2436000 :     if (fl_ctx->print_pretty)
     787                 :     115360 :         set_print_width(fl_ctx);
     788                 :    2436000 :     fl_ctx->print_princ = (symbol_value(fl_ctx->printreadablysym) == fl_ctx->F);
     789                 :            : 
     790                 :    2436000 :     value_t pl = symbol_value(fl_ctx->printlengthsym);
     791         [ -  + ]:    2436000 :     if (isfixnum(pl)) fl_ctx->print_length = numval(pl);
     792                 :    2436000 :     else fl_ctx->print_length = -1;
     793                 :    2436000 :     pl = symbol_value(fl_ctx->printlevelsym);
     794         [ -  + ]:    2436000 :     if (isfixnum(pl)) fl_ctx->print_level = numval(pl);
     795                 :    2436000 :     else fl_ctx->print_level = -1;
     796                 :    2436000 :     fl_ctx->P_LEVEL = 0;
     797                 :            : 
     798                 :    2436000 :     fl_ctx->printlabel = 0;
     799                 :    2436000 :     print_traverse(fl_ctx, v);
     800                 :    2436000 :     fl_ctx->HPOS = fl_ctx->VPOS = 0;
     801                 :            : 
     802                 :    2436000 :     fl_print_child(fl_ctx, f, v);
     803                 :            : 
     804   [ +  -  -  + ]:    2436000 :     if (fl_ctx->print_level >= 0 || fl_ctx->print_length >= 0) {
     805                 :          0 :         memset(fl_ctx->consflags, 0, 4*bitvector_nwords(fl_ctx->heapsize/sizeof(cons_t)));
     806                 :            :     }
     807                 :            : 
     808   [ +  +  +  -  :    3102340 :     if ((iscons(v) || isvector(v) || isfunction(v) || iscvalue(v)) &&
          -  +  -  -  +  
                +  +  + ]
     809   [ +  -  +  -  :     666408 :         !fl_isstring(fl_ctx, v) && v!=fl_ctx->T && v!=fl_ctx->F && v!=fl_ctx->NIL) {
                   +  - ]
     810                 :         72 :         htable_reset(&fl_ctx->printconses, 32);
     811                 :            :     }
     812                 :    2436000 : }
     813                 :            : 
     814                 :         30 : void fl_print_init(fl_context_t *fl_ctx)
     815                 :            : {
     816                 :         30 :     htable_new(&fl_ctx->printconses, 32);
     817                 :         30 :     fl_ctx->SCR_WIDTH = 80;
     818                 :         30 :     fl_ctx->HPOS = 0;
     819                 :         30 : }

Generated by: LCOV version 1.14