⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfls.c

📁 OXCC is a multipass, interpreting C compiler with several language extensions. It generates an Archi
💻 C
📖 第 1 页 / 共 5 页
字号:
        numeric_users = 1;
        break;

      case 'p':
        indicator_style = not_programs;
        break;

      case 'q':
        qmark_funny_chars = 1;
        quote_funny_chars = 0;
        break;

      case 'r':
        sort_reverse = 1;
        break;

      case 's':
        print_block_size = 1;
        break;

      case 't':
        sort_type = sort_time;
        break;

      case 'u':
        time_type = time_atime;
        break;

      case 'w':
        line_length = atoi (optarg);
        if (line_length < 1)
          error (1, 0, "invalid line width: %s", optarg);
        break;

      case 'x':
        format = horizontal;
        break;

      case 'A':
        all_files = 1;
        break;

      case 'B':
        add_ignore_pattern ("*~");
        add_ignore_pattern (".*~");
        break;

      case 'C':
        format = many_per_line;
        break;

      case 'F':
        indicator_style = all;
        break;

      case 'I':
        add_ignore_pattern (optarg);
        break;

      case 'L':
        trace_links = 1;
        break;

      case 'N':
        quote_funny_chars = 0;
        qmark_funny_chars = 0;
        break;

      case 'Q':
        quote_as_string = 1;
        quote_funny_chars = 1;
        qmark_funny_chars = 0;
        break;

      case 'R':
        trace_dirs = 1;
        break;

      case 'S':
        sort_type = sort_size;
        break;

      case 'T':
        tabsize = atoi (optarg);
        if (tabsize < 1)
          error (1, 0, "invalid tab size: %s", optarg);
        break;

      case 'U':
        sort_type = sort_none;
        break;

      case 'X':
        sort_type = sort_extension;
        break;

      case '1':
        format = one_per_line;
        break;

      case 10:    /* +sort */
        longind = argmatch (optarg, sort_args);
        if (longind < 0)
        {
          invalid_arg ("sort type", optarg, longind);
          usage ();
        }
        sort_type = sort_types[longind];
        break;

      case 11:    /* +time */
        longind = argmatch (optarg, time_args);
        if (longind < 0)
        {
          invalid_arg ("time type", optarg, longind);
          usage ();
        }
        time_type = time_types[longind];
        break;

      case 12:    /* +format */
        longind = argmatch (optarg, format_args);
        if (longind < 0)
        {
          invalid_arg ("format type", optarg, longind);
          usage ();
        }
        format = formats[longind];
        break;

      default:
        usage ();
    }
  }

  return optind;
}

/* Request that the directory named `name' have its contents listed later.
   If `realname' is nonzero, it will be used instead of `name' when the
   directory name is printed.  This allows symbolic links to directories
   to be treated as regular directories but still be listed under their
   real names. */

void
queue_directory (name, realname, thispend)
     char *name;
char *realname;
struct pending *thispend;

{
  struct pending *new;

  new = (struct pending *) xmalloc (sizeof (struct pending));
  new->next = pending_dirs;
  pending_dirs = new;
  new->name = copystring (name);
  if (realname)
    new->realname = copystring (realname);
  else
    new->realname = NULL;
  if(thispend)
    new->list_patterns = thispend->list_patterns;
  else
    new->list_patterns = NULL;
}

/* Read directory `name', and list the files in it.
   If `realname' is nonzero, print its name instead of `name';
   this is used for symbolic links to directories. */

void
print_dir (thispend)
  struct pending *thispend;

{
  register void *reading;
  CFDIRENT *next;
  register long total_blocks = 0;
  char *name;
  char *realname;

  errno = 0;
  name = thispend->name;
  realname = thispend->realname;

  reading = opendir (name);
  if (!reading)
  {
#ifdef PCDOS
    errno = 2;/* it seems to have a small vocabulary, so ENOENT */
#endif
    error (0, errno, "%s", name);
    return;
  }
  /* Read the directory entries, and insert the subfiles into the `files'
     table.  */
  clear_files ();

  while (next = (void*)readdir (reading))
  {
    if (file_interesting (next, thispend))
      total_blocks += gobble_file (next->d_name, 0, name, next);
  }
  closedir (reading);

  /* Sort the directory contents.  */
  sort_files ();

  /* If any member files are subdirectories, perhaps they should have their
     contents listed rather than being mentioned here as files.  */

  if (trace_dirs)
    extract_dirs_from_files (name, 1, thispend);

  if (print_dir_name)
  {
    if (realname)
      printf ("%s:\n", realname);
    else
      printf ("%s:\n", name);
  }

#ifndef PCDOS
  if (format == long_format || print_block_size)
    printf ("total %u\n", total_blocks);
#endif

  if (files_index)
    print_current_files ();

#ifdef PCDOS
  if(format == long_format || format == many_per_line || print_block_size)
  {
    printf ("\t%d file(s)\t", files_index);
    if(print_block_size)
      printf ("%lu blocks allocated\n", total_blocks);
    else
      printf ("%lu blocks used\n", total_blocks);
  }
#endif

  if (pending_dirs)
    putchar ('\n');
}

/* Add `pattern' to the list of patterns for which files that match are
   listed.  */

void
add_list_pattern (pattern)
     char *pattern;

{
  register struct ignore_pattern *list;

  list = (struct ignore_pattern *) xmalloc (sizeof (struct ignore_pattern));
  list->pattern = pattern;
  /* Add it to the head of the linked list. */
  list->next = pending_dirs->list_patterns;
  pending_dirs->list_patterns = list;
}
/* Add `pattern' to the list of patterns for which files that match are
   not listed.  */

void
add_ignore_pattern (pattern)
     char *pattern;

{
  register struct ignore_pattern *ignore;

  ignore = (struct ignore_pattern *) xmalloc (sizeof (struct ignore_pattern));
  ignore->pattern = pattern;
  /* Add it to the head of the linked list. */
  ignore->next = ignore_patterns;
  ignore_patterns = ignore;
}

/* Return nonzero if the file in `next' should be listed. */

int
file_interesting (dirp, thispend)
     register CFDIRENT *dirp;
register struct pending *thispend;

{
  register struct ignore_pattern *ignore;

  /* exclude files which match the ignore_pattern list */
  for (ignore = ignore_patterns; ignore; ignore = ignore->next)
    if (glob_match (ignore->pattern, dirp->d_name, 1))
      return 0;

  /* include files which match the list_pattern list */

  for (ignore = thispend->list_patterns; ignore; ignore = ignore->next)
  {
    if (glob_match (ignore->pattern, dirp->d_name, 1))
      goto file_maybe_ok;
  }
  if(thispend->list_patterns) return 0;

file_maybe_ok:
  if (really_all_files
      || dirp->d_name[0] != '.'
      || (all_files
      && dirp->d_name[1] != '\0'
      && (dirp->d_name[1] != '.' || dirp->d_name[2] != '\0')))
    return 1;

  return 0;
}

/* Enter and remove entries in the table `files'.  */

/* Empty the table of files. */

void
clear_files ()

{
  register int i;

  for (i = 0; i < files_index; i++)
  {
    free (files[i].name);
    if (files[i].linkname)
      free (files[i].linkname);
  }

  files_index = 0;
  block_size_size = 3;
}

/* Add a file to the current table of files.
   Verify that the file exists, and print an error message if it does not.
   Return the number of blocks that the file occupies.  */

long
gobble_file (name, explicit_arg, dirname, dirp)
   char *name;
int explicit_arg;
char *dirname;
CFDIRENT *dirp;

{
  long blocks;
  register int val;
  register char *path;
  struct file *f;
  int printable;

  if (files_index == nfiles)
  {
    nfiles *= 2;
    files = (struct file *) xrealloc (files, sizeof (struct file) * nfiles);
  }

  f = &files[files_index];
  f->linkname = NULL;
  f->linkmode = 0;
  if(!dirp)
  	   printable = 1;
  else printable = is_printable(name, dirp->d_namlen);	

  if (explicit_arg && printable && if_pattern(name))
  {/* The shell passed a pattern which needs globbing locally */
    char ch, *pat;

    if(path = rindex(name, '/'))
    {
      pat = path+1;
      if(path == name || path[-1] == ':')
        ++path;

      ch = *path;
      *path = '\0';
      if( ((pending_dirs) ? (strcmp(pending_dirs->name, name)) : 1))
        queue_directory (name, NULL, NULL);
      *path = ch;
      add_list_pattern(pat);
      return 0;
    }
    if(name[1] == ':')
    {/* e.g. b:*.h */
      ch = name[2];
      name[2] = '\0';
      if( ((pending_dirs) ? (strcmp(pending_dirs->name, name)) : 1))
        queue_directory (name, NULL, NULL);
      name[2] = ch;
      add_list_pattern(&name[2]);
      return 0;
    }
    else
    {
      if(!pending_dirs)
        queue_directory ("./", NULL, NULL);
      add_list_pattern(name);
      return 0;
    }
    return 0;
  }
  blocks = 0;
  if (explicit_arg || format_needs_stat)
  {
  LSTAT *sp = &f->stats;
	if(dirp)
	{
		sp->st_mode = dirp->d_mode;
		sp->st_size = dirp->d_bytesused;
		sp->st_alloc = dirp->d_bytesalloc;
		sp->st_mtime = dirp->d_mtime;
		sp->st_ctime = dirp->d_ctime;
		sp->st_atime = sp->st_mtime;
		sp->st_ino = dirp->d_ino;
		if(sp->st_mode & (M_HASHDIR|M_TREEDIR))
			 sp->st_mode |= S_IFDIR;
		else sp->st_mode |= S_IFREG;
	} else {
	CFSTAT s;
		cfstat(name, &s);
		sp->st_mode = s.st_mode;
		sp->st_size = s.st_size;
		sp->st_alloc = s.st_size;
		sp->st_mtime = s.st_mtime;
		sp->st_ctime = s.st_ctime;
		sp->st_atime = s.st_atime;
		sp->st_ino = s.st_ino;
		if(sp->st_mode & (M_HASHDIR|M_TREEDIR))
			 sp->st_mode |= S_IFDIR;
		else sp->st_mode |= S_IFREG;
	}
settype:
    switch (sp->st_mode & S_IFMT)
    {

      case S_IFDIR:
        if (explicit_arg && !immediate_dirs)
          f->filetype = arg_directory;
        else
          f->filetype = directory;
        break;

      default:
        f->filetype = normal;
        break;
    }

    blocks = (long)convert_blocks(ST_NBLOCKS(sp), kilobyte_blocks);

    if(blocks >= 1000 && block_size_size < 4)
      block_size_size = 4;
    if(blocks >= 10000 && block_size_size < 5)
      block_size_size = 5;
    if(blocks >= 100000 && block_size_size < 6)
      block_size_size = 6;
    if(blocks >= 1000000 && block_size_size < 7)
      block_size_size = 7;
  }
  if(dirp)
  {
	  if(is_printable(dirp->d_name, dirp->d_namlen))
	  {
		  f->name = xmalloc(dirp->d_namlen+1);
		  memcpy(f->name, dirp->d_name, dirp->d_namlen+1);
		  f->namlen = dirp->d_namlen;
	  } else {/* print a tidbit of the key, in hex */
		 f->name = xmalloc(16);
		 f->namlen = cfsprintf(f->name, "0x%x", *((long *)dirp->d_name));
	  }
  } else {
  	f->namlen = strlen(name);
  	f->name = xmalloc(f->namlen+1);
  	strcpy(f->name, name);
  }
  files_index++;

  return blocks;
}


/* Remove any entries from `files' that are for directories,
   and queue them to be listed as directories instead.
   `dirname' is the prefix to prepend to each dirname
   to make it correct relative to ls's working dir.
   `recursive' is nonzero if we should not treat `.' and `..' as dirs.
   This is desirable when processing directories recursively.  */

void
extract_dirs_from_files (dirname, recursive, thispend)
     char *dirname;
int recursive;
struct pending *thispend;

{
  register int i, j;
  register char *path;
  int dirlen;

  dirlen = strlen (dirname) + 2;
  /* Queue the directories last one first, because queueing reverses the
     order.  */
  for (i = files_index - 1; i >= 0; i--)
    if ((files[i].filetype == directory || files[i].filetype == arg_directory)
  && (!recursive || is_not_dot_or_dotdot (files[i].name)))
    {
      if (files[i].name[0] == '/' || dirname[0] == 0)
      {
        queue_directory (files[i].name, files[i].linkname, thispend);
      }
      else
      {
        path = (char *) xmalloc (strlen (files[i].name) + dirlen);
        attach (path, dirname, files[i].name);
        queue_directory (path, files[i].linkname, thispend);
        free (path);
      }
      if (  files[i].filetype == arg_directory
        || (files[i].filetype == directory && thispend->list_patterns))
        free (files[i].name);
    }

  /* Now delete the directories from the table, compacting all the remaining

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -