pike.git / src / combine_path.h

version» Context lines:

pike.git/src/combine_path.h:1: + #undef IS_SEP + #undef IS_ABS + #undef IS_ROOT + #undef F_COMBINE_PATH + #undef APPEND_PATH    -  + #define COMBINE_PATH_DEBUG 0 +  + #ifdef UNIX_COMBINE_PATH + #define IS_SEP(X) ( (X)=='/' ) + #define IS_ABS(X) (IS_SEP( INDEX_PCHARP((X),0))?1:0) + #define APPEND_PATH append_path_unix + #define F_COMBINE_PATH f_combine_path_unix + #endif /* UNIX_COMBINE_PATH */ +  +  +  + #ifdef NT_COMBINE_PATH + #define IS_SEP(X) ( (X) == '/' || (X) == '\\' ) +  + static int find_absolute(PCHARP s) + { +  int c0=INDEX_PCHARP(s,0); +  int c1=c0?INDEX_PCHARP(s,1):0; +  if(isalpha(c0) && c1==':' && IS_SEP(INDEX_PCHARP(s,2))) +  return 3; +  +  if(IS_SEP(c0) && IS_SEP(c1)) +  { +  int l; +  for(l=2;isalpha(INDEX_PCHARP(s,l));l++); +  return l; +  } +  +  return 0; + } + #define IS_ABS(X) find_absolute((X)) + #define IS_ROOT(X) ( IS_SEP( INDEX_PCHARP((X),0) )?1:0) +  + #define APPEND_PATH append_path_nt + #define F_COMBINE_PATH f_combine_path_nt +  + #endif /* NT_COMBINE_PATH */ +  + static void APPEND_PATH(struct string_builder *s, +  PCHARP path, +  size_t len) + { +  size_t from=0; +  int tmp,c; +  int abs=0; +  +  /* First, check if path is absolute, +  * if so ignore anything already in 's' +  */ +  abs=IS_ABS(MKPCHARP_STR(s->s)); +  if((tmp=IS_ABS(path))) +  { +  s->s->len=0; +  s->known_shift=0; +  string_builder_append(s, path, tmp); +  from+=tmp; +  abs++; +  } + #ifdef IS_ROOT +  else if((tmp=IS_ROOT(path))) +  { +  int tmp2; +  abs++; +  s->known_shift=0; +  if((tmp2=IS_ABS(MKPCHARP_STR(s->s)))) +  { +  s->s->len=tmp2; +  }else{ +  s->s->len=0; +  string_builder_append(s, path, tmp); +  } +  from+=tmp; +  } + #endif +  + #define LAST_PUSHED() (s->s->len ? index_shared_string(s->s,s->s->len-1) : 0) + #define PUSH(X) string_builder_putchar(s,(X)) +  +  if(s->s->len && !IS_SEP(LAST_PUSHED())) +  PUSH('/'); +  +  while(s->s->len==2) +  { +  PCHARP to=MKPCHARP_STR(s->s); +  if(INDEX_PCHARP(to, 0) == '.') +  { +  s->s->len=0; +  s->known_shift=0; +  } +  } +  +  while(1) +  { + #if COMBINE_PATH_DEBUG > 1 +  s->s->str[s->s->len]=0; +  fprintf(stderr,"combine_path(2), TO: %s\n",s->s->str); +  fprintf(stderr,"combine_path(2), FROM (%d): %s\n",from,path.ptr+from); + #endif +  if(IS_SEP(LAST_PUSHED())) +  { +  while(s->s->len && IS_SEP(LAST_PUSHED())) +  s->s->len--; +  PUSH('/'); +  if(from<len && INDEX_PCHARP(path, from) == '.') +  { +  int c3; + #if COMBINE_PATH_DEBUG > 0 +  s->s->str[s->s->len]=0; +  fprintf(stderr,"combine_path(0), TO: %s\n",s->s->str); +  fprintf(stderr,"combine_path(0), FROM (%d): %s\n",from,path.ptr+from); + #endif +  +  switch(INDEX_PCHARP(path, from+1)) +  { +  case '.': +  c3=INDEX_PCHARP(path, from+2); +  if(IS_SEP(c3) || !c3) +  { +  int tmp=s->s->len-1; +  +  while(--tmp>=0) +  if(IS_SEP(index_shared_string(s->s,tmp))) +  break; +  tmp++; +  +  if(index_shared_string(s->s,tmp)=='.' && +  index_shared_string(s->s,tmp+1)=='.' && +  ( IS_SEP(index_shared_string(s->s,tmp+2)) || +  !index_shared_string(s->s,tmp+2))) +  break; +  +  +  from+=2; +  s->s->len=tmp; +  s->known_shift=0; +  + #if COMBINE_PATH_DEBUG > 0 +  s->s->str[s->s->len]=0; +  fprintf(stderr,"combine_path(1), TO: %s\n",s->s->str); +  fprintf(stderr,"combine_path(1), FROM (%d): %s\n",from,path.ptr+from); + #endif +  continue; +  } +  break; +  +  case 0: +  case '/': + #ifdef NT_COMBINE_PATH +  case '\\': + #endif +  from++; +  continue; +  } +  } +  } +  +  if(from>=len) break; +  PUSH(INDEX_PCHARP(path, from++)); +  } +  if(s->s->len && +  !IS_SEP(INDEX_PCHARP(path, from-1)) && +  IS_SEP(LAST_PUSHED())) +  s->s->len--; +  +  if(!s->s->len) +  { +  if(abs) +  { +  PUSH('/'); +  }else{ +  PUSH('.'); +  } +  } + } +  + void F_COMBINE_PATH(INT32 args) + { +  int e; +  int root=0; +  struct string_builder ret; +  ONERROR tmp; +  +  check_all_args("combine_path",args,BIT_STRING, BIT_STRING | BIT_MANY | BIT_VOID, 0); +  +  +  init_string_builder(&ret, 0); +  SET_ONERROR(tmp, free_string_builder, &ret); +  +  for(e=args-1;e>root;e--) +  { +  if(IS_ABS(MKPCHARP_STR(Pike_sp[e-args].u.string))) +  { +  root=e; +  break; +  } +  } +  +  APPEND_PATH(&ret, +  MKPCHARP_STR(Pike_sp[root-args].u.string), +  Pike_sp[root-args].u.string->len); +  root++; +  + #ifdef IS_ROOT +  for(e=args-1;e>root;e--) +  { +  if(IS_ROOT(MKPCHARP_STR(Pike_sp[e-args].u.string))) +  { +  root=e; +  break; +  } +  } + #endif +  +  while(root<args) +  { +  APPEND_PATH(&ret, +  MKPCHARP_STR(Pike_sp[root-args].u.string), +  Pike_sp[root-args].u.string->len); +  root++; +  } +  UNSET_ONERROR(tmp); +  pop_n_elems(args); +  push_string(finish_string_builder(&ret)); + } +  +  +  + #undef UNIX_COMBINE_PATH + #undef NT_COMBINE_PATH   Newline at end of file added.