Example #1
0
static
char *mkidx_pathname(char *dest, size_t size, const char *pathname,
                     const char *suffix) 
{
    char *ext, *bn = NULL;
    int suffix_len;

    suffix_len = strlen(suffix);
    
    if (strlen(pathname) + suffix_len + 1 > size)
        return NULL;
    
    bn = n_basenam(pathname);
    if ((ext = strrchr(bn, '.')) == NULL || strcmp(ext, ".dir") == 0) {
        snprintf(dest, size, "%s%s", pathname, suffix);
        
    } else {
        int len = ext - pathname + 1;
        n_assert(len + suffix_len + strlen(ext) + 1 < size);
        n_strncpy(dest, pathname, len);
        strcat(dest, suffix);
        
        if (strstr(suffix, ext) == NULL)
            strcat(dest, ext);
        dest[size - 1] = '\0';
    }

    return dest;
}
Example #2
0
static char *command_options_generator(const char *text, int state)
{
    static tn_array *opts_table = NULL;
    
    if (state == 0) {
        struct poclidek_cmd *command = NULL;
        char *p, *e = NULL, line[64];
        int i, len;
        
        p = rl_line_buffer;

        if ((e = strchr(p, ' ')) == NULL)
            return NULL;
        
        n_assert(e - p + 1 <= 64);
        
        n_strncpy(line, p, e - p + 1);
    
        for (i = 0; i < n_array_size(sh_ctx.cctx->commands); i++) {
            struct poclidek_cmd *cmd = n_array_nth(sh_ctx.cctx->commands, i);
        
            if (n_str_eq(cmd->name, line)) {
                if (cmd->aliasto) {
                    struct poclidek_cmd tmpcmd;
                
                    tmpcmd.name = cmd->aliasto;
                    command = n_array_bsearch(sh_ctx.cctx->commands, &tmpcmd);

                } else {
                    command = cmd;
                }
            
                break;
            }
        }
        
        if (command == NULL)
            return NULL;
    
        opts_table = n_array_new(4, NULL, (tn_fn_cmp)strcmp);
    
        len = strlen(&text[2]);
    
        for (i = 0; !option_is_end(&command->argp_opts[i]); i++) {
            const struct argp_option *argp_opt = &command->argp_opts[i];
        
            /* skip hidden options */
            if (argp_opt->flags & OPTION_HIDDEN)
                continue;
        
            if (argp_opt->name && strncmp(argp_opt->name, &text[2], len) == 0) {
                n_array_push(opts_table, (void *) argp_opt->name);
            }
        }
    
        n_array_sort(opts_table);
    }
    
    if (state >= n_array_size(opts_table)) {
        n_array_cfree(&opts_table);
        return NULL;
    }
    
    return n_str_concat("--", n_array_nth(opts_table, state), NULL);
}
Example #3
0
static zword smart_tokeniser(zword dictionarytable,
			     const char *text, unsigned length, BOOL is_begin)
{
  zword word_num = 0;
  unsigned tlength = (length < 12) ? length : 12;
  char tbuffer[13];

  /* Letter replacements are tried in this order - */
  const char fixmeletters[] = "abcdefghijklmnopqrstuvwxyz";
  /* char fixmeletters[] = "etaonrishdlfcmugpywbvkxjqz"; */

  
  word_num = find_word(dictionarytable, text, length);  

  /* Some game files don't contain abbreviations for common commands */
  if(!word_num && do_expand && length == 1 && is_begin) {
    const char * const abbrevs[26] = {
      "a",              "b",           "close",          "down",
      "east",           "f",           "again",          "h",
      "inventory",      "j",           "attack",         "look",
      "m",              "north",       "oops",           "open",
      "quit",           "drop",        "south",          "take",
      "up",             "v",           "west",           "examine",
      "yes",            "wait"
    };
    if('a' <= text[0] && text[0] <= 'z') {
      strcpy(tbuffer, abbrevs[text[0] - 'a']);
      tlength = strlen(tbuffer);
      word_num = find_word(dictionarytable, tbuffer, tlength);
    }
  }

  /* Check for various typing errors */

  /* Don't attempt typo correction in very short words */
  if(do_spell_correct && length >= 3) {

    if(!word_num) {  /* Check for transposes */
      /* To fix, try all possible transposes */
      unsigned position;
      for(position = 1; position < tlength; position++) {
	unsigned s;
	for(s = 0; s < tlength; s++)
	  tbuffer[s] = text[s];

	tbuffer[position - 1] = text[position];
	tbuffer[position]     = text[position - 1];

	word_num = find_word(dictionarytable, tbuffer, tlength);
	if(word_num)
	  break;
      }
    }

    if(!word_num) {  /* Check for deletions */
      /* To fix, try all possible insertions */
      unsigned position;
      for(position = 0; position <= tlength; position++) {
	unsigned s;
	for(s = 0; s < position; s++)    /* letters before the insertion */
	  tbuffer[s] = text[s];

	for(s = position; s < tlength; s++)       /* after the insertion */
	  tbuffer[s + 1] = text[s];

	/* try each letter */
	for(s = 0; s < sizeof(fixmeletters); s++) {
	  tbuffer[position] = fixmeletters[s];
	  word_num = find_word(dictionarytable, tbuffer, tlength + 1);
	  if(word_num)
	    break;
	}

	if(word_num) {
	  tlength++;
	  break;
	}
      }
    }

    if(!word_num) {  /* Check for insertions */
      /* To fix, try all possible deletions */
      unsigned position;
      for(position = 0; position < tlength; position++) {
	unsigned s;
	for(s = 0; s < position; s++)    /* letters before the deletion */
	  tbuffer[s] = text[s];

	for(s = position + 1; s < tlength; s++)   /* after the deletion */
	  tbuffer[s - 1] = text[s];

	word_num = find_word(dictionarytable, tbuffer, tlength - 1);

	if(word_num) {
	  tlength--;
	  break;
	}
      }
    }

    if(!word_num) {  /* Check for substitutions */
      /* To fix, try all possible substitutions */
      unsigned position;
      for(position = 0; position < tlength; position++) {
      unsigned s;
      for(s = 0; s < tlength; s++)
	tbuffer[s] = text[s];

      /* try each letter */
      for(s = 0; s < sizeof(fixmeletters); s++) {
	tbuffer[position] = fixmeletters[s];
	word_num = find_word(dictionarytable, tbuffer, tlength);
	if(word_num)
	  break;
      }

      if(word_num)
	break;
      }
    }
  }

  /* Report any corrections made */
  if(word_num) {
    struct Typocorrection *p;
    char original[13], changedto[13];
    n_strncpy(original, text, 13);
    n_strncpy(changedto, tbuffer, 13);
    if(length < 13)
      original[length] = 0;
    if(tlength < 13)
      changedto[tlength] = 0;

    LEsearch(recent_corrections, p, ((n_strncmp(p->original, original, 13) == 0) &&
				     (n_strncmp(p->changedto, changedto, 13) == 0)));

    /* Only print a correction if it hasn't yet been reported this turn */
    if(!p) {
      struct Typocorrection newcorrection;
      n_strncpy(newcorrection.original, original, 13);
      n_strncpy(newcorrection.changedto, changedto, 13);
      LEadd(recent_corrections, newcorrection);

      set_glk_stream_current();

      if(allow_output) {
	glk_put_char('[');
	w_glk_put_buffer(text, length);
	w_glk_put_string(" -> ");
	w_glk_put_buffer(tbuffer, tlength);
	glk_put_char(']');
	glk_put_char(10);
      }
    }
  }

  return word_num;
}
Example #4
0
static
int pdir_difftoc_vacuum(const char *idxpath, const char *diffpath,
                        const char *suffix)
{
    tn_array     *lines; 
    char         line[2048], *dn, *bn, tmp[PATH_MAX];
    char         difftoc_path[PATH_MAX], difftoc_path_bak[PATH_MAX];
    struct stat  st_idx, st;
    struct vfile *vf;
    int          lineno, i, len;
    off_t        diffs_size;

    if (poldek__is_in_testing_mode())
        return 1;
    
    if (stat(idxpath, &st_idx) != 0) {
        logn(LOGERR, "vaccum diff: stat %s: %m", idxpath);
        return 0;
    }

    if (!mkidx_pathname(difftoc_path, sizeof(difftoc_path), diffpath, suffix))
        return 0;
    
    n_strncpy(tmp, difftoc_path, sizeof(tmp));
    n_basedirnam(tmp, &dn, &bn);

    
    if ((vf = vfile_open(difftoc_path, VFT_TRURLIO, VFM_RO)) == NULL)
        return 0;
    
    lines = n_array_new(128, NULL, NULL);
    while ((len = n_stream_gets(vf->vf_tnstream, line, sizeof(line))) > 0) {
        char *l;

        l = alloca(len + 1);
        memcpy(l, line, len + 1);
        n_array_push(lines, l);
        DBGF("l = [%s]\n", l);
    }
    
    if (n_array_size(lines)) {
        snprintf(difftoc_path_bak, sizeof(difftoc_path_bak), "%s-",
                 difftoc_path);
        rename(difftoc_path, difftoc_path_bak);
    }
    vfile_close(vf);

    if ((vf = vfile_open(difftoc_path, VFT_TRURLIO, VFM_RW)) == NULL) {
        rename(difftoc_path_bak, difftoc_path);
        n_array_free(lines);
        return 0;
    }
    
    lineno = 0;
    diffs_size = 0;
    for (i = n_array_size(lines) - 1; i >= 0; i--) {
        char *p, *l, path[PATH_MAX];

        l = n_array_nth(lines, i);
        if ((p = strchr(l, ' ')) == NULL) {
            logn(LOGERR, _("%s: format error"), path);
            *l = '\0';
            continue;
        }
        
        *p = '\0';
        /*                         "- 1" to save space for ".mdd" (to unlink mdd too) */
        snprintf(path, sizeof(path) - 1, "%s/%s", dn, l);

        *p = ' ';
        
        if (stat(path, &st) != 0) {
            if (errno != ENOENT)
                logn(LOGERR, "vaccum diff: stat %s: %m", l);
            *l = '\0';
            continue;
        }
        DBGF("path = (%s) %ld, %ld, %ld\n", path, st.st_size, diffs_size,
             st_idx.st_size);
        
        if (lineno) {
            if (vf_valid_path(path)) {
                char *p;
                
                msgn(1, _("Removing outdated diff %s"), n_basenam(path));
                unlink(path);
                if ((p = strrchr(path, '.')) && strcmp(p, ".gz") == 0) {
                    strcpy(p, ".mdd");
                    //msgn(1, _("Removing outdated MDD %s"), n_basenam(path));
                    unlink(path);
                }
            }
            
        } else {
            if (diffs_size + st.st_size > (st_idx.st_size * 0.9))
                lineno = i;
            else
                diffs_size += st.st_size;
        }
    }

    for (i = lineno; i < n_array_size(lines); i++) {
        char *l;
        
        l = n_array_nth(lines, i);
        if (*l)
            n_stream_printf(vf->vf_tnstream, "%s", l);
    }

    vfile_close(vf);
    n_array_free(lines);
    return 1;
}