LCOV - code coverage report
Current view: top level - io/source/txt - txt_writer.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.42.0_alltests Lines: 41 77 53.2 %
Date: 2022-10-01 11:23:42 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /* File: txt_writer.c; Copyright and License: see below */
       2             : 
       3             : #include "txt/txt_writer.h"
       4             : #include "trace/trace.h"
       5             : #include "tslog/tslog.h"
       6             : #include <stdio.h>
       7             : #include <stdbool.h>
       8             : #include <assert.h>
       9             : 
      10             : enum txt_writer_indent_enum {
      11             :     TXT_WRITER_INDENT_COLUMN = 48,  /*!< the text column in which the id starts */
      12             : };
      13             : 
      14             : static const char TXT_ID_INDENT_SPACES[TXT_WRITER_INDENT_COLUMN+1] = "                                                ";
      15             : static const char TXT_NEWLINE[] = "\n";
      16             : 
      17          14 : void txt_writer_init ( txt_writer_t *this_,
      18             :                        universal_output_stream_t *output )
      19             : {
      20          14 :     TRACE_BEGIN();
      21          14 :     assert( NULL != output );
      22             : 
      23          14 :     (*this_).output = output;
      24             : 
      25          14 :     TRACE_END();
      26          14 : }
      27             : 
      28          14 : void txt_writer_destroy( txt_writer_t *this_ )
      29             : {
      30          14 :     TRACE_BEGIN();
      31             : 
      32          14 :     (*this_).output = NULL;
      33             : 
      34          14 :     TRACE_END();
      35          14 : }
      36             : 
      37          14 : int txt_writer_write_indent_multiline_string ( txt_writer_t *this_,
      38             :                                                const char *indent,
      39             :                                                const char *multiline_string )
      40             : {
      41          14 :     TRACE_BEGIN();
      42          14 :     assert( NULL != indent );
      43          14 :     assert( NULL != (*this_).output );
      44          14 :     int result = 0;
      45          14 :     const size_t indent_length = strlen( indent );
      46             : 
      47          14 :     if ( NULL != multiline_string )
      48             :     {
      49          12 :         const char *line_start = multiline_string;
      50          12 :         size_t line_length = 0;
      51          12 :         bool ignore_newline = false;  /* newlines after returns are ignored */
      52             : 
      53          12 :         size_t length = strlen( multiline_string );
      54          76 :         for ( size_t index = 0; index < length; index ++ )
      55             :         {
      56          64 :             bool end_of_line = false;
      57             : 
      58          64 :             char current = multiline_string[index];
      59          64 :             if ( '\r' == current )
      60             :             {
      61             :                 ignore_newline = true;
      62             :                 end_of_line = true;
      63             :             }
      64          56 :             else if ( '\n' == current )
      65             :             {
      66           8 :                 if ( ignore_newline )
      67             :                 {
      68           4 :                     line_start = &(multiline_string[index+1]);
      69             :                 }
      70             :                 else
      71             :                 {
      72             :                     end_of_line = true;
      73             :                 }
      74             :                 ignore_newline = false;
      75             :             }
      76             :             else
      77             :             {
      78          48 :                 ignore_newline = false;
      79          48 :                 line_length ++;
      80          48 :                 if ( index+1 == length )
      81             :                 {
      82           4 :                     end_of_line = true;
      83             :                 }
      84             :             }
      85             : 
      86          64 :             if ( end_of_line )
      87             :             {
      88             :                 /* print indent pattern */
      89          16 :                 result |= universal_output_stream_write ( (*this_).output, indent, indent_length );
      90             : 
      91             :                 /* print next line */
      92          16 :                 result |= universal_output_stream_write ( (*this_).output, line_start, line_length );
      93             : 
      94             :                 /* print newline */
      95          16 :                 result |= universal_output_stream_write ( (*this_).output, TXT_NEWLINE, strlen(TXT_NEWLINE) );
      96             : 
      97             :                 /* reset line indices */
      98          16 :                 line_start = &(multiline_string[index+1]);
      99          16 :                 line_length = 0;
     100             :             }
     101             :         }
     102             :     }
     103             : 
     104          14 :     TRACE_END_ERR( result );
     105          14 :     return result;
     106             : }
     107             : 
     108           0 : int txt_writer_write_indent_id ( txt_writer_t *this_,
     109             :                                  int indent_width,
     110             :                                  data_id_t id )
     111             : {
     112           0 :     TRACE_BEGIN();
     113           0 :     assert( DATA_TABLE_VOID != data_id_get_table(&id) );
     114           0 :     assert( DATA_ROW_ID_VOID != data_id_get_row_id(&id) );
     115           0 :     assert( NULL != (*this_).output );
     116           0 :     assert( sizeof(TXT_ID_INDENT_SPACES) == 1+TXT_WRITER_INDENT_COLUMN );
     117           0 :     int result = 0;
     118             : 
     119             :     /* indent */
     120           0 :     if ( indent_width > TXT_WRITER_INDENT_COLUMN )
     121             :     {
     122           0 :         TSLOG_ERROR_INT( "more spaces requested than available. missing:", indent_width - TXT_WRITER_INDENT_COLUMN );
     123           0 :         indent_width = TXT_WRITER_INDENT_COLUMN;
     124             :     }
     125           0 :     if ( indent_width > 0 )
     126             :     {
     127           0 :         result |= universal_output_stream_write( (*this_).output, &TXT_ID_INDENT_SPACES, indent_width );
     128             :     }
     129             : 
     130             :     /* print id */
     131             :     {
     132           0 :         char id_buf[DATA_ID_MAX_UTF8STRING_SIZE+2];
     133           0 :         utf8stringbuf_t id_str = UTF8STRINGBUF( id_buf );
     134           0 :         utf8stringbuf_clear( id_str );
     135           0 :         utf8stringbuf_append_str( id_str, " [" );
     136           0 :         data_id_to_utf8stringbuf( &id, id_str );
     137           0 :         utf8stringbuf_append_str( id_str, "]" );
     138             : 
     139           0 :         const unsigned int len = utf8stringbuf_get_length(id_str);
     140           0 :         result |= universal_output_stream_write( (*this_).output, utf8stringbuf_get_string(id_str), len );
     141             :     }
     142             : 
     143           0 :     TRACE_END_ERR( result );
     144           0 :     return result;
     145             : }
     146             : 
     147           0 : int txt_writer_write_plain_id ( txt_writer_t *this_, data_id_t id )
     148             : {
     149           0 :     TRACE_BEGIN();
     150           0 :     assert( DATA_TABLE_VOID != data_id_get_table(&id) );
     151           0 :     assert( DATA_ROW_ID_VOID != data_id_get_row_id(&id) );
     152           0 :     assert( NULL != (*this_).output );
     153           0 :     int result = 0;
     154             : 
     155             :     /* print id */
     156             :     {
     157           0 :         char id_buf[DATA_ID_MAX_UTF8STRING_SIZE];
     158           0 :         utf8stringbuf_t id_str = UTF8STRINGBUF( id_buf );
     159           0 :         utf8stringbuf_clear( id_str );
     160           0 :         data_id_to_utf8stringbuf( &id, id_str );
     161             : 
     162           0 :         const unsigned int len = utf8stringbuf_get_length(id_str);
     163           0 :         result |= universal_output_stream_write ( (*this_).output, utf8stringbuf_get_string(id_str), len );
     164             :     }
     165             : 
     166           0 :     TRACE_END_ERR( result );
     167           0 :     return result;
     168             : }
     169             : 
     170             : 
     171             : /*
     172             : Copyright 2017-2022 Andreas Warnke
     173             : 
     174             : Licensed under the Apache License, Version 2.0 (the "License");
     175             : you may not use this file except in compliance with the License.
     176             : You may obtain a copy of the License at
     177             : 
     178             :     http://www.apache.org/licenses/LICENSE-2.0
     179             : 
     180             : Unless required by applicable law or agreed to in writing, software
     181             : distributed under the License is distributed on an "AS IS" BASIS,
     182             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     183             : See the License for the specific language governing permissions and
     184             : limitations under the License.
     185             : */

Generated by: LCOV version 1.14