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

📄 gtkfilesel.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 5 页
字号:
  struct stat ent_sbuf;  char path_buf[MAXPATHLEN*2];  gint path_buf_len;  sent = g_new(CompletionDirSent, 1);  sent->mtime = sbuf->st_mtime;  sent->inode = sbuf->st_ino;  sent->device = sbuf->st_dev;  path_buf_len = strlen(dir_name);  if (path_buf_len > MAXPATHLEN)    {      cmpl_errno = CMPL_ERRNO_TOO_LONG;      return NULL;    }  strcpy(path_buf, dir_name);  directory = opendir(dir_name);  if(!directory)    {      cmpl_errno = errno;      return NULL;    }  while((dirent_ptr = readdir(directory)) != NULL)    {      int entry_len = strlen(dirent_ptr->d_name);      buffer_size += entry_len + 1;      entry_count += 1;      if(path_buf_len + entry_len + 2 >= MAXPATHLEN)	{	  cmpl_errno = CMPL_ERRNO_TOO_LONG; 	  closedir(directory);	  return NULL;	}    }  sent->name_buffer = g_new(gchar, buffer_size);  sent->entries = g_new(CompletionDirEntry, entry_count);  sent->entry_count = entry_count;  buffer_ptr = sent->name_buffer;  rewinddir(directory);  for(i = 0; i < entry_count; i += 1)    {      dirent_ptr = readdir(directory);      if(!dirent_ptr)	{	  cmpl_errno = errno;	  closedir(directory);	  return NULL;	}      strcpy(buffer_ptr, dirent_ptr->d_name);      sent->entries[i].entry_name = buffer_ptr;      buffer_ptr += strlen(dirent_ptr->d_name);      *buffer_ptr = 0;      buffer_ptr += 1;      path_buf[path_buf_len] = '/';      strcpy(path_buf + path_buf_len + 1, dirent_ptr->d_name);      if (stat_subdirs)	{	  if(stat(path_buf, &ent_sbuf) >= 0 && S_ISDIR(ent_sbuf.st_mode))	    sent->entries[i].is_dir = 1;	  else	    /* stat may fail, and we don't mind, since it could be a	     * dangling symlink. */	    sent->entries[i].is_dir = 0;	}      else	sent->entries[i].is_dir = 1;    }  qsort(sent->entries, sent->entry_count, sizeof(CompletionDirEntry), compare_cmpl_dir);  closedir(directory);  return sent;}static gbooleancheck_dir(gchar *dir_name, struct stat *result, gboolean *stat_subdirs){  /* A list of directories that we know only contain other directories.   * Trying to stat every file in these directories would be very   * expensive.   */  static struct {    gchar *name;    gboolean present;    struct stat statbuf;  } no_stat_dirs[] = {    { "/afs", FALSE, { 0 } },    { "/net", FALSE, { 0 } }  };  static const gint n_no_stat_dirs = sizeof(no_stat_dirs) / sizeof(no_stat_dirs[0]);  static gboolean initialized = FALSE;  gint i;  if (!initialized)    {      initialized = TRUE;      for (i = 0; i < n_no_stat_dirs; i++)	{	  if (stat (no_stat_dirs[i].name, &no_stat_dirs[i].statbuf) == 0)	    no_stat_dirs[i].present = TRUE;	}    }  if(stat(dir_name, result) < 0)    {      cmpl_errno = errno;      return FALSE;    }  *stat_subdirs = TRUE;  for (i=0; i<n_no_stat_dirs; i++)    {      if (no_stat_dirs[i].present &&	  (no_stat_dirs[i].statbuf.st_dev == result->st_dev) &&	  (no_stat_dirs[i].statbuf.st_ino == result->st_ino))	{	  *stat_subdirs = FALSE;	  break;	}    }  return TRUE;}/* open a directory by absolute pathname */static CompletionDir*open_dir(gchar* dir_name, CompletionState* cmpl_state){  struct stat sbuf;  gboolean stat_subdirs;  CompletionDirSent *sent;  GList* cdsl;  if (!check_dir (dir_name, &sbuf, &stat_subdirs))    return NULL;  cdsl = cmpl_state->directory_sent_storage;  while (cdsl)    {      sent = cdsl->data;      if(sent->inode == sbuf.st_ino &&	 sent->mtime == sbuf.st_mtime &&	 sent->device == sbuf.st_dev)	return attach_dir(sent, dir_name, cmpl_state);      cdsl = cdsl->next;    }  sent = open_new_dir(dir_name, &sbuf, stat_subdirs);  if (sent) {    cmpl_state->directory_sent_storage =      g_list_prepend(cmpl_state->directory_sent_storage, sent);    return attach_dir(sent, dir_name, cmpl_state);  }  return NULL;}static CompletionDir*attach_dir(CompletionDirSent* sent, gchar* dir_name, CompletionState *cmpl_state){  CompletionDir* new_dir;  new_dir = g_new(CompletionDir, 1);  cmpl_state->directory_storage =    g_list_prepend(cmpl_state->directory_storage, new_dir);  new_dir->sent = sent;  new_dir->fullname = g_strdup(dir_name);  new_dir->fullname_len = strlen(dir_name);  return new_dir;}static gintcorrect_dir_fullname(CompletionDir* cmpl_dir){  gint length = strlen(cmpl_dir->fullname);  struct stat sbuf;  if (strcmp(cmpl_dir->fullname + length - 2, "/.") == 0)    {      if (length == 2) 	{	  strcpy(cmpl_dir->fullname, "/");	  cmpl_dir->fullname_len = 1;	  return TRUE;	} else {	  cmpl_dir->fullname[length - 2] = 0;	}    }  else if (strcmp(cmpl_dir->fullname + length - 3, "/./") == 0)    cmpl_dir->fullname[length - 2] = 0;  else if (strcmp(cmpl_dir->fullname + length - 3, "/..") == 0)    {      if(length == 3)	{	  strcpy(cmpl_dir->fullname, "/");	  cmpl_dir->fullname_len = 1;	  return TRUE;	}      if(stat(cmpl_dir->fullname, &sbuf) < 0)	{	  cmpl_errno = errno;	  return FALSE;	}      cmpl_dir->fullname[length - 2] = 0;      if(!correct_parent(cmpl_dir, &sbuf))	return FALSE;    }  else if (strcmp(cmpl_dir->fullname + length - 4, "/../") == 0)    {      if(length == 4)	{	  strcpy(cmpl_dir->fullname, "/");	  cmpl_dir->fullname_len = 1;	  return TRUE;	}      if(stat(cmpl_dir->fullname, &sbuf) < 0)	{	  cmpl_errno = errno;	  return FALSE;	}      cmpl_dir->fullname[length - 3] = 0;      if(!correct_parent(cmpl_dir, &sbuf))	return FALSE;    }  cmpl_dir->fullname_len = strlen(cmpl_dir->fullname);  return TRUE;}static gintcorrect_parent(CompletionDir* cmpl_dir, struct stat *sbuf){  struct stat parbuf;  gchar *last_slash;  gchar *new_name;  gchar c = 0;  last_slash = strrchr(cmpl_dir->fullname, '/');  g_assert(last_slash);  if(last_slash != cmpl_dir->fullname)    { /* last_slash[0] = 0; */ }  else    {      c = last_slash[1];      last_slash[1] = 0;    }  if (stat(cmpl_dir->fullname, &parbuf) < 0)    {      cmpl_errno = errno;      return FALSE;    }  if (parbuf.st_ino == sbuf->st_ino && parbuf.st_dev == sbuf->st_dev)    /* it wasn't a link */    return TRUE;  if(c)    last_slash[1] = c;  /* else    last_slash[0] = '/'; */  /* it was a link, have to figure it out the hard way */  new_name = find_parent_dir_fullname(cmpl_dir->fullname);  if (!new_name)    return FALSE;  g_free(cmpl_dir->fullname);  cmpl_dir->fullname = new_name;  return TRUE;}static gchar*find_parent_dir_fullname(gchar* dirname){  gchar buffer[MAXPATHLEN];  gchar buffer2[MAXPATHLEN];#if defined(sun) && !defined(__SVR4)  if(!getwd(buffer))#else  if(!getcwd(buffer, MAXPATHLEN))#endif        {      cmpl_errno = errno;      return NULL;    }  if(chdir(dirname) != 0 || chdir("..") != 0)    {      cmpl_errno = errno;      return NULL;    }#if defined(sun) && !defined(__SVR4)  if(!getwd(buffer2))#else  if(!getcwd(buffer2, MAXPATHLEN))#endif    {      chdir(buffer);      cmpl_errno = errno;      return NULL;    }  if(chdir(buffer) != 0)    {      cmpl_errno = errno;      return NULL;    }  return g_strdup(buffer2);}/**********************************************************************//*                        Completion Operations                       *//**********************************************************************/static PossibleCompletion*attempt_homedir_completion(gchar* text_to_complete,			   CompletionState *cmpl_state){  gint index, length;  if (!cmpl_state->user_dir_name_buffer &&      !get_pwdb(cmpl_state))    return NULL;  length = strlen(text_to_complete) - 1;  cmpl_state->user_completion_index += 1;  while(cmpl_state->user_completion_index < cmpl_state->user_directories_len)    {      index = first_diff_index(text_to_complete + 1,			       cmpl_state->user_directories			       [cmpl_state->user_completion_index].login);      switch(index)	{	case PATTERN_MATCH:	  break;	default:	  if(cmpl_state->last_valid_char < (index + 1))	    cmpl_state->last_valid_char = index + 1;	  cmpl_state->user_completion_index += 1;	  continue;	}      cmpl_state->the_completion.is_a_completion = 1;      cmpl_state->the_completion.is_directory = 1;      append_completion_text("~", cmpl_state);      append_completion_text(cmpl_state->			      user_directories[cmpl_state->user_completion_index].login,			     cmpl_state);      return append_completion_text("/", cmpl_state);    }  if(text_to_complete[1] ||     cmpl_state->user_completion_index > cmpl_state->user_directories_len)    {      cmpl_state->user_completion_index = -1;      return NULL;    }  else    {      cmpl_state->user_completion_index += 1;      cmpl_state->the_completion.is_a_completion = 1;      cmpl_state->the_completion.is_directory = 1;      return append_completion_text("~/", cmpl_state);    }}/* returns the index (>= 0) of the first differing character, * PATTERN_MATCH if the completion matches */static gintfirst_diff_index(gchar* pat, gchar* text){  gint diff = 0;  while(*pat && *text && *text == *pat)    {      pat += 1;      text += 1;      diff += 1;    }  if(*pat)    return diff;  return PATTERN_MATCH;}static PossibleCompletion*append_completion_text(gchar* text, CompletionState* cmpl_state){  gint len, i = 1;  if(!cmpl_state->the_completion.text)    return NULL;  len = strlen(text) + strlen(cmpl_state->the_completion.text) + 1;  if(cmpl_state->the_completion.text_alloc > len)    {      strcat(cmpl_state->the_completion.text, text);      return &cmpl_state->the_completion;    }  while(i < len) { i <<= 1; }  cmpl_state->the_completion.text_alloc = i;  cmpl_state->the_completion.text = (gchar*)g_realloc(cmpl_state->the_completion.text, i);  if(!cmpl_state->the_completion.text)    return NULL;  else    {      strcat(cmpl_state->the_completion.text, text);      return &cmpl_state->the_completion;    }}static CompletionDir*find_completion_dir(gchar* text_to_complete,		    gchar** remaining_text,		    CompletionState* cmpl_state){  gchar* first_slash = strchr(text_to_complete, '/');  CompletionDir* dir = cmpl_state->reference_dir;  CompletionDir* next;  *remaining_text = text_to_complete;  while(first_slash)    {      gint le

⌨️ 快捷键说明

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