Fossil SCM

Complete re-write of the comment printing algorithm, taking the preservation of any pre-existing formatting within the comment into account. No attempt is made to avoid breaking a line in the middle of a word.

mistachkin 2014-06-19 21:25 experimental
Commit 89aa595f8828b70c092a699195bbd008414b92de
1 file changed +96 -49
+96 -49
--- src/comformat.c
+++ src/comformat.c
@@ -34,99 +34,146 @@
3434
*/
3535
#ifndef COMMENT_LEGACY_LINE_LENGTH
3636
# define COMMENT_LEGACY_LINE_LENGTH (78)
3737
#endif
3838
39
+/*
40
+** This is the number of spaces to print when a tab character is seen.
41
+*/
42
+#ifndef COMMENT_TAB_WIDTH
43
+# define COMMENT_TAB_WIDTH (8)
44
+#endif
45
+
3946
/*
4047
** Given a comment string zText, format that string for printing
4148
** on a TTY. Assume that the output cursors is indent spaces from
4249
** the left margin and that a single line can contain no more than
43
-** lineLength characters. Indent all subsequent lines by indent.
50
+** width characters. Indent all subsequent lines by indent.
4451
**
4552
** Return the number of newlines that are output.
4653
*/
47
-int comment_print(const char *zText, int indent, int lineLength){
48
- int tlen = lineLength - indent;
49
- int len = 0, doIndent = 0, lineCnt = 0;
54
+int comment_print(const char *zText, int indent, int width){
55
+ int maxChars = width - indent;
56
+ int lineCnt = 0;
5057
const char *zLine;
5158
5259
#if defined(_WIN32)
53
- if( lineLength<0 ){
60
+ if( width<0 ){
5461
CONSOLE_SCREEN_BUFFER_INFO csbi;
5562
memset(&csbi, 0, sizeof(CONSOLE_SCREEN_BUFFER_INFO));
5663
if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) ){
57
- tlen = csbi.srWindow.Right - csbi.srWindow.Left - indent;
64
+ maxChars = csbi.srWindow.Right - csbi.srWindow.Left - indent;
5865
}
5966
}
6067
#elif defined(TIOCGWINSZ)
61
- if( lineLength<0 ){
68
+ if( width<0 ){
6269
struct winsize w;
6370
memset(&w, 0, sizeof(struct winsize));
6471
if( ioctl(0, TIOCGWINSZ, &w)!=-1 ){
65
- tlen = w.ws_col - indent;
72
+ maxChars = w.ws_col - indent;
6673
}
6774
}
6875
#else
69
- if( lineLength<0 ){
76
+ if( width<0 ){
7077
/*
7178
** Fallback to using more-or-less the "legacy semantics" of hard-coding
7279
** the maximum line length to a value reasonable for the vast majority
7380
** of supported systems.
7481
*/
75
- tlen = COMMENT_LEGACY_LINE_LENGTH - indent;
82
+ maxChars = COMMENT_LEGACY_LINE_LENGTH - indent;
7683
}
7784
#endif
7885
if( zText==0 ) zText = "(NULL)";
79
- if( tlen<=0 ){
80
- tlen = strlen(zText);
86
+ if( maxChars<=0 ){
87
+ maxChars = strlen(zText);
8188
}
8289
while( fossil_isspace(zText[0]) ){ zText++; }
8390
if( zText[0]==0 ){
84
- if( !doIndent ){
85
- fossil_print("\n");
86
- lineCnt++;
87
- }
91
+ fossil_print("\n");
92
+ lineCnt++;
8893
return lineCnt;
8994
}
9095
zLine = zText;
9196
for(;;){
92
- if( zText[0]==0 ){
93
- if( doIndent ){
94
- fossil_print("%*s", indent, "");
95
- }
96
- fossil_print("%.*s", (int)(zText - zLine), zLine);
97
- if( fossil_force_newline() ){
98
- lineCnt++;
99
- }
100
- break;
101
- }
102
- len += ((zText[0]=='\t') ? 8 : 1);
103
- if( zText[0]=='\n' || len>=tlen ){
104
- const char *zNewLine;
105
- if( doIndent ){
106
- fossil_print("%*s", indent, "");
107
- }
108
- doIndent = 1;
109
- zNewLine = zText + 1;
110
- while( zText>zLine && !fossil_isspace(zText[0]) ){ zText--; }
111
- if( zText>zLine ){
112
- fossil_print("%.*s", (int)(zText - zLine), zLine);
113
- zLine = zText;
114
- }else{
115
- fossil_print("%.*s", (int)(zNewLine - zLine), zLine);
116
- zLine = zNewLine;
117
- }
118
- if( fossil_force_newline() ){
119
- lineCnt++;
120
- }
121
- if( !zLine++ ) break;
122
- len = 0;
123
- }
124
- zText++;
97
+ comment_print_line(zLine, zLine>zText ? indent : 0,
98
+ maxChars, &lineCnt, &zLine);
99
+ if( !zLine || !zLine[0] ) break;
125100
}
126101
return lineCnt;
127102
}
103
+
104
+/*
105
+** This function prints one logical line of a comment, stopping when it hits
106
+** a new line -OR- runs out of space on the logical line.
107
+*/
108
+void comment_print_line(
109
+ const char *zLine, /* [in] The comment line to print. */
110
+ int indent, /* [in] Number of spaces to indent, zero for none. */
111
+ int lineChars, /* [in] Maximum number of characters to print. */
112
+ int *pLineCnt, /* [in/out] Pointer to the total line count. */
113
+ const char **pzLine /* [out] Pointer to the end of the logical line. */
114
+){
115
+ int index = 0, charCnt = 0, lineCnt = 0, maxChars;
116
+ if( !zLine ) return;
117
+ if( lineChars<=0 ) return;
118
+ comment_print_indent(zLine, indent, &index);
119
+ maxChars = lineChars;
120
+ for(;;){
121
+ char c = zLine[index];
122
+ if( c==0 ){
123
+ break;
124
+ }else{
125
+ index++;
126
+ }
127
+ if( c=='\n' ){
128
+ charCnt = 0;
129
+ lineCnt++;
130
+ }else if( c=='\t' ){
131
+ charCnt++;
132
+ if( maxChars<COMMENT_TAB_WIDTH ){
133
+ fossil_print(" ");
134
+ break;
135
+ }
136
+ maxChars -= COMMENT_TAB_WIDTH;
137
+ }else{
138
+ charCnt++;
139
+ maxChars--;
140
+ }
141
+ fossil_print("%c", c);
142
+ if( maxChars==0 ) break;
143
+ if( c=='\n' ) break;
144
+ }
145
+ if( charCnt>0 || lineCnt==0 ){
146
+ fossil_print("\n");
147
+ lineCnt++;
148
+ }
149
+ if( pLineCnt ){
150
+ *pLineCnt += lineCnt;
151
+ }
152
+ if( pzLine ){
153
+ *pzLine = zLine + index;
154
+ }
155
+}
156
+
157
+/*
158
+** This function is called when printing a logical comment line to perform
159
+** the necessary indenting.
160
+*/
161
+void comment_print_indent(
162
+ const char *zLine, /* [in] The comment line being printed. */
163
+ int indent, /* [in] Number of spaces to indent, zero for none. */
164
+ int *piIndex /* [in/out] Pointer to first non-space character. */
165
+){
166
+ if( indent>0 ){
167
+ fossil_print("%*s", indent, "");
168
+ if( zLine && piIndex ){
169
+ int index = *piIndex;
170
+ while( fossil_isspace(zLine[index]) ){ index++; }
171
+ *piIndex = index;
172
+ }
173
+ }
174
+}
128175
129176
/*
130177
**
131178
** COMMAND: test-comment-format
132179
**
133180
--- src/comformat.c
+++ src/comformat.c
@@ -34,99 +34,146 @@
34 */
35 #ifndef COMMENT_LEGACY_LINE_LENGTH
36 # define COMMENT_LEGACY_LINE_LENGTH (78)
37 #endif
38
 
 
 
 
 
 
 
39 /*
40 ** Given a comment string zText, format that string for printing
41 ** on a TTY. Assume that the output cursors is indent spaces from
42 ** the left margin and that a single line can contain no more than
43 ** lineLength characters. Indent all subsequent lines by indent.
44 **
45 ** Return the number of newlines that are output.
46 */
47 int comment_print(const char *zText, int indent, int lineLength){
48 int tlen = lineLength - indent;
49 int len = 0, doIndent = 0, lineCnt = 0;
50 const char *zLine;
51
52 #if defined(_WIN32)
53 if( lineLength<0 ){
54 CONSOLE_SCREEN_BUFFER_INFO csbi;
55 memset(&csbi, 0, sizeof(CONSOLE_SCREEN_BUFFER_INFO));
56 if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) ){
57 tlen = csbi.srWindow.Right - csbi.srWindow.Left - indent;
58 }
59 }
60 #elif defined(TIOCGWINSZ)
61 if( lineLength<0 ){
62 struct winsize w;
63 memset(&w, 0, sizeof(struct winsize));
64 if( ioctl(0, TIOCGWINSZ, &w)!=-1 ){
65 tlen = w.ws_col - indent;
66 }
67 }
68 #else
69 if( lineLength<0 ){
70 /*
71 ** Fallback to using more-or-less the "legacy semantics" of hard-coding
72 ** the maximum line length to a value reasonable for the vast majority
73 ** of supported systems.
74 */
75 tlen = COMMENT_LEGACY_LINE_LENGTH - indent;
76 }
77 #endif
78 if( zText==0 ) zText = "(NULL)";
79 if( tlen<=0 ){
80 tlen = strlen(zText);
81 }
82 while( fossil_isspace(zText[0]) ){ zText++; }
83 if( zText[0]==0 ){
84 if( !doIndent ){
85 fossil_print("\n");
86 lineCnt++;
87 }
88 return lineCnt;
89 }
90 zLine = zText;
91 for(;;){
92 if( zText[0]==0 ){
93 if( doIndent ){
94 fossil_print("%*s", indent, "");
95 }
96 fossil_print("%.*s", (int)(zText - zLine), zLine);
97 if( fossil_force_newline() ){
98 lineCnt++;
99 }
100 break;
101 }
102 len += ((zText[0]=='\t') ? 8 : 1);
103 if( zText[0]=='\n' || len>=tlen ){
104 const char *zNewLine;
105 if( doIndent ){
106 fossil_print("%*s", indent, "");
107 }
108 doIndent = 1;
109 zNewLine = zText + 1;
110 while( zText>zLine && !fossil_isspace(zText[0]) ){ zText--; }
111 if( zText>zLine ){
112 fossil_print("%.*s", (int)(zText - zLine), zLine);
113 zLine = zText;
114 }else{
115 fossil_print("%.*s", (int)(zNewLine - zLine), zLine);
116 zLine = zNewLine;
117 }
118 if( fossil_force_newline() ){
119 lineCnt++;
120 }
121 if( !zLine++ ) break;
122 len = 0;
123 }
124 zText++;
125 }
126 return lineCnt;
127 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
129 /*
130 **
131 ** COMMAND: test-comment-format
132 **
133
--- src/comformat.c
+++ src/comformat.c
@@ -34,99 +34,146 @@
34 */
35 #ifndef COMMENT_LEGACY_LINE_LENGTH
36 # define COMMENT_LEGACY_LINE_LENGTH (78)
37 #endif
38
39 /*
40 ** This is the number of spaces to print when a tab character is seen.
41 */
42 #ifndef COMMENT_TAB_WIDTH
43 # define COMMENT_TAB_WIDTH (8)
44 #endif
45
46 /*
47 ** Given a comment string zText, format that string for printing
48 ** on a TTY. Assume that the output cursors is indent spaces from
49 ** the left margin and that a single line can contain no more than
50 ** width characters. Indent all subsequent lines by indent.
51 **
52 ** Return the number of newlines that are output.
53 */
54 int comment_print(const char *zText, int indent, int width){
55 int maxChars = width - indent;
56 int lineCnt = 0;
57 const char *zLine;
58
59 #if defined(_WIN32)
60 if( width<0 ){
61 CONSOLE_SCREEN_BUFFER_INFO csbi;
62 memset(&csbi, 0, sizeof(CONSOLE_SCREEN_BUFFER_INFO));
63 if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) ){
64 maxChars = csbi.srWindow.Right - csbi.srWindow.Left - indent;
65 }
66 }
67 #elif defined(TIOCGWINSZ)
68 if( width<0 ){
69 struct winsize w;
70 memset(&w, 0, sizeof(struct winsize));
71 if( ioctl(0, TIOCGWINSZ, &w)!=-1 ){
72 maxChars = w.ws_col - indent;
73 }
74 }
75 #else
76 if( width<0 ){
77 /*
78 ** Fallback to using more-or-less the "legacy semantics" of hard-coding
79 ** the maximum line length to a value reasonable for the vast majority
80 ** of supported systems.
81 */
82 maxChars = COMMENT_LEGACY_LINE_LENGTH - indent;
83 }
84 #endif
85 if( zText==0 ) zText = "(NULL)";
86 if( maxChars<=0 ){
87 maxChars = strlen(zText);
88 }
89 while( fossil_isspace(zText[0]) ){ zText++; }
90 if( zText[0]==0 ){
91 fossil_print("\n");
92 lineCnt++;
 
 
93 return lineCnt;
94 }
95 zLine = zText;
96 for(;;){
97 comment_print_line(zLine, zLine>zText ? indent : 0,
98 maxChars, &lineCnt, &zLine);
99 if( !zLine || !zLine[0] ) break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100 }
101 return lineCnt;
102 }
103
104 /*
105 ** This function prints one logical line of a comment, stopping when it hits
106 ** a new line -OR- runs out of space on the logical line.
107 */
108 void comment_print_line(
109 const char *zLine, /* [in] The comment line to print. */
110 int indent, /* [in] Number of spaces to indent, zero for none. */
111 int lineChars, /* [in] Maximum number of characters to print. */
112 int *pLineCnt, /* [in/out] Pointer to the total line count. */
113 const char **pzLine /* [out] Pointer to the end of the logical line. */
114 ){
115 int index = 0, charCnt = 0, lineCnt = 0, maxChars;
116 if( !zLine ) return;
117 if( lineChars<=0 ) return;
118 comment_print_indent(zLine, indent, &index);
119 maxChars = lineChars;
120 for(;;){
121 char c = zLine[index];
122 if( c==0 ){
123 break;
124 }else{
125 index++;
126 }
127 if( c=='\n' ){
128 charCnt = 0;
129 lineCnt++;
130 }else if( c=='\t' ){
131 charCnt++;
132 if( maxChars<COMMENT_TAB_WIDTH ){
133 fossil_print(" ");
134 break;
135 }
136 maxChars -= COMMENT_TAB_WIDTH;
137 }else{
138 charCnt++;
139 maxChars--;
140 }
141 fossil_print("%c", c);
142 if( maxChars==0 ) break;
143 if( c=='\n' ) break;
144 }
145 if( charCnt>0 || lineCnt==0 ){
146 fossil_print("\n");
147 lineCnt++;
148 }
149 if( pLineCnt ){
150 *pLineCnt += lineCnt;
151 }
152 if( pzLine ){
153 *pzLine = zLine + index;
154 }
155 }
156
157 /*
158 ** This function is called when printing a logical comment line to perform
159 ** the necessary indenting.
160 */
161 void comment_print_indent(
162 const char *zLine, /* [in] The comment line being printed. */
163 int indent, /* [in] Number of spaces to indent, zero for none. */
164 int *piIndex /* [in/out] Pointer to first non-space character. */
165 ){
166 if( indent>0 ){
167 fossil_print("%*s", indent, "");
168 if( zLine && piIndex ){
169 int index = *piIndex;
170 while( fossil_isspace(zLine[index]) ){ index++; }
171 *piIndex = index;
172 }
173 }
174 }
175
176 /*
177 **
178 ** COMMAND: test-comment-format
179 **
180

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button