1 #include "format_print.h"
10 static int align_left
;
13 static int numlen(int num
)
27 static int stack_print(char *buf
, char *stack
, int stack_len
)
33 while (i
< width
&& stack_len
)
34 buf
[i
++] = stack
[--stack_len
];
40 if (stack_len
> width
)
42 pad_len
= width
- stack_len
;
46 buf
[i
++] = stack
[--stack_len
];
50 buf
[i
++] = stack
[--stack_len
];
55 static int print_num(char *buf
, int num
)
63 for (i
= 0; i
< width
; i
++)
69 stack
[p
++] = num
% 10 + '0';
73 return stack_print(buf
, stack
, p
);
76 /* print '{,-}{h:,}mm:ss' */
77 static int print_time(char *buf
, int t
)
93 /* put all chars to stack in reverse order ;) */
94 stack
[p
++] = s
% 10 + '0';
95 stack
[p
++] = s
/ 10 + '0';
97 stack
[p
++] = m
% 10 + '0';
98 stack
[p
++] = m
/ 10 + '0';
102 stack
[p
++] = h
% 10 + '0';
109 return stack_print(buf
, stack
, p
);
112 static void print_str(char *buf
, int *idx
, const char *str
)
122 d
+= u_copy_chars(buf
+ d
, str
, &i
);
125 memset(buf
+ d
, ' ', ws_len
);
130 ws_len
= width
- u_str_width(str
);
133 memset(buf
+ d
, ' ', ws_len
);
143 u_get_char(str
, &s
, &u
);
148 /* gaah, skipped too much */
149 if (u_char_width(u
) == 2) {
155 buf
[d
++] = hex_tab
[(u
>> 4) & 0xf];
157 buf
[d
++] = hex_tab
[u
& 0xf];
166 d
+= u_copy_chars(buf
+ d
, str
+ s
, &w
);
174 u_get_char(str
, &s
, &u
);
177 u_set_char(buf
, &d
, u
);
183 static void print(char *str
, const char *format
, const struct format_option
*fopts
)
185 /* format and str indices */
189 const struct format_option
*fo
;
192 u_get_char(format
, &s
, &u
);
194 u_set_char(str
, &d
, u
);
197 u_get_char(format
, &s
, &u
);
199 u_set_char(str
, &d
, u
);
210 u_get_char(format
, &s
, &u
);
215 u_get_char(format
, &s
, &u
);
221 u_get_char(format
, &s
, &u
);
223 for (fo
= fopts
; fo
->ch
; fo
++) {
228 memset(str
+ d
, ' ', width
);
230 } else if (type
== FO_STR
) {
231 print_str(str
, &d
, fo
->fo_str
);
232 } else if (type
== FO_INT
) {
233 d
+= print_num(str
+ d
, fo
->fo_int
);
234 } else if (type
== FO_TIME
) {
235 d
+= print_time(str
+ d
, fo
->fo_time
);
244 static char *l_str
= NULL
;
245 static char *r_str
= NULL
;
246 /* sizes in bytes. not counting the terminating 0! */
247 static int l_str_size
= -1;
248 static int r_str_size
= -1;
250 int format_print(char *str
, int str_width
, const char *format
, const struct format_option
*fopts
)
252 /* lengths of left and right aligned texts */
261 const struct format_option
*fo
;
265 u_get_char(format
, &s
, &u
);
267 (*len
) += u_char_width(u
);
270 u_get_char(format
, &s
, &u
);
276 /* right aligned text starts */
282 u_get_char(format
, &s
, &u
);
285 /* minimum length of this field */
288 u_get_char(format
, &s
, &u
);
290 for (fo
= fopts
; ; fo
++) {
298 } else if (type
== FO_STR
) {
299 l
= u_str_width(fo
->fo_str
);
300 } else if (type
== FO_INT
) {
301 l
= numlen(fo
->fo_int
);
302 } else if (type
== FO_TIME
) {
310 l
+= numlen(t
/ 3600) + 6;
325 /* max utf-8 char len is 4 */
329 if (l_str_size
< lsize
) {
332 l_str
= xnew(char, l_str_size
+ 1);
333 l_str
[l_str_size
] = 0;
335 if (r_str_size
< rsize
) {
338 r_str
= xnew(char, r_str_size
+ 1);
339 r_str
[r_str_size
] = 0;
345 print(l_str
, format
, fopts
);
348 int ul
= u_str_width(l_str
);
350 d_print("L %d != %d: size=%d '%s'\n", ul
, llen
, lsize
, l_str
);
355 print(r_str
, format
+ eq_pos
+ 1, fopts
);
358 int ul
= u_str_width(r_str
);
360 d_print("R %d != %d: size=%d '%s'\n", ul
, rlen
, rsize
, r_str
);
365 /* NOTE: any invalid UTF-8 bytes have already been converted to <xx>
366 * (ASCII) where x is hex digit
369 if (llen
+ rlen
<= str_width
) {
371 int ws_len
= str_width
- llen
- rlen
;
374 /* I would use strcpy if it returned anything useful */
376 str
[pos
] = l_str
[pos
];
379 memset(str
+ pos
, ' ', ws_len
);
380 strcpy(str
+ pos
+ ws_len
, r_str
);
382 int l_space
= str_width
- rlen
;
387 pos
= u_copy_chars(str
, l_str
, &l_space
);
391 idx
= u_skip_chars(r_str
, &w
);
395 strcpy(str
+ pos
, r_str
+ idx
);
400 /* FIXME: compare with struct format_option[] */
401 int format_valid(const char *format
)
408 u_get_char(format
, &s
, &u
);
412 u_get_char(format
, &s
, &u
);
413 if (u
== '%' || u
== '=')
416 u_get_char(format
, &s
, &u
);
419 u_get_char(format
, &s
, &u
);
422 u_get_char(format
, &s
, &u
);