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

📄 cplmatch.c

📁 xorp源码hg
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 2000, 2001 by Martin C. Shepherd. *  * All rights reserved. *  * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, and/or sell copies of the Software, and to permit persons * to whom the Software is furnished to do so, provided that the above * copyright notice(s) and this permission notice appear in all copies of * the Software and that both the above copyright notice(s) and this * permission notice appear in supporting documentation. *  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *  * Except as contained in this notice, the name of a copyright holder * shall not be used in advertising or otherwise to promote the sale, use * or other dealings in this Software without prior written authorization * of the copyright holder. *//* * Standard includes. */#include <stdlib.h>#include <stdio.h>#include <string.h>/* * Local includes. */#include "libtecla.h"#include "stringrp.h"#include "pathutil.h"#include "cplfile.h"/* * Specify the number of strings to allocate when the string free-list * is exhausted. This also sets the number of elements to expand the * matches[] array by whenever it is found to be too small. */#define STR_BLK_FACT 100/* * Set the max length of the error-reporting string. There is no point * in this being longer than the width of a typical terminal window. * In composing error messages, I have assumed that this number is * at least 80, so don't decrease it below 80. */#define ERRLEN 200/* * Completion matches are recorded in containers of the following * type. */struct WordCompletion {  StringGroup *sg;        /* Memory for a group of strings */  int matches_dim;        /* The allocated size of result.matches[] */  char errmsg[ERRLEN+1];  /* The error-reporting buffer */  CplMatches result;      /* Completions to be returned to the caller */  CompleteFile *cf;       /* The resources used for filename completion */};static void cpl_sort_matches(WordCompletion *cpl);static void cpl_zap_duplicates(WordCompletion *cpl);static void cpl_clear_completions(WordCompletion *cpl);static int cpl_cmp_matches(const void *v1, const void *v2);static int cpl_cmp_suffixes(const void *v1, const void *v2);/* * The new_CplFileConf() constructor sets the integer first member of * the returned object to the following magic number. On seeing this, * cpl_file_completions() knows when it is passed a valid CplFileConf * object. */#define CFC_ID_CODE 4568/* * A pointer to a structure of the following type can be passed to * the builtin file-completion callback function to modify its behavior. */struct CplFileConf {  int id;             /* new_CplFileConf() sets this to CFC_ID_CODE */  int escaped;        /* If none-zero, backslashes in the input line are */                      /*  interpreted as escaping special characters and */                      /*  spaces, and any special characters and spaces in */                      /*  the listed completions will also be escaped with */                      /*  added backslashes. This is the default behaviour. */                      /* If zero, backslashes are interpreted as being */                      /*  literal parts of the filename, and none are added */                      /*  to the completion suffixes. */  int file_start;     /* The index in the input line of the first character */                      /*  of the filename. If you specify -1 here, */                      /*  cpl_file_completions() identifies the */                      /*  the start of the filename by looking backwards for */                      /*  an unescaped space, or the beginning of the line. */  CplCheckFn *chk_fn; /* If not zero, this argument specifies a */                      /*  function to call to ask whether a given */                      /*  file should be included in the list */                      /*  of completions. */  void *chk_data;     /* Anonymous data to be passed to check_fn(). */};static void cpl_init_FileConf(CplFileConf *cfc);/*....................................................................... * Create a new string-completion object. * * Output: *  return    WordCompletion *  The new object, or NULL on error. */WordCompletion *new_WordCompletion(void){  WordCompletion *cpl;  /* The object to be returned *//* * Allocate the container. */  cpl = (WordCompletion *) malloc(sizeof(WordCompletion));  if(!cpl) {    fprintf(stderr, "new_WordCompletion: Insufficient memory.\n");    return NULL;  };/* * Before attempting any operation that might fail, initialize the * container at least up to the point at which it can safely be passed * to del_WordCompletion(). */  cpl->sg = NULL;  cpl->matches_dim = 0;  cpl->result.suffix = NULL;  cpl->result.cont_suffix = NULL;  cpl->result.matches = NULL;  cpl->result.nmatch = 0;  cpl->cf = NULL;/* * Allocate an object that allows a group of strings to be allocated * efficiently by placing many of them in contiguous string segments. */  cpl->sg = _new_StringGroup(_pu_pathname_dim());  if(!cpl->sg)    return del_WordCompletion(cpl);/* * Allocate an array for matching completions. This will be extended later * if needed. */  cpl->matches_dim = STR_BLK_FACT;  cpl->result.matches = (CplMatch *) malloc(sizeof(cpl->result.matches[0]) *					    cpl->matches_dim);  if(!cpl->result.matches) {    fprintf(stderr,     "new_WordCompletion: Insufficient memory to allocate array of matches.\n");    return del_WordCompletion(cpl);  };/* * Allocate a filename-completion resource object. */  cpl->cf = _new_CompleteFile();  if(!cpl->cf)    return del_WordCompletion(cpl);  return cpl;}/*....................................................................... * Delete a string-completion object. * * Input: *  cpl    WordCompletion *  The object to be deleted. * Output: *  return WordCompletion *  The deleted object (always NULL). */WordCompletion *del_WordCompletion(WordCompletion *cpl){  if(cpl) {    cpl->sg = _del_StringGroup(cpl->sg);    if(cpl->result.matches) {      free(cpl->result.matches);      cpl->result.matches = NULL;      cpl->cf = _del_CompleteFile(cpl->cf);    };    free(cpl);  };  return NULL;}/*....................................................................... * This function is designed to be called by CplMatchFn callback * functions. It adds one possible completion of the token that is being * completed to an array of completions. If the completion needs any * special quoting to be valid when displayed in the input line, this * quoting must be included in the string. * * Input: *  cpl     WordCompletion *  The argument of the same name that was passed *                            to the calling CplMatchFn callback function. *  line        const char *  The input line, as received by the callback *                            function. *  word_start         int    The index within line[] of the start of the *                            word that is being completed. *  word_end           int    The index within line[] of the character which *                            follows the incomplete word, as received by the *                            calling callback function. *  suffix      const char *  The appropriately quoted string that could *                            be appended to the incomplete token to complete *                            it. A copy of this string will be allocated *                            internally. *  type_suffix const char *  When listing multiple completions, gl_get_line() *                            appends this string to the completion to indicate *                            its type to the user. If not pertinent pass "". *                            Otherwise pass a literal or static string. *  cont_suffix const char *  If this turns out to be the only completion, *                            gl_get_line() will append this string as *                            a continuation. For example, the builtin *                            file-completion callback registers a directory *                            separator here for directory matches, and a *                            space otherwise. If the match were a function *                            name you might want to append an open *                            parenthesis, etc.. If not relevant pass "". *                            Otherwise pass a literal or static string. * Output: *  return             int    0 - OK. *                            1 - Error. */int cpl_add_completion(WordCompletion *cpl, const char *line,		       int word_start, int word_end, const char *suffix,		       const char *type_suffix, const char *cont_suffix){  CplMatch *match; /* The container of the new match */  char *string;    /* A newly allocated copy of the completion string *//* * Check the arguments. */  if(!cpl)    return 1;  if(!suffix)    return 0;  if(!type_suffix)    type_suffix = "";  if(!cont_suffix)    cont_suffix = "";/* * Do we need to extend the array of matches[]? */  if(cpl->result.nmatch+1 > cpl->matches_dim) {    int needed = cpl->matches_dim + STR_BLK_FACT;    CplMatch *matches = (CplMatch *) realloc(cpl->result.matches,			    sizeof(cpl->result.matches[0]) * needed);    if(!matches) {      strcpy(cpl->errmsg, "Insufficient memory to extend array of matches.");      return 1;    };    cpl->result.matches = matches;    cpl->matches_dim = needed;  };/* * Allocate memory to store the combined completion prefix and the * new suffix. */  string = _sg_alloc_string(cpl->sg, word_end-word_start + strlen(suffix));  if(!string) {    strcpy(cpl->errmsg, "Insufficient memory to extend array of matches.");    return 1;  };/* * Compose the string. */  strncpy(string, line + word_start, word_end - word_start);  strcpy(string + word_end - word_start, suffix);/* * Record the new match. */  match = cpl->result.matches + cpl->result.nmatch++;  match->completion = string;  match->suffix = string + word_end - word_start;  match->type_suffix = type_suffix;/* * Record the continuation suffix. */  cpl->result.cont_suffix = cont_suffix;  return 0;}/*....................................................................... * Sort the array of matches. * * Input: *  cpl   WordCompletion *  The completion resource object. */static void cpl_sort_matches(WordCompletion *cpl){  qsort(cpl->result.matches, cpl->result.nmatch,	sizeof(cpl->result.matches[0]), cpl_cmp_matches);}/*....................................................................... * This is a qsort() comparison function used to sort matches. * * Input: *  v1, v2   void *  Pointers to the two matches to be compared. * Output: *  return    int    -1 -> v1 < v2. *                    0 -> v1 == v2 *                    1 -> v1 > v2 */static int cpl_cmp_matches(const void *v1, const void *v2){  const CplMatch *m1 = (const CplMatch *) v1;  const CplMatch *m2 = (const CplMatch *) v2;

⌨️ 快捷键说明

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