📄 ls.c
字号:
case DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION: dereference = DEREF_COMMAND_LINE_SYMLINK_TO_DIR; break; case 'I': add_ignore_pattern (optarg); break; case 'L': dereference = DEREF_ALWAYS; break; case 'N': set_quoting_style (NULL, literal_quoting_style); break; case 'Q': set_quoting_style (NULL, c_quoting_style); break; case 'R': recursive = 1; break; case 'S': sort_type = sort_size; sort_type_specified = 1; break; case 'T': { long int tmp_long; if (xstrtol (optarg, NULL, 0, &tmp_long, NULL) != LONGINT_OK || tmp_long < 0 || tmp_long > INT_MAX) error (EXIT_FAILURE, 0, _("invalid tab size: %s"), quotearg (optarg)); tabsize = (int) tmp_long; break; } case 'U': sort_type = sort_none; sort_type_specified = 1; break; case 'X': sort_type = sort_extension; sort_type_specified = 1; break; case '1': /* -1 has no effect after -l. */ if (format != long_format) format = one_per_line; break; case AUTHOR_OPTION: print_author = true; break; case SORT_OPTION: sort_type = XARGMATCH ("--sort", optarg, sort_args, sort_types); sort_type_specified = 1; break; case TIME_OPTION: time_type = XARGMATCH ("--time", optarg, time_args, time_types); break; case FORMAT_OPTION: format = XARGMATCH ("--format", optarg, format_args, format_types); break; case FULL_TIME_OPTION: format = long_format; time_style_option = "full-iso"; break; case COLOR_OPTION: { int i; if (optarg) i = XARGMATCH ("--color", optarg, color_args, color_types); else /* Using --color with no argument is equivalent to using --color=always. */ i = color_always; print_with_color = (i == color_always || (i == color_if_tty && isatty (STDOUT_FILENO))); if (print_with_color) { /* Don't use TAB characters in output. Some terminal emulators can't handle the combination of tabs and color codes on the same line. */ tabsize = 0; } break; } case INDICATOR_STYLE_OPTION: indicator_style = XARGMATCH ("--indicator-style", optarg, indicator_style_args, indicator_style_types); break; case QUOTING_STYLE_OPTION: set_quoting_style (NULL, XARGMATCH ("--quoting-style", optarg, quoting_style_args, quoting_style_vals)); break; case TIME_STYLE_OPTION: time_style_option = optarg; break; case SHOW_CONTROL_CHARS_OPTION: qmark_funny_chars = 0; break; case BLOCK_SIZE_OPTION: human_output_opts = human_options (optarg, true, &output_block_size); file_output_block_size = output_block_size; break; case SI_OPTION: human_output_opts = human_autoscale | human_SI; file_output_block_size = output_block_size = 1; break; case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); default: usage (EXIT_FAILURE); } } filename_quoting_options = clone_quoting_options (NULL); if (get_quoting_style (filename_quoting_options) == escape_quoting_style) set_char_quoting (filename_quoting_options, ' ', 1); if (indicator_style != none) { char const *p; for (p = "*=@|" + (int) indicator_style - 1; *p; p++) set_char_quoting (filename_quoting_options, *p, 1); } dirname_quoting_options = clone_quoting_options (NULL); set_char_quoting (dirname_quoting_options, ':', 1); /* --dired is meaningful only with --format=long (-l). Otherwise, ignore it. FIXME: warn about this? Alternatively, make --dired imply --format=long? */ if (dired && format != long_format) dired = 0; /* If -c or -u is specified and not -l (or any other option that implies -l), and no sort-type was specified, then sort by the ctime (-c) or atime (-u). The behavior of ls when using either -c or -u but with neither -l nor -t appears to be unspecified by POSIX. So, with GNU ls, `-u' alone means sort by atime (this is the one that's not specified by the POSIX spec), -lu means show atime and sort by name, -lut means show atime and sort by atime. */ if ((time_type == time_ctime || time_type == time_atime) && !sort_type_specified && format != long_format) { sort_type = sort_time; } if (format == long_format) { char *style = time_style_option; static char const posix_prefix[] = "posix-"; if (! style) if (! (style = getenv ("TIME_STYLE"))) style = "posix-long-iso"; while (strncmp (style, posix_prefix, sizeof posix_prefix - 1) == 0) { if (! hard_locale (LC_TIME)) return optind; style += sizeof posix_prefix - 1; } if (*style == '+') { char *p0 = style + 1; char *p1 = strchr (p0, '\n'); if (! p1) p1 = p0; else { if (strchr (p1 + 1, '\n')) error (EXIT_FAILURE, 0, _("invalid time style format %s"), quote (p0)); *p1++ = '\0'; } long_time_format[0] = p0; long_time_format[1] = p1; } else switch (XARGMATCH ("time style", style, time_style_args, time_style_types)) { case full_iso_time_style: long_time_format[0] = long_time_format[1] = "%Y-%m-%d %H:%M:%S.%N %z"; break; case long_iso_time_style: long_time_format[0] = long_time_format[1] = "%Y-%m-%d %H:%M"; break; case iso_time_style: long_time_format[0] = "%Y-%m-%d "; long_time_format[1] = "%m-%d %H:%M"; break; case locale_time_style: if (hard_locale (LC_TIME)) { unsigned int i; for (i = 0; i < 2; i++) long_time_format[i] = dcgettext (NULL, long_time_format[i], LC_TIME); } } } return optind;}/* Parse a string as part of the LS_COLORS variable; this may involve decoding all kinds of escape characters. If equals_end is set an unescaped equal sign ends the string, otherwise only a : or \0 does. Returns the number of characters output, or -1 on failure. The resulting string is *not* null-terminated, but may contain embedded nulls. Note that both dest and src are char **; on return they point to the first free byte after the array and the character that ended the input string, respectively. */static intget_funky_string (char **dest, const char **src, int equals_end){ int num; /* For numerical codes */ int count; /* Something to count with */ enum { ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR } state; const char *p; char *q; p = *src; /* We don't want to double-indirect */ q = *dest; /* the whole darn time. */ count = 0; /* No characters counted in yet. */ num = 0; state = ST_GND; /* Start in ground state. */ while (state < ST_END) { switch (state) { case ST_GND: /* Ground state (no escapes) */ switch (*p) { case ':': case '\0': state = ST_END; /* End of string */ break; case '\\': state = ST_BACKSLASH; /* Backslash scape sequence */ ++p; break; case '^': state = ST_CARET; /* Caret escape */ ++p; break; case '=': if (equals_end) { state = ST_END; /* End */ break; } /* else fall through */ default: *(q++) = *(p++); ++count; break; } break; case ST_BACKSLASH: /* Backslash escaped character */ switch (*p) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': state = ST_OCTAL; /* Octal sequence */ num = *p - '0'; break; case 'x': case 'X': state = ST_HEX; /* Hex sequence */ num = 0; break; case 'a': /* Bell */ num = 7; /* Not all C compilers know what \a means */ break; case 'b': /* Backspace */ num = '\b'; break; case 'e': /* Escape */ num = 27; break; case 'f': /* Form feed */ num = '\f'; break; case 'n': /* Newline */ num = '\n'; break; case 'r': /* Carriage return */ num = '\r'; break; case 't': /* Tab */ num = '\t'; break; case 'v': /* Vtab */ num = '\v'; break; case '?': /* Delete */ num = 127; break; case '_': /* Space */ num = ' '; break; case '\0': /* End of string */ state = ST_ERROR; /* Error! */ break; default: /* Escaped character like \ ^ : = */ num = *p; break; } if (state == ST_BACKSLASH) { *(q++) = num; ++count; state = ST_GND; } ++p; break; case ST_OCTAL: /* Octal sequence */ if (*p < '0' || *p > '7') { *(q++) = num; ++count; state = ST_GND; } else num = (num << 3) + (*(p++) - '0'); break; case ST_HEX: /* Hex sequence */ switch (*p) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': num = (num << 4) + (*(p++) - '0'); break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': num = (num << 4) + (*(p++) - 'a') + 10; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': num = (num << 4) + (*(p++) - 'A') + 10; break; default: *(q++) = num; ++count; state = ST_GND; break; } break; case ST_CARET: /* Caret escape */ state = ST_GND; /* Should be the next state... */ if (*p >= '@' && *p <= '~') { *(q++) = *(p++) & 037; ++count; } else if (*p == '?') { *(q++) = 127; ++count; } else state = ST_ERROR; break; default: abort (); } } *dest = q; *src = p; return state == ST_ERROR ? -1 : count;}static voidparse_ls_color (void){ const char *p; /* Pointer to character being parsed */ char *buf; /* color_buf buffer pointer */ int state; /* State of parser */ int ind_no; /* Indicator number */ char label[3]; /* Indicator label */ struct color_ext_type *ext; /* Extension we are working on */ if ((p = getenv ("LS_COLORS")) == NULL || *p == '\0') return; ext = NULL; strcpy (label, "??"); /* This is an overly conservative estimate, but any possible LS_COLORS string will *not* generate a color_buf longer than itself, so it is a safe way of allocating a buffer in advance. */ buf = color_buf = xstrdup (p); state = 1; while (state > 0) { switch (state) { case 1: /* First label character */ switch (*p) { case ':': ++p; break; case '*': /* Allocate new extension block and add to head of linked list (this way a later definition will override an earlier one, which can be useful for having terminal-specific defs override global). */ ext = XMALLOC (struct color_ext_type, 1); ext->next = color_ext_list; color_ext_list = ext; ++p; ext->ext.string = buf; state = (ext->ext.len = get_funky_string (&buf, &p, 1)) < 0 ? -1 : 4; break; case '\0': state = 0; /* Done! */ break; default: /* Assume it is file type label */ label[0] = *(p++); state = 2; break; } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -