Exemple #1
0
Lisp_Object
directory_files_internal (Lisp_Object directory, Lisp_Object full,
			  Lisp_Object match, Lisp_Object nosort, bool attrs,
			  Lisp_Object id_format)
{
  ptrdiff_t directory_nbytes;
  Lisp_Object list, dirfilename, encoded_directory;
  struct re_pattern_buffer *bufp = NULL;
  bool needsep = 0;
  ptrdiff_t count = SPECPDL_INDEX ();
  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
#ifdef WINDOWSNT
  Lisp_Object w32_save = Qnil;
#endif

  /* Don't let the compiler optimize away all copies of DIRECTORY,
     which would break GC; see Bug#16986.  Although this is required
     only in the common case where GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS,
     it shouldn't break anything in the other cases.  */
  Lisp_Object volatile directory_volatile = directory;

  /* Because of file name handlers, these functions might call
     Ffuncall, and cause a GC.  */
  list = encoded_directory = dirfilename = Qnil;
  GCPRO5 (match, directory, list, dirfilename, encoded_directory);
  dirfilename = Fdirectory_file_name (directory);

  if (!NILP (match))
    {
      CHECK_STRING (match);

      /* MATCH might be a flawed regular expression.  Rather than
	 catching and signaling our own errors, we just call
	 compile_pattern to do the work for us.  */
      /* Pass 1 for the MULTIBYTE arg
	 because we do make multibyte strings if the contents warrant.  */
# ifdef WINDOWSNT
      /* Windows users want case-insensitive wildcards.  */
      bufp = compile_pattern (match, 0,
			      BVAR (&buffer_defaults, case_canon_table), 0, 1);
# else	/* !WINDOWSNT */
      bufp = compile_pattern (match, 0, Qnil, 0, 1);
# endif	 /* !WINDOWSNT */
    }

  /* Note: ENCODE_FILE and DECODE_FILE can GC because they can run
     run_pre_post_conversion_on_str which calls Lisp directly and
     indirectly.  */
  dirfilename = ENCODE_FILE (dirfilename);
  encoded_directory = ENCODE_FILE (directory);

  /* Now *bufp is the compiled form of MATCH; don't call anything
     which might compile a new regexp until we're done with the loop!  */

  int fd;
  DIR *d = open_directory (dirfilename, &fd);

  /* Unfortunately, we can now invoke expand-file-name and
     file-attributes on filenames, both of which can throw, so we must
     do a proper unwind-protect.  */
  record_unwind_protect_ptr (directory_files_internal_unwind, d);

#ifdef WINDOWSNT
  if (attrs)
    {
      extern int is_slow_fs (const char *);

      /* Do this only once to avoid doing it (in w32.c:stat) for each
	 file in the directory, when we call Ffile_attributes below.  */
      record_unwind_protect (directory_files_internal_w32_unwind,
			     Vw32_get_true_file_attributes);
      w32_save = Vw32_get_true_file_attributes;
      if (EQ (Vw32_get_true_file_attributes, Qlocal))
	{
	  /* w32.c:stat will notice these bindings and avoid calling
	     GetDriveType for each file.  */
	  if (is_slow_fs (SDATA (dirfilename)))
	    Vw32_get_true_file_attributes = Qnil;
	  else
	    Vw32_get_true_file_attributes = Qt;
	}
    }
#endif

  directory_nbytes = SBYTES (directory);
  re_match_object = Qt;

  /* Decide whether we need to add a directory separator.  */
  if (directory_nbytes == 0
      || !IS_ANY_SEP (SREF (directory, directory_nbytes - 1)))
    needsep = 1;

  /* Loop reading directory entries.  */
  for (struct dirent *dp; (dp = read_dirent (d, directory)); )
    {
      ptrdiff_t len = dirent_namelen (dp);
      Lisp_Object name = make_unibyte_string (dp->d_name, len);
      Lisp_Object finalname = name;
      struct gcpro gcpro1, gcpro2;
      GCPRO2 (finalname, name);

      /* Note: DECODE_FILE can GC; it should protect its argument,
	 though.  */
      name = DECODE_FILE (name);
      len = SBYTES (name);

      /* Now that we have unwind_protect in place, we might as well
	 allow matching to be interrupted.  */
      immediate_quit = 1;
      QUIT;

      bool wanted = (NILP (match)
		     || re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0);

      immediate_quit = 0;

      if (wanted)
	{
	  if (!NILP (full))
	    {
	      Lisp_Object fullname;
	      ptrdiff_t nbytes = len + directory_nbytes + needsep;
	      ptrdiff_t nchars;

	      fullname = make_uninit_multibyte_string (nbytes, nbytes);
	      memcpy (SDATA (fullname), SDATA (directory),
		      directory_nbytes);

	      if (needsep)
		SSET (fullname, directory_nbytes, DIRECTORY_SEP);

	      memcpy (SDATA (fullname) + directory_nbytes + needsep,
		      SDATA (name), len);

	      nchars = multibyte_chars_in_text (SDATA (fullname), nbytes);

	      /* Some bug somewhere.  */
	      if (nchars > nbytes)
		emacs_abort ();

	      STRING_SET_CHARS (fullname, nchars);
	      if (nchars == nbytes)
		STRING_SET_UNIBYTE (fullname);

	      finalname = fullname;
	    }
	  else
	    finalname = name;

	  if (attrs)
	    {
	      Lisp_Object fileattrs
		= file_attributes (fd, dp->d_name, id_format);
	      list = Fcons (Fcons (finalname, fileattrs), list);
	    }
	  else
	    list = Fcons (finalname, list);
	}

      UNGCPRO;
    }

  block_input ();
  closedir (d);
  unblock_input ();
#ifdef WINDOWSNT
  if (attrs)
    Vw32_get_true_file_attributes = w32_save;
#endif

  /* Discard the unwind protect.  */
  specpdl_ptr = specpdl + count;

  if (NILP (nosort))
    list = Fsort (Fnreverse (list),
		  attrs ? Qfile_attributes_lessp : Qstring_lessp);

  (void) directory_volatile;
  RETURN_UNGCPRO (list);
}
Exemple #2
0
/*-----------------------------------------------------------------------------------*/
EK_EVENTHANDLER(directory_eventhandler, ev, data)
{
  unsigned char i;
  EK_EVENTHANDLER_ARGS(ev, data);

  if(ev == EK_EVENT_INIT) {
    ctk_window_new(&window, width, height, "Directory");

    /*    loaddirectory();*/
    makewindow(0);
    show_statustext("Loading directory...");
    startloading();
    
    ctk_window_open(&window);

  } else if(ev == EK_EVENT_CONTINUE) {
    read_dirent();
    load_dirent();
    if(loading != 0) {
      ek_post(id, EK_EVENT_CONTINUE, NULL);
    }
  } else if(ev == ctk_signal_widget_activate) {
    if(data == (ek_data_t)&reloadbutton) {
      for(i = 0; dscs[i] != NULL; ++i) {
	LOADER_UNLOAD_DSC(dscs[i]);
	dscs[i] = NULL;
      }     
      /*      loaddirectory();*/
      startloading();
      makewindow(0);
      ctk_window_open(&window);
    } else if(data == (ek_data_t)&morebutton) {
      makewindow(morestart);
      ctk_window_open(&window);
    } else if(data == (ek_data_t)&backbutton) {
      makewindow(0);
      ctk_window_open(&window);
    } else if(data == (ek_data_t)&autoexitbutton) {
      autoexit = 1 - autoexit;
      if(autoexit == 1) {
	ctk_label_set_text(&autoexitlabel, autoexiton);
      } else {
	ctk_label_set_text(&autoexitlabel, autoexitoff);
      }
      CTK_WIDGET_REDRAW(&autoexitlabel);
    } else {
      for(i = 0; dscs[i] != NULL; ++i) {
	if(data == (ek_data_t)(dscs[i]->icon)) {
	  program_handler_load(dscs[i]->prgname, NULL);
	  if(autoexit) {
	    ctk_window_close(&window);
	    quit();
	  }
	  break;
	}
      }
    }
  } else if(ev == ctk_signal_widget_select) {
    if(data == (ek_data_t)&reloadbutton) {
      show_statustext("Reload directory");
    } else if(data == (ek_data_t)&morebutton) {
      show_statustext("Show more files");
    } else if(data == (ek_data_t)&backbutton) {
      show_statustext("Show first files");
    } else if(data == (ek_data_t)&autoexitbutton) {
      show_statustext("Exit when loading program");
    } else {
      for(i = 0; dscs[i] != NULL; ++i) {
	if(data == (ek_data_t)(dscs[i]->icon)) {
	  show_statustext(dscs[i]->description);
	  break;
	}
      }
    }
  } else if(ev == ctk_signal_window_close &&
	    data == (ek_data_t)&window) {
    quit();
  } else if(ev == EK_EVENT_REQUEST_EXIT) {
    ctk_window_close(&window);
    quit();
  }
}
Exemple #3
0
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(directory_process, ev, data)
{
  unsigned char i;

  PROCESS_BEGIN();
  
  width = ctk_draw_width() - 2;
  height = ctk_draw_height() - 2 - CTK_CONF_MENUS;
  
  ctk_window_new(&window, width, height, "Directory");
  
  /*    loaddirectory();*/
  makewindow(0);
  show_statustext("Loading directory...");
  startloading();
  
  ctk_window_open(&window);

  while(1) {
    PROCESS_WAIT_EVENT();
    if(ev == PROCESS_EVENT_CONTINUE) {
      read_dirent();
      load_dirent();
      if(loading != 0) {
	process_post(&directory_process, PROCESS_EVENT_CONTINUE, NULL);
      }
    } else if(ev == ctk_signal_widget_activate) {
      if(data == (process_data_t)&reloadbutton) {
	for(i = 0; dscs[i] != NULL; ++i) {
	  LOADER_UNLOAD_DSC(dscs[i]);
	  dscs[i] = NULL;
	}     
	/*      loaddirectory();*/
	startloading();
	makewindow(0);
	ctk_window_open(&window);
      } else if(data == (process_data_t)&morebutton) {
	makewindow(morestart);
	ctk_window_open(&window);
      } else if(data == (process_data_t)&backbutton) {
	makewindow(0);
	ctk_window_open(&window);
      } else if(data == (process_data_t)&autoexitbutton) {
	autoexit = 1 - autoexit;
	if(autoexit == 1) {
	  ctk_label_set_text(&autoexitlabel, autoexiton);
	} else {
	  ctk_label_set_text(&autoexitlabel, autoexitoff);
	}
	CTK_WIDGET_REDRAW(&autoexitlabel);
      } else {
	for(i = 0; dscs[i] != NULL; ++i) {
	  if(data == (process_data_t)(dscs[i]->icon)) {
	    program_handler_load(dscs[i]->prgname, NULL);
	    if(autoexit) {
	      ctk_window_close(&window);
	      quit();
	    }
	    break;
	  }
	}
      }
    } else if(ev == ctk_signal_widget_select) {
      if(data == (process_data_t)&reloadbutton) {
	show_statustext("Reload directory");
      } else if(data == (process_data_t)&morebutton) {
	show_statustext("Show more files");
      } else if(data == (process_data_t)&backbutton) {
	show_statustext("Show first files");
      } else if(data == (process_data_t)&autoexitbutton) {
	show_statustext("Exit when loading program");
      } else {
	for(i = 0; dscs[i] != NULL; ++i) {
	  if(data == (process_data_t)(dscs[i]->icon)) {
	    show_statustext(dscs[i]->description);
	    break;
	  }
	}
      }
    } else if(ev == ctk_signal_window_close &&
	      data == (process_data_t)&window) {
      quit();
    } else if(ev == PROCESS_EVENT_EXIT) {
      ctk_window_close(&window);
      quit();
    }
  }
  PROCESS_END();
}
Exemple #4
0
Lisp_Object
directory_files_internal (Lisp_Object directory, Lisp_Object full,
			  Lisp_Object match, Lisp_Object nosort, bool attrs,
			  Lisp_Object id_format)
{
  ptrdiff_t directory_nbytes;
  Lisp_Object list, dirfilename, encoded_directory;
  bool needsep = 0;
  ptrdiff_t count = SPECPDL_INDEX ();
#ifdef WINDOWSNT
  Lisp_Object w32_save = Qnil;
#endif

  /* Don't let the compiler optimize away all copies of DIRECTORY,
     which would break GC; see Bug#16986.  */
  Lisp_Object volatile directory_volatile = directory;

  /* Because of file name handlers, these functions might call
     Ffuncall, and cause a GC.  */
  list = encoded_directory = dirfilename = Qnil;
  dirfilename = Fdirectory_file_name (directory);

  /* Note: ENCODE_FILE and DECODE_FILE can GC because they can run
     run_pre_post_conversion_on_str which calls Lisp directly and
     indirectly.  */
  dirfilename = ENCODE_FILE (dirfilename);
  encoded_directory = ENCODE_FILE (directory);

  int fd;
  DIR *d = open_directory (dirfilename, &fd);

  /* Unfortunately, we can now invoke expand-file-name and
     file-attributes on filenames, both of which can throw, so we must
     do a proper unwind-protect.  */
  record_unwind_protect_ptr (directory_files_internal_unwind, d);

#ifdef WINDOWSNT
  if (attrs)
    {
      /* Do this only once to avoid doing it (in w32.c:stat) for each
	 file in the directory, when we call file_attributes below.  */
      record_unwind_protect (directory_files_internal_w32_unwind,
			     Vw32_get_true_file_attributes);
      w32_save = Vw32_get_true_file_attributes;
      if (EQ (Vw32_get_true_file_attributes, Qlocal))
	{
	  /* w32.c:stat will notice these bindings and avoid calling
	     GetDriveType for each file.  */
	  if (is_slow_fs (SSDATA (dirfilename)))
	    Vw32_get_true_file_attributes = Qnil;
	  else
	    Vw32_get_true_file_attributes = Qt;
	}
    }
#endif

  directory_nbytes = SBYTES (directory);
  re_match_object = Qt;

  /* Decide whether we need to add a directory separator.  */
  if (directory_nbytes == 0
      || !IS_ANY_SEP (SREF (directory, directory_nbytes - 1)))
    needsep = 1;

  /* Windows users want case-insensitive wildcards.  */
  Lisp_Object case_table =
#ifdef WINDOWSNT
    BVAR (&buffer_defaults, case_canon_table)
#else
    Qnil
#endif
    ;

  if (!NILP (match))
    CHECK_STRING (match);

  /* Loop reading directory entries.  */
  for (struct dirent *dp; (dp = read_dirent (d, directory)); )
    {
      ptrdiff_t len = dirent_namelen (dp);
      Lisp_Object name = make_unibyte_string (dp->d_name, len);
      Lisp_Object finalname = name;

      /* Note: DECODE_FILE can GC; it should protect its argument,
	 though.  */
      name = DECODE_FILE (name);
      len = SBYTES (name);

      /* Now that we have unwind_protect in place, we might as well
	 allow matching to be interrupted.  */
      maybe_quit ();

      bool wanted = (NILP (match) ||
                     fast_string_match_internal (
                       match, name, case_table) >= 0);

      if (wanted)
	{
	  if (!NILP (full))
	    {
	      Lisp_Object fullname;
	      ptrdiff_t nbytes = len + directory_nbytes + needsep;
	      ptrdiff_t nchars;

	      fullname = make_uninit_multibyte_string (nbytes, nbytes);
	      memcpy (SDATA (fullname), SDATA (directory),
		      directory_nbytes);

	      if (needsep)
		SSET (fullname, directory_nbytes, DIRECTORY_SEP);

	      memcpy (SDATA (fullname) + directory_nbytes + needsep,
		      SDATA (name), len);

	      nchars = multibyte_chars_in_text (SDATA (fullname), nbytes);

	      /* Some bug somewhere.  */
	      if (nchars > nbytes)
		emacs_abort ();

	      STRING_SET_CHARS (fullname, nchars);
	      if (nchars == nbytes)
		STRING_SET_UNIBYTE (fullname);

	      finalname = fullname;
	    }
	  else
	    finalname = name;

	  if (attrs)
	    {
	      Lisp_Object fileattrs
		= file_attributes (fd, dp->d_name, directory, name, id_format);
	      list = Fcons (Fcons (finalname, fileattrs), list);
	    }
	  else
	    list = Fcons (finalname, list);
	}
    }

  closedir (d);
#ifdef WINDOWSNT
  if (attrs)
    Vw32_get_true_file_attributes = w32_save;
#endif

  /* Discard the unwind protect.  */
  specpdl_ptr = specpdl + count;

  if (NILP (nosort))
    list = Fsort (Fnreverse (list),
		  attrs ? Qfile_attributes_lessp : Qstring_lessp);

  (void) directory_volatile;
  return list;
}