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

📄 cplfile.c

📁 BCAST Implementation for NS2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*....................................................................... * Return a description of the last path-completion error that occurred. * * Input: *  cf    CompleteFile *  The path-completion resource object. * Output: *  return  const char *  The description of the last error. */const char *_cf_last_error(CompleteFile *cf){  return cf ? cf->errmsg : "NULL CompleteFile argument";}/*....................................................................... * Lookup the home directory of the specified user, or the current user * if no name is specified, appending it to output pathname. * * Input: *  cf  CompleteFile *  The pathname completion resource object. *  user  const char *  The username to lookup, or "" to lookup the *                      current user. * Output: *  return        int    0 - OK. *                       1 - Error. */static int cf_expand_home_dir(CompleteFile *cf, const char *user){/* * Attempt to lookup the home directory. */  const char *home_dir = _hd_lookup_home_dir(cf->home, user);/* * Failed? */  if(!home_dir) {    strncpy(cf->errmsg, _hd_last_home_dir_error(cf->home), ERRLEN);    cf->errmsg[ERRLEN] = '\0';    return 1;  };/* * Append the home directory to the pathname string. */  if(_pn_append_to_path(cf->path, home_dir, -1, 0) == NULL) {    strcpy(cf->errmsg, "Insufficient memory for home directory expansion");    return 1;  };  return 0;}/*....................................................................... * Lookup and report all completions of a given username prefix. * * Input: *  cf     CompleteFile *  The filename-completion resource object. *  cpl  WordCompletion *  The object in which to record the completions. *  prefix   const char *  The prefix of the usernames to lookup. *  line     const char *  The command-line in which the username appears. *  word_start      int    The index within line[] of the start of the *                         username that is being completed. *  word_end        int    The index within line[] of the character which *                         follows the incomplete username. *  escaped         int    True if the completions need to have special *                         characters escaped. * Output: *  return          int    0 - OK. *                         1 - Error. */static int cf_complete_username(CompleteFile *cf, WordCompletion *cpl,				const char *prefix, const char *line,				int word_start, int word_end, int escaped){/* * Set up a container of anonymous arguments to be sent to the * username-lookup iterator. */  CfHomeArgs args;  args.cf = cf;  args.cpl = cpl;  args.prefix = prefix;  args.line = line;  args.word_start = word_start;  args.word_end = word_end;  args.escaped = escaped;/* * Iterate through the list of users, recording those which start * with the specified prefix. */  if(_hd_scan_user_home_dirs(cf->home, &args, cf_homedir_callback)) {    strncpy(cf->errmsg, _hd_last_home_dir_error(cf->home), ERRLEN);    cf->errmsg[ERRLEN] = '\0';    return 1;  };  return 0;}/*....................................................................... * The user/home-directory scanner callback function (see homedir.h) * used by cf_complete_username(). */static HOME_DIR_FN(cf_homedir_callback){/* * Get the file-completion resources from the anonymous data argument. */  CfHomeArgs *args = (CfHomeArgs *) data;  WordCompletion *cpl = args->cpl;  CompleteFile *cf = args->cf;/* * Get the length of the username prefix. */  int prefix_len = strlen(args->prefix);/* * Get the length of the latest user name that is to be compared to * the prefix. */  int name_len = strlen(usrnam);/* * See if the latest username starts with the prefix that we are * searching for, and record its suffix in the array of matches if so. */  if(name_len >= prefix_len && strncmp(args->prefix, usrnam, prefix_len)==0) {/* * Copy the username into the pathname work buffer, adding backslash * escapes where needed. */    if(cf_prepare_suffix(cf, usrnam+prefix_len, args->escaped)) {      strncpy(errmsg, cf->errmsg, maxerr);      errmsg[maxerr] = '\0';      return 1;    };/* * Report the completion suffix that was copied above. */    if(cpl_add_completion(cpl, args->line, args->word_start, args->word_end,			  cf->buff->name, FS_DIR_SEP, FS_DIR_SEP)) {      strncpy(errmsg, cpl_last_error(cpl), maxerr);      errmsg[maxerr] = '\0';      return 1;    };  };  return 0;}/*....................................................................... * Report possible completions of the filename in cf->path->name[]. * * Input: *  cf      CompleteFile *  The file-completion resource object. *  cpl   WordCompletion *  The object in which to record the completions. *  line      const char *  The input line, as received by the callback *                          function. *  word_start       int    The index within line[] of the start of the *                          last component of the filename that is being *                          completed. *  word_end         int    The index within line[] of the character which *                          follows the incomplete filename. *  escaped          int    If true, escape special characters in the *                          completion suffixes. *  check_fn  CplCheckFn *  If not zero, this argument specifies a *                          function to call to ask whether a given *                          file should be included in the list *                          of completions. *  check_data      void *  Anonymous data to be passed to check_fn(). * Output: *  return           int    0 - OK. *                          1 - Error. */static int cf_complete_entry(CompleteFile *cf, WordCompletion *cpl,			     const char *line, int word_start, int word_end,			     int escaped, CplCheckFn *check_fn,			     void *check_data){  const char *dirpath;   /* The name of the parent directory */  int start;             /* The index of the start of the last filename */                         /*  component in the transcribed filename. */  const char *prefix;    /* The filename prefix to be completed */  int prefix_len;        /* The length of the filename prefix */  const char *file_name; /* The lastest filename being compared */  int waserr = 0;        /* True after errors */  int terminated=0;      /* True if the directory part had to be terminated *//* * Get the pathname string and its current length. */  char *pathname = cf->path->name;  int pathlen = strlen(pathname);/* * Locate the start of the final component of the pathname. */  for(start=pathlen - 1; start >= 0 &&      strncmp(pathname + start, FS_DIR_SEP, FS_DIR_SEP_LEN) != 0; start--)    ;/* * Is the parent directory the root directory? */  if(start==0 ||     (start < 0 && strncmp(pathname, FS_ROOT_DIR, FS_ROOT_DIR_LEN) == 0)) {    dirpath = FS_ROOT_DIR;    start += FS_ROOT_DIR_LEN;/* * If we found a directory separator then the part which precedes the * last component is the name of the directory to be opened. */  } else if(start > 0) {/* * The _dr_open_dir() function requires the directory name to be '\0' * terminated, so temporarily do this by overwriting the first character * of the directory separator. */    pathname[start] = '\0';    dirpath = pathname;    terminated = 1;/* * We reached the start of the pathname before finding a directory * separator, so arrange to open the current working directory. */  } else {    start = 0;    dirpath = FS_PWD;  };/* * Attempt to open the directory. */  if(_dr_open_dir(cf->dr, dirpath, NULL)) {    const char *fmt = "Can't open directory: %.*s";    sprintf(cf->errmsg, fmt, ERRLEN - strlen(fmt), dirpath);    return 1;  };/* * If removed above, restore the directory separator and skip over it * to the start of the filename. */  if(terminated) {    memcpy(pathname + start, FS_DIR_SEP, FS_DIR_SEP_LEN);    start += FS_DIR_SEP_LEN;  };/* * Get the filename prefix and its length. */  prefix = pathname + start;  prefix_len = strlen(prefix);/* * Traverse the directory, looking for files who's prefixes match the * last component of the pathname. */  while((file_name = _dr_next_file(cf->dr)) != NULL && !waserr) {    int name_len = strlen(file_name);/* * Is the latest filename a possible completion of the filename prefix? */    if(name_len >= prefix_len && strncmp(prefix, file_name, prefix_len)==0) {/* * When listing all files in a directory, don't list files that start * with '.'. This is how hidden files are denoted in UNIX. */      if(prefix_len > 0 || file_name[0] != '.') {/* * Copy the completion suffix into the work pathname cf->buff->name, * adding backslash escapes if needed. */	if(cf_prepare_suffix(cf, file_name + prefix_len, escaped)) {	  waserr = 1;	} else {/* * We want directories to be displayed with directory suffixes, * and other fully completed filenames to be followed by spaces. * To check the type of the file, append the current suffix * to the path being completed, check the filetype, then restore * the path to its original form. */	  const char *cont_suffix = "";  /* The suffix to add if fully */                                         /*  completed. */	  const char *type_suffix = "";  /* The suffix to add when listing */	  if(_pn_append_to_path(cf->path, file_name + prefix_len,				-1, escaped) == NULL) {	    strcpy(cf->errmsg, "Insufficient memory to complete filename.");	    return 1;	  };/* * Specify suffixes according to the file type. */	  if(_pu_path_is_dir(cf->path->name)) {	    cont_suffix = FS_DIR_SEP;	    type_suffix = FS_DIR_SEP;	  } else if(!check_fn || check_fn(check_data, cf->path->name)) {	    cont_suffix = " ";	  } else {	    cf->path->name[pathlen] = '\0';	    continue;	  };/* * Remove the temporarily added suffix. */	  cf->path->name[pathlen] = '\0';/* * Record the latest completion. */	  if(cpl_add_completion(cpl, line, word_start, word_end, cf->buff->name,				type_suffix, cont_suffix))	    waserr = 1;	};      };    };  };/* * Close the directory. */  _dr_close_dir(cf->dr);  return waserr;}/*....................................................................... * Read a username or environment variable name, stopping when a directory * separator is seen, when the end of the string is reached, or the * output buffer overflows. * * Input: *  cf   CompleteFile *  The file-completion resource object. *  type         char *  The capitalized name of the type of name being read. *  string       char *  The string who's prefix contains the name. *  slen          int    The number of characters in string[]. *  nambuf       char *  The output name buffer. *  nammax        int    The longest string that will fit in nambuf[], excluding *                       the '\0' terminator. * Output: *  return       char *  A pointer to nambuf on success. On error NULL is *                       returned and a description of the error is recorded *                       in cf->errmsg[]. */static char *cf_read_name(CompleteFile *cf, const char *type,			  const char *string, int slen,			  char *nambuf, int nammax){  int namlen;         /* The number of characters in nambuf[] */  const char *sptr;   /* A pointer into string[] *//* * Work out the max number of characters that should be copied. */  int nmax = nammax < slen ? nammax : slen;/* * Get the environment variable name that follows the dollar. */  for(sptr=string,namlen=0;      namlen < nmax && (slen-namlen < FS_DIR_SEP_LEN ||			strncmp(sptr, FS_DIR_SEP, FS_DIR_SEP_LEN) != 0);      namlen++) {    nambuf[namlen] = *sptr++;  };/* * Did the name overflow the buffer? */  if(namlen >= nammax) {    const char *fmt = "%.*s name too long";    sprintf(cf->errmsg, fmt, ERRLEN - strlen(fmt), type);    return NULL;  };/* * Terminate the string. */  nambuf[namlen] = '\0';  return nambuf;}/*....................................................................... * Using the work buffer cf->buff, make a suitably escaped copy of a * given completion suffix, ready to be passed to cpl_add_completion(). * * Input: *  cf   CompleteFile *  The file-completion resource object. *  suffix       char *  The suffix to be copied. *  add_escapes   int    If true, escape special characters. * Output: *  return        int    0 - OK. *                       1 - Error. */static int cf_prepare_suffix(CompleteFile *cf, const char *suffix,			     int add_escapes){  const char *sptr; /* A pointer into suffix[] */  int nbsl;         /* The number of backslashes to add to the suffix */  int i;/* * How long is the suffix? */  int suffix_len = strlen(suffix);/* * Clear the work buffer. */  _pn_clear_path(cf->buff);/* * Count the number of backslashes that will have to be added to * escape spaces, tabs, backslashes and wildcard characters. */  nbsl = 0;  if(add_escapes) {    for(sptr = suffix; *sptr; sptr++) {      switch(*sptr) {      case ' ': case '\t': case '\\': case '*': case '?': case '[':	nbsl++;	break;      };    };  };/* * Arrange for the output path buffer to have sufficient room for the * both the suffix and any backslashes that have to be inserted. */  if(_pn_resize_path(cf->buff, suffix_len + nbsl) == NULL) {    strcpy(cf->errmsg, "Insufficient memory to complete filename");    return 1;  };/* * If the suffix doesn't need any escapes, copy it directly into the * work buffer. */  if(nbsl==0) {    strcpy(cf->buff->name, suffix);  } else {/* * Make a copy with special characters escaped? */    if(nbsl > 0) {      const char *src = suffix;      char *dst = cf->buff->name;      for(i=0; i<suffix_len; i++) {	switch(*src) {	case ' ': case '\t': case '\\': case '*': case '?': case '[':	  *dst++ = '\\';	};	*dst++ = *src++;      };      *dst = '\0';    };  };  return 0;}

⌨️ 快捷键说明

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