source: mainline/uspace/lib/fmtutil/fmtutil.c@ a35b458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/*
2 * Copyright (c) 2011 Martin Sucha
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <io/console.h>
30#include <errno.h>
31#include <fmtutil.h>
32#include <stdlib.h>
33#include <str.h>
34
35typedef struct {
36 align_mode_t alignment;
37 bool newline_always;
38 size_t width;
39} printmode_t;
40
41errno_t print_wrapped_console(const char *str, align_mode_t alignment)
42{
43 console_ctrl_t *console = console_init(stdin, stdout);
44 if (console == NULL) {
45 printf("%s", str);
46 return EOK;
47 }
48 sysarg_t con_rows, con_cols, con_col, con_row;
49 errno_t rc = console_get_size(console, &con_cols, &con_rows);
50 if (rc != EOK) {
51 return rc;
52 }
53 rc = console_get_pos(console, &con_col, &con_row);
54 if (rc != EOK) {
55 return rc;
56 }
57 if (con_col != 0) {
58 printf("\n");
59 }
60 return print_wrapped(str, con_cols, alignment);
61}
62
63/** Line consumer that prints the lines aligned according to spec
64 *
65 **/
66static errno_t print_line(wchar_t *wstr, size_t chars, bool last, void *data)
67{
68 printmode_t *pm = (printmode_t *) data;
69 wchar_t old_char = wstr[chars];
70 wstr[chars] = 0;
71 errno_t rc = print_aligned_w(wstr, pm->width, last, pm->alignment);
72 wstr[chars] = old_char;
73 return rc;
74}
75
76errno_t print_wrapped(const char *str, size_t width, align_mode_t mode)
77{
78 printmode_t pm;
79 pm.alignment = mode;
80 pm.newline_always = false;
81 pm.width = width;
82 wchar_t *wstr = str_to_awstr(str);
83 if (wstr == NULL) {
84 return ENOMEM;
85 }
86 errno_t rc = wrap(wstr, width, print_line, &pm);
87 free(wstr);
88 return rc;
89}
90
91errno_t print_aligned_w(const wchar_t *wstr, size_t width, bool last,
92 align_mode_t mode)
93{
94 size_t i;
95 size_t len = wstr_length(wstr);
96 if (mode == ALIGN_LEFT || (mode == ALIGN_JUSTIFY && last)) {
97 for (i = 0; i < width; i++) {
98 if (i < len)
99 putchar(wstr[i]);
100 else
101 putchar(' ');
102 }
103 }
104 else if (mode == ALIGN_RIGHT) {
105 for (i = 0; i < width; i++) {
106 if (i < width - len)
107 putchar(' ');
108 else
109 putchar(wstr[i- (width - len)]);
110 }
111 }
112 else if (mode == ALIGN_CENTER) {
113 size_t padding = (width - len) / 2;
114 for (i = 0; i < width; i++) {
115 if ((i < padding) || ((i - padding) >= len))
116 putchar(' ');
117 else
118 putchar(wstr[i-padding]);
119 }
120 }
121 else if (mode == ALIGN_JUSTIFY) {
122 size_t words = 0;
123 size_t word_chars = 0;
124 bool space = true;
125 for (i = 0; i < len; i++) {
126 if (space && wstr[i] != ' ') {
127 words++;
128 }
129 space = wstr[i] == ' ';
130 if (!space) word_chars++;
131 }
132 size_t done_words = 0;
133 size_t done_chars = 0;
134 if (words == 0)
135 goto skip_words;
136 size_t excess_spaces = width - word_chars - (words-1);
137 space = true;
138 i = 0;
139 size_t j;
140 while (i < len) {
141 /* Find a word */
142 while (i < len && wstr[i] == ' ') i++;
143 if (i == len) break;
144 if (done_words) {
145 size_t spaces = 1 + (((done_words *
146 excess_spaces) / (words - 1)) -
147 (((done_words - 1) * excess_spaces) /
148 (words - 1)));
149 for (j = 0; j < spaces; j++) {
150 putchar(' ');
151 }
152 done_chars += spaces;
153 }
154 while (i < len && wstr[i] != ' ') {
155 putchar(wstr[i++]);
156 done_chars++;
157 }
158 done_words++;
159 }
160skip_words:
161 while (done_chars < width) {
162 putchar(' ');
163 done_chars++;
164 }
165 }
166 else {
167 return EINVAL;
168 }
169
170 return EOK;
171}
172errno_t print_aligned(const char *str, size_t width, bool last, align_mode_t mode)
173{
174 wchar_t *wstr = str_to_awstr(str);
175 if (wstr == NULL) {
176 return ENOMEM;
177 }
178 errno_t rc = print_aligned_w(wstr, width, last, mode);
179 free(wstr);
180 return rc;
181}
182
183errno_t wrap(wchar_t *wstr, size_t width, line_consumer_fn consumer, void *data)
184{
185 size_t word_start = 0;
186 size_t last_word_end = 0;
187 size_t line_start = 0;
188 size_t line_len = 0;
189 size_t pos = 0;
190
191 /*
192 * Invariants:
193 * * line_len = last_word_end - line_start
194 * * line_start <= last_word_end <= word_start <= pos
195 */
196
197 while (wstr[pos] != 0) {
198 /* Skip spaces and process newlines */
199 while (wstr[pos] == ' ' || wstr[pos] == '\n') {
200 if (wstr[pos] == '\n') {
201 consumer(wstr + line_start, line_len, true,
202 data);
203 last_word_end = line_start = pos + 1;
204 line_len = 0;
205 }
206 pos++;
207 }
208 word_start = pos;
209 /* Find end of word */
210 while (wstr[pos] != 0 && wstr[pos] != ' ' &&
211 wstr[pos] != '\n')
212 pos++;
213 bool last = wstr[pos] == 0;
214 /* Check if the line still fits width */
215 if (pos - line_start > width) {
216 if (line_len > 0)
217 consumer(wstr + line_start, line_len, last,
218 data);
219 line_start = last_word_end = word_start;
220 line_len = 0;
221 }
222 /* Check if we need to force wrap of long word*/
223 if (pos - word_start > width) {
224 consumer(wstr + word_start, width, last, data);
225 pos = line_start = last_word_end = word_start + width;
226 line_len = 0;
227 }
228 last_word_end = pos;
229 line_len = last_word_end - line_start;
230 }
231 /* Here we have less than width chars starting from line_start.
232 * Moreover, the last portion does not contain spaces or newlines
233 */
234 if (pos - line_start > 0)
235 consumer(wstr + line_start, pos - line_start, true, data);
236
237 return EOK;
238}
239
Note: See TracBrowser for help on using the repository browser.