ash: fix bug 585 (>"$VAR_WITH_UNICODE_CHARS" problem)
[oweals/busybox.git] / editors / diff.c
index d7eccfbba09fccc5e9f9833d33beed15ddc5be0a..e3933e72424cc22ada27a9a76227e10e0431ac60 100644 (file)
@@ -103,8 +103,8 @@ struct globals {
        smallint exit_status;
        int opt_U_context;
        size_t max_context;     /* size of context_vec_start */
-       USE_FEATURE_DIFF_DIR(int dl_count;)
-       USE_FEATURE_DIFF_DIR(char **dl;)
+       IF_FEATURE_DIFF_DIR(int dl_count;)
+       IF_FEATURE_DIFF_DIR(char **dl;)
        char *opt_S_start;
        const char *label1;
        const char *label2;
@@ -858,7 +858,7 @@ static void print_header(const char *file1, const char *file2)
  * lines appended (beginning at b).  If c is greater than d then there are
  * lines missing from the to file.
  */
-static void change(char *file1, FILE *f1, char *file2, FILE *f2,
+static void change(const char *file1, FILE *f1, const char *file2, FILE *f2,
                        int a, int b, int c, int d)
 {
        if ((a > b && c > d) || (option_mask32 & FLAG_q)) {
@@ -902,7 +902,7 @@ static void change(char *file1, FILE *f1, char *file2, FILE *f2,
 }
 
 
-static void output(char *file1, FILE *f1, char *file2, FILE *f2)
+static void output(const char *file1, FILE *f1, const char *file2, FILE *f2)
 {
        /* Note that j0 and j1 can't be used as they are defined in math.h.
         * This also allows the rather amusing variable 'j00'... */
@@ -999,7 +999,7 @@ static void output(char *file1, FILE *f1, char *file2, FILE *f2)
  */
 /* NB: files can be not REGular. The only sure thing that they
  * are not both DIRectories. */
-static unsigned diffreg(char *file1, char *file2, int flags)
+static unsigned diffreg(const char *file1, const char *file2, int flags)
 {
        int *member;     /* will be overlaid on nfile[1] */
        int *class;      /* will be overlaid on nfile[0] */
@@ -1022,13 +1022,11 @@ static unsigned diffreg(char *file1, char *file2, int flags)
 
        if (flags & D_EMPTY1)
                /* can't be stdin, but xfopen_stdin() is smaller code */
-               f1 = xfopen_stdin(bb_dev_null);
-       else
-               f1 = xfopen_stdin(file1);
+               file1 = bb_dev_null;
+       f1 = xfopen_stdin(file1);
        if (flags & D_EMPTY2)
-               f2 = xfopen_stdin(bb_dev_null);
-       else
-               f2 = xfopen_stdin(file2);
+               file2 = bb_dev_null;
+       f2 = xfopen_stdin(file2);
 
        /* NB: if D_EMPTY1/2 is set, other file is always a regular file,
         * not pipe/fifo/chardev/etc - D_EMPTY is used by "diff -r" only,
@@ -1059,6 +1057,7 @@ static unsigned diffreg(char *file1, char *file2, int flags)
 
        member = (int *) nfile[1];
        equiv(sfile[0], slen[0], sfile[1], slen[1], member);
+//TODO: xrealloc_vector?
        member = xrealloc(member, (slen[1] + 2) * sizeof(int));
 
        class = (int *) nfile[0];
@@ -1164,12 +1163,11 @@ static void do_diff(char *dir1, char *path1, char *dir2, char *path2)
 #if ENABLE_FEATURE_DIFF_DIR
 /* This function adds a filename to dl, the directory listing. */
 static int FAST_FUNC add_to_dirlist(const char *filename,
-               struct stat *sb ATTRIBUTE_UNUSED,
+               struct stat *sb UNUSED_PARAM,
                void *userdata,
-               int depth ATTRIBUTE_UNUSED)
+               int depth UNUSED_PARAM)
 {
-       /* +2: with space for eventual trailing NULL */
-       dl = xrealloc(dl, (dl_count+2) * sizeof(dl[0]));
+       dl = xrealloc_vector(dl, 5, dl_count);
        dl[dl_count] = xstrdup(filename + (int)(ptrdiff_t)userdata);
        dl_count++;
        return TRUE;
@@ -1189,7 +1187,7 @@ static char **get_recursive_dirlist(char *path)
                recursive_action(path, ACTION_RECURSE|ACTION_FOLLOWLINKS,
                                        add_to_dirlist, /* file_action */
                                        NULL, /* dir_action */
-                                       (void*)(strlen(path) + 1),
+                                       (void*)(ptrdiff_t)(strlen(path) + 1),
                                        0);
        } else {
                DIR *dp;
@@ -1271,7 +1269,7 @@ static void diffdir(char *p1, char *p2)
 
 
 int diff_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-int diff_main(int argc ATTRIBUTE_UNUSED, char **argv)
+int diff_main(int argc UNUSED_PARAM, char **argv)
 {
        int gotstdin = 0;
        char *f1, *f2;
@@ -1300,6 +1298,8 @@ int diff_main(int argc ATTRIBUTE_UNUSED, char **argv)
         */
        f1 = argv[0];
        f2 = argv[1];
+       /* Compat: "diff file name_which_doesnt_exist" exits with 2 */
+       xfunc_error_retval = 2;
        if (LONE_DASH(f1)) {
                fstat(STDIN_FILENO, &stb1);
                gotstdin++;
@@ -1310,6 +1310,7 @@ int diff_main(int argc ATTRIBUTE_UNUSED, char **argv)
                gotstdin++;
        } else
                xstat(f2, &stb2);
+       xfunc_error_retval = 1;
 
        if (gotstdin && (S_ISDIR(stb1.st_mode) || S_ISDIR(stb2.st_mode)))
                bb_error_msg_and_die("can't compare stdin to a directory");