aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2014-04-05 22:57:46 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2014-04-05 22:57:46 +0200
commit32afd3aa6039b911816a68972b2366095cb777de (patch)
tree0012b72050ed4be21829148bf6cc51fcf3db9d26
parente7430867a8ad61bbea20d05fc2f9fc5094e211dc (diff)
downloadbusybox-w32-32afd3aa6039b911816a68972b2366095cb777de.tar.gz
busybox-w32-32afd3aa6039b911816a68972b2366095cb777de.tar.bz2
busybox-w32-32afd3aa6039b911816a68972b2366095cb777de.zip
vi: some simplifications
function old new delta file_insert 301 315 +14 init_text_buffer 179 171 -8 colon 2889 2878 -11 file_size 37 - -37 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/2 up/down: 14/-56) Total: -42 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/vi.c236
1 files changed, 120 insertions, 116 deletions
diff --git a/editors/vi.c b/editors/vi.c
index a978e0fcb..24a9f60a8 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -491,7 +491,6 @@ struct globals {
491} while (0) 491} while (0)
492 492
493 493
494static int init_text_buffer(char *); // init from file or create new
495static void edit_file(char *); // edit one file 494static void edit_file(char *); // edit one file
496static void do_cmd(int); // execute a command 495static void do_cmd(int); // execute a command
497static int next_tabstop(int); 496static int next_tabstop(int);
@@ -543,7 +542,6 @@ static void cookmode(void); // return to "cooked" mode on tty
543static int mysleep(int); 542static int mysleep(int);
544static int readit(void); // read (maybe cursor) key from stdin 543static int readit(void); // read (maybe cursor) key from stdin
545static int get_one_char(void); // read 1 char from stdin 544static int get_one_char(void); // read 1 char from stdin
546static int file_size(const char *); // what is the byte size of "fn"
547#if !ENABLE_FEATURE_VI_READONLY 545#if !ENABLE_FEATURE_VI_READONLY
548#define file_insert(fn, p, update_ro_status) file_insert(fn, p) 546#define file_insert(fn, p, update_ro_status) file_insert(fn, p)
549#endif 547#endif
@@ -578,8 +576,8 @@ static char *char_search(char *, const char *, int, int); // search for pattern
578#if ENABLE_FEATURE_VI_COLON 576#if ENABLE_FEATURE_VI_COLON
579static char *get_one_address(char *, int *); // get colon addr, if present 577static char *get_one_address(char *, int *); // get colon addr, if present
580static char *get_address(char *, int *, int *); // get two colon addrs, if present 578static char *get_address(char *, int *, int *); // get two colon addrs, if present
581static void colon(char *); // execute the "colon" mode cmds
582#endif 579#endif
580static void colon(char *); // execute the "colon" mode cmds
583#if ENABLE_FEATURE_VI_USE_SIGNALS 581#if ENABLE_FEATURE_VI_USE_SIGNALS
584static void winch_sig(int); // catch window size changes 582static void winch_sig(int); // catch window size changes
585static void suspend_sig(int); // catch ctrl-Z 583static void suspend_sig(int); // catch ctrl-Z
@@ -725,32 +723,29 @@ int vi_main(int argc, char **argv)
725static int init_text_buffer(char *fn) 723static int init_text_buffer(char *fn)
726{ 724{
727 int rc; 725 int rc;
728 int size = file_size(fn); // file size. -1 means does not exist.
729 726
730 flush_undo_data(); 727 flush_undo_data();
728 modified_count = 0;
729 last_modified_count = -1;
730#if ENABLE_FEATURE_VI_YANKMARK
731 /* init the marks */
732 memset(mark, 0, sizeof(mark));
733#endif
731 734
732 /* allocate/reallocate text buffer */ 735 /* allocate/reallocate text buffer */
733 free(text); 736 free(text);
734 text_size = size + 10240; 737 text_size = 10240;
735 screenbegin = dot = end = text = xzalloc(text_size); 738 screenbegin = dot = end = text = xzalloc(text_size);
736 739
737 if (fn != current_filename) { 740 if (fn != current_filename) {
738 free(current_filename); 741 free(current_filename);
739 current_filename = xstrdup(fn); 742 current_filename = xstrdup(fn);
740 } 743 }
741 if (size < 0) { 744 rc = file_insert(fn, text, 1);
745 if (rc < 0) {
742 // file doesnt exist. Start empty buf with dummy line 746 // file doesnt exist. Start empty buf with dummy line
743 char_insert(text, '\n', NO_UNDO); 747 char_insert(text, '\n', NO_UNDO);
744 rc = 0;
745 } else {
746 rc = file_insert(fn, text, 1);
747 } 748 }
748 modified_count = 0;
749 last_modified_count = -1;
750#if ENABLE_FEATURE_VI_YANKMARK
751 /* init the marks. */
752 memset(mark, 0, sizeof(mark));
753#endif
754 return rc; 749 return rc;
755} 750}
756 751
@@ -1018,13 +1013,71 @@ static void setops(const char *args, const char *opname, int flg_no,
1018} 1013}
1019#endif 1014#endif
1020 1015
1016#endif /* FEATURE_VI_COLON */
1017
1021// buf must be no longer than MAX_INPUT_LEN! 1018// buf must be no longer than MAX_INPUT_LEN!
1022static void colon(char *buf) 1019static void colon(char *buf)
1023{ 1020{
1021#if !ENABLE_FEATURE_VI_COLON
1022 /* Simple ":cmd" handler with minimal set of commands */
1023 char *p = buf;
1024 int cnt;
1025
1026 if (*p == ':')
1027 p++;
1028 cnt = strlen(p);
1029 if (cnt == 0)
1030 return;
1031 if (strncmp(p, "quit", cnt) == 0
1032 || strncmp(p, "q!", cnt) == 0
1033 ) {
1034 if (modified_count && p[1] != '!') {
1035 status_line_bold("No write since last change (:%s! overrides)", p);
1036 } else {
1037 editing = 0;
1038 }
1039 return;
1040 }
1041 if (strncmp(p, "write", cnt) == 0
1042 || strncmp(p, "wq", cnt) == 0
1043 || strncmp(p, "wn", cnt) == 0
1044 || (p[0] == 'x' && !p[1])
1045 ) {
1046 cnt = file_write(current_filename, text, end - 1);
1047 if (cnt < 0) {
1048 if (cnt == -1)
1049 status_line_bold("Write error: %s", strerror(errno));
1050 } else {
1051 modified_count = 0;
1052 last_modified_count = -1;
1053 status_line("'%s' %dL, %dC",
1054 current_filename,
1055 count_lines(text, end - 1), cnt
1056 );
1057 if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
1058 || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
1059 ) {
1060 editing = 0;
1061 }
1062 }
1063 return;
1064 }
1065 if (strncmp(p, "file", cnt) == 0) {
1066 last_status_cksum = 0; // force status update
1067 return;
1068 }
1069 if (sscanf(p, "%d", &cnt) > 0) {
1070 dot = find_line(cnt);
1071 dot_skip_over_ws();
1072 return;
1073 }
1074 not_implemented(p);
1075#else
1076
1024 char c, *orig_buf, *buf1, *q, *r; 1077 char c, *orig_buf, *buf1, *q, *r;
1025 char *fn, cmd[MAX_INPUT_LEN], args[MAX_INPUT_LEN]; 1078 char *fn, cmd[MAX_INPUT_LEN], args[MAX_INPUT_LEN];
1026 int i, l, li, ch, b, e; 1079 int i, l, li, b, e;
1027 int useforce, forced = FALSE; 1080 int useforce;
1028 1081
1029 // :3154 // if (-e line 3154) goto it else stay put 1082 // :3154 // if (-e line 3154) goto it else stay put
1030 // :4,33w! foo // write a portion of buffer to file "foo" 1083 // :4,33w! foo // write a portion of buffer to file "foo"
@@ -1046,7 +1099,7 @@ static void colon(char *buf)
1046 if (*buf == ':') 1099 if (*buf == ':')
1047 buf++; // move past the ':' 1100 buf++; // move past the ':'
1048 1101
1049 li = ch = i = 0; 1102 li = i = 0;
1050 b = e = -1; 1103 b = e = -1;
1051 q = text; // assume 1,$ for the range 1104 q = text; // assume 1,$ for the range
1052 r = end - 1; 1105 r = end - 1;
@@ -1127,6 +1180,8 @@ static void colon(char *buf)
1127 dot = yank_delete(q, r, 1, YANKDEL, ALLOW_UNDO); // save, then delete lines 1180 dot = yank_delete(q, r, 1, YANKDEL, ALLOW_UNDO); // save, then delete lines
1128 dot_skip_over_ws(); 1181 dot_skip_over_ws();
1129 } else if (strncmp(cmd, "edit", i) == 0) { // Edit a file 1182 } else if (strncmp(cmd, "edit", i) == 0) { // Edit a file
1183 int size;
1184
1130 // don't edit, if the current file has been modified 1185 // don't edit, if the current file has been modified
1131 if (modified_count && !useforce) { 1186 if (modified_count && !useforce) {
1132 status_line_bold("No write since last change (:%s! overrides)", cmd); 1187 status_line_bold("No write since last change (:%s! overrides)", cmd);
@@ -1144,8 +1199,7 @@ static void colon(char *buf)
1144 goto ret; 1199 goto ret;
1145 } 1200 }
1146 1201
1147 if (init_text_buffer(fn) < 0) 1202 size = init_text_buffer(fn);
1148 goto ret;
1149 1203
1150#if ENABLE_FEATURE_VI_YANKMARK 1204#if ENABLE_FEATURE_VI_YANKMARK
1151 if (Ureg >= 0 && Ureg < 28) { 1205 if (Ureg >= 0 && Ureg < 28) {
@@ -1161,12 +1215,14 @@ static void colon(char *buf)
1161 li = count_lines(text, end - 1); 1215 li = count_lines(text, end - 1);
1162 status_line("'%s'%s" 1216 status_line("'%s'%s"
1163 IF_FEATURE_VI_READONLY("%s") 1217 IF_FEATURE_VI_READONLY("%s")
1164 " %dL, %dC", current_filename, 1218 " %dL, %dC",
1165 (file_size(fn) < 0 ? " [New file]" : ""), 1219 current_filename,
1220 (size < 0 ? " [New file]" : ""),
1166 IF_FEATURE_VI_READONLY( 1221 IF_FEATURE_VI_READONLY(
1167 ((readonly_mode) ? " [Readonly]" : ""), 1222 ((readonly_mode) ? " [Readonly]" : ""),
1168 ) 1223 )
1169 li, ch); 1224 li, (int)(end - text)
1225 );
1170 } else if (strncmp(cmd, "file", i) == 0) { // what File is this 1226 } else if (strncmp(cmd, "file", i) == 0) { // what File is this
1171 if (b != -1 || e != -1) { 1227 if (b != -1 || e != -1) {
1172 status_line_bold("No address allowed on this command"); 1228 status_line_bold("No address allowed on this command");
@@ -1255,6 +1311,8 @@ static void colon(char *buf)
1255 } 1311 }
1256 editing = 0; 1312 editing = 0;
1257 } else if (strncmp(cmd, "read", i) == 0) { // read file into text[] 1313 } else if (strncmp(cmd, "read", i) == 0) { // read file into text[]
1314 int size;
1315
1258 fn = args; 1316 fn = args;
1259 if (!fn[0]) { 1317 if (!fn[0]) {
1260 status_line_bold("No filename given"); 1318 status_line_bold("No filename given");
@@ -1268,23 +1326,24 @@ static void colon(char *buf)
1268 q = next_line(q); 1326 q = next_line(q);
1269 { // dance around potentially-reallocated text[] 1327 { // dance around potentially-reallocated text[]
1270 uintptr_t ofs = q - text; 1328 uintptr_t ofs = q - text;
1271 ch = file_insert(fn, q, 0); 1329 size = file_insert(fn, q, /*update_ro:*/ 0);
1272 q = text + ofs; 1330 q = text + ofs;
1273 } 1331 }
1274 if (ch < 0) 1332 if (size < 0)
1275 goto ret; // nothing was inserted 1333 goto ret; // nothing was inserted
1276 // how many lines in text[]? 1334 // how many lines in text[]?
1277 li = count_lines(q, q + ch - 1); 1335 li = count_lines(q, q + size - 1);
1278 status_line("'%s'" 1336 status_line("'%s'"
1279 IF_FEATURE_VI_READONLY("%s") 1337 IF_FEATURE_VI_READONLY("%s")
1280 " %dL, %dC", fn, 1338 " %dL, %dC",
1339 fn,
1281 IF_FEATURE_VI_READONLY((readonly_mode ? " [Readonly]" : ""),) 1340 IF_FEATURE_VI_READONLY((readonly_mode ? " [Readonly]" : ""),)
1282 li, ch); 1341 li, size
1283 if (ch > 0) { 1342 );
1343 if (size > 0) {
1284 // if the insert is before "dot" then we need to update 1344 // if the insert is before "dot" then we need to update
1285 if (q <= dot) 1345 if (q <= dot)
1286 dot += ch; 1346 dot += size;
1287 // modified_count++;
1288 } 1347 }
1289 } else if (strncmp(cmd, "rewind", i) == 0) { // rewind cmd line args 1348 } else if (strncmp(cmd, "rewind", i) == 0) { // rewind cmd line args
1290 if (modified_count && !useforce) { 1349 if (modified_count && !useforce) {
@@ -1409,6 +1468,9 @@ static void colon(char *buf)
1409 || strncmp(cmd, "wn", i) == 0 1468 || strncmp(cmd, "wn", i) == 0
1410 || (cmd[0] == 'x' && !cmd[1]) 1469 || (cmd[0] == 'x' && !cmd[1])
1411 ) { 1470 ) {
1471 int size;
1472 //int forced = FALSE;
1473
1412 // is there a file name to write to? 1474 // is there a file name to write to?
1413 if (args[0]) { 1475 if (args[0]) {
1414 fn = args; 1476 fn = args;
@@ -1421,34 +1483,33 @@ static void colon(char *buf)
1421#endif 1483#endif
1422 // how many lines in text[]? 1484 // how many lines in text[]?
1423 li = count_lines(q, r); 1485 li = count_lines(q, r);
1424 ch = r - q + 1; 1486 size = r - q + 1;
1425 // see if file exists- if not, its just a new file request 1487 //if (useforce) {
1426 if (useforce) {
1427 // if "fn" is not write-able, chmod u+w 1488 // if "fn" is not write-able, chmod u+w
1428 // sprintf(syscmd, "chmod u+w %s", fn); 1489 // sprintf(syscmd, "chmod u+w %s", fn);
1429 // system(syscmd); 1490 // system(syscmd);
1430 forced = TRUE; 1491 // forced = TRUE;
1431 } 1492 //}
1432 l = file_write(fn, q, r); 1493 l = file_write(fn, q, r);
1433 if (useforce && forced) { 1494 //if (useforce && forced) {
1434 // chmod u-w 1495 // chmod u-w
1435 // sprintf(syscmd, "chmod u-w %s", fn); 1496 // sprintf(syscmd, "chmod u-w %s", fn);
1436 // system(syscmd); 1497 // system(syscmd);
1437 forced = FALSE; 1498 // forced = FALSE;
1438 } 1499 //}
1439 if (l < 0) { 1500 if (l < 0) {
1440 if (l == -1) 1501 if (l == -1)
1441 status_line_bold_errno(fn); 1502 status_line_bold_errno(fn);
1442 } else { 1503 } else {
1443 status_line("'%s' %dL, %dC", fn, li, l); 1504 status_line("'%s' %dL, %dC", fn, li, l);
1444 if (q == text && r == end - 1 && l == ch) { 1505 if (q == text && r == end - 1 && l == size) {
1445 modified_count = 0; 1506 modified_count = 0;
1446 last_modified_count = -1; 1507 last_modified_count = -1;
1447 } 1508 }
1448 if ((cmd[0] == 'x' || cmd[1] == 'q' || cmd[1] == 'n' 1509 if ((cmd[0] == 'x' || cmd[1] == 'q' || cmd[1] == 'n'
1449 || cmd[0] == 'X' || cmd[1] == 'Q' || cmd[1] == 'N' 1510 || cmd[0] == 'X' || cmd[1] == 'Q' || cmd[1] == 'N'
1450 ) 1511 )
1451 && l == ch 1512 && l == size
1452 ) { 1513 ) {
1453 editing = 0; 1514 editing = 0;
1454 } 1515 }
@@ -1475,9 +1536,8 @@ static void colon(char *buf)
1475 colon_s_fail: 1536 colon_s_fail:
1476 status_line(":s expression missing delimiters"); 1537 status_line(":s expression missing delimiters");
1477#endif 1538#endif
1478}
1479
1480#endif /* FEATURE_VI_COLON */ 1539#endif /* FEATURE_VI_COLON */
1540}
1481 1541
1482static void Hit_Return(void) 1542static void Hit_Return(void)
1483{ 1543{
@@ -2851,17 +2911,6 @@ static char *get_input_line(const char *prompt)
2851#undef buf 2911#undef buf
2852} 2912}
2853 2913
2854static int file_size(const char *fn) // what is the byte size of "fn"
2855{
2856 struct stat st_buf;
2857 int cnt;
2858
2859 cnt = -1;
2860 if (fn && stat(fn, &st_buf) == 0) // see if file exists
2861 cnt = (int) st_buf.st_size;
2862 return cnt;
2863}
2864
2865// might reallocate text[]! 2914// might reallocate text[]!
2866static int file_insert(const char *fn, char *p, int update_ro_status) 2915static int file_insert(const char *fn, char *p, int update_ro_status)
2867{ 2916{
@@ -2869,42 +2918,40 @@ static int file_insert(const char *fn, char *p, int update_ro_status)
2869 int fd, size; 2918 int fd, size;
2870 struct stat statbuf; 2919 struct stat statbuf;
2871 2920
2872 /* Validate file */
2873 if (stat(fn, &statbuf) < 0) {
2874 status_line_bold_errno(fn);
2875 goto fi0;
2876 }
2877 if (!S_ISREG(statbuf.st_mode)) {
2878 // This is not a regular file
2879 status_line_bold("'%s' is not a regular file", fn);
2880 goto fi0;
2881 }
2882 if (p < text || p > end) { 2921 if (p < text || p > end) {
2883 status_line_bold("Trying to insert file outside of memory"); 2922 status_line_bold("Trying to insert file outside of memory");
2884 goto fi0; 2923 return cnt;
2885 } 2924 }
2886 2925
2887 // read file to buffer
2888 fd = open(fn, O_RDONLY); 2926 fd = open(fn, O_RDONLY);
2889 if (fd < 0) { 2927 if (fd < 0) {
2890 status_line_bold_errno(fn); 2928 status_line_bold_errno(fn);
2891 goto fi0; 2929 return cnt;
2930 }
2931
2932 /* Validate file */
2933 if (fstat(fd, &statbuf) < 0) {
2934 status_line_bold_errno(fn);
2935 goto fi;
2936 }
2937 if (!S_ISREG(statbuf.st_mode)) {
2938 status_line_bold("'%s' is not a regular file", fn);
2939 goto fi;
2892 } 2940 }
2893 size = (statbuf.st_size < INT_MAX ? (int)statbuf.st_size : INT_MAX); 2941 size = (statbuf.st_size < INT_MAX ? (int)statbuf.st_size : INT_MAX);
2894 p += text_hole_make(p, size); 2942 p += text_hole_make(p, size);
2895 cnt = safe_read(fd, p, size); 2943 cnt = full_read(fd, p, size);
2896 if (cnt < 0) { 2944 if (cnt < 0) {
2897 status_line_bold_errno(fn); 2945 status_line_bold_errno(fn);
2898 p = text_hole_delete(p, p + size - 1, NO_UNDO); // un-do buffer insert 2946 p = text_hole_delete(p, p + size - 1, NO_UNDO); // un-do buffer insert
2899 } else if (cnt < size) { 2947 } else if (cnt < size) {
2900 // There was a partial read, shrink unused space text[] 2948 // There was a partial read, shrink unused space
2901 p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO); // un-do buffer insert 2949 p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO);
2902 status_line_bold("can't read '%s'", fn); 2950 status_line_bold("can't read '%s'", fn);
2903 } 2951 }
2904// if (cnt >= size) 2952 fi:
2905// modified_count++;
2906 close(fd); 2953 close(fd);
2907 fi0: 2954
2908#if ENABLE_FEATURE_VI_READONLY 2955#if ENABLE_FEATURE_VI_READONLY
2909 if (update_ro_status 2956 if (update_ro_status
2910 && ((access(fn, W_OK) < 0) || 2957 && ((access(fn, W_OK) < 0) ||
@@ -3821,50 +3868,7 @@ static void do_cmd(int c)
3821 break; 3868 break;
3822 case ':': // :- the colon mode commands 3869 case ':': // :- the colon mode commands
3823 p = get_input_line(":"); // get input line- use "status line" 3870 p = get_input_line(":"); // get input line- use "status line"
3824#if ENABLE_FEATURE_VI_COLON
3825 colon(p); // execute the command 3871 colon(p); // execute the command
3826#else
3827 if (*p == ':')
3828 p++; // move past the ':'
3829 cnt = strlen(p);
3830 if (cnt <= 0)
3831 break;
3832 if (strncmp(p, "quit", cnt) == 0
3833 || strncmp(p, "q!", cnt) == 0 // delete lines
3834 ) {
3835 if (modified_count && p[1] != '!') {
3836 status_line_bold("No write since last change (:%s! overrides)", p);
3837 } else {
3838 editing = 0;
3839 }
3840 } else if (strncmp(p, "write", cnt) == 0
3841 || strncmp(p, "wq", cnt) == 0
3842 || strncmp(p, "wn", cnt) == 0
3843 || (p[0] == 'x' && !p[1])
3844 ) {
3845 cnt = file_write(current_filename, text, end - 1);
3846 if (cnt < 0) {
3847 if (cnt == -1)
3848 status_line_bold("Write error: %s", strerror(errno));
3849 } else {
3850 modified_count = 0;
3851 last_modified_count = -1;
3852 status_line("'%s' %dL, %dC", current_filename, count_lines(text, end - 1), cnt);
3853 if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
3854 || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
3855 ) {
3856 editing = 0;
3857 }
3858 }
3859 } else if (strncmp(p, "file", cnt) == 0) {
3860 last_status_cksum = 0; // force status update
3861 } else if (sscanf(p, "%d", &j) > 0) {
3862 dot = find_line(j); // go to line # j
3863 dot_skip_over_ws();
3864 } else { // unrecognized cmd
3865 not_implemented(p);
3866 }
3867#endif /* !FEATURE_VI_COLON */
3868 break; 3872 break;
3869 case '<': // <- Left shift something 3873 case '<': // <- Left shift something
3870 case '>': // >- Right shift something 3874 case '>': // >- Right shift something