1 /* ASCII strings utilities
2 Copyright (C) 2007 Free Software Foundation, Inc.
7 The file_date routine is mostly from GNU's fileutils package,
8 written by Richard Stallman and David MacKenzie.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
34 /* using g_ascii function from glib
35 * on terminal are showed only ascii characters (lower then 0x80)
38 static const char replch
= '?';
41 str_ascii_insert_replace_char (GString
* buffer
)
43 g_string_append_c (buffer
, replch
);
47 str_ascii_is_valid_string (const char *text
)
53 str_ascii_is_valid_char (const char *ch
, size_t size
)
59 str_ascii_cnext_char (const char **text
)
65 str_ascii_cprev_char (const char **text
)
71 str_ascii_cnext_noncomb_char (const char **text
)
83 str_ascii_cprev_noncomb_char (const char **text
, const char *begin
)
95 str_ascii_isspace (const char *text
)
97 return g_ascii_isspace ((gchar
) text
[0]);
101 str_ascii_ispunct (const char *text
)
103 return g_ascii_ispunct ((gchar
) text
[0]);
107 str_ascii_isalnum (const char *text
)
109 return g_ascii_isalnum ((gchar
) text
[0]);
113 str_ascii_isdigit (const char *text
)
115 return g_ascii_isdigit ((gchar
) text
[0]);
119 str_ascii_isprint (const char *text
)
121 return g_ascii_isprint ((gchar
) text
[0]);
125 str_ascii_iscombiningmark (const char *text
)
131 str_ascii_toupper (const char *text
, char **out
, size_t * remain
)
135 (*out
)[0] = (char) g_ascii_toupper ((gchar
) text
[0]);
142 str_ascii_tolower (const char *text
, char **out
, size_t * remain
)
146 (*out
)[0] = (char) g_ascii_tolower ((gchar
) text
[0]);
153 str_ascii_length (const char *text
)
155 return strlen (text
);
159 str_ascii_length2 (const char *text
, int size
)
161 return (size
>= 0) ? min (strlen (text
), size
) : strlen (text
);
165 str_ascii_vfs_convert_to (GIConv coder
, const char *string
,
166 int size
, GString
* buffer
)
168 g_string_append_len (buffer
, string
, size
);
174 str_ascii_term_form (const char *text
)
176 static char result
[BUF_MEDIUM
];
183 remain
= sizeof (result
);
184 length
= strlen (text
);
186 /* go throw all characters and check, if they are ascii and printable */
187 for (; pos
< length
&& remain
> 1; pos
++, actual
++, remain
--)
189 actual
[0] = isascii ((unsigned char) text
[pos
]) ? text
[pos
] : '?';
190 actual
[0] = g_ascii_isprint ((gchar
) actual
[0]) ? actual
[0] : '.';
198 str_ascii_fit_to_term (const char *text
, int width
, int just_mode
)
200 static char result
[BUF_MEDIUM
];
207 length
= strlen (text
);
209 remain
= sizeof (result
);
214 switch (HIDE_FIT (just_mode
))
218 ident
= (width
- length
) / 2;
221 ident
= width
- length
;
225 /* add space before text */
228 memset (actual
, ' ', ident
);
232 /* copy all characters */
233 for (; pos
< length
&& remain
> 1; pos
++, actual
++, remain
--)
235 actual
[0] = isascii ((unsigned char) text
[pos
]) ? text
[pos
] : '?';
236 actual
[0] = g_ascii_isprint ((gchar
) actual
[0]) ? actual
[0] : '.';
239 /* add space after text */
240 if (width
- length
- ident
> 0)
242 if (remain
<= width
- length
- ident
)
244 memset (actual
, ' ', width
- length
- ident
);
245 actual
+= width
- length
- ident
;
246 remain
-= width
- length
- ident
;
251 if (IS_FIT (just_mode
))
253 /* copy prefix of text, that is not wider than width / 2 */
254 for (; pos
+ 1 <= width
/ 2 && remain
> 1;
255 actual
++, pos
++, remain
--)
257 actual
[0] = isascii ((unsigned char) text
[pos
])
259 actual
[0] = g_ascii_isprint ((gchar
) actual
[0])
269 pos
+= length
- width
+ 1;
271 /* copy suffix of text */
272 for (; pos
< length
&& remain
> 1; pos
++, actual
++, remain
--)
274 actual
[0] = isascii ((unsigned char) text
[pos
])
276 actual
[0] = g_ascii_isprint ((gchar
) actual
[0])
283 switch (HIDE_FIT (just_mode
))
286 ident
= (length
- width
) / 2;
289 ident
= length
- width
;
293 /* copy substring text, substring start from ident and take width
294 * characters from text */
296 for (; pos
< ident
+ width
&& remain
> 1;
297 pos
++, actual
++, remain
--)
299 actual
[0] = isascii ((unsigned char) text
[pos
])
301 actual
[0] = g_ascii_isprint ((gchar
) actual
[0])
313 str_ascii_term_trim (const char *text
, int width
)
315 static char result
[BUF_MEDIUM
];
321 length
= strlen (text
);
323 remain
= sizeof (result
);
329 memset (actual
, '.', width
);
335 memset (actual
, '.', 3);
339 pos
+= length
- width
+ 3;
341 /* copy suffix of text */
342 for (; pos
< length
&& remain
> 1; pos
++, actual
++, remain
--)
344 actual
[0] = isascii ((unsigned char) text
[pos
])
346 actual
[0] = g_ascii_isprint ((gchar
) actual
[0])
353 /* copy all characters */
354 for (; pos
< length
&& remain
> 1; pos
++, actual
++, remain
--)
356 actual
[0] = isascii ((unsigned char) text
[pos
]) ? text
[pos
] : '?';
357 actual
[0] = g_ascii_isprint ((gchar
) actual
[0]) ? actual
[0] : '.';
366 str_ascii_term_width2 (const char *text
, size_t length
)
368 return (length
!= (size_t) (-1))
369 ? min (strlen (text
), length
) : strlen (text
);
373 str_ascii_term_width1 (const char *text
)
375 return str_ascii_term_width2 (text
, (size_t) (-1));
379 str_ascii_term_char_width (const char *text
)
385 str_ascii_msg_term_size (const char *text
, int *lines
, int *columns
)
390 char *p
, *tmp
= g_strdup (text
);
398 q
= strchr (p
, '\n');
405 width
= str_ascii_term_width1 (p
);
406 if (width
> (*columns
))
419 str_ascii_term_substring (const char *text
, int start
, int width
)
421 static char result
[BUF_MEDIUM
];
428 remain
= sizeof (result
);
429 length
= strlen (text
);
434 /* copy at most width characters from text from start */
435 for (; pos
< length
&& width
> 0 && remain
> 1;
436 pos
++, width
--, actual
++, remain
--)
439 actual
[0] = isascii ((unsigned char) text
[pos
]) ? text
[pos
] : '?';
440 actual
[0] = g_ascii_isprint ((gchar
) actual
[0]) ? actual
[0] : '.';
444 /* if text is shorter then width, add space to the end */
445 for (; width
> 0 && remain
> 1; actual
++, remain
--, width
--)
455 str_ascii_trunc (const char *text
, int width
)
457 static char result
[MC_MAXPATHLEN
];
464 remain
= sizeof (result
);
465 length
= strlen (text
);
469 /* copy prefix of text */
470 for (; pos
+ 1 <= width
/ 2 && remain
> 1; actual
++, pos
++, remain
--)
472 actual
[0] = isascii ((unsigned char) text
[pos
]) ? text
[pos
] : '?';
473 actual
[0] = g_ascii_isprint ((gchar
) actual
[0]) ? actual
[0] : '.';
482 pos
+= length
- width
+ 1;
484 /* copy suffix of text */
485 for (; pos
< length
&& remain
> 1; pos
++, actual
++, remain
--)
487 actual
[0] = isascii ((unsigned char) text
[pos
]) ? text
[pos
] : '?';
488 actual
[0] = g_ascii_isprint ((gchar
) actual
[0]) ? actual
[0] : '.';
493 /* copy all characters */
494 for (; pos
< length
&& remain
> 1; pos
++, actual
++, remain
--)
496 actual
[0] = isascii ((unsigned char) text
[pos
]) ? text
[pos
] : '?';
497 actual
[0] = g_ascii_isprint ((gchar
) actual
[0]) ? actual
[0] : '.';
507 str_ascii_offset_to_pos (const char *text
, size_t length
)
513 str_ascii_column_to_pos (const char *text
, size_t pos
)
519 str_ascii_create_search_needle (const char *needle
, int case_sen
)
521 return (char *) needle
;
525 str_ascii_release_search_needle (char *needle
, int case_sen
)
530 str_ascii_search_first (const char *text
, const char *search
, int case_sen
)
537 fold_text
= (case_sen
) ? (char *) text
: g_ascii_strdown (text
, -1);
538 fold_search
= (case_sen
) ? (char *) search
: g_ascii_strdown (search
, -1);
540 match
= g_strstr_len (fold_text
, -1, fold_search
);
543 offset
= match
- fold_text
;
544 match
= text
+ offset
;
550 g_free (fold_search
);
557 str_ascii_search_last (const char *text
, const char *search
, int case_sen
)
564 fold_text
= (case_sen
) ? (char *) text
: g_ascii_strdown (text
, -1);
565 fold_search
= (case_sen
) ? (char *) search
: g_ascii_strdown (search
, -1);
567 match
= g_strrstr_len (fold_text
, -1, fold_search
);
570 offset
= match
- fold_text
;
571 match
= text
+ offset
;
577 g_free (fold_search
);
584 str_ascii_compare (const char *t1
, const char *t2
)
586 return strcmp (t1
, t2
);
590 str_ascii_ncompare (const char *t1
, const char *t2
)
592 return strncmp (t1
, t2
, min (strlen (t1
), strlen (t2
)));
596 str_ascii_casecmp (const char *t1
, const char *t2
)
598 return g_ascii_strcasecmp (t1
, t2
);
602 str_ascii_ncasecmp (const char *t1
, const char *t2
)
604 return g_ascii_strncasecmp (t1
, t2
, min (strlen (t1
), strlen (t2
)));
608 str_ascii_fix_string (char *text
)
610 for (; text
[0] != '\0'; text
++)
612 text
[0] = ((unsigned char) text
[0] < 128) ? text
[0] : '?';
617 str_ascii_create_key (const char *text
, int case_sen
)
619 return (char *) text
;
623 str_ascii_key_collate (const char *t1
, const char *t2
, int case_sen
)
625 return (case_sen
) ? strcmp (t1
, t2
) : g_ascii_strcasecmp (t1
, t2
);
629 str_ascii_release_key (char *key
, int case_sen
)
634 str_ascii_prefix (const char *text
, const char *prefix
)
637 for (result
= 0; text
[result
] != '\0' && prefix
[result
] != '\0'
638 && text
[result
] == prefix
[result
]; result
++);
643 str_ascii_caseprefix (const char *text
, const char *prefix
)
646 for (result
= 0; text
[result
] != '\0' && prefix
[result
] != '\0'
647 && g_ascii_toupper (text
[result
]) ==
648 g_ascii_toupper (prefix
[result
]); result
++);
656 struct str_class result
;
658 result
.vfs_convert_to
= str_ascii_vfs_convert_to
;
659 result
.insert_replace_char
= str_ascii_insert_replace_char
;
660 result
.is_valid_string
= str_ascii_is_valid_string
;
661 result
.is_valid_char
= str_ascii_is_valid_char
;
662 result
.cnext_char
= str_ascii_cnext_char
;
663 result
.cprev_char
= str_ascii_cprev_char
;
664 result
.cnext_char_safe
= str_ascii_cnext_char
;
665 result
.cprev_char_safe
= str_ascii_cprev_char
;
666 result
.cnext_noncomb_char
= str_ascii_cnext_noncomb_char
;
667 result
.cprev_noncomb_char
= str_ascii_cprev_noncomb_char
;
668 result
.isspace
= str_ascii_isspace
;
669 result
.ispunct
= str_ascii_ispunct
;
670 result
.isalnum
= str_ascii_isalnum
;
671 result
.isdigit
= str_ascii_isdigit
;
672 result
.isprint
= str_ascii_isprint
;
673 result
.iscombiningmark
= str_ascii_iscombiningmark
;
674 result
.toupper
= str_ascii_toupper
;
675 result
.tolower
= str_ascii_tolower
;
676 result
.length
= str_ascii_length
;
677 result
.length2
= str_ascii_length2
;
678 result
.length_noncomb
= str_ascii_length
;
679 result
.fix_string
= str_ascii_fix_string
;
680 result
.term_form
= str_ascii_term_form
;
681 result
.fit_to_term
= str_ascii_fit_to_term
;
682 result
.term_trim
= str_ascii_term_trim
;
683 result
.term_width2
= str_ascii_term_width2
;
684 result
.term_width1
= str_ascii_term_width1
;
685 result
.term_char_width
= str_ascii_term_char_width
;
686 result
.msg_term_size
= str_ascii_msg_term_size
;
687 result
.term_substring
= str_ascii_term_substring
;
688 result
.trunc
= str_ascii_trunc
;
689 result
.offset_to_pos
= str_ascii_offset_to_pos
;
690 result
.column_to_pos
= str_ascii_column_to_pos
;
691 result
.create_search_needle
= str_ascii_create_search_needle
;
692 result
.release_search_needle
= str_ascii_release_search_needle
;
693 result
.search_first
= str_ascii_search_first
;
694 result
.search_last
= str_ascii_search_last
;
695 result
.compare
= str_ascii_compare
;
696 result
.ncompare
= str_ascii_ncompare
;
697 result
.casecmp
= str_ascii_casecmp
;
698 result
.ncasecmp
= str_ascii_ncasecmp
;
699 result
.prefix
= str_ascii_prefix
;
700 result
.caseprefix
= str_ascii_caseprefix
;
701 result
.create_key
= str_ascii_create_key
;
702 result
.create_key_for_filename
= str_ascii_create_key
;
703 result
.key_collate
= str_ascii_key_collate
;
704 result
.release_key
= str_ascii_release_key
;