diff options
author | irungentoo <irungentoo@gmail.com> | 2013-11-10 16:45:33 -0800 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2013-11-10 16:45:33 -0800 |
commit | ba000a24248ec3c4053201c5822d2334d34712f8 (patch) | |
tree | 0fe944663eaa5892f2e9c58e6320a897bd311b0c | |
parent | 572fb60392f2bdbea0b738ab9cc4eca2aefe6585 (diff) | |
parent | 4993928888ccec0b2c894d695e9f4736b63d6a80 (diff) |
Merge pull request #643 from FullName/nTox-patches
Started as a simple bugfix for wrap(), expanded to more detailed help.
-rw-r--r-- | testing/nTox.c | 230 | ||||
-rw-r--r-- | testing/nTox.h | 15 |
2 files changed, 203 insertions, 42 deletions
diff --git a/testing/nTox.c b/testing/nTox.c index 9b22ff5b..22756957 100644 --- a/testing/nTox.c +++ b/testing/nTox.c | |||
@@ -51,12 +51,42 @@ | |||
51 | #endif | 51 | #endif |
52 | 52 | ||
53 | char lines[HISTORY][STRING_LENGTH]; | 53 | char lines[HISTORY][STRING_LENGTH]; |
54 | uint8_t flag[HISTORY]; | ||
54 | char input_line[STRING_LENGTH]; | 55 | char input_line[STRING_LENGTH]; |
55 | 56 | ||
56 | char *help = "[i] commands:\n/f ID (to add friend)\n/m friendnumber message " | 57 | /* wrap: continuation mark */ |
57 | "(to send message)\n/s status (to change status)\n[i] /l list (l" | 58 | const size_t wrap_cont_len = 3; |
58 | "ist friends)\n/h for help\n/i for info\n/n nick (to change nick" | 59 | const char wrap_cont_str[] = "\n+ "; |
59 | "name)\n/q (to quit)"; | 60 | |
61 | /* documented: fdmnlsahxgiztq */ | ||
62 | /* undocumented: d (tox_do()) */ | ||
63 | |||
64 | /* 221 characters */ | ||
65 | char *help_main = | ||
66 | "[i] Available main commands:\n+ " | ||
67 | "/x (to print one's own id)|" | ||
68 | "/s status (to change status, e.g. AFK)|" | ||
69 | "/n nick (to change your nickname)|" | ||
70 | "/q (to quit)|" | ||
71 | "/h friend (for friend related commands)|" | ||
72 | "/h group (for group related commands)"; | ||
73 | |||
74 | /* 229 characters */ | ||
75 | char *help_friend = | ||
76 | "[i] Available friend commands:\n+ " | ||
77 | "/l list (to list friends)|" | ||
78 | "/f ID (to send a friend request)|" | ||
79 | "/a request no. (to accept a friend request)|" | ||
80 | "/m friend no. message (to send a message)|" | ||
81 | "/t friend no. filename (to send a file to a friend)"; | ||
82 | |||
83 | /* 166 characters */ | ||
84 | char *help_group = | ||
85 | "[i] Available group commands:\n+ " | ||
86 | "/g (to create a new group)|" | ||
87 | "/i friend no. group no. (to invite a friend to a group)|" | ||
88 | "/z group no. message (to send a message to a group)"; | ||
89 | |||
60 | int x, y; | 90 | int x, y; |
61 | 91 | ||
62 | typedef struct { | 92 | typedef struct { |
@@ -207,18 +237,28 @@ void get_id(Tox *m, char *data) | |||
207 | } | 237 | } |
208 | } | 238 | } |
209 | 239 | ||
210 | void new_lines(char *line) | 240 | void new_lines_mark(char *line, uint8_t special) |
211 | { | 241 | { |
212 | int i = 0; | 242 | int i = 0; |
213 | 243 | ||
214 | for (i = HISTORY - 1; i > 0; i--) | 244 | for (i = HISTORY - 1; i > 0; i--) { |
215 | strncpy(lines[i], lines[i - 1], STRING_LENGTH - 1); | 245 | strncpy(lines[i], lines[i - 1], STRING_LENGTH - 1); |
246 | flag[i] = flag[i - 1]; | ||
247 | } | ||
216 | 248 | ||
217 | strncpy(lines[0], line, STRING_LENGTH - 1); | 249 | strncpy(lines[0], line, STRING_LENGTH - 1); |
250 | flag[i] = special; | ||
251 | |||
218 | do_refresh(); | 252 | do_refresh(); |
219 | } | 253 | } |
220 | 254 | ||
255 | void new_lines(char *line) | ||
256 | { | ||
257 | new_lines_mark(line, 0); | ||
258 | } | ||
221 | 259 | ||
260 | |||
261 | const char ptrn_friend[] = "[i] Friend: %s\n+ id: %i"; | ||
222 | void print_friendlist(Tox *m) | 262 | void print_friendlist(Tox *m) |
223 | { | 263 | { |
224 | char name[TOX_MAX_NAME_LENGTH]; | 264 | char name[TOX_MAX_NAME_LENGTH]; |
@@ -226,13 +266,13 @@ void print_friendlist(Tox *m) | |||
226 | new_lines("[i] Friend List:"); | 266 | new_lines("[i] Friend List:"); |
227 | 267 | ||
228 | while (tox_getname(m, i, (uint8_t *)name) != -1) { | 268 | while (tox_getname(m, i, (uint8_t *)name) != -1) { |
229 | /* account for the longest name and the longest "base" string */ | 269 | /* account for the longest name and the longest "base" string and number (int) */ |
230 | char fstring[TOX_MAX_NAME_LENGTH + strlen("[i] Friend: NULL\n\tid: ")]; | 270 | char fstring[TOX_MAX_NAME_LENGTH + strlen(ptrn_friend) + 21]; |
231 | 271 | ||
232 | if (strlen(name) <= 0) { | 272 | if (strlen(name) <= 0) { |
233 | sprintf(fstring, "[i] Friend: No Friend!\n\tid: %i", i); | 273 | sprintf(fstring, ptrn_friend, "No name?", i); |
234 | } else { | 274 | } else { |
235 | sprintf(fstring, "[i] Friend: %s\n\tid: %i", (uint8_t *)name, i); | 275 | sprintf(fstring, ptrn_friend, (uint8_t *)name, i); |
236 | } | 276 | } |
237 | 277 | ||
238 | i++; | 278 | i++; |
@@ -240,7 +280,7 @@ void print_friendlist(Tox *m) | |||
240 | } | 280 | } |
241 | 281 | ||
242 | if (i == 0) | 282 | if (i == 0) |
243 | new_lines("\tno friends! D:"); | 283 | new_lines("+ no friends! D:"); |
244 | } | 284 | } |
245 | 285 | ||
246 | char *format_message(Tox *m, char *message, int friendnum) | 286 | char *format_message(Tox *m, char *message, int friendnum) |
@@ -329,7 +369,6 @@ void line_eval(Tox *m, char *line) | |||
329 | } | 369 | } |
330 | 370 | ||
331 | new_lines(numstring); | 371 | new_lines(numstring); |
332 | do_refresh(); | ||
333 | } else if (inpt_command == 'd') { | 372 | } else if (inpt_command == 'd') { |
334 | tox_do(m); | 373 | tox_do(m); |
335 | } else if (inpt_command == 'm') { //message command: /m friendnumber messsage | 374 | } else if (inpt_command == 'm') { //message command: /m friendnumber messsage |
@@ -400,10 +439,18 @@ void line_eval(Tox *m, char *line) | |||
400 | new_lines(numchar); | 439 | new_lines(numchar); |
401 | } | 440 | } |
402 | } | 441 | } |
403 | |||
404 | do_refresh(); | ||
405 | } else if (inpt_command == 'h') { //help | 442 | } else if (inpt_command == 'h') { //help |
406 | new_lines(help); | 443 | if (line[2] == ' ') { |
444 | if (line[3] == 'f') { | ||
445 | new_lines_mark(help_friend, 1); | ||
446 | return; | ||
447 | } else if (line[3] == 'g') { | ||
448 | new_lines_mark(help_group, 1); | ||
449 | return; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | new_lines_mark(help_main, 1); | ||
407 | } else if (inpt_command == 'x') { //info | 454 | } else if (inpt_command == 'x') { //info |
408 | char idstring[200]; | 455 | char idstring[200]; |
409 | get_id(m, idstring); | 456 | get_id(m, idstring); |
@@ -453,20 +500,132 @@ void line_eval(Tox *m, char *line) | |||
453 | } | 500 | } |
454 | } | 501 | } |
455 | 502 | ||
503 | /* basic wrap, ignores embedded '\t', '\n' or '|' */ | ||
456 | void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width) | 504 | void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width) |
457 | { | 505 | { |
458 | strcpy(output, input); | 506 | strcpy(output, input); |
459 | size_t i, len = strlen(output); | 507 | size_t i, k, m, len = strlen(output); |
460 | 508 | ||
461 | for (i = line_width; i < len; i = i + line_width) { | 509 | for (i = line_width; i < len; i = i + line_width) { |
462 | while (output[i] != ' ' && i != 0) { | 510 | /* look backward for a space to turn into a new line */ |
463 | i--; | 511 | k = i; |
512 | m = i - line_width; | ||
513 | |||
514 | while (output[k] != ' ' && k > m) { | ||
515 | k--; | ||
516 | } | ||
517 | |||
518 | if (k > 0) { | ||
519 | /* replace and set as new line start */ | ||
520 | output[k] = '\n'; | ||
521 | i = k + 1; | ||
522 | } else { | ||
523 | /* nothing found backwards: look forward */ | ||
524 | while ((i < len) && (output[i] != ' ')) | ||
525 | i++; | ||
526 | |||
527 | if (i < len) | ||
528 | output[i] = '\n'; | ||
464 | } | 529 | } |
530 | } | ||
531 | } | ||
532 | |||
533 | /* | ||
534 | * extended wrap, honors '\n', accepts '|' as "break here when necessary" | ||
535 | * marks wrapped lines with "+ " in front, which does expand output | ||
536 | * does NOT honor '\t': would require a lot more work (and tab width isn't always 8) | ||
537 | */ | ||
538 | void wrap_bars(char output[STRING_LENGTH], char input[STRING_LENGTH], size_t line_width) | ||
539 | { | ||
540 | size_t len = strlen(input); | ||
541 | size_t ipos, opos = 0; | ||
542 | size_t bar_avail = 0, space_avail = 0, nl_got = 0; /* in opos */ | ||
543 | |||
544 | for (ipos = 0; ipos < len; ipos++) { | ||
545 | if (opos - nl_got < line_width) { | ||
546 | /* not yet at the limit */ | ||
547 | char c = input[ipos]; | ||
548 | |||
549 | if (c == ' ') | ||
550 | space_avail = opos; | ||
551 | |||
552 | output[opos++] = input[ipos]; | ||
553 | |||
554 | if (opos >= STRING_LENGTH) { | ||
555 | opos = STRING_LENGTH - 1; | ||
556 | break; | ||
557 | } | ||
558 | |||
559 | if (c == '|') { | ||
560 | output[opos - 1] = ' '; | ||
561 | bar_avail = opos; | ||
562 | |||
563 | if (opos + 2 >= STRING_LENGTH) { | ||
564 | opos = STRING_LENGTH - 1; | ||
565 | break; | ||
566 | } | ||
465 | 567 | ||
466 | if (i > 0) { | 568 | output[opos++] = '|'; |
467 | output[i] = '\n'; | 569 | output[opos++] = ' '; |
570 | } | ||
571 | |||
572 | if (c == '\n') | ||
573 | nl_got = opos; | ||
574 | |||
575 | continue; | ||
576 | } else { | ||
577 | /* at the limit */ | ||
578 | if (bar_avail > nl_got) { | ||
579 | /* overwrite */ | ||
580 | memcpy(output + bar_avail - 1, wrap_cont_str, wrap_cont_len); | ||
581 | nl_got = bar_avail; | ||
582 | |||
583 | ipos--; | ||
584 | continue; | ||
585 | } | ||
586 | |||
587 | if (space_avail > nl_got) { | ||
588 | if (opos + wrap_cont_len - 1 >= STRING_LENGTH) { | ||
589 | opos = STRING_LENGTH - 1; | ||
590 | break; | ||
591 | } | ||
592 | |||
593 | /* move forward by 2 characters */ | ||
594 | memmove(output + space_avail + 3, output + space_avail + 1, opos - (space_avail + 1)); | ||
595 | memcpy(output + space_avail, wrap_cont_str, wrap_cont_len); | ||
596 | nl_got = space_avail + 1; | ||
597 | |||
598 | opos += 2; | ||
599 | ipos--; | ||
600 | continue; | ||
601 | } | ||
602 | |||
603 | char c = input[ipos]; | ||
604 | |||
605 | if ((c == '|') || (c == ' ') || (c == '\n')) { | ||
606 | if (opos + wrap_cont_len >= STRING_LENGTH) { | ||
607 | opos = STRING_LENGTH - 1; | ||
608 | break; | ||
609 | } | ||
610 | |||
611 | memcpy(output + opos, wrap_cont_str, wrap_cont_len); | ||
612 | |||
613 | nl_got = opos; | ||
614 | opos += wrap_cont_len; | ||
615 | } | ||
616 | |||
617 | output[opos++] = input[ipos]; | ||
618 | |||
619 | if (opos >= STRING_LENGTH) { | ||
620 | opos = STRING_LENGTH - 1; | ||
621 | break; | ||
622 | } | ||
623 | |||
624 | continue; | ||
468 | } | 625 | } |
469 | } | 626 | } |
627 | |||
628 | output[opos] = 0; | ||
470 | } | 629 | } |
471 | 630 | ||
472 | int count_lines(char *string) | 631 | int count_lines(char *string) |
@@ -502,7 +661,11 @@ void do_refresh() | |||
502 | int i; | 661 | int i; |
503 | 662 | ||
504 | for (i = 0; i < HISTORY; i++) { | 663 | for (i = 0; i < HISTORY; i++) { |
505 | wrap(wrap_output, lines[i], x); | 664 | if (flag[i]) |
665 | wrap_bars(wrap_output, lines[i], x); | ||
666 | else | ||
667 | wrap(wrap_output, lines[i], x); | ||
668 | |||
506 | L = count_lines(wrap_output); | 669 | L = count_lines(wrap_output); |
507 | count = count + L; | 670 | count = count + L; |
508 | 671 | ||
@@ -635,18 +798,21 @@ static int load_data_or_init(Tox *m, char *path) | |||
635 | return 0; | 798 | return 0; |
636 | } | 799 | } |
637 | 800 | ||
638 | void print_help(void) | 801 | void print_help(char *prog_name) |
639 | { | 802 | { |
640 | printf("nTox %.1f - Command-line tox-core client\n", 0.1); | 803 | printf("nTox %.1f - Command-line tox-core client\n", 0.1); |
641 | puts("Options:"); | 804 | printf("Usage: %s [--ipv4|--ipv6] IP PORT KEY [-f keyfile]\n", prog_name); |
642 | puts("\t-h\t-\tPrint this help and exit."); | 805 | |
643 | puts("\t-f\t-\tSpecify a keyfile to read (or write to) from."); | 806 | puts("Options: (order IS relevant)"); |
807 | puts(" --ipv4 / --ipv6 [Optional] Support IPv4 only or IPv4 & IPv6."); | ||
808 | puts(" IP PORT KEY [REQUIRED] A server to connect to (IP/Port) and its key."); | ||
809 | puts(" -f keyfile [Optional] Specify a keyfile to read from and write to."); | ||
644 | } | 810 | } |
645 | 811 | ||
646 | void print_invite(Tox *m, int friendnumber, uint8_t *group_public_key, void *userdata) | 812 | void print_invite(Tox *m, int friendnumber, uint8_t *group_public_key, void *userdata) |
647 | { | 813 | { |
648 | char msg[256]; | 814 | char msg[256]; |
649 | sprintf(msg, "[i] recieved group chat invite from: %u, auto accepting and joining. group number: %u", friendnumber, | 815 | sprintf(msg, "[i] received group chat invite from: %u, auto accepting and joining. group number: %u", friendnumber, |
650 | tox_join_groupchat(m, friendnumber, group_public_key)); | 816 | tox_join_groupchat(m, friendnumber, group_public_key)); |
651 | new_lines(msg); | 817 | new_lines(msg); |
652 | } | 818 | } |
@@ -713,7 +879,12 @@ void write_file(Tox *m, int friendnumber, uint8_t filenumber, uint8_t *data, uin | |||
713 | int main(int argc, char *argv[]) | 879 | int main(int argc, char *argv[]) |
714 | { | 880 | { |
715 | if (argc < 4) { | 881 | if (argc < 4) { |
716 | printf("Usage: %s [--ipv4|--ipv6] IP PORT KEY [-f keyfile]\n", argv[0]); | 882 | if ((argc == 2) && !strcmp(argv[1], "-h")) { |
883 | print_help(argv[0]); | ||
884 | exit(0); | ||
885 | } | ||
886 | |||
887 | printf("Usage: %s [--ipv4|--ipv6] IP PORT KEY [-f keyfile] (or %s -h for help)\n", argv[0], argv[0]); | ||
717 | exit(0); | 888 | exit(0); |
718 | } | 889 | } |
719 | 890 | ||
@@ -730,11 +901,6 @@ int main(int argc, char *argv[]) | |||
730 | char idstring[200] = {0}; | 901 | char idstring[200] = {0}; |
731 | Tox *m; | 902 | Tox *m; |
732 | 903 | ||
733 | if ((argc == 2) && !strcmp(argv[1], "-h")) { | ||
734 | print_help(); | ||
735 | exit(0); | ||
736 | } | ||
737 | |||
738 | /* [-f keyfile] MUST be last two arguments, no point in walking over the list | 904 | /* [-f keyfile] MUST be last two arguments, no point in walking over the list |
739 | * especially not a good idea to accept it anywhere in the middle */ | 905 | * especially not a good idea to accept it anywhere in the middle */ |
740 | if (argc > argvoffset + 3) | 906 | if (argc > argvoffset + 3) |
diff --git a/testing/nTox.h b/testing/nTox.h index a72ce0c2..44def142 100644 --- a/testing/nTox.h +++ b/testing/nTox.h | |||
@@ -24,24 +24,19 @@ | |||
24 | #ifndef NTOX_H | 24 | #ifndef NTOX_H |
25 | #define NTOX_H | 25 | #define NTOX_H |
26 | 26 | ||
27 | #include <stdio.h> | 27 | /* |
28 | #include <stdlib.h> | 28 | * module actually exports nothing for the outside |
29 | #include <string.h> | 29 | */ |
30 | #include <curses.h> | 30 | |
31 | #include <ctype.h> | 31 | #include <ctype.h> |
32 | #include <curses.h> | ||
32 | 33 | ||
33 | #include "../toxcore/tox.h" | 34 | #include "../toxcore/tox.h" |
34 | 35 | ||
35 | #define STRING_LENGTH 256 | 36 | #define STRING_LENGTH 256 |
36 | #define HISTORY 50 | 37 | #define HISTORY 50 |
37 | #define PUB_KEY_BYTES 32 | ||
38 | 38 | ||
39 | uint32_t resolve_addr(const char *address); | ||
40 | void new_lines(char *line); | 39 | void new_lines(char *line); |
41 | void line_eval(Tox *m, char *line); | ||
42 | void wrap(char output[STRING_LENGTH], char input[STRING_LENGTH], int line_width) ; | ||
43 | int count_lines(char *string) ; | ||
44 | char *appender(char *str, const char c); | ||
45 | void do_refresh(); | 40 | void do_refresh(); |
46 | 41 | ||
47 | #endif | 42 | #endif |