1 /* radare - LGPL - Copyright 2007-2020 - pancake */
2
3 #include "r_types.h"
4 #include "r_util.h"
5 #include "r_cons.h"
6 #include "r_bin.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <stdarg.h>
12
13 // TODO: simplify this horrible loop
r_str_trim_path(char * s)14 R_API void r_str_trim_path(char *s) {
15 char *src, *dst, *p;
16 int i = 0;
17 if (!s || !*s) {
18 return;
19 }
20 dst = src = s + 1;
21 while (*src) {
22 if (*(src - 1) == '/' && *src == '.' && *(src + 1) == '.') {
23 if (*(src + 2) == '/' || *(src + 2) == '\0') {
24 p = dst - 1;
25 while (s != p) {
26 if (*p == '/') {
27 if (i) {
28 dst = p + 1;
29 i = 0;
30 break;
31 }
32 i = 1;
33 }
34 p--;
35 }
36 if (s == p && *p == '/') {
37 dst = p + 1;
38 }
39 src = src + 2;
40 } else {
41 *dst = *src;
42 dst++;
43 }
44 } else if (*src == '/' && *(src + 1) == '.' && (*(src + 2) == '/' || *(src + 2) == '\0')) {
45 src++;
46 } else if (*src != '/' || *(src - 1) != '/') {
47 *dst = *src;
48 dst++;
49 }
50 src++;
51 }
52 if (dst > s + 1 && *(dst - 1) == '/') {
53 *(dst - 1) = 0;
54 } else {
55 *dst = 0;
56 }
57 }
58
r_str_trim_lines(char * str)59 R_API char* r_str_trim_lines(char *str) {
60 RList *list = r_str_split_list (str, "\n", 0);
61 char *s;
62 RListIter *iter;
63 RStrBuf *sb = r_strbuf_new ("");
64 r_list_foreach (list, iter, s) {
65 //r_str_ansi_trim (s, -1, 99999);
66 r_str_ansi_filter (s, NULL, NULL, -1);
67 r_str_trim (s);
68 if (*s) {
69 r_strbuf_appendf (sb, "%s\n", s);
70 }
71 }
72 r_list_free (list);
73 free (str);
74 return r_strbuf_drain (sb);
75 }
76
r_str_trim_dup(const char * str)77 R_API char *r_str_trim_dup(const char *str) {
78 char *a = strdup (str);
79 r_str_trim (a);
80 return a;
81 }
82
83 // Returns a pointer to the first non-whitespace character of str.
84 // TODO: Find a better name: to r_str_trim_head_ro(), r_str_skip_head or so
r_str_trim_head_ro(const char * str)85 R_API const char *r_str_trim_head_ro(const char *str) {
86 r_return_val_if_fail (str, NULL);
87 for (; *str && IS_WHITECHAR (*str); str++) {
88 ;
89 }
90 return str;
91 }
92
93 // TODO: find better name
r_str_trim_head_wp(const char * str)94 R_API const char *r_str_trim_head_wp(const char *str) {
95 r_return_val_if_fail (str, NULL);
96 for (; *str && !IS_WHITESPACE (*str); str++) {
97 ;
98 }
99 return str;
100 }
101
102 /* remove spaces from the head of the string.
103 * the string is changed in place */
r_str_trim_head(char * str)104 R_API void r_str_trim_head(char *str) {
105 char *p = (char *)r_str_trim_head_ro (str);
106 if (p) {
107 memmove (str, p, strlen (p) + 1);
108 }
109 }
110
111 // Remove whitespace chars from the tail of the string, replacing them with
112 // null bytes. The string is changed in-place.
r_str_trim_tail(char * str)113 R_API void r_str_trim_tail(char *str) {
114 r_return_if_fail (str);
115 size_t length = strlen (str);
116 while (length-- > 0) {
117 if (IS_WHITECHAR (str[length])) {
118 str[length] = '\0';
119 } else {
120 break;
121 }
122 }
123 }
124
125 // Removes spaces from the head of the string, and zeros out whitespaces from
126 // the tail of the string. The string is changed in place.
r_str_trim(char * str)127 R_API void r_str_trim(char *str) {
128 r_str_trim_head (str);
129 r_str_trim_tail (str);
130 }
131
132 // no copy, like trim_head+tail but with trim_head_ro, beware heap issues
133 // TODO: rename to r_str_trim_weak() ?
r_str_trim_nc(char * str)134 R_API char *r_str_trim_nc(char *str) {
135 char *s = (char *)r_str_trim_head_ro (str);
136 r_str_trim_tail (s);
137 return s;
138 }
139
140 /* supposed to chop a string with ansi controls to max length of n. */
r_str_ansi_trim(char * str,int str_len,int n)141 R_API int r_str_ansi_trim(char *str, int str_len, int n) {
142 r_return_val_if_fail (str, 0);
143 char ch, ch2;
144 int back = 0, i = 0, len = 0;
145 /* simple case - no need to cut */
146 if (str_len < 0) {
147 str_len = strlen (str);
148 }
149 if (n >= str_len) {
150 str[str_len] = 0;
151 return str_len;
152 }
153 while ((i < str_len) && str[i] && len < n && n > 0) {
154 ch = str[i];
155 ch2 = str[i + 1];
156 if (ch == 0x1b) {
157 if (ch2 == '\\') {
158 i++;
159 } else if (ch2 == ']') {
160 if (!strncmp (str + 2 + 5, "rgb:", 4)) {
161 i += 18;
162 }
163 } else if (ch2 == '[') {
164 for (++i; (i < str_len) && str[i] && str[i] != 'J' && str[i] != 'm' && str[i] != 'H';
165 i++) {
166 ;
167 }
168 }
169 } else if ((str[i] & 0xc0) != 0x80) {
170 len++;
171 }
172 i++;
173 back = i; /* index in the original array */
174 }
175 str[back] = 0;
176 return back;
177 }
178