Skip to content

Commit f1c4d0f

Browse files
committed
improve line wrapping
1 parent d2f1b63 commit f1c4d0f

4 files changed

Lines changed: 76 additions & 118 deletions

File tree

src/exppp/exppp.c

Lines changed: 67 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,14 @@ int count_newlines( char * s ) {
9292
return count;
9393
}
9494

95+
/** true if last char through exp_output was a space */
96+
static bool printedSpaceLast = false;
97+
9598
void exp_output( char * buf, int len ) {
9699
FILE * fp = ( exppp_fp ? exppp_fp : stdout );
97100

98101
error_sym.line += count_newlines( buf );
99-
102+
printedSpaceLast = ( *( buf + len - 1) == ' ' );
100103
if( exppp_buf ) {
101104
/* output to string */
102105
if( len > exppp_buflen ) {
@@ -114,8 +117,8 @@ void exp_output( char * buf, int len ) {
114117
}
115118

116119
void wrap( const char * fmt, ... ) {
117-
char * p;
118120
char buf[10000];
121+
char * p, * start = buf;
119122
int len;
120123
va_list args;
121124

@@ -125,6 +128,12 @@ void wrap( const char * fmt, ... ) {
125128

126129
len = strlen( buf );
127130

131+
/* eliminate leading whitespace */
132+
while( ( *start == ' ' ) && ( ( printedSpaceLast ) || ( *( start + 1 ) == ' ' ) ) ){
133+
start++;
134+
len--;
135+
}
136+
128137
/* 1st condition checks if string cant fit into current line */
129138
/* 2nd condition checks if string cant fit into any line */
130139
/* I.e., if we still can't fit after indenting, don't bother to */
@@ -139,14 +148,14 @@ void wrap( const char * fmt, ... ) {
139148
curpos = indent2; /* reset current position */
140149
}
141150

142-
exp_output( buf, len );
151+
exp_output( start, len );
143152

144153
if( len ) {
145154
/* reset cur position based on last newline seen */
146-
if( 0 == ( p = strrchr( buf, '\n' ) ) ) {
155+
if( 0 == ( p = strrchr( start, '\n' ) ) ) {
147156
curpos += len;
148157
} else {
149-
curpos = len + buf - p;
158+
curpos = len + start - p;
150159
}
151160
}
152161
}
@@ -322,111 +331,73 @@ const char * real2exp( double r ) {
322331
#undef PP_SMALL_BUF_SZ
323332
}
324333

325-
/** write delimiter, newline, indent spaces, '+', and delimiter to str
326-
* \param str pointer to pointer to char
327-
* \param indent number of spaces for indentation
328-
* \param first true if first call - skips delimiter before newline
329-
* \return count of chars added to str
330-
*
331-
* *str is assumed to have enough space
332-
*
333-
* Will not work with encoded strings
334+
/** Find next '.' in null-terminated string, return number of chars
335+
* If no '.' found, returns length of string
334336
*/
335-
unsigned int insertStrBrk( char * * const str, unsigned int indent, bool first ) {
336-
unsigned int i = 0;
337-
if( !first ) {
338-
**str = '\'';
339-
( *str )++;
337+
int nextBreakpoint( const char * pos, const char * end ) {
338+
int i = 0;
339+
while( ( *pos != '.' ) && ( *pos != '\0' ) && ( pos < end ) ) {
340+
i++;
341+
pos++;
340342
}
341-
** str = '\n';
342-
( *str )++;
343-
while( i < indent ) {
344-
**str = ' ';
345-
( *str )++;
343+
if( *pos == '.' ) {
346344
i++;
347345
}
348-
if( !first ) {
349-
**str = '+';
350-
( *str )++;
351-
** str = ' ';
352-
( *str )++;
346+
return i;
347+
}
348+
349+
/** true if it makes sense to break before printing next part of the string */
350+
bool shouldBreak( int len ) {
351+
if( ( curpos > indent2 ) &&
352+
( ( curpos + len ) > exppp_linelength ) ) {
353+
return true;
354+
}
355+
return false;
356+
}
357+
358+
/** Insert newline if it makes sense. */
359+
void maybeBreak( int len, bool first ) {
360+
if( shouldBreak( len ) ) {
361+
if( first ) {
362+
raw( "\n%*s'", indent2, "" );
363+
} else {
364+
raw( "'\n%*s+ '", indent2, "" );
365+
}
366+
} else if( first ) {
367+
/* staying on same line */
368+
raw( "%s", ( printedSpaceLast ? "'": " '" ) );
353369
}
354-
** str = '\'';
355-
( *str )++;
356-
return 2 + indent + ( first ? 3 : 0 ); /* 2 for \n' , +3 if first */
357370
}
358371

359372
/** Break a long un-encoded string up for output and enclose in ''
360-
* if it is too long, error
361-
* if too short, enclose in '' but don't insert line breaks
373+
* if short, enclose in '' but don't insert line breaks
362374
* \param in the input string
363375
*
364-
* use globals indent2 and curpos
376+
* side effects: output via raw()
377+
* reads globals indent2 and curpos
365378
*/
366-
const char * breakLongStr( const char * in ) {
367-
const unsigned int minbreak = 50; /* if line is longer than this, try to break it */
368-
static char buf[8192] = { 0 }, * optr;
369-
const char * iptr = in;
370-
371-
/* error message to print when we can't return `in` because it is too long and needs wrapped in '' */
372-
const char * errmsg = "ERROR: Cannot break long string of len %d:\n%s\n";
373-
374-
unsigned int inlen = strlen( in ), linelen = 0;
375-
376-
/* used to ensure that we don't overflow the buffer */
377-
int extrachars = 8191 - inlen;
378-
optr = buf;
379-
380-
if( inlen < minbreak ) {
381-
*optr = '\'';
382-
optr++;
383-
strcpy( optr, in );
384-
optr += inlen;
385-
*optr = '\'';
386-
optr++;
387-
*optr = '\0';
388-
return buf;
389-
}
390-
if( inlen > 8000 ) {
391-
/* 8000 gives us 191 extra chars for '\n + ' */
392-
fprintf( stderr, errmsg, inlen, in );
393-
abort();
394-
}
395-
if( indent2 < curpos ) {
396-
/* start with a newline, indent, and delimiter */
397-
extrachars -= insertStrBrk( &optr, indent2, true );
398-
if( extrachars <= ( int ) indent2 + 7 ) {
399-
fprintf( stderr, errmsg, inlen, in );
400-
abort();
401-
}
402-
} else {
403-
*optr = ' ';
404-
optr++;
405-
*optr = '\'';
406-
optr++;
379+
void breakLongStr( const char * in ) {
380+
const char * iptr = in, * end;
381+
unsigned int inlen = strlen( in );
382+
bool first = true;
383+
/* used to ensure that we don't overrun the input buffer */
384+
end = in + inlen;
385+
386+
if( ( ( int ) inlen + curpos ) < exppp_linelength ) {
387+
/* short enough to fit on current line */
388+
raw( "%s%s'", ( printedSpaceLast ? "'": " '" ), in );
389+
return;
407390
}
408391

409-
/* copy */
410-
while( *iptr ) {
411-
*optr = *iptr;
412-
optr++;
413-
iptr++;
414-
linelen++;
415-
/* look for '.' to break after, as long as there is something after it and the line is reasonably long */
416-
if( ( *( iptr - 1 ) == '.' ) && ( *iptr != '\0' ) && ( linelen >= minbreak ) ) {
417-
extrachars -= insertStrBrk( &optr, indent2, false );
418-
if( extrachars <= ( int ) indent2 + 7 ) {
419-
fprintf( stderr, errmsg, inlen, in );
420-
abort();
421-
}
422-
linelen = 0;
423-
}
392+
/* insert newlines at dots as necessary */
393+
while( ( iptr < end ) && ( *iptr ) ) {
394+
int i = nextBreakpoint( iptr, end );
395+
maybeBreak( i, first );
396+
first = false;
397+
raw( "%.*s", i, iptr );
398+
iptr += i;
424399
}
425-
*optr = '\'';
426-
optr++;
427-
*optr = '\0';
428-
optr++;
429-
return buf;
400+
raw( "' ");
430401
}
431402

432403
/* Interfacing Definitions */

src/exppp/pp.h

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,27 +39,14 @@ void wrap( const char * fmt, ... );
3939
*/
4040
const char * real2exp( double r );
4141

42-
/** write delimiter, newline, indent spaces, '+', and delimiter to str
43-
* \param str pointer to pointer to char
44-
* \param indent number of spaces for indentation
45-
* \param first true if first call - skips delimiter before newline
46-
* \return count of chars added to str
47-
*
48-
* *str is assumed to have enough space
49-
*
50-
* Will not work with encoded strings
51-
*/
52-
unsigned int insertStrBrk( char * * const str, unsigned int indent, bool first );
53-
54-
/** Break a long un-encoded string up for output and enclose in ''
55-
* if it is too long, error
56-
* if too short, enclose in '' but don't insert line breaks
42+
/** Break a long un-encoded string up, enclose in '', output via raw()
43+
* if short, don't insert line breaks
5744
* \param in the input string
5845
*
59-
* use globals indent2 and curpos
60-
* TODO: update curpos before returning
46+
* side effects: output via raw()
47+
* reads globals indent2 and curpos
6148
*/
62-
const char * breakLongStr( const char * in );
49+
void breakLongStr( const char * in );
6350

6451
int finish_buffer();
6552
int minimum( int a, int b, int c );

src/exppp/pretty_expr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void EXPR__out( Expression e, int paren, unsigned int previous_op ) {
7373
if( TYPEis_encoded( e->type ) ) {
7474
wrap( "\"%s\"", e->symbol.name );
7575
} else {
76-
wrap( "%s", breakLongStr( e->symbol.name ) );
76+
breakLongStr( e->symbol.name );
7777
}
7878
break;
7979
case entity_:
@@ -300,7 +300,7 @@ void EXPRstring( char * buffer, Expression e ) {
300300
if( TYPEis_encoded( e->type ) ) {
301301
sprintf( buffer, "\"%s\"", e->symbol.name );
302302
} else {
303-
sprintf( buffer, "%s", breakLongStr( e->symbol.name ) );
303+
sprintf( buffer, "%s", e->symbol.name );
304304
}
305305
break;
306306
case entity_:

src/exppp/pretty_scope.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#ifndef PRETTY_SCOPE_H
22
#define PRETTY_SCOPE_H
33

4-
#include "../express/linklist.h"
5-
#include "../express/scope.h"
4+
#include <express/linklist.h>
5+
#include <express/scope.h>
66

77
#include "pp.h"
88

0 commit comments

Comments
 (0)