~ubuntu-branches/debian/sid/neovim/sid

« back to all changes in this revision

Viewing changes to src/nvim/path.c

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2016-04-18 21:42:19 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20160418214219-1e6d4o1fwqarzk46
Tags: 0.1.3-1
* New upstream release.  (Closes: #820562)
* debian/control:
  + Remove unnecessary luarocks Build-Depends
  + Add libkvm-dev Build-Depends for kfreebsd-*
  + Add python(3)-neovim to Recommends.  (Closes: #812737)
  + Declare compiance with policy 3.9.8, no changes needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
268
268
 */
269
269
bool dir_of_file_exists(char_u *fname)
270
270
{
271
 
  char_u      *p;
272
 
  int c;
273
 
  bool retval;
274
 
 
275
 
  p = path_tail_with_sep(fname);
276
 
  if (p == fname)
 
271
  char_u *p = path_tail_with_sep(fname);
 
272
  if (p == fname) {
277
273
    return true;
278
 
  c = *p;
 
274
  }
 
275
  char_u c = *p;
279
276
  *p = NUL;
280
 
  retval = os_isdir(fname);
 
277
  bool retval = os_isdir(fname);
281
278
  *p = c;
282
279
  return retval;
283
280
}
539
536
                             size_t wildoff, int flags, bool didstar)
540
537
  FUNC_ATTR_NONNULL_ALL
541
538
{
542
 
  char_u      *buf;
543
 
  char_u      *p, *s, *e;
544
539
  int start_len = gap->ga_len;
545
 
  char_u      *pat;
546
 
  int starts_with_dot;
547
 
  int matches;
548
 
  int len;
 
540
  size_t len;
549
541
  bool starstar = false;
550
 
  static int stardepth = 0;         /* depth for "**" expansion */
 
542
  static int stardepth = 0;  // depth for "**" expansion
551
543
 
552
544
  /* Expanding "**" may take a long time, check for CTRL-C. */
553
545
  if (stardepth > 0) {
556
548
      return 0;
557
549
  }
558
550
 
559
 
  /* make room for file name */
560
 
  buf = xmalloc(STRLEN(path) + BASENAMELEN + 5);
 
551
  // Make room for file name.  When doing encoding conversion the actual
 
552
  // length may be quite a bit longer, thus use the maximum possible length.
 
553
  char_u *buf = xmalloc(MAXPATHL);
561
554
 
562
 
  /*
563
 
   * Find the first part in the path name that contains a wildcard.
564
 
   * When EW_ICASE is set every letter is considered to be a wildcard.
565
 
   * Copy it into "buf", including the preceding characters.
566
 
   */
567
 
  p = buf;
568
 
  s = buf;
569
 
  e = NULL;
 
555
  // Find the first part in the path name that contains a wildcard.
 
556
  // When EW_ICASE is set every letter is considered to be a wildcard.
 
557
  // Copy it into "buf", including the preceding characters.
 
558
  char_u *p = buf;
 
559
  char_u *s = buf;
 
560
  char_u *e = NULL;
570
561
  const char_u *path_end = path;
571
562
  while (*path_end != NUL) {
572
563
    /* May ignore a wildcard that has a backslash before it; it will
587
578
      e = p;
588
579
    }
589
580
    if (has_mbyte) {
590
 
      len = (*mb_ptr2len)(path_end);
 
581
      len = (size_t)(*mb_ptr2len)(path_end);
591
582
      STRNCPY(p, path_end, len);
592
583
      p += len;
593
584
      path_end += len;
612
603
    if (p[0] == '*' && p[1] == '*')
613
604
      starstar = true;
614
605
 
615
 
  /* convert the file pattern to a regexp pattern */
616
 
  starts_with_dot = (*s == '.');
617
 
  pat = file_pat_to_reg_pat(s, e, NULL, FALSE);
 
606
  // convert the file pattern to a regexp pattern
 
607
  int starts_with_dot = (*s == '.');
 
608
  char_u *pat = file_pat_to_reg_pat(s, e, NULL, false);
618
609
  if (pat == NULL) {
619
610
    xfree(buf);
620
611
    return 0;
645
636
  if (!didstar && stardepth < 100 && starstar && e - s == 2
646
637
      && *path_end == '/') {
647
638
    STRCPY(s, path_end + 1);
648
 
    ++stardepth;
649
 
    (void)do_path_expand(gap, buf, (int)(s - buf), flags, true);
650
 
    --stardepth;
 
639
    stardepth++;
 
640
    (void)do_path_expand(gap, buf, (size_t)(s - buf), flags, true);
 
641
    stardepth--;
651
642
  }
652
643
  *s = NUL;
653
644
 
702
693
  xfree(buf);
703
694
  vim_regfree(regmatch.regprog);
704
695
 
705
 
  matches = gap->ga_len - start_len;
706
 
  if (matches > 0)
 
696
  size_t matches = (size_t)(gap->ga_len - start_len);
 
697
  if (matches > 0) {
707
698
    qsort(((char_u **)gap->ga_data) + start_len, matches,
708
 
        sizeof(char_u *), pstrcmp);
 
699
          sizeof(char_u *), pstrcmp);
 
700
  }
709
701
  return matches;
710
702
}
711
703
 
735
727
 */
736
728
static bool is_unique(char_u *maybe_unique, garray_T *gap, int i)
737
729
{
738
 
  int candidate_len;
739
 
  int other_path_len;
740
 
  char_u  **other_paths = (char_u **)gap->ga_data;
741
 
  char_u  *rival;
 
730
  char_u **other_paths = (char_u **)gap->ga_data;
742
731
 
743
732
  for (int j = 0; j < gap->ga_len; j++) {
744
 
    if (j == i)
745
 
      continue;        /* don't compare it with itself */
746
 
 
747
 
    candidate_len = (int)STRLEN(maybe_unique);
748
 
    other_path_len = (int)STRLEN(other_paths[j]);
749
 
    if (other_path_len < candidate_len)
750
 
      continue;        /* it's different when it's shorter */
751
 
 
752
 
    rival = other_paths[j] + other_path_len - candidate_len;
 
733
    if (j == i) {
 
734
      continue;  // don't compare it with itself
 
735
    }
 
736
    size_t candidate_len = STRLEN(maybe_unique);
 
737
    size_t other_path_len = STRLEN(other_paths[j]);
 
738
    if (other_path_len < candidate_len) {
 
739
      continue;  // it's different when it's shorter
 
740
    }
 
741
    char_u *rival = other_paths[j] + other_path_len - candidate_len;
753
742
    if (fnamecmp(maybe_unique, rival) == 0
754
 
        && (rival == other_paths[j] || vim_ispathsep(*(rival - 1))))
755
 
      return false;        /* match */
 
743
        && (rival == other_paths[j] || vim_ispathsep(*(rival - 1)))) {
 
744
      return false;  // match
 
745
    }
756
746
  }
757
 
 
758
 
  return true;    /* no match found */
 
747
  return true;  // no match found
759
748
}
760
749
 
761
750
/*
769
758
 */
770
759
static void expand_path_option(char_u *curdir, garray_T *gap)
771
760
{
772
 
  char_u      *path_option = *curbuf->b_p_path == NUL
773
 
                             ? p_path : curbuf->b_p_path;
774
 
  char_u      *buf;
775
 
  int len;
776
 
 
777
 
  buf = xmalloc(MAXPATHL);
 
761
  char_u *path_option = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
 
762
  char_u *buf = xmalloc(MAXPATHL);
778
763
 
779
764
  while (*path_option != NUL) {
780
765
    copy_option_part(&path_option, buf, MAXPATHL, " ,");
786
771
      if (curbuf->b_ffname == NULL)
787
772
        continue;
788
773
      char_u *p = path_tail(curbuf->b_ffname);
789
 
      len = (int)(p - curbuf->b_ffname);
790
 
      if (len + (int)STRLEN(buf) >= MAXPATHL)
 
774
      size_t len = (size_t)(p - curbuf->b_ffname);
 
775
      if (len + STRLEN(buf) >= MAXPATHL) {
791
776
        continue;
792
 
      if (buf[1] == NUL)
 
777
      }
 
778
      if (buf[1] == NUL) {
793
779
        buf[len] = NUL;
794
 
      else
 
780
      } else {
795
781
        STRMOVE(buf + len, buf + 2);
 
782
      }
796
783
      memmove(buf, curbuf->b_ffname, len);
797
784
      simplify_filename(buf);
798
 
    } else if (buf[0] == NUL)
799
 
      /* relative to current directory */
800
 
      STRCPY(buf, curdir);
801
 
    else if (path_with_url((char *)buf))
802
 
      /* URL can't be used here */
803
 
      continue;
804
 
    else if (!path_is_absolute_path(buf)) {
805
 
      /* Expand relative path to their full path equivalent */
806
 
      len = (int)STRLEN(curdir);
807
 
      if (len + (int)STRLEN(buf) + 3 > MAXPATHL)
 
785
    } else if (buf[0] == NUL) {
 
786
      STRCPY(buf, curdir);  // relative to current directory
 
787
    } else if (path_with_url((char *)buf)) {
 
788
      continue;  // URL can't be used here
 
789
    } else if (!path_is_absolute_path(buf)) {
 
790
      // Expand relative path to their full path equivalent
 
791
      size_t len = STRLEN(curdir);
 
792
      if (len + STRLEN(buf) + 3 > MAXPATHL) {
808
793
        continue;
 
794
      }
809
795
      STRMOVE(buf + len + 1, buf);
810
796
      STRCPY(buf, curdir);
811
797
      buf[len] = PATHSEP;
859
845
 */
860
846
static void uniquefy_paths(garray_T *gap, char_u *pattern)
861
847
{
862
 
  int len;
863
 
  char_u      **fnames = (char_u **)gap->ga_data;
 
848
  char_u **fnames = (char_u **)gap->ga_data;
864
849
  bool sort_again = false;
865
 
  char_u      *pat;
866
 
  char_u      *file_pattern;
867
 
  char_u      *curdir;
868
850
  regmatch_T regmatch;
869
851
  garray_T path_ga;
870
 
  char_u      **in_curdir = NULL;
871
 
  char_u      *short_name;
 
852
  char_u **in_curdir = NULL;
 
853
  char_u *short_name;
872
854
 
873
855
  ga_remove_duplicate_strings(gap);
874
856
  ga_init(&path_ga, (int)sizeof(char_u *), 1);
875
857
 
876
 
  /*
877
 
   * We need to prepend a '*' at the beginning of file_pattern so that the
878
 
   * regex matches anywhere in the path. FIXME: is this valid for all
879
 
   * possible patterns?
880
 
   */
881
 
  len = (int)STRLEN(pattern);
882
 
  file_pattern = xmalloc(len + 2);
 
858
  // We need to prepend a '*' at the beginning of file_pattern so that the
 
859
  // regex matches anywhere in the path. FIXME: is this valid for all
 
860
  // possible patterns?
 
861
  size_t len = STRLEN(pattern);
 
862
  char_u *file_pattern = xmalloc(len + 2);
883
863
  file_pattern[0] = '*';
884
864
  file_pattern[1] = NUL;
885
865
  STRCAT(file_pattern, pattern);
886
 
  pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, TRUE);
 
866
  char_u *pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, true);
887
867
  xfree(file_pattern);
888
868
  if (pat == NULL)
889
869
    return;
894
874
  if (regmatch.regprog == NULL)
895
875
    return;
896
876
 
897
 
  curdir = xmalloc(MAXPATHL);
 
877
  char_u *curdir = xmalloc(MAXPATHL);
898
878
  os_dirname(curdir, MAXPATHL);
899
879
  expand_path_option(curdir, &path_ga);
900
880
 
901
 
  in_curdir = xcalloc(gap->ga_len, sizeof(char_u *));
 
881
  in_curdir = xcalloc((size_t)gap->ga_len, sizeof(char_u *));
902
882
 
903
883
  for (int i = 0; i < gap->ga_len && !got_int; i++) {
904
884
    char_u      *path = fnames[i];
907
887
    char_u      *pathsep_p;
908
888
    char_u      *path_cutoff;
909
889
 
910
 
    len = (int)STRLEN(path);
 
890
    len = STRLEN(path);
911
891
    is_in_curdir = fnamencmp(curdir, path, dir_end - path) == 0
912
892
                   && curdir[dir_end - path] == NUL;
913
893
    if (is_in_curdir)
1112
1092
int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
1113
1093
                         char_u ***file, int flags)
1114
1094
{
1115
 
  int i;
1116
1095
  garray_T ga;
1117
 
  char_u              *p;
 
1096
  char_u *p;
1118
1097
  static bool recursive = false;
1119
1098
  int add_pat;
1120
1099
  bool did_expand_in_path = false;
1139
1118
   * avoids starting the shell for each argument separately.
1140
1119
   * For `=expr` do use the internal function.
1141
1120
   */
1142
 
  for (i = 0; i < num_pat; i++) {
 
1121
  for (int i = 0; i < num_pat; i++) {
1143
1122
    if (has_special_wildchar(pat[i])
1144
 
        && !(vim_backtick(pat[i]) && pat[i][1] == '=')
1145
 
        )
 
1123
        && !(vim_backtick(pat[i]) && pat[i][1] == '=')) {
1146
1124
      return mch_expand_wildcards(num_pat, pat, num_file, file, flags);
 
1125
    }
1147
1126
  }
1148
1127
#endif
1149
1128
 
1154
1133
   */
1155
1134
  ga_init(&ga, (int)sizeof(char_u *), 30);
1156
1135
 
1157
 
  for (i = 0; i < num_pat; ++i) {
 
1136
  for (int i = 0; i < num_pat; ++i) {
1158
1137
    add_pat = -1;
1159
1138
    p = pat[i];
1160
1139
 
1161
 
    if (vim_backtick(p))
 
1140
    if (vim_backtick(p)) {
1162
1141
      add_pat = expand_backtick(&ga, p, flags);
1163
 
    else {
1164
 
      /*
1165
 
       * First expand environment variables, "~/" and "~user/".
1166
 
       */
 
1142
      if (add_pat == -1) {
 
1143
        recursive = false;
 
1144
        FreeWild(ga.ga_len, (char_u **)ga.ga_data);
 
1145
        *num_file = 0;
 
1146
        *file = NULL;
 
1147
        return FAIL;
 
1148
      }
 
1149
    } else {
 
1150
      // First expand environment variables, "~/" and "~user/".
1167
1151
      if (has_env_var(p) || *p == '~') {
1168
1152
        p = expand_env_save_opt(p, true);
1169
1153
        if (p == NULL)
1206
1190
          recursive = true;
1207
1191
          did_expand_in_path = true;
1208
1192
        } else {
1209
 
          add_pat = path_expand(&ga, p, flags);
 
1193
          size_t tmp_add_pat = path_expand(&ga, p, flags);
 
1194
          assert(tmp_add_pat <= INT_MAX);
 
1195
          add_pat = (int)tmp_add_pat;
1210
1196
        }
1211
1197
      }
1212
1198
    }
1246
1232
  return *p == '`' && *(p + 1) != NUL && *(p + STRLEN(p) - 1) == '`';
1247
1233
}
1248
1234
 
1249
 
/*
1250
 
 * Expand an item in `backticks` by executing it as a command.
1251
 
 * Currently only works when pat[] starts and ends with a `.
1252
 
 * Returns number of file names found.
1253
 
 */
1254
 
static int 
1255
 
expand_backtick (
 
1235
// Expand an item in `backticks` by executing it as a command.
 
1236
// Currently only works when pat[] starts and ends with a `.
 
1237
// Returns number of file names found, -1 if an error is encountered.
 
1238
static int expand_backtick(
1256
1239
    garray_T *gap,
1257
1240
    char_u *pat,
1258
1241
    int flags              /* EW_* flags */
1259
1242
)
1260
1243
{
1261
 
  char_u      *p;
1262
 
  char_u      *cmd;
1263
 
  char_u      *buffer;
 
1244
  char_u *p;
 
1245
  char_u *buffer;
1264
1246
  int cnt = 0;
1265
 
  int i;
1266
1247
 
1267
 
  /* Create the command: lop off the backticks. */
1268
 
  cmd = vim_strnsave(pat + 1, (int)STRLEN(pat) - 2);
 
1248
  // Create the command: lop off the backticks.
 
1249
  char_u *cmd = vim_strnsave(pat + 1, STRLEN(pat) - 2);
1269
1250
 
1270
1251
  if (*cmd == '=')          /* `={expr}`: Expand expression */
1271
1252
    buffer = eval_to_string(cmd + 1, &p, TRUE);
1273
1254
    buffer = get_cmd_output(cmd, NULL,
1274
1255
        (flags & EW_SILENT) ? kShellOptSilent : 0, NULL);
1275
1256
  xfree(cmd);
1276
 
  if (buffer == NULL)
1277
 
    return 0;
 
1257
  if (buffer == NULL) {
 
1258
    return -1;
 
1259
  }
1278
1260
 
1279
1261
  cmd = buffer;
1280
1262
  while (*cmd != NUL) {
1284
1266
      ++p;
1285
1267
    /* add an entry if it is not empty */
1286
1268
    if (p > cmd) {
1287
 
      i = *p;
 
1269
      char_u i = *p;
1288
1270
      *p = NUL;
1289
1271
      addfile(gap, cmd, flags);
1290
1272
      *p = i;
1537
1519
    char_u *rel_fname         /* file we are searching relative to */
1538
1520
)
1539
1521
{
1540
 
  char_u      *file_name;
1541
 
  int c;
1542
 
  char_u      *tofree = NULL;
 
1522
  char_u *file_name;
 
1523
  char_u *tofree = NULL;
1543
1524
 
1544
1525
  if ((options & FNAME_INCL) && *curbuf->b_p_inex != NUL) {
1545
1526
    tofree = eval_includeexpr(ptr, len);
1550
1531
  }
1551
1532
 
1552
1533
  if (options & FNAME_EXP) {
1553
 
    file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS,
1554
 
                                  TRUE, rel_fname);
 
1534
    file_name = find_file_in_path(ptr, len, options & ~FNAME_MESS, true,
 
1535
                                  rel_fname);
1555
1536
 
1556
1537
    /*
1557
1538
     * If the file could not be found in a normal way, try applying
1568
1549
      }
1569
1550
    }
1570
1551
    if (file_name == NULL && (options & FNAME_MESS)) {
1571
 
      c = ptr[len];
 
1552
      char_u c = ptr[len];
1572
1553
      ptr[len] = NUL;
1573
1554
      EMSG2(_("E447: Can't find file \"%s\" in path"), ptr);
1574
1555
      ptr[len] = c;
1627
1608
/// @param      force is a flag to force expanding even if the path is absolute
1628
1609
///
1629
1610
/// @return           FAIL for failure, OK otherwise
1630
 
int vim_FullName(const char *fname, char *buf, int len, bool force)
 
1611
int vim_FullName(const char *fname, char *buf, size_t len, bool force)
1631
1612
  FUNC_ATTR_NONNULL_ARG(2)
1632
1613
{
1633
1614
  int retval = OK;
1775
1756
 */
1776
1757
int pathcmp(const char *p, const char *q, int maxlen)
1777
1758
{
1778
 
  int i;
 
1759
  int i, j;
1779
1760
  int c1, c2;
1780
1761
  const char  *s = NULL;
1781
1762
 
1782
 
  for (i = 0; maxlen < 0 || i < maxlen; i += MB_PTR2LEN((char_u *)p + i)) {
 
1763
  for (i = 0, j = 0; maxlen < 0 || (i < maxlen && j < maxlen);) {
1783
1764
    c1 = PTR2CHAR((char_u *)p + i);
1784
 
    c2 = PTR2CHAR((char_u *)q + i);
 
1765
    c2 = PTR2CHAR((char_u *)q + j);
1785
1766
 
1786
1767
    /* End of "p": check if "q" also ends or just has a slash. */
1787
1768
    if (c1 == NUL) {
1788
1769
      if (c2 == NUL)        /* full match */
1789
1770
        return 0;
1790
1771
      s = q;
 
1772
      i = j;
1791
1773
      break;
1792
1774
    }
1793
1775
 
1811
1793
      return p_fic ? vim_toupper(c1) - vim_toupper(c2)
1812
1794
             : c1 - c2;         /* no match */
1813
1795
    }
 
1796
 
 
1797
    i += MB_PTR2LEN((char_u *)p + i);
 
1798
    j += MB_PTR2LEN((char_u *)q + j);
1814
1799
  }
1815
 
  if (s == NULL)        /* "i" ran into "maxlen" */
 
1800
  if (s == NULL) {  // "i" or "j" ran into "maxlen"
1816
1801
    return 0;
 
1802
  }
1817
1803
 
1818
1804
  c1 = PTR2CHAR((char_u *)s + i);
1819
1805
  c2 = PTR2CHAR((char_u *)s + i + MB_PTR2LEN((char_u *)s + i));
2008
1994
 */
2009
1995
int match_suffix(char_u *fname)
2010
1996
{
2011
 
  int fnamelen, setsuflen;
2012
 
  char_u      *setsuf;
2013
 
#define MAXSUFLEN 30        /* maximum length of a file suffix */
 
1997
#define MAXSUFLEN 30  // maximum length of a file suffix
2014
1998
  char_u suf_buf[MAXSUFLEN];
2015
1999
 
2016
 
  fnamelen = (int)STRLEN(fname);
2017
 
  setsuflen = 0;
2018
 
  for (setsuf = p_su; *setsuf; ) {
 
2000
  size_t fnamelen = STRLEN(fname);
 
2001
  size_t setsuflen = 0;
 
2002
  for (char_u *setsuf = p_su; *setsuf; ) {
2019
2003
    setsuflen = copy_option_part(&setsuf, suf_buf, MAXSUFLEN, ".,");
2020
2004
    if (setsuflen == 0) {
2021
2005
      char_u *tail = path_tail(fname);
2026
2010
        break;
2027
2011
      }
2028
2012
    } else {
2029
 
      if (fnamelen >= setsuflen
2030
 
          && fnamencmp(suf_buf, fname + fnamelen - setsuflen,
2031
 
              (size_t)setsuflen) == 0)
 
2013
      if (fnamelen >= setsuflen &&
 
2014
          fnamencmp(suf_buf, fname + fnamelen - setsuflen, setsuflen) == 0) {
2032
2015
        break;
 
2016
      }
2033
2017
      setsuflen = 0;
2034
2018
    }
2035
2019
  }
2040
2024
///
2041
2025
/// @param directory Directory name, relative to current directory.
2042
2026
/// @return `FAIL` for failure, `OK` for success.
2043
 
int path_full_dir_name(char *directory, char *buffer, int len)
 
2027
int path_full_dir_name(char *directory, char *buffer, size_t len)
2044
2028
{
2045
2029
  int SUCCESS = 0;
2046
2030
  int retval = OK;
2082
2066
 
2083
2067
// Append to_append to path with a slash in between.
2084
2068
// Append to_append to path with a slash in between.
2085
 
int append_path(char *path, const char *to_append, int max_len)
 
2069
int append_path(char *path, const char *to_append, size_t max_len)
2086
2070
{
2087
 
  int current_length = STRLEN(path);
2088
 
  int to_append_length = STRLEN(to_append);
 
2071
  size_t current_length = strlen(path);
 
2072
  size_t to_append_length = strlen(to_append);
2089
2073
 
2090
2074
  // Do not append empty strings.
2091
2075
  if (to_append_length == 0) {
2120
2104
 
2121
2105
/// Expand a given file to its absolute path.
2122
2106
///
2123
 
/// @param fname The filename which should be expanded.
2124
 
/// @param buf Buffer to store the absolute path of `fname`.
2125
 
/// @param len Length of `buf`.
2126
 
/// @param force Also expand when `fname` is already absolute.
2127
 
/// @return `FAIL` for failure, `OK` for success.
2128
 
static int path_get_absolute_path(const char_u *fname, char_u *buf, int len, int force)
 
2107
/// @param  fname  filename which should be expanded.
 
2108
/// @param  buf    buffer to store the absolute path of "fname".
 
2109
/// @param  len    length of "buf".
 
2110
/// @param  force  also expand when "fname" is already absolute.
 
2111
///
 
2112
/// @return FAIL for failure, OK for success.
 
2113
static int path_get_absolute_path(const char_u *fname, char_u *buf,
 
2114
                                  size_t len, int force)
2129
2115
{
2130
2116
  char_u *p;
2131
2117
  *buf = NUL;