@@ -17,13 +17,32 @@ static void usage( void)
1717 exit ( 0 );
1818}
1919
20- static inline size_t _calc_emit_buf_size ( size_t prefix_length ,
21- size_t text_length )
20+ static inline size_t calc_emit_buf_size ( size_t prefix_length ,
21+ size_t text_length )
2222{
2323 // "prefix" '"' <characters> '"' '\n' '\0'
2424 return ( prefix_length + 1 + text_length + 1 + 1 + 1 );
2525}
2626
27+
28+ static size_t tabs_extra ( char * s , size_t tab_size )
29+ {
30+ size_t n ;
31+ size_t extra ;
32+ int c ;
33+
34+ if ( ! tab_size )
35+ return ( 0 );
36+
37+ extra = tab_size - 1 ;
38+ n = 0 ;
39+ while ( c = * s ++ )
40+ n += (c == '\t' ) ? extra : 0 ;
41+
42+ return ( n );
43+ }
44+
45+
2746struct emit
2847{
2948 FILE * fp ;
@@ -39,6 +58,9 @@ struct emit
3958};
4059
4160
61+ static char warning_prefix [] = "mulle-c-string-escape warning" ;
62+
63+
4264static void emit_init ( struct emit * e ,
4365 char * prefix ,
4466 unsigned int line_length ,
@@ -47,35 +69,53 @@ static void emit_init( struct emit *e,
4769{
4870 size_t prefix_length ;
4971 size_t text_length ;
72+ size_t visible_cut ;
5073
5174 memset ( e , 0 , sizeof ( * e ));
5275
5376 if ( ! line_length )
5477 line_length = 80 ;
5578
5679 if ( line_length <= 3 )
57- usage ();
80+ {
81+ fprintf ( stderr , "%s : line length too small\n" , warning_prefix );
82+ line_length = 80 ;
83+ }
5884
5985 text_length = line_length - 3 ;
6086
6187 // todo: should parse prefix for tab charactes and adjust length
6288 if ( ! prefix )
6389 {
64- if ( text_length <= e -> tab_size )
65- usage ();
66- text_length -= e -> tab_size ; // 8 i
67- prefix = "\t" ;
90+ if ( text_length <= tab_size )
91+ {
92+ fprintf ( stderr , "%s : tab size too large\n" , warning_prefix );
93+ tab_size = 0 ;
94+ prefix = "" ;
95+ }
96+ else
97+ {
98+ text_length -= tab_size ; // 8 i
99+ prefix = "\t" ;
100+ }
68101 prefix_length = 1 ;
69102 }
70103 else
71104 {
72105 prefix_length = strlen ( prefix );
73- if ( text_length <= prefix_length )
74- usage ();
75- text_length -= prefix_length ;
106+ if ( text_length > prefix_length )
107+ text_length -= prefix_length ;
108+ else
109+ fprintf ( stderr , "%s : prefix is too large to fit\n" , warning_prefix );
110+
111+ visible_cut = tabs_extra ( prefix , tab_size );
112+ if ( visible_cut < text_length )
113+ text_length -= visible_cut ;
114+ else
115+ fprintf ( stderr , "%s : tabs take up too much room\n" , warning_prefix );
76116 }
77117
78- e -> buf = malloc ( _calc_emit_buf_size ( prefix_length , text_length ));
118+ e -> buf = malloc ( calc_emit_buf_size ( prefix_length , text_length ));
79119 if ( ! e -> buf )
80120 abort ();
81121
@@ -108,13 +148,10 @@ static inline void emit_set_flush_on_lf( struct emit *e, int flush_on_lf)
108148
109149static void emit_done ( struct emit * e )
110150{
111- if ( e )
112- {
113- free ( e -> buf );
114- fflush ( e -> fp );
115- if ( e -> fp != stdout )
116- fclose ( e -> fp );
117- }
151+ free ( e -> buf );
152+ fflush ( e -> fp );
153+ if ( e -> fp != stdout )
154+ fclose ( e -> fp );
118155}
119156
120157
@@ -357,26 +394,25 @@ int main( int argc, char *argv[])
357394 if ( i != argc )
358395 usage ();
359396
360- c = getc_unlocked ( fin );
361- if ( c == EOF )
362- return ( 0 );
363-
364397 emit_init ( & e , prefix , line_length , tab_size , fout );
365398 emit_set_escape_tab ( & e , escape_tab );
366399 emit_set_flush_on_lf ( & e , flush_on_lf );
367400
368- // need a look ahead (d)
369- do
401+ c = getc_unlocked ( fin );
402+ if ( c != EOF )
370403 {
371- d = getc_unlocked ( fin );
372- emit_char_escape_if_needed ( & e , c , d );
373- c = d ;
404+ // need a look ahead (d)
405+ do
406+ {
407+ d = getc_unlocked ( fin );
408+ emit_char_escape_if_needed ( & e , c , d );
409+ c = d ;
410+ }
411+ while ( c != EOF );
412+
413+ if ( emit_length ( & e ))
414+ emit_flush ( & e );
374415 }
375- while ( c != EOF );
376-
377- if ( emit_length ( & e ))
378- emit_flush ( & e );
379-
380416 emit_done ( & e );
381417
382418 return ( 0 );
0 commit comments