예제 #1
0
파일: string.cpp 프로젝트: otrempe/watchman
bool w_is_path_absolute_cstr_len(const char *path, uint32_t len) {
#ifdef _WIN32
  char drive_letter;

  if (len <= 2) {
    return false;
  }

  // "\something"
  if (is_slash(path[0])) {
    // "\\something" is absolute, "\something" is relative to the current
    // dir of the current drive, whatever that may be, for a given process
    return is_slash(path[1]);
  }

  drive_letter = (char)tolower(path[0]);
  // "C:something"
  if (drive_letter >= 'a' && drive_letter <= 'z' && path[1] == ':') {
    // "C:\something" is absolute, but "C:something" is relative to
    // the current dir on the C drive(!)
    return is_slash(path[2]);
  }
  // we could check for things like NUL:, COM: and so on here.
  // While those are technically absolute names, we can't watch them, so
  // we don't consider them absolute for the purposes of checking whether
  // the path is a valid watchable root
  return false;
#else
  return len > 0 && path[0] == '/';
#endif
}
예제 #2
0
char *
tr_sys_path_basename (const char  * path,
                      tr_error   ** error)
{
  if (path == NULL || path[0] == '\0')
    return tr_strdup (".");

  if (!is_valid_path (path))
    {
      set_system_error (error, ERROR_PATH_NOT_FOUND);
      return NULL;
    }

  const char * end = path + strlen (path);
  while (end > path && is_slash (*(end - 1)))
    --end;

  if (end == path)
    return tr_strdup ("/");

  const char * name = end;
  while (name > path && *(name - 1) != ':' && !is_slash (*(name - 1)))
    --name;

  if (name == end)
    return tr_strdup ("/");

  return tr_strndup (name, end - name);
}
예제 #3
0
char* tr_sys_path_dirname(char const* path, tr_error** error)
{
    if (path == NULL || path[0] == '\0')
    {
        return tr_strdup(".");
    }

    if (!is_valid_path(path))
    {
        set_system_error(error, ERROR_PATH_NOT_FOUND);
        return NULL;
    }

    bool const is_unc = is_unc_path(path);

    if (is_unc && path[2] == '\0')
    {
        return tr_strdup(path);
    }

    char const* end = path + strlen(path);

    while (end > path && is_slash(*(end - 1)))
    {
        --end;
    }

    if (end == path)
    {
        return tr_strdup("/");
    }

    char const* name = end;

    while (name > path && *(name - 1) != ':' && !is_slash(*(name - 1)))
    {
        --name;
    }

    while (name > path && is_slash(*(name - 1)))
    {
        --name;
    }

    if (name == path)
    {
        return tr_strdup(is_unc ? "\\\\" : ".");
    }

    if (name > path && *(name - 1) == ':' && *name != '\0' && !is_slash(*name))
    {
        return tr_strdup_printf("%c:.", path[0]);
    }

    return tr_strndup(path, name - path);
}
예제 #4
0
static int16_t final_slash_l(cell *c)
 {
 int16_t i;
 uchar fnt;

 get_b_lines(c,&bl);
 if (c->row+c->h>=bl.b3+MIN(3,MAX(1,c->h/10)))
  return 0;
 if ((c->flg & (c_f_let|c_f_bad)) == 0)
   return 0;   // AL 940318
 if (c->flg & c_f_dust)
   return 0;   // AL 940318
 if ((fnt=c->prevl->font|c->nextl->font)&c_fp_ser && !(fnt&c_fp_gelv))
  return 0;
 c->nvers-=MAX(0,c->nvers-(VERS_IN_CELL-4));
 c->vers[c->nvers].let='l';
 c->vers[c->nvers+1].let='I';
 c->vers[c->nvers+2].let='1';
 c->vers[c->nvers].prob=c->vers[c->nvers+1].prob=c->vers[c->nvers+2].prob=
							    c->vers[0].prob;
 for (i=0; i<c->nvers; i++)
  if (memchr("lI1",c->vers[i].let,3))
   c->vers[i].prob=0;
 c->nvers+=3;
 c->vers[c->nvers].let=0;
 if (c->env!=NULL && !is_slash(c))
  c->vers[0].prob=MAX(2,c->vers[0].prob-50);
 sort_vers(c);
 return 1;
 }
예제 #5
0
UInt32 Archive::find_dir(const wstring& path) {
  if (file_list.empty())
    make_index();

  ArcFileInfo dir_info;
  dir_info.is_dir = true;
  dir_info.parent = c_root_index;
  size_t begin_pos = 0;
  while (begin_pos < path.size()) {
    size_t end_pos = begin_pos;
    while (end_pos < path.size() && !is_slash(path[end_pos])) end_pos++;
    if (end_pos != begin_pos) {
      dir_info.name.assign(path.data() + begin_pos, end_pos - begin_pos);
      FileIndexRange fi_range = equal_range(file_list_index.begin(), file_list_index.end(), -1, [&] (UInt32 left, UInt32 right) -> bool {
        const ArcFileInfo& fi_left = left == -1 ? dir_info : file_list[left];
        const ArcFileInfo& fi_right = right == -1 ? dir_info : file_list[right];
        return fi_left < fi_right;
      });
      if (fi_range.first == fi_range.second)
        FAIL(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND));
      dir_info.parent = *fi_range.first;
    }
    begin_pos = end_pos + 1;
  }
  return dir_info.parent;
}
예제 #6
0
파일: string.cpp 프로젝트: otrempe/watchman
w_string_piece w_string_piece::dirName() const {
  for (auto end = e_; end >= s_; --end) {
    if (is_slash(*end)) {
      /* found the end of the parent dir */
      return w_string_piece(s_, end - s_);
    }
  }
  return nullptr;
}
예제 #7
0
파일: string.cpp 프로젝트: otrempe/watchman
// Compute the basename of path, return that as a string
w_string_t *w_string_new_basename_typed(const char *path,
    w_string_type_t type) {
  const char *base;
  base = path + strlen(path);
  while (base > path && !is_slash(base[-1])) {
    base--;
  }
  return w_string_new_typed(base, type);
}
예제 #8
0
파일: string.cpp 프로젝트: otrempe/watchman
w_string_piece w_string_piece::baseName() const {
  for (auto end = e_; end >= s_; --end) {
    if (is_slash(*end)) {
      /* found the end of the parent dir */
      return w_string_piece(end + 1, e_ - (end + 1));
    }
  }

  return *this;
}
예제 #9
0
파일: string.cpp 프로젝트: otrempe/watchman
w_string_t *w_string_canon_path(w_string_t *str)
{
  int end;
  int trim = 0;

  for (end = str->len - 1; end >= 0 && is_slash(str->buf[end]); end--) {
    trim++;
  }
  if (trim) {
    return w_string_slice(str, 0, str->len - trim);
  }
  w_string_addref(str);
  return str;
}
예제 #10
0
파일: string.cpp 프로젝트: otrempe/watchman
w_string_t *w_string_dirname(w_string_t *str)
{
  int end;

  /* can't use libc strXXX functions because we may be operating
   * on a slice */
  for (end = str->len - 1; end >= 0; end--) {
    if (is_slash(str->buf[end])) {
      /* found the end of the parent dir */
      return w_string_slice(str, 0, end);
    }
  }

  return NULL;
}
예제 #11
0
bool
tr_sys_path_is_relative (const char * path)
{
  assert (path != NULL);

  /* UNC path: `\\...`. */
  if (is_unc_path (path))
    return false;

  /* Local path: `X:` or `X:\...`. */
  if (isalpha (path[0]) && path[1] == ':' && (path[2] == '\0' || is_slash (path[2])))
    return false;

  return true;
}
예제 #12
0
파일: string.cpp 프로젝트: otrempe/watchman
w_string_t *w_string_basename(w_string_t *str)
{
  int end;

  /* can't use libc strXXX functions because we may be operating
   * on a slice */
  for (end = str->len - 1; end >= 0; end--) {
    if (is_slash(str->buf[end])) {
      /* found the end of the parent dir */
      return w_string_slice(str, end + 1, str->len - (end + 1));
    }
  }

  w_string_addref(str);
  return str;
}
예제 #13
0
bool tr_sys_path_is_relative(char const* path)
{
    TR_ASSERT(path != NULL);

    /* UNC path: `\\...`. */
    if (is_unc_path(path))
    {
        return false;
    }

    /* Local path: `X:` or `X:\...`. */
    if (isalpha(path[0]) && path[1] == ':' && (path[2] == '\0' || is_slash(path[2])))
    {
        return false;
    }

    return true;
}
예제 #14
0
void fix_slashes(char * in,char * out)
{ 
 int slash_count;
 for(slash_count=1;in && out && *in;in++)
 {
  if(is_slash(*in))
  {
   slash_count++;
   continue;
  } else {
   if(slash_count)
   {
    slash_count=0;
    *out++='/';
   }
   *out++=*in;
  }
 }
 *out='\0';
}
예제 #15
0
파일: string.cpp 프로젝트: otrempe/watchman
// Return the normalized (lowercase) filename suffix
w_string_t *w_string_suffix(w_string_t *str)
{
  int end;
  char name_buf[128];
  char *buf;

  /* can't use libc strXXX functions because we may be operating
   * on a slice */
  for (end = str->len - 1; end >= 0; end--) {
    if (str->buf[end] == '.') {
      if (str->len - end > sizeof(name_buf)) {
        // Too long
        return NULL;
      }

      buf = name_buf;
      end++;
      while ((unsigned)end < str->len) {
        *buf = (char)tolower((uint8_t)str->buf[end]);
        end++;
        buf++;
      }
      *buf = '\0';
      return w_string_new_typed(name_buf, str->type);
    } else if (str->len - end >= sizeof(name_buf)) {
      // We haven't found the '.' yet but the suffix will never fit in our local
      // buffer
      return nullptr;
    }

    if (is_slash(str->buf[end])) {
      // No suffix
      return NULL;
    }
  }

  // Has no suffix
  return NULL;
}
예제 #16
0
static const char *
relocate_path(const char *dir, const char *s)
{
  SB sb;
  const char *r;
  const char *execdir = LUA_EXECDIR;
  int lexecdir = strlen(execdir);
  int ldir = strlen(dir);
  sbinit(&sb);
  while ((r = strstr(s, execdir)))
    {
      sbaddn(&sb, s, r-s);
      sbaddn(&sb, dir, ldir);
      s = r + lexecdir;
      while (is_slash(s[0]))
        {
          if (is_dot(s[1]) && is_slash(s[2]))
            {
              s += 2;
              continue;
            }
          if (is_dot(s[1]) && is_dot(s[2]) && is_slash(s[3]) )
            {
              s += 3;
              while (sb.buffer && sb.len>0 && is_slash(sb.buffer[sb.len-1]))
                sb.len -= 1;
              while (sb.buffer && sb.len>0 && !is_slash(sb.buffer[sb.len-1]))
                sb.len -= 1;
              while (sb.buffer && sb.len>0 && is_slash(sb.buffer[sb.len-1]))
                sb.len -= 1;
              continue;
            }
          break;
        }
    }
  sbaddn(&sb, s, strlen(s));
  sbadd1(&sb, 0);
#ifdef LUA_WIN
  r = _strdup(sb.buffer);
#else
  r = strdup(sb.buffer);
#endif
  sbfree(&sb);
  return r;
}
예제 #17
0
static int16_t final_no_slash(cell *c)
 {
 int16_t i;
 uchar fnt;

 if (c->env==NULL)
  return 0;
 for (i=1; i<c->nvers; i++)
  if (c->vers[i].let=='/') break;
 if (i==c->nvers)
  return 0;
 if ((fnt=c->prevl->font|c->nextl->font)&c_fp_ser && !(fnt&c_fp_gelv) &&
     !(c->font&c_fp_ser))
  {
  c->vers[i].let=c->vers[0].let;
  c->vers[0].let='/';
  return 1;
  }
 if (is_slash(c))
  return 0;
 c->vers[i].prob=0;
 sort_vers(c);
 return 1;
 }
예제 #18
0
DMZ_INTERNAL void find_character_groups_for_stripe(IplImage *card_y, IplImage *sobel_image, int stripe_base_row, long stripe_sum, GroupedRectsList &expiry_groups, GroupedRectsList &name_groups) {
#if DEBUG_EXPIRY_SEGMENTATION_PERFORMANCE
  dmz_debug_timer_start(1);
#endif
  
  // "Expanded" stripe is kSmallCharacterHeight + 2 scan lines in height ("expanded" refers to the "+ 2" -- one extra scan line above and below the input stripe)
  CvSize  card_image_size = cvGetSize(sobel_image);
  int     expanded_stripe_top = stripe_base_row - 1;
  CvRect  expanded_stripe_rect = cvRect(0, expanded_stripe_top, card_image_size.width, MIN(kSmallCharacterHeight + 2, card_image_size.height - expanded_stripe_top));

  // Any rect whose pixel-sum is less than rectangle_summation_threshold is too dim to care about
#define RECT_AVERAGE_THRESHOLD_FACTOR 5
  long rect_average_based_on_stripe_sum = ((stripe_sum * kSmallCharacterWidth) / card_image_size.width);
  float rectangle_summation_threshold = rect_average_based_on_stripe_sum / RECT_AVERAGE_THRESHOLD_FACTOR;
  
  // [1] Calculate the pixel-sum for each possible character rectangle within the stripe...
  CharacterRectList rect_list;
  float rect_sum_total = 0;
  float rect_sum_average = 0;
  long rect_sum = 0;
  
  // [1a] Calculate pixel-sum for the leftmost character rect
  
  for (int col = 0; col < kSmallCharacterWidth; col++) {
    for (int row = 0; row < expanded_stripe_rect.height; row++) {
      rect_sum += CV_IMAGE_ELEM(sobel_image, short, stripe_base_row + row, col);
    }
  }
  
  // [1b] For each possible character rect...
  
  for (int col = 0; col < card_image_size.width - kSmallCharacterWidth + 1; col++) {
    
    // Record pixel-sum of current character rect (ignoring excessively dim rects)
    
    if (rect_sum > rectangle_summation_threshold) {
      CharacterRect rect;
      rect.top = expanded_stripe_rect.y;
      rect.left = col;
      rect.sum = rect_sum;
      rect_list.push_back(rect);
      
      rect_sum_total += (float)rect_sum;
    }
    
    if (col < card_image_size.width - kSmallCharacterWidth) {
      
      // Update pixels-sum by subtracting the leftmost pixel values and adding the next pixel values to the right
      
      for (int row = 0; row < expanded_stripe_rect.height; row++) {
        rect_sum -= CV_IMAGE_ELEM(sobel_image, short, stripe_base_row + row, col);
        rect_sum += CV_IMAGE_ELEM(sobel_image, short, stripe_base_row + row, col + kSmallCharacterWidth);
      }
    }
  }
  
  if (rect_list.empty()) {
    return;
  }
  
  rect_sum_average = (rect_sum_total / rect_list.size());
#define RECT_SUM_THRESHOLD_FACTOR 0.8
  float rect_sum_threshold = (float) (RECT_SUM_THRESHOLD_FACTOR * rect_sum_average);
  
#if DEBUG_EXPIRY_SEGMENTATION_PERFORMANCE
  dmz_debug_timer_print("calc all rects", 1);
#endif
  
  // [2] Sort rectangles descending by sum
  
  std::sort(rect_list.begin(), rect_list.end(), CharacterRectCompareSumDescending());
  
#if DEBUG_EXPIRY_SEGMENTATION_PERFORMANCE
  char msg[256];
  sprintf(msg, "sort %ld non-zero rects", rect_list.size());
  dmz_debug_timer_print(msg, 1);
#endif
  
  // [3] Find the non-overlapping rectangles, ignoring rectangles whose sum is excessively small (compared to the average rect sum)
  
  GroupedRectsList non_overlapping_rect_list;
  
  bool non_overlapping_rect_mask[expanded_stripe_rect.width];
  memset(non_overlapping_rect_mask, 0, sizeof(non_overlapping_rect_mask));
  
  for (CharacterRectListIterator rect = rect_list.begin(); rect != rect_list.end(); ++ rect) {
    if ((float)rect->sum <= rect_sum_threshold) {
      break;
    }
    
    if (!non_overlapping_rect_mask[rect->left] && !non_overlapping_rect_mask[rect->left + kSmallCharacterWidth - 1]) {
      GroupedRects grouped_rect;
      grouped_rect.top = rect->top;
      grouped_rect.left = rect->left;
      grouped_rect.width = kSmallCharacterWidth;
      grouped_rect.height = expanded_stripe_rect.height;
      grouped_rect.grouped_yet = false;
      grouped_rect.sum = rect->sum;
      grouped_rect.character_width = kSmallCharacterWidth;
      non_overlapping_rect_list.push_back(grouped_rect);
      
      non_overlapping_rect_mask[rect->left + 0] = true;
      non_overlapping_rect_mask[rect->left + 1] = true;
      non_overlapping_rect_mask[rect->left + 2] = true;
      non_overlapping_rect_mask[rect->left + 3] = true;
      non_overlapping_rect_mask[rect->left + 4] = true;
      non_overlapping_rect_mask[rect->left + 5] = true;
      non_overlapping_rect_mask[rect->left + 6] = true;
      non_overlapping_rect_mask[rect->left + 7] = true;
      non_overlapping_rect_mask[rect->left + 8] = true;
      assert(8 == kSmallCharacterWidth - 1);
    }
  }
  
#if DEBUG_EXPIRY_SEGMENTATION_PERFORMANCE
  char msg2[256];
  sprintf(msg2, "find %ld non-overlapping rects", non_overlapping_rect_list.size());
  dmz_debug_timer_print(msg2, 1);
#endif
  
  // "local group" = a set of character rects with inter-rect horizontal gaps of less than kSmallCharacterWidth
  // "super-group" = a set of local groups with inter-group horizontal gaps of less than 2 * kSmallCharacterWidth
  //
  // Expiry must be a local group (for now, anyhow).
  // Name is a super-group (since we'll get firstname and lastname as separate local groups).
  
  // [4] Collect character rects into local groups
  
  GroupedRectsList local_groups;
  gather_into_groups(local_groups, non_overlapping_rect_list, kSmallCharacterWidth);
  
#if DEBUG_EXPIRY_SEGMENTATION_PERFORMANCE
  char msg3[256];
  sprintf(msg3, "%ld local groups", local_groups.size());
  dmz_debug_timer_print(msg3, 1);
#endif
  
  // [5] Collect local groups into super-groups
  GroupedRectsList super_groups;
  // Let's skip these for the moment, while we're focusing on expiry:
  // gather_into_groups(super_groups, local_groups, 2 * kSmallCharacterWidth);
  
#if DEBUG_EXPIRY_SEGMENTATION_PERFORMANCE
  char msg4[256];
  sprintf(msg4, "%ld super-groups", super_groups.size());
  dmz_debug_timer_print(msg4, 1);
#endif
  
  GroupedRectsList new_groups;
  for (GroupedRectsListIterator group = local_groups.begin(); group != local_groups.end(); ++group) {
    if (group->character_rects.size() >= kMinimumExpiryStripCharacters - 1) {
      new_groups.push_back(*group);
    }
  }
  local_groups = new_groups;
  
  new_groups.clear();
  for (GroupedRectsListIterator group = super_groups.begin(); group != super_groups.end(); ++group) {
    if (group->character_rects.size() >= kMinimumNameStripCharacters - 1) {
      new_groups.push_back(*group);
    }
  }
  super_groups = new_groups;
  
#if DEBUG_EXPIRY_SEGMENTATION_PERFORMANCE
  char msg5[256];
  sprintf(msg5, "width-filtering -> %ld local groups, %ld super-groups", local_groups.size(), super_groups.size());
  dmz_debug_timer_print(msg5, 1);
#endif
  
  for (GroupedRectsListIterator group = local_groups.begin(); group != local_groups.end(); ++group) {
    regrid_group(sobel_image, *group);
  }
  
  for (GroupedRectsListIterator group = super_groups.begin(); group != super_groups.end(); ++group) {
    regrid_group(sobel_image, *group);
  }
  
#if DEBUG_EXPIRY_SEGMENTATION_PERFORMANCE
  dmz_debug_timer_print("regrid the groups", 1);
#endif
  
  for (int index = (int)local_groups.size() - 1; index >= 0; index--) {
    optimize_character_rects(sobel_image, local_groups[index]);
    if (local_groups[index].character_rects.size() == 0) {
      local_groups.erase(local_groups.begin() + index);
      // dmz_debug_print("Erasing local_group %d, which is now empty.\n", index);
    }
  }
  
  for (int index = (int)super_groups.size() - 1; index >= 0; index--) {
    optimize_character_rects(sobel_image, super_groups[index]);
    if (super_groups[index].character_rects.size() == 0) {
      super_groups.erase(super_groups.begin() + index);
    }
  }
  
#if DEBUG_EXPIRY_SEGMENTATION_PERFORMANCE
  dmz_debug_timer_print("shrink the character rects", 1);
#endif
  
  new_groups.clear();
  for (GroupedRectsListIterator group = local_groups.begin(); group != local_groups.end(); ++group) {
    if (group->character_rects.size() >= kMinimumExpiryStripCharacters) {
      new_groups.push_back(*group);
    }
  }
  local_groups = new_groups;
  
  new_groups.clear();
  for (GroupedRectsListIterator group = super_groups.begin(); group != super_groups.end(); ++group) {
    if (group->character_rects.size() >= kMinimumNameStripCharacters) {
      new_groups.push_back(*group);
    }
  }
  super_groups = new_groups;
  
#if DEBUG_EXPIRY_SEGMENTATION_PERFORMANCE
  char msg6[256];
  sprintf(msg6, "width-filtering -> %ld local groups, %ld super-groups", local_groups.size(), super_groups.size());
  dmz_debug_timer_print(msg6, 1);
#endif
  
  // Add local groups to the passed-in expiry_groups GroupedRectsList, iff they contain a slash in a reasonable position
  
  static IplImage *as_float = NULL;
  if (as_float == NULL) {
    as_float = cvCreateImage(cvSize(kTrimmedCharacterImageWidth, kTrimmedCharacterImageHeight), IPL_DEPTH_32F, 1);
  }
  
  for (GroupedRectsListIterator group = local_groups.begin(); group != local_groups.end(); ++group) {
    if (group->character_rects.size() < 5) {
      continue;
    }
    for (size_t firstCharacterIndex = 0; firstCharacterIndex + 4 < group->character_rects.size(); firstCharacterIndex++) {
      if (is_slash(sobel_image, as_float, &group->character_rects[firstCharacterIndex + 2])) {
        GroupedRects grouped_5_characters;
        grouped_5_characters.top = group->character_rects[firstCharacterIndex].top;
        grouped_5_characters.left = group->character_rects[firstCharacterIndex].left;
        grouped_5_characters.width = kSmallCharacterWidth;
        grouped_5_characters.height = kSmallCharacterHeight;
        grouped_5_characters.grouped_yet = false;
        grouped_5_characters.sum = 0;
        grouped_5_characters.character_width = kTrimmedCharacterImageWidth;
        grouped_5_characters.pattern = ExpiryPatternMMsYY;
        
        for (size_t index = 0; index < 5; index++) {
          CharacterRect char_rect = group->character_rects[firstCharacterIndex + index];
          int formerBottom = grouped_5_characters.top + grouped_5_characters.height;
          grouped_5_characters.top = MIN(char_rect.top, grouped_5_characters.top);
          grouped_5_characters.width = (char_rect.left + kSmallCharacterWidth) - grouped_5_characters.left;
          grouped_5_characters.height = MAX(char_rect.top + kSmallCharacterHeight, formerBottom) - grouped_5_characters.top;
          grouped_5_characters.character_rects.push_back(char_rect);
        }
        
        expiry_groups.push_back(grouped_5_characters);
      }
    }
  }
  
#if DEBUG_EXPIRY_SEGMENTATION_PERFORMANCE
  dmz_debug_timer_print("insert local groups into expiry_groups param", 1);
#endif
  
  // Add supergroups to the passed-in name_groups GroupedRectsList
  name_groups.insert(name_groups.end(), super_groups.begin(), super_groups.end());

#if DEBUG_EXPIRY_SEGMENTATION_PERFORMANCE
  dmz_debug_timer_print("insert supergroups into name_groups param", 1);
#endif
}
예제 #19
0
int CLY_IsUNC(const char* path)
{
  if (!is_slash(path[0]) || !is_slash(path[1]) || is_term(path[2]))
    return 0;
  return 1;
}
예제 #20
0
void Archive::make_index() {
  num_indices = 0;
  CHECK_COM(in_arc->GetNumberOfItems(&num_indices));
  file_list.clear();
  file_list.reserve(num_indices);

  struct DirInfo {
    UInt32 index;
    UInt32 parent;
    wstring name;
    bool operator<(const DirInfo& dir_info) const {
      if (parent == dir_info.parent)
        return lstrcmpiW(name.c_str(), dir_info.name.c_str()) < 0;
      else
        return parent < dir_info.parent;
    }
  };
  typedef set<DirInfo> DirList;
  map<UInt32, unsigned> dir_index_map;
  DirList dir_list;

  DirInfo dir_info;
  UInt32 dir_index = 0;
  ArcFileInfo file_info;
  wstring path;
  PropVariant prop;
  for (UInt32 i = 0; i < num_indices; i++) {
    // is directory?
    file_info.is_dir = in_arc->GetProperty(i, kpidIsDir, prop.ref()) == S_OK && prop.is_bool() && prop.get_bool();

    // file name
    if (in_arc->GetProperty(i, kpidPath, prop.ref()) == S_OK && prop.is_str())
      path.assign(prop.get_str());
    else
      path.assign(get_default_name());
    size_t name_end_pos = path.size();
    while (name_end_pos && is_slash(path[name_end_pos - 1])) name_end_pos--;
    size_t name_pos = name_end_pos;
    while (name_pos && !is_slash(path[name_pos - 1])) name_pos--;
    file_info.name.assign(path.data() + name_pos, name_end_pos - name_pos);

    // split path into individual directories and put them into DirList
    dir_info.parent = c_root_index;
    size_t begin_pos = 0;
    while (begin_pos < name_pos) {
      dir_info.index = dir_index;
      size_t end_pos = begin_pos;
      while (end_pos < name_pos && !is_slash(path[end_pos])) end_pos++;
      if (end_pos != begin_pos) {
        dir_info.name.assign(path.data() + begin_pos, end_pos - begin_pos);
        pair<DirList::iterator, bool> ins_pos = dir_list.insert(dir_info);
        if (ins_pos.second)
          dir_index++;
        dir_info.parent = ins_pos.first->index;
      }
      begin_pos = end_pos + 1;
    }
    file_info.parent = dir_info.parent;

    if (file_info.is_dir) {
      dir_info.index = dir_index;
      dir_info.parent = file_info.parent;
      dir_info.name = file_info.name;
      pair<DirList::iterator, bool> ins_pos = dir_list.insert(dir_info);
      if (ins_pos.second) {
        dir_index++;
        dir_index_map[dir_info.index] = i;
      }
      else {
        if (dir_index_map.count(ins_pos.first->index))
          file_info.parent = c_dup_index;
        else
          dir_index_map[ins_pos.first->index] = i;
      }
    }

    file_list.push_back(file_info);
  }

  // add directories that not present in archive index
  file_list.reserve(file_list.size() + dir_list.size() - dir_index_map.size());
  dir_index = num_indices;
  for_each(dir_list.begin(), dir_list.end(), [&] (const DirInfo& dir_info) {
    if (dir_index_map.count(dir_info.index) == 0) {
      dir_index_map[dir_info.index] = dir_index;
      file_info.parent = dir_info.parent;
      file_info.name = dir_info.name;
      file_info.is_dir = true;
      dir_index++;
      file_list.push_back(file_info);
    }
  });

  // fix parent references
  for_each(file_list.begin(), file_list.end(), [&] (ArcFileInfo& file_info) {
    if (file_info.parent != c_root_index)
      file_info.parent = dir_index_map[file_info.parent];
  });

  // create search index
  file_list_index.clear();
  file_list_index.reserve(file_list.size());
  for (UInt32 i = 0; i < file_list.size(); i++) {
    file_list_index.push_back(i);
  }
  sort(file_list_index.begin(), file_list_index.end(), [&] (UInt32 left, UInt32 right) -> bool {
    return file_list[left] < file_list[right];
  });

  load_arc_attr();
}
예제 #21
0
static inline bool
is_unc_path (const char * path)
{
  return is_slash (path[0]) && path[1] == path[0];
}
예제 #22
0
파일: fixpath.c 프로젝트: idispatch/tvision
/* Takes as input an arbitrary path.  Fixes up the path by:
 1. Removing consecutive slashes
 2. Removing trailing slashes
 3. Making the path absolute if it wasn't already
 4. Removing "." in the path
 5. Removing ".." entries in the path (and the directory above them)
 */
void _fixpath(const char *in, char *out) {
    const char *ip = in;
    char *op = out;

    /* Convert ~ to the HOME environment variable */
    if (*ip == '~' && (is_slash(ip[1]) || !ip[1])) {
        const char *home = getenv("HOME");
        if (home) {
            strcpy(op, home);
            op += strlen(op);
            ip++;
            if (!*ip)
                return;
        }
    }

    /* Convert relative path to absolute */
    if (!is_slash(*ip)) {
        getcurdir(0, op);
        op += strlen(op);
    }

#if defined(TVOSf_QNX4)
    /* Skip the first slashes, which are a node number part */
    /* Full QNX4 pathname is //node/dirpath/filename        */
    if ((ip==in) && (is_slash(*ip)) && (is_slash(*(ip+1))))
    {
        *op=*ip;
        ip++;
        op++;
    }
#endif // TVOSf_QNX4
    /* Step through the input path */
    while (*ip) {
        /* Skip input slashes */
        if (is_slash(*ip)) {
            ip++;
            continue;
        }

        /* Skip "." and output nothing */
        if (*ip == '.' && is_term(*(ip + 1))) {
            ip++;
            continue;
        }

        /* Skip ".." and remove previous output directory */
        if (*ip == '.' && *(ip + 1) == '.' && is_term(*(ip + 2))) {
            ip += 2;
            /* Don't back up over root '/' */
            if (op > out)
                /* This requires "/" to follow drive spec */
                while (!is_slash(*--op))
                    ;
            continue;
        }

        /* Copy path component from in to out */
        *op++ = '/';
        while (!is_term(*ip))
            *op++ = *ip++;
    }

    /* If root directory, insert trailing slash */
    if (op == out)
        *op++ = '/';

    /* Null terminate the output */
    *op = '\0';

}
예제 #23
0
파일: fixpath.c 프로젝트: idispatch/tvision
/* Takes as input an arbitrary path.  Fixes up the path by:
 1. Removing consecutive slashes
 2. Removing trailing slashes
 3. Making the path absolute if it wasn't already
 4. Removing "." in the path
 5. Removing ".." entries in the path (and the directory above them)
 6. Adding a drive specification if one wasn't there
 7. Converting all slashes to '/'
 */
void
_fixpath(const char *in, char *out)
{
    int drive_number = 0;
    const char *ip = in;
    char *op = out;
    int unc = CLY_IsUNC(in); /* is a UNC pathname */

    /* Add drive specification to output string */
    if (((*ip >= 'a' && *ip <= 'z') ||
            (*ip >= 'A' && *ip <= 'Z'))
            && (*(ip + 1) == ':'))
    {
        if (*ip >= 'a' && *ip <= 'z')
        {
            drive_number = *ip - 'a';
            *op++ = *ip++;
        }
        else
        {
            drive_number = *ip - 'A';
            *op++ = (char)(drive_number + 'a');
            ++ip;
        }
        *op++ = *ip++;
    }
    else if (!unc)
    {
        drive_number = __fp_getdisk();
        *op++ = (char)(drive_number + 'a');
        *op++ = ':';
    }

    /* Convert relative path to absolute */
    if (!is_slash(*ip))
    {
        *op++ = '/';
        op = __fp_getcurdir(op, drive_number);
    }

    /* Handle UNC path */
    if (unc)
    {
        *op++ = *ip++;
    }

    /* Step through the input path */
    while (*ip)
    {
        /* Skip input slashes */
        if (is_slash(*ip))
        {
            ip++;
            continue;
        }

        /* Skip "." and output nothing */
        if (*ip == '.' && is_term(*(ip + 1)))
        {
            ip++;
            continue;
        }

        /* Skip ".." and remove previous output directory */
        if (*ip == '.' && *(ip + 1) == '.' && is_term(*(ip + 2)))
        {
            ip += 2;
            /* Don't back up over drive spec */
            if (op > out + 2)
            {
                /* This requires "/" to follow drive spec */
                --op;
                while (!is_slash(*op)) --op;
            }
            continue;
        }

        /* Copy path component from in to out */
        *op++ = '/';
        while (!is_term(*ip)) *op++ = *ip++;
    }

    /* If root directory, insert trailing slash */
    if (op == out + 2) *op++ = '/';

    /* Null terminate the output */
    *op = '\0';

    /* Convert backslashes to slashes */
    for (op = out; *op; op++)
        if (*op == '\\') *op = '/';
}
예제 #24
0
파일: util.c 프로젝트: ystk/debian-lzop
char *maybe_rename_file(const char *original_name)
{
    static char dosified_name[PATH_MAX+1];
    static const char illegal_chars_dos[] = ".+, ;=[]|<>\":?*";
    const char *illegal_chars = illegal_chars_dos;
    int idx, dot_idx;
    const char *s = original_name;
    char *d = dosified_name;

    /* Support for Win32 VFAT systems, when available.  */
#if defined(__DJGPP__)
    if (_use_lfn(original_name))
        illegal_chars = illegal_chars_dos + 8;
#elif (ACC_OS_WIN32 || ACC_OS_WIN64 || ACC_OS_CYGWIN)
    illegal_chars = illegal_chars_dos + 8;
#endif

    /* Get past the drive letter, if any. */
    if (fn_is_drive(s))
    {
        *d++ = *s++;
        *d++ = *s++;
    }

    for (idx = 0, dot_idx = -1; *s; s++, d++)
    {
        if (strchr(illegal_chars, *s))
        {
            /* Dots are special on DOS: it doesn't allow them as the leading
             character, and a file name cannot have more than a single dot.
             We leave the first non-leading dot alone, unless it comes too
             close to the beginning of the name: we want sh.lex.c to become
             sh_lex.c, not sh.lex-c.  */
            if (*s == '.')
            {
                if (idx == 0
                    && (is_slash(s[1]) || s[1] == '\0'
                        || (s[1] == '.' && (is_slash(s[2]) || s[2] == '\0'))))
                {
                    /* Copy "./" and "../" verbatim.  */
                    *d++ = *s++;
                    if (*s == '.')
                        *d++ = *s++;
                    *d = *s;
                }
                else if (idx == 0)
                    *d = '_';
                else if (dot_idx >= 0)
                {
                    if (dot_idx < 5) /* 5 is merely a heuristic ad-hoc'ery */
                    {
                        d[dot_idx - idx] = '_'; /* replace previous dot */
                        *d = '.';
                    }
                    else
                        *d = '-';
                }
                else
                    *d = '.';

                if (*s == '.')
                    dot_idx = idx;
            }
            else if (*s == '+' && s[1] == '+')
            {
                if (idx - 2 == dot_idx) /* .c++, .h++ etc. */
                {
                    *d++ = 'x';
                    *d   = 'x';
                }
                else
                {
                    /* libg++ etc.  */
                    memcpy (d, "plus", 4);
                    d += 3;
                }
                s++;
                idx++;
            }
            else
                *d = '_';
        }
        else
            *d = *s;
        if (is_slash(*s))
        {
            idx = 0;
            dot_idx = -1;
        }
        else
            idx++;
    }

    *d = '\0';

#if defined(S_ISCHR)
    /* We could have a file in an archive whose name is reserved
     on MS-DOS by a device driver.  Trying to extract such a
     file would fail at best and wedge us at worst.  We need to
     rename such files.  */

    if (idx > 0)
    {
        struct stat st_buf;
        char *base = d - idx;
        int i = 0;

        /* The list of character devices is not constant: it depends on
         what device drivers did they install in their CONFIG.SYS.
         `stat' will tell us if the basename of the file name is a
         characer device.  */
        while (stat(base, &st_buf) == 0 && S_ISCHR(st_buf.st_mode))
        {
            size_t blen = strlen(base);

            /* I don't believe any DOS character device names begin with a
             `_'.  But in case they invent such a device, let us try twice.  */
            if (++i > 2)
                return (char *)0;

            /* Prepend a '_'.  */
            memmove(base + 1, base, blen + 1);
            base[0] = '_';
        }
    }
#endif

    return dosified_name;
}