#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
-/* Return an int indicating the result of comparing two integers.
- Subtracting doesn't always work, due to overflow. */
-#define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b))
-
/* Unix-based readdir implementations have historically returned a dirent.d_ino
value that is sometimes not equal to the stat-obtained st_ino value for
that same entry. This error occurs for a readdir entry that refers
/* Initial size of hash table.
Most hierarchies are likely to be shallower than this. */
-#define INITIAL_TABLE_SIZE 30
+enum { INITIAL_TABLE_SIZE = 30 };
/* The set of 'active' directories, from the current command-line argument
to the level in the hierarchy at which files are being listed.
static char const *hostname;
/* mode of appropriate file for colorization */
-#define FILE_OR_LINK_MODE(File) \
- ((color_symlink_as_referent && (File)->linkok) \
- ? (File)->linkmode : (File)->stat.st_mode)
+static mode_t
+file_or_link_mode (struct fileinfo const *file)
+{
+ return (color_symlink_as_referent && file->linkok
+ ? file->linkmode : file->stat.st_mode);
+}
/* Record of one pending directory waiting to be listed. */
/* The minimum width of a column is 3: 1 character for the name and 2
for the separating white space. */
-#define MIN_COLUMN_WIDTH 3
+enum { MIN_COLUMN_WIDTH = 3 };
-/* This zero-based index is used solely with the --dired option.
- When that option is in effect, this counter is incremented for each
- byte of output generated by this program so that the beginning
+/* This zero-based index is for the --dired option. It is incremented
+ for each byte of output generated by this program so that the beginning
and ending indices (in that output) of every file name can be recorded
and later output themselves. */
static size_t dired_pos;
-#define DIRED_PUTCHAR(c) do {putchar ((c)); ++dired_pos;} while (0)
+static void
+dired_outbyte (char c)
+{
+ dired_pos++;
+ putchar (c);
+}
-/* Write S to STREAM and increment DIRED_POS by S_LEN. */
-#define DIRED_FPUTS(s, stream, s_len) \
- do {fputs (s, stream); dired_pos += s_len;} while (0)
+/* Output the buffer S, of length S_LEN, and increment DIRED_POS by S_LEN. */
+static void
+dired_outbuf (char const *s, size_t s_len)
+{
+ dired_pos += s_len;
+ fwrite (s, sizeof *s, s_len, stdout);
+}
-/* Like DIRED_FPUTS, but for use when S is a literal string. */
-#define DIRED_FPUTS_LITERAL(s, stream) \
- do {fputs (s, stream); dired_pos += sizeof (s) - 1;} while (0)
+/* Output the string S, and increment DIRED_POS by its length. */
+static void
+dired_outstring (char const *s)
+{
+ dired_outbuf (s, strlen (s));
+}
-#define DIRED_INDENT() \
- do \
- { \
- if (dired) \
- DIRED_FPUTS_LITERAL (" ", stdout); \
- } \
- while (0)
+static void
+dired_indent (void)
+{
+ if (dired)
+ dired_outstring (" ");
+}
/* With --dired, store pairs of beginning and ending indices of file names. */
static struct obstack dired_obstack;
static struct obstack subdired_obstack;
/* Save the current index on the specified obstack, OBS. */
-#define PUSH_CURRENT_DIRED_POS(obs) \
- do \
- { \
- if (dired) \
- obstack_grow (obs, &dired_pos, sizeof (dired_pos)); \
- } \
- while (0)
+static void
+push_current_dired_pos (struct obstack *obs)
+{
+ if (dired)
+ obstack_grow (obs, &dired_pos, sizeof dired_pos);
+}
/* With -R, this stack is used to help detect directory cycles.
The device/inode pairs on this stack mirror the pairs in the
return *di;
}
-/* Note the use commented out below:
-#define ASSERT_MATCHING_DEV_INO(Name, Di) \
- do \
- { \
- struct stat sb; \
- assert (Name); \
- assert (0 <= stat (Name, &sb)); \
- assert (sb.st_dev == Di.st_dev); \
- assert (sb.st_ino == Di.st_ino); \
- } \
- while (0)
-*/
+static void
+assert_matching_dev_ino (char const *name, struct dev_ino di)
+{
+ struct stat sb;
+ assert (name);
+ assert (0 <= stat (name, &sb));
+ assert (sb.st_dev == di.st_dev);
+ assert (sb.st_ino == di.st_ino);
+}
/* Write to standard output PREFIX, followed by the quoting style and
a space-separated list of the integers stored in OS all on one line. */
return ret;
}
-static inline int
+static int
do_stat (char const *name, struct stat *st)
{
return do_statx (AT_FDCWD, name, st, 0, calc_req_mask ());
}
-static inline int
+static int
do_lstat (char const *name, struct stat *st)
{
return do_statx (AT_FDCWD, name, st, AT_SYMLINK_NOFOLLOW, calc_req_mask ());
}
-static inline int
+static int
stat_for_mode (char const *name, struct stat *st)
{
return do_statx (AT_FDCWD, name, st, 0, STATX_MODE);
}
/* dev+ino should be static, so no need to sync with backing store */
-static inline int
+static int
stat_for_ino (char const *name, struct stat *st)
{
return do_statx (AT_FDCWD, name, st, 0, STATX_INO);
}
-static inline int
+static int
fstat_for_ino (int fd, struct stat *st)
{
return do_statx (fd, "", st, AT_EMPTY_PATH, STATX_INO);
}
#else
-static inline int
+static int
do_stat (char const *name, struct stat *st)
{
return stat (name, st);
}
-static inline int
+static int
do_lstat (char const *name, struct stat *st)
{
return lstat (name, st);
}
-static inline int
+static int
stat_for_mode (char const *name, struct stat *st)
{
return stat (name, st);
}
-static inline int
+static int
stat_for_ino (char const *name, struct stat *st)
{
return stat (name, st);
}
-static inline int
+static int
fstat_for_ino (int fd, struct stat *st)
{
return fstat (fd, st);
}
}
-static inline void
+static void
signal_init (void)
{
signal_setup (true);
}
-static inline void
+static void
signal_restore (void)
{
signal_setup (false);
{
print_current_files ();
if (pending_dirs)
- DIRED_PUTCHAR ('\n');
+ dired_outbyte ('\n');
}
else if (n_files <= 1 && pending_dirs && pending_dirs->next == 0)
print_dir_name = false;
entry from the active_dir_set hash table. */
struct dev_ino di = dev_ino_pop ();
struct dev_ino *found = hash_remove (active_dir_set, &di);
- /* ASSERT_MATCHING_DEV_INO (thispend->realname, di); */
+ if (false)
+ assert_matching_dev_ino (thispend->realname, di);
assert (found);
dev_ino_free (found);
free_pending_ent (thispend);
if (recursive || print_dir_name)
{
if (!first)
- DIRED_PUTCHAR ('\n');
+ dired_outbyte ('\n');
first = false;
- DIRED_INDENT ();
+ dired_indent ();
char *absolute_name = NULL;
if (print_hyperlink)
free (absolute_name);
- DIRED_FPUTS_LITERAL (":\n", stdout);
+ dired_outstring (":\n");
}
/* Read the directory entries, and insert the subfiles into the 'cwd_file'
if (format == long_format || print_block_size)
{
- char const *p;
- char buf[LONGEST_HUMAN_READABLE + 1];
-
- DIRED_INDENT ();
- p = _("total");
- DIRED_FPUTS (p, stdout, strlen (p));
- DIRED_PUTCHAR (' ');
- p = human_readable (total_blocks, buf, human_output_opts,
- ST_NBLOCKSIZE, output_block_size);
- DIRED_FPUTS (p, stdout, strlen (p));
- DIRED_PUTCHAR ('\n');
+ char buf[LONGEST_HUMAN_READABLE + 3];
+ char *p = human_readable (total_blocks, buf + 1, human_output_opts,
+ ST_NBLOCKSIZE, output_block_size);
+ char *pend = p + strlen (p);
+ *--p = ' ';
+ *pend++ = '\n';
+ dired_indent ();
+ dired_outstring (_("total"));
+ dired_outbuf (p, pend - p);
}
if (cwd_n_used)
typedef void const *V;
typedef int (*qsortFunc)(V a, V b);
-/* Used below in DEFINE_SORT_FUNCTIONS for _df_ sort function variants.
- The do { ... } while(0) makes it possible to use the macro more like
- a statement, without violating C89 rules: */
-#define DIRFIRST_CHECK(a, b) \
- do \
- { \
- bool a_is_dir = is_linked_directory ((struct fileinfo const *) a);\
- bool b_is_dir = is_linked_directory ((struct fileinfo const *) b);\
- if (a_is_dir && !b_is_dir) \
- return -1; /* a goes before b */ \
- if (!a_is_dir && b_is_dir) \
- return 1; /* b goes before a */ \
- } \
- while (0)
+/* Used below in DEFINE_SORT_FUNCTIONS for _df_ sort function variants. */
+static int
+dirfirst_check (struct fileinfo const *a, struct fileinfo const *b,
+ int (*cmp) (V, V))
+{
+ int diff = is_linked_directory (b) - is_linked_directory (a);
+ return diff ? diff : cmp (a, b);
+}
/* Define the 8 different sort function variants required for each sortkey.
KEY_NAME is a token describing the sort key, e.g., ctime, atime, size.
\
/* direct, dirfirst versions */ \
static int xstrcoll_df_##key_name (V a, V b) \
- { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, xstrcoll); } \
+ { return dirfirst_check (a, b, xstrcoll_##key_name); } \
static int _GL_ATTRIBUTE_PURE strcmp_df_##key_name (V a, V b) \
- { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, strcmp); } \
+ { return dirfirst_check (a, b, strcmp_##key_name); } \
\
/* reverse, dirfirst versions */ \
static int rev_xstrcoll_df_##key_name (V a, V b) \
- { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, xstrcoll); } \
+ { return dirfirst_check (a, b, rev_xstrcoll_##key_name); } \
static int _GL_ATTRIBUTE_PURE rev_strcmp_df_##key_name (V a, V b) \
- { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, strcmp); }
+ { return dirfirst_check (a, b, rev_strcmp_##key_name); }
-static inline int
+static int
cmp_ctime (struct fileinfo const *a, struct fileinfo const *b,
int (*cmp) (char const *, char const *))
{
return diff ? diff : cmp (a->name, b->name);
}
-static inline int
+static int
cmp_mtime (struct fileinfo const *a, struct fileinfo const *b,
int (*cmp) (char const *, char const *))
{
return diff ? diff : cmp (a->name, b->name);
}
-static inline int
+static int
cmp_atime (struct fileinfo const *a, struct fileinfo const *b,
int (*cmp) (char const *, char const *))
{
return diff ? diff : cmp (a->name, b->name);
}
-static inline int
+static int
cmp_btime (struct fileinfo const *a, struct fileinfo const *b,
int (*cmp) (char const *, char const *))
{
return diff ? diff : cmp (a->name, b->name);
}
-static inline int
+static int
+off_cmp (off_t a, off_t b)
+{
+ return a < b ? -1 : a > b;
+}
+
+static int
cmp_size (struct fileinfo const *a, struct fileinfo const *b,
int (*cmp) (char const *, char const *))
{
- int diff = longdiff (b->stat.st_size, a->stat.st_size);
+ int diff = off_cmp (b->stat.st_size, a->stat.st_size);
return diff ? diff : cmp (a->name, b->name);
}
-static inline int
+static int
cmp_name (struct fileinfo const *a, struct fileinfo const *b,
int (*cmp) (char const *, char const *))
{
/* Compare file extensions. Files with no extension are 'smallest'.
If extensions are the same, compare by file names instead. */
-static inline int
+static int
cmp_extension (struct fileinfo const *a, struct fileinfo const *b,
int (*cmp) (char const *, char const *))
{
/* Return the (cached) screen width,
for the NAME associated with the passed fileinfo F. */
-static inline size_t
+static size_t
fileinfo_name_width (struct fileinfo const *f)
{
return f->width
: quote_name_width (f->name, filename_quoting_options, f->quoted);
}
-static inline int
+static int
cmp_width (struct fileinfo const *a, struct fileinfo const *b,
int (*cmp) (char const *, char const *))
{
because they all use a string comparison (either as the primary or secondary
sort key), and xstrcoll has the ability to do a longjmp if strcoll fails for
locale reasons. Lastly, filevercmp is ALWAYS available with gnulib. */
-static inline int
+static int
cmp_version (struct fileinfo const *a, struct fileinfo const *b)
{
return filevercmp (a->name, b->name);
}
-static int xstrcoll_version (V a, V b)
-{ return cmp_version (a, b); }
-static int rev_xstrcoll_version (V a, V b)
-{ return cmp_version (b, a); }
-static int xstrcoll_df_version (V a, V b)
-{ DIRFIRST_CHECK (a, b); return cmp_version (a, b); }
-static int rev_xstrcoll_df_version (V a, V b)
-{ DIRFIRST_CHECK (a, b); return cmp_version (b, a); }
+static int
+xstrcoll_version (V a, V b)
+{
+ return cmp_version (a, b);
+}
+static int
+rev_xstrcoll_version (V a, V b)
+{
+ return cmp_version (b, a);
+}
+static int
+xstrcoll_df_version (V a, V b)
+{
+ return dirfirst_check (a, b, xstrcoll_version);
+}
+static int
+rev_xstrcoll_df_version (V a, V b)
+{
+ return dirfirst_check (a, b, rev_xstrcoll_version);
+}
/* We have 2^3 different variants for each sort-key function
{
set_normal_color ();
print_long_format (sorted_file[i]);
- DIRED_PUTCHAR ('\n');
+ dired_outbyte ('\n');
}
break;
}
static void
format_user_or_group (char const *name, unsigned long int id, int width)
{
- size_t len;
-
if (name)
{
int width_gap = width - mbswidth (name, 0);
int pad = MAX (0, width_gap);
- fputs (name, stdout);
- len = strlen (name) + pad;
+ dired_outstring (name);
do
- putchar (' ');
+ dired_outbyte (' ');
while (pad--);
}
else
- {
- printf ("%*lu ", width, id);
- len = width;
- }
-
- dired_pos += len + 1;
+ dired_pos += printf ("%*lu ", width, id);
}
/* Print the name or id of the user with id U, using a print width of
! f->stat_ok ? "?" : umaxtostr (f->stat.st_nlink, hbuf));
}
- DIRED_INDENT ();
+ dired_indent ();
if (print_owner || print_group || print_author || print_scontext)
{
- DIRED_FPUTS (buf, stdout, p - buf);
+ dired_outbuf (buf, p - buf);
if (print_owner)
format_user (f->stat.st_uid, owner_width, f->stat_ok);
six_months_ago.tv_nsec = current_time.tv_nsec;
recent = (timespec_cmp (six_months_ago, when_timespec) < 0
- && (timespec_cmp (when_timespec, current_time) < 0));
+ && timespec_cmp (when_timespec, current_time) < 0);
/* We assume here that all time zones are offset from UTC by a
whole number of seconds. */
{
p += s;
*p++ = ' ';
-
- /* NUL-terminate the string -- fputs (via DIRED_FPUTS) requires it. */
- *p = '\0';
}
else
{
/* FIXME: (maybe) We discarded when_timespec.tv_nsec. */
}
- DIRED_FPUTS (buf, stdout, p - buf);
+ dired_outbuf (buf, p - buf);
size_t w = print_name_with_quoting (f, false, &dired_obstack, p - buf);
if (f->filetype == symbolic_link)
{
if (f->linkname)
{
- DIRED_FPUTS_LITERAL (" -> ", stdout);
+ dired_outstring (" -> ");
print_name_with_quoting (f, true, NULL, (p - buf) + w + 4);
if (indicator_style != none)
print_type_indicator (true, f->linkmode, unknown);
needs_general_quoting, NULL, &pad);
if (pad && allow_pad)
- DIRED_PUTCHAR (' ');
+ dired_outbyte (' ');
if (color)
print_color_indicator (color);
}
if (stack)
- PUSH_CURRENT_DIRED_POS (stack);
+ push_current_dired_pos (stack);
fwrite (buf + skip_quotes, 1, len - (skip_quotes * 2), stdout);
dired_pos += len;
if (stack)
- PUSH_CURRENT_DIRED_POS (stack);
+ push_current_dired_pos (stack);
if (absolute_name)
{
{
char c = get_type_indicator (stat_ok, mode, type);
if (c)
- DIRED_PUTCHAR (c);
+ dired_outbyte (c);
return !!c;
}
else
{
name = f->name;
- mode = FILE_OR_LINK_MODE (f);
+ mode = file_or_link_mode (f);
linkok = f->linkok;
}