Add util function to locate a column in a string
This will help to parse the result of "adb shell ip route" to find the device IP address. PR #2827 <https://github.com/Genymobile/scrcpy/pull/2827>
This commit is contained in:
parent
3bf6fd2894
commit
b52f87a892
3 changed files with 67 additions and 0 deletions
|
@ -304,3 +304,29 @@ sc_str_truncate(char *data, size_t len, const char *endchars) {
|
||||||
data[idx] = '\0';
|
data[idx] = '\0';
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
sc_str_index_of_column(const char *s, unsigned col, const char *seps) {
|
||||||
|
size_t colidx = 0;
|
||||||
|
|
||||||
|
size_t idx = 0;
|
||||||
|
while (s[idx] != '\0' && colidx != col) {
|
||||||
|
size_t r = strcspn(&s[idx], seps);
|
||||||
|
idx += r;
|
||||||
|
|
||||||
|
if (s[idx] == '\0') {
|
||||||
|
// Not found
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t consecutive_seps = strspn(&s[idx], seps);
|
||||||
|
assert(consecutive_seps); // At least one
|
||||||
|
idx += consecutive_seps;
|
||||||
|
|
||||||
|
if (s[idx] != '\0') {
|
||||||
|
++colidx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return col == colidx ? (ssize_t) idx : -1;
|
||||||
|
}
|
||||||
|
|
|
@ -114,4 +114,24 @@ sc_str_wrap_lines(const char *input, unsigned columns, unsigned indent);
|
||||||
size_t
|
size_t
|
||||||
sc_str_truncate(char *data, size_t len, const char *endchars);
|
sc_str_truncate(char *data, size_t len, const char *endchars);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the start of a column in a string
|
||||||
|
*
|
||||||
|
* A string may represent several columns, separated by some "spaces"
|
||||||
|
* (separators). This function aims to find the start of the column number
|
||||||
|
* `col`.
|
||||||
|
*
|
||||||
|
* For example, to find the 4th column (column number 3):
|
||||||
|
*
|
||||||
|
* // here
|
||||||
|
* // v
|
||||||
|
* const char *s = "abc def ghi jk";
|
||||||
|
* ssize_t index = sc_str_index_of_column(s, 3, " ");
|
||||||
|
* assert(index == 16); // points to "jk"
|
||||||
|
*
|
||||||
|
* Return -1 if no such column exists.
|
||||||
|
*/
|
||||||
|
ssize_t
|
||||||
|
sc_str_index_of_column(const char *s, unsigned col, const char *seps);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -364,6 +364,26 @@ static void test_truncate(void) {
|
||||||
assert(!strcmp("hello", s4));
|
assert(!strcmp("hello", s4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_index_of_column(void) {
|
||||||
|
assert(sc_str_index_of_column("a bc d", 0, " ") == 0);
|
||||||
|
assert(sc_str_index_of_column("a bc d", 1, " ") == 2);
|
||||||
|
assert(sc_str_index_of_column("a bc d", 2, " ") == 6);
|
||||||
|
assert(sc_str_index_of_column("a bc d", 3, " ") == -1);
|
||||||
|
|
||||||
|
assert(sc_str_index_of_column("a ", 0, " ") == 0);
|
||||||
|
assert(sc_str_index_of_column("a ", 1, " ") == -1);
|
||||||
|
|
||||||
|
assert(sc_str_index_of_column("", 0, " ") == 0);
|
||||||
|
assert(sc_str_index_of_column("", 1, " ") == -1);
|
||||||
|
|
||||||
|
assert(sc_str_index_of_column("a \t \t bc \t d\t", 0, " \t") == 0);
|
||||||
|
assert(sc_str_index_of_column("a \t \t bc \t d\t", 1, " \t") == 8);
|
||||||
|
assert(sc_str_index_of_column("a \t \t bc \t d\t", 2, " \t") == 15);
|
||||||
|
assert(sc_str_index_of_column("a \t \t bc \t d\t", 3, " \t") == -1);
|
||||||
|
|
||||||
|
assert(sc_str_index_of_column(" a bc d", 1, " ") == 2);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
(void) argc;
|
(void) argc;
|
||||||
(void) argv;
|
(void) argv;
|
||||||
|
@ -384,5 +404,6 @@ int main(int argc, char *argv[]) {
|
||||||
test_strlist_contains();
|
test_strlist_contains();
|
||||||
test_wrap_lines();
|
test_wrap_lines();
|
||||||
test_truncate();
|
test_truncate();
|
||||||
|
test_index_of_column();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue