pike.git / src / modules / _Stdio / stat.c

version» Context lines:

pike.git/src/modules/_Stdio/stat.c:217:    STAT_ENUM_END};      static struct pike_string *stat_index_strs[STAT_ENUM_END];      static struct pike_string *str_type_reg, *str_type_dir, *str_type_lnk,    *str_type_chr, *str_type_blk, *str_type_fifo, *str_type_sock, *str_type_unknown;      #define THIS_STAT ((struct stat_storage*)(Pike_fp->current_storage))      static void stat_index_set (INT32 args); + static void _stat_index_set (INT_TYPE pos, struct svalue *val, int is_int, INT64 intval);      static int stat_compat_set (INT_TYPE pos, INT64 val)   {    if (pos < 0) pos += 7;    switch (pos) {    case 0: DO_NOT_WARN(THIS_STAT->s.st_mode = (int) val); break;    case 1:    if (val >= 0) {    THIS_STAT->s.st_mode = (THIS_STAT->s.st_mode & ~S_IFMT) | S_IFREG;    THIS_STAT->s.st_size = DO_NOT_WARN ((off_t) val);
pike.git/src/modules/_Stdio/stat.c:306:    *! @[stat] is an object, typically another @[Stdio.Stat]. The    *! stat info is copied from the object by getting the values of    *! @expr{mode@}, @expr{size@}, @expr{atime@}, @expr{mtime@},    *! @expr{ctime@}, @expr{uid@}, @expr{gid@}, @expr{dev@}, @expr{ino@},    *! @expr{nlink@}, and @expr{rdev@}.    *! @item    *! @[stat] is a seven element array on the 'traditional' LPC    *! stat-array form (see the class doc).    *! @endul    */ - static void stat_create (INT32 args) - { -  if (args >= 1 && !UNSAFE_IS_ZERO (Pike_sp - 1)) { -  pop_n_elems (args - 1); -  args = 1; -  -  if (TYPEOF(sp[-1]) == T_OBJECT) -  if (sp[-1].u.object->prog == stat_program) { -  *THIS_STAT = *(struct stat_storage *) sp[-1].u.object->storage; -  pop_stack(); -  return; -  } -  -  if ((1 << TYPEOF(sp[-1])) & (BIT_PROGRAM|BIT_OBJECT|BIT_MAPPING)) { -  - #define ASSIGN_INDEX(ENUM) \ -  do { \ -  stack_dup(); \ -  ref_push_string (stat_index_strs[ENUM]); \ -  SET_SVAL_SUBTYPE(sp[-1], 1); \ -  o_index(); \ -  if (!IS_UNDEFINED (sp-1)) { \ -  ref_push_string (stat_index_strs[ENUM]); \ -  stack_swap(); \ -  stat_index_set (2); \ -  } \ -  pop_stack(); \ -  } while (0) -  -  ASSIGN_INDEX (STAT_MODE); -  ASSIGN_INDEX (STAT_SIZE); -  ASSIGN_INDEX (STAT_ATIME); -  ASSIGN_INDEX (STAT_MTIME); -  ASSIGN_INDEX (STAT_CTIME); -  ASSIGN_INDEX (STAT_UID); -  ASSIGN_INDEX (STAT_GID); -  ASSIGN_INDEX (STAT_DEV); -  ASSIGN_INDEX (STAT_INO); -  ASSIGN_INDEX (STAT_NLINK); -  ASSIGN_INDEX (STAT_RDEV); - #ifdef HAVE_STRUCT_STAT_BLOCKS -  ASSIGN_INDEX (STAT_BLKSIZE); -  ASSIGN_INDEX (STAT_BLOCKS); - #endif -  } -  -  else if (TYPEOF(sp[-1]) == T_ARRAY) { -  struct array *a = sp[-1].u.array; -  int i; -  if (a->size != 7) -  SIMPLE_BAD_ARG_ERROR ("Stat create", 1, "stat array with 7 elements"); -  for (i = 0; i < 7; i++) { -  INT64 val; -  if (TYPEOF(ITEM(a)[i]) == T_INT) -  val = ITEM(a)[i].u.integer; -  else if (TYPEOF(ITEM(a)[i]) == T_OBJECT && -  is_bignum_object (ITEM(a)[i].u.object)) { -  if (!int64_from_bignum (&val, ITEM(a)[i].u.object)) -  Pike_error ("Stat create: Too big integer in stat array.\n"); -  } -  else -  SIMPLE_BAD_ARG_ERROR ("Stat create", 1, "array(int)"); -  stat_compat_set (i, val); -  } -  } -  -  else -  SIMPLE_BAD_ARG_ERROR ("Stat create", 1, "void|Stdio.Stat|array(int)"); -  } -  -  pop_n_elems (args); - } -  +    void f_min(INT32 args);   void f_max(INT32 args);      static void _stat_index(INT_TYPE code)   {    if (!code) {    /* Fall back to a normal index on this object, in case    * someone inherited us. */    struct svalue res;    object_index_no_free2 (&res, fp->current_object, 0, sp-1);
pike.git/src/modules/_Stdio/stat.c:603:    while (from<=to)    {    stat_push_compat(from++);    n++;    }    f_aggregate(n);    }   }       - static void stat_index_set (INT32 args) + static void _stat_index_set (INT_TYPE code, struct svalue *val, int got_int_val, INT64 int_val )   { -  int got_int_val = 0; -  INT64 int_val; + #define BAD_ARG_2(X) bad_arg_error("Stat.`[]=", Pike_sp-2,2,2,X,val,msg_bad_arg,2,"Stat.`[]=",X)    -  if (args < 2) -  SIMPLE_TOO_FEW_ARGS_ERROR ("Stat `[]=", 2); -  -  if (args > 2) { -  pop_n_elems (args - 2); -  args = 2; -  } -  -  if (TYPEOF(sp[-1]) == T_INT) -  int_val = sp[-1].u.integer, got_int_val = 1; -  else if (TYPEOF(sp[-1]) == T_OBJECT && is_bignum_object (sp[-1].u.object)) +  if( got_int_val == -1 )    { -  if (!int64_from_bignum (&int_val, sp[-1].u.object)) +  if (TYPEOF(*val) == T_INT) +  int_val = val->u.integer, got_int_val = 1; +  else if (TYPEOF(*val) == T_OBJECT && is_bignum_object (val->u.object)) +  { +  if (!int64_from_bignum (&int_val, val->u.object))    Pike_error ("Stat `[]=: Too big integer as value.\n");    else    got_int_val = 1;    } -  -  /* shouldn't there be an else clause here ? */ -  /* No, the second argument is checked further below depending on -  * what the first is. /mast */ -  -  if (TYPEOF(sp[-2]) == T_INT) { -  if (!got_int_val) -  SIMPLE_BAD_ARG_ERROR ("Stat `[]=", 2, -  "integer when the first argument is an integer"); -  if (!stat_compat_set (sp[-2].u.integer, int_val)) -  SIMPLE_BAD_ARG_ERROR ("Stat `[]=", 1, "int(0..6)|string"); +     }    -  else if (TYPEOF(sp[-2]) == T_STRING) { -  INT_TYPE code; -  -  ref_push_mapping (stat_map); -  push_svalue (sp-3); -  f_index (2); -  code = sp[-1].u.integer; -  pop_stack(); -  -  if (!code) { -  /* Fall back to a normal index set on this object, in case -  * someone inherited us. */ -  object_set_index2 (fp->current_object, 0, sp-2, sp-1); -  stack_swap(); -  pop_stack(); -  return; -  } -  +     switch (code) { -  case 0: -  SIMPLE_BAD_ARG_ERROR ("Stat `[]=", 1, "a valid index"); -  +     case STAT_MODE_STRING: -  if (TYPEOF(sp[-1]) != T_STRING) -  SIMPLE_BAD_ARG_ERROR ("Stat `[]=", 2, "string"); +  if (TYPEOF(*val) != T_STRING) +  BAD_ARG_2("string");       /* FIXME: Handle modes on the form u+rw, perhaps? */    -  if (sp[-1].u.string->len != 10) -  SIMPLE_BAD_ARG_ERROR ("Stat `[]=", 2, "mode string with 10 chars"); +  if (val->u.string->len != 10) +  BAD_ARG_2("mode string with 10 chars");       { -  PCHARP str = MKPCHARP_STR (sp[-1].u.string); +  PCHARP str = MKPCHARP_STR (val->u.string);    int mode = THIS_STAT->s.st_mode;       switch (INDEX_PCHARP (str, 0)) {    case '-': mode = (mode & ~S_IFMT) | S_IFREG; break;    case 'd': mode = (mode & ~S_IFMT) | S_IFDIR; break;    case 'l': mode = (mode & ~S_IFMT) | S_IFLNK; break;    case 'c': mode = (mode & ~S_IFMT) | S_IFCHR; break;    case 'b': mode = (mode & ~S_IFMT) | S_IFBLK; break;    case 'f': mode = (mode & ~S_IFMT) | S_IFIFO; break;    case 's': mode = (mode & ~S_IFMT) | S_IFSOCK; break;
pike.git/src/modules/_Stdio/stat.c:733:    case 'x': mode = (mode & ~S_ISVTX) | S_IXOTH; break;    case 'T': mode = (mode & ~S_IXOTH) | S_ISVTX; break;    case 't': mode |= S_IXOTH | S_ISVTX; break;    }       THIS_STAT->s.st_mode = mode;    }    break;       case STAT_TYPE: -  if (TYPEOF(sp[-1]) != T_STRING) -  SIMPLE_BAD_ARG_ERROR ("Stat `[]=", 2, "string"); +  if (TYPEOF(*val) != T_STRING) +  BAD_ARG_2("string");    -  if (sp[-1].u.string == str_type_reg) +  if (val->u.string == str_type_reg)    THIS_STAT->s.st_mode = (THIS_STAT->s.st_mode & ~S_IFMT) | S_IFREG; -  else if (sp[-1].u.string == str_type_dir) +  else if (val->u.string == str_type_dir)    THIS_STAT->s.st_mode = (THIS_STAT->s.st_mode & ~S_IFMT) | S_IFDIR; -  else if (sp[-1].u.string == str_type_lnk) +  else if (val->u.string == str_type_lnk)    THIS_STAT->s.st_mode = (THIS_STAT->s.st_mode & ~S_IFMT) | S_IFLNK; -  else if (sp[-1].u.string == str_type_chr) +  else if (val->u.string == str_type_chr)    THIS_STAT->s.st_mode = (THIS_STAT->s.st_mode & ~S_IFMT) | S_IFCHR; -  else if (sp[-1].u.string == str_type_blk) +  else if (val->u.string == str_type_blk)    THIS_STAT->s.st_mode = (THIS_STAT->s.st_mode & ~S_IFMT) | S_IFBLK; -  else if (sp[-1].u.string == str_type_fifo) +  else if (val->u.string == str_type_fifo)    THIS_STAT->s.st_mode = (THIS_STAT->s.st_mode & ~S_IFMT) | S_IFIFO; -  else if (sp[-1].u.string == str_type_sock) +  else if (val->u.string == str_type_sock)    THIS_STAT->s.st_mode = (THIS_STAT->s.st_mode & ~S_IFMT) | S_IFSOCK; -  else if (sp[-1].u.string == str_type_unknown) +  else if (val->u.string == str_type_unknown)    THIS_STAT->s.st_mode = THIS_STAT->s.st_mode & ~S_IFMT;    else -  SIMPLE_BAD_ARG_ERROR ("Stat `[]=", 2, "valid type string"); +  BAD_ARG_2("valid type string");    break;       case STAT_ISREG:    THIS_STAT->s.st_mode &= ~S_IFMT; -  if (!UNSAFE_IS_ZERO (sp-1)) THIS_STAT->s.st_mode |= S_IFREG; +  if (!UNSAFE_IS_ZERO (val)) THIS_STAT->s.st_mode |= S_IFREG;    break;    case STAT_ISDIR:    THIS_STAT->s.st_mode &= ~S_IFMT; -  if (!UNSAFE_IS_ZERO (sp-1)) THIS_STAT->s.st_mode |= S_IFDIR; +  if (!UNSAFE_IS_ZERO (val)) THIS_STAT->s.st_mode |= S_IFDIR;    break;    case STAT_ISLNK:    THIS_STAT->s.st_mode &= ~S_IFMT; -  if (!UNSAFE_IS_ZERO (sp-1)) THIS_STAT->s.st_mode |= S_IFLNK; +  if (!UNSAFE_IS_ZERO (val)) THIS_STAT->s.st_mode |= S_IFLNK;    break;    case STAT_ISCHR:    THIS_STAT->s.st_mode &= ~S_IFMT; -  if (!UNSAFE_IS_ZERO (sp-1)) THIS_STAT->s.st_mode |= S_IFCHR; +  if (!UNSAFE_IS_ZERO (val)) THIS_STAT->s.st_mode |= S_IFCHR;    break;    case STAT_ISBLK:    THIS_STAT->s.st_mode &= ~S_IFMT; -  if (!UNSAFE_IS_ZERO (sp-1)) THIS_STAT->s.st_mode |= S_IFBLK; +  if (!UNSAFE_IS_ZERO (val)) THIS_STAT->s.st_mode |= S_IFBLK;    break;    case STAT_ISFIFO:    THIS_STAT->s.st_mode &= ~S_IFMT; -  if (!UNSAFE_IS_ZERO (sp-1)) THIS_STAT->s.st_mode |= S_IFIFO; +  if (!UNSAFE_IS_ZERO (val)) THIS_STAT->s.st_mode |= S_IFIFO;    break;    case STAT_ISSOCK:    THIS_STAT->s.st_mode &= ~S_IFMT; -  if (!UNSAFE_IS_ZERO (sp-1)) THIS_STAT->s.st_mode |= S_IFSOCK; +  if (!UNSAFE_IS_ZERO (val)) THIS_STAT->s.st_mode |= S_IFSOCK;    break;       default:    if (!got_int_val) -  SIMPLE_BAD_ARG_ERROR ("Stat `[]=", 2, "integer"); +  BAD_ARG_2("integer");       switch (code) {    case STAT_DEV: DO_NOT_WARN(THIS_STAT->s.st_dev = (int) int_val); break;    case STAT_INO: DO_NOT_WARN(THIS_STAT->s.st_ino = (int) int_val); break;    case STAT_MODE: DO_NOT_WARN(THIS_STAT->s.st_mode = (int) int_val); break;    case STAT_NLINK: DO_NOT_WARN(THIS_STAT->s.st_nlink = (int) int_val); break;    case STAT_UID: DO_NOT_WARN(THIS_STAT->s.st_uid = (int) int_val); break;    case STAT_GID: DO_NOT_WARN(THIS_STAT->s.st_gid = (int) int_val); break;    case STAT_RDEV: DO_NOT_WARN(THIS_STAT->s.st_rdev = (int) int_val); break;    case STAT_SIZE: THIS_STAT->s.st_size = DO_NOT_WARN ((off_t) int_val); break;   #ifdef HAVE_STRUCT_STAT_BLOCKS    case STAT_BLKSIZE: DO_NOT_WARN(THIS_STAT->s.st_blksize = int_val); break;    case STAT_BLOCKS: DO_NOT_WARN(THIS_STAT->s.st_blocks = int_val); break;   #endif    case STAT_ATIME: THIS_STAT->s.st_atime = DO_NOT_WARN ((time_t) int_val); break;    case STAT_MTIME: THIS_STAT->s.st_mtime = DO_NOT_WARN ((time_t) int_val); break;    case STAT_CTIME: THIS_STAT->s.st_ctime = DO_NOT_WARN ((time_t) int_val); break;    -  + #ifdef PIKE_DEBUG    default:    Pike_fatal ("stat_index_set is not kept up-to-date with stat_map.\n"); -  + #endif    }    }   }    -  + static void stat_index_set (INT32 args) + { +  int got_int_val = 0; +  INT64 int_val; +  +  if (args < 2) +  SIMPLE_TOO_FEW_ARGS_ERROR ("Stat `[]=", 2); +  +  if (args > 2) { +  pop_n_elems (args - 2); +  args = 2; +  } +  +  if (TYPEOF(sp[-1]) == T_INT) +  int_val = sp[-1].u.integer, got_int_val = 1; +  else if (TYPEOF(sp[-1]) == T_OBJECT && is_bignum_object (sp[-1].u.object)) +  { +  if (!int64_from_bignum (&int_val, sp[-1].u.object)) +  Pike_error ("Stat `[]=: Too big integer as value.\n"); +  else +  got_int_val = 1; +  } +  +  /* shouldn't there be an else clause here ? */ +  /* No, the second argument is checked further below depending on +  * what the first is. /mast */ +  +  if (TYPEOF(sp[-2]) == T_INT) { +  if (!got_int_val) +  SIMPLE_BAD_ARG_ERROR ("Stat `[]=", 2, +  "integer when the first argument is an integer"); +  if (!stat_compat_set (sp[-2].u.integer, int_val)) +  SIMPLE_BAD_ARG_ERROR ("Stat `[]=", 1, "int(0..6)|string"); +  } +  else if (TYPEOF(sp[-2]) == T_STRING) { +  INT_TYPE code; +  struct svalue *tmp; +  tmp = low_mapping_string_lookup( stat_map, sp[-2].u.string ); +  if (!tmp) +  { +  /* Fall back to a normal index set on this object, in case +  * someone inherited us. */ +  object_set_index2 (fp->current_object, 0, sp-2, sp-1); +  stack_swap(); +  pop_stack(); +  return; +  } +  _stat_index_set( tmp->u.integer, sp-1, got_int_val, int_val); +  } +     else SIMPLE_BAD_ARG_ERROR ("Stat `[]=", 1, "int(0..6)|string");       stack_swap();    pop_stack();   }    -  + static void stat_indices(INT32 args); + static void stat_values(INT32 args); +    static void stat_cast(INT32 args)   {    if (!args)    SIMPLE_TOO_FEW_ARGS_ERROR("Stat cast",1);    if (TYPEOF(sp[-args]) == T_STRING && !sp[-args].u.string->size_shift)    { -  if (strncmp(sp[-args].u.string->str,"array",5)==0) +  if (strcmp(sp[-args].u.string->str,"array")==0)    {    pop_n_elems(args);    push_int(0);    push_int(6);    stat_index(2);    return;    } -  +  if (strcmp(sp[-args].u.string->str,"mapping")==0) +  { +  stat_indices(0); +  stat_values(0); +  push_mapping(mkmapping(Pike_sp[-2].u.array, Pike_sp[-1].u.array)); +  stack_pop_n_elems_keep_top(2); +  return;    } -  +  }    SIMPLE_BAD_ARG_ERROR("Stat cast",1,    "string(\"array\")");   }      static void stat__sprintf(INT32 args)   {    int n=0, x;       if (args<1)    SIMPLE_TOO_FEW_ARGS_ERROR("_sprintf",2);
pike.git/src/modules/_Stdio/stat.c:894:    for (i=0; i<z; i++)    {    ref_push_object(fp->current_object);    push_svalue(a->item+i);    f_index(2);    }    f_aggregate(z);    stack_pop_keep_top();   }    + #ifdef __GNUC__ + /* Without this gcc inlines all the function calls to _index_set etc below. +  +  It's really rather pointless. And we really need a better way to +  avoid this than adding a lot of -Os around the code. :) + */ + #pragma GCC optimize "-Os" + #endif +  + static void stat_create (INT32 args) + { +  if (args >= 1 && !UNSAFE_IS_ZERO (Pike_sp - 1)) { +  pop_n_elems (args - 1); +  args = 1; +  +  if (TYPEOF(sp[-1]) == T_OBJECT) +  if (sp[-1].u.object->prog == stat_program) { +  *THIS_STAT = *(struct stat_storage *) sp[-1].u.object->storage; +  pop_stack(); +  return; +  } +  +  if ((1 << TYPEOF(sp[-1])) & (BIT_PROGRAM|BIT_OBJECT|BIT_MAPPING)) +  { +  struct keypair *k; +  int e; +  NEW_MAPPING_LOOP( stat_map->data ) +  { +  push_svalue(&k->ind); +  SET_SVAL_SUBTYPE(sp[-1],1); +  o_index(); +  if(!IS_UNDEFINED(sp-1)) { +  _stat_index_set( k->val.u.integer, sp-1, -1,0 ); +  } +  pop_stack(); +  } +  } +  else if (TYPEOF(sp[-1]) == T_ARRAY) +  { +  struct array *a = sp[-1].u.array; +  int i; +  if (a->size != 7) +  SIMPLE_BAD_ARG_ERROR ("Stat create", 1, "stat array with 7 elements"); +  for (i = 0; i < 7; i++) { +  INT64 val; +  if (TYPEOF(ITEM(a)[i]) == T_INT) +  val = ITEM(a)[i].u.integer; +  else if (TYPEOF(ITEM(a)[i]) == T_OBJECT && +  is_bignum_object (ITEM(a)[i].u.object)) { +  if (!int64_from_bignum (&val, ITEM(a)[i].u.object)) +  Pike_error ("Stat create: Too big integer in stat array.\n"); +  } +  else +  SIMPLE_BAD_ARG_ERROR ("Stat create", 1, "array(int)"); +  stat_compat_set (i, val); +  } +  } +  +  else +  SIMPLE_BAD_ARG_ERROR ("Stat create", 1, "void|Stdio.Stat|array(int)"); +  } +  +  pop_n_elems (args); + }   #undef THIS_STAT      void push_stat(PIKE_STAT_T *s)   {    struct object *o;    struct stat_storage *stor;    o=clone_object(stat_program,0);    stor=(struct stat_storage*)get_storage(o,stat_program);    stor->s=*s;    push_object(o);   }    -  +    /*! @endclass    */   /*! @endmodule    */      /* ---------------------------------------------------------------- */      void init_stdio_stat()   { -  INT_TYPE n=0; +  unsigned int n=0;    -  MAKE_CONSTANT_SHARED_STRING (str_type_reg, "reg"); -  MAKE_CONSTANT_SHARED_STRING (str_type_dir, "dir"); -  MAKE_CONSTANT_SHARED_STRING (str_type_lnk, "lnk"); -  MAKE_CONSTANT_SHARED_STRING (str_type_chr, "chr"); -  MAKE_CONSTANT_SHARED_STRING (str_type_blk, "blk"); -  MAKE_CONSTANT_SHARED_STRING (str_type_fifo, "fifo"); -  MAKE_CONSTANT_SHARED_STRING (str_type_sock, "sock"); -  MAKE_CONSTANT_SHARED_STRING (str_type_unknown, "unknown"); -  - #define INIT_INDEX(ENUM, TXT) do { \ -  MAKE_CONSTANT_SHARED_STRING (stat_index_strs[ENUM], TXT); \ -  n++; ref_push_string (stat_index_strs[ENUM]); push_int (ENUM); \ -  } while (0) -  -  INIT_INDEX (STAT_DEV, "dev"); -  INIT_INDEX (STAT_INO, "ino"); -  INIT_INDEX (STAT_MODE, "mode"); -  INIT_INDEX (STAT_NLINK, "nlink"); -  INIT_INDEX (STAT_UID, "uid"); -  INIT_INDEX (STAT_GID, "gid"); -  INIT_INDEX (STAT_RDEV, "rdev"); -  INIT_INDEX (STAT_SIZE, "size"); +  static const struct { +  const char *name; +  const INT_TYPE id; +  } __indices[] = { +  {"dev",STAT_DEV}, +  {"ino",STAT_INO}, +  {"mode",STAT_MODE}, +  {"nlink",STAT_NLINK}, +  {"uid",STAT_UID}, +  {"gid",STAT_GID}, +  {"rdev",STAT_RDEV}, +  {"size",STAT_SIZE},   #ifdef HAVE_STRUCT_STAT_BLOCKS -  INIT_INDEX (STAT_BLKSIZE, "blksize"); -  INIT_INDEX (STAT_BLOCKS, "blocks"); +  {"blksize",STAT_BLKSIZE}, +  {"blocks",STAT_BLOCKS},   #endif -  INIT_INDEX (STAT_ATIME, "atime"); -  INIT_INDEX (STAT_MTIME, "mtime"); -  INIT_INDEX (STAT_CTIME, "ctime"); +  {"atime",STAT_ATIME}, +  {"mtime",STAT_MTIME}, +  {"ctime",STAT_CTIME},    -  INIT_INDEX (STAT_ISLNK, "islnk"); -  INIT_INDEX (STAT_ISREG, "isreg"); -  INIT_INDEX (STAT_ISDIR, "isdir"); -  INIT_INDEX (STAT_ISCHR, "ischr"); -  INIT_INDEX (STAT_ISBLK, "isblk"); -  INIT_INDEX (STAT_ISFIFO, "isfifo"); -  INIT_INDEX (STAT_ISSOCK, "issock"); +  {"islnk",STAT_ISLNK}, +  {"isreg",STAT_ISREG}, +  {"isdir",STAT_ISDIR}, +  {"ischr",STAT_ISCHR}, +  {"isblk",STAT_ISBLK}, +  {"isfifo",STAT_ISFIFO}, +  {"issock",STAT_ISSOCK},    -  INIT_INDEX (STAT_TYPE, "type"); -  INIT_INDEX (STAT_MODE_STRING, "mode_string"); +  {"type",STAT_TYPE}, +  {"mode_string",STAT_MODE_STRING} +  };    -  f_aggregate_mapping(n*2); -  stat_map=sp[-1].u.mapping; +  str_type_reg = make_shared_string("reg"); +  str_type_dir = make_shared_string("dir"); +  str_type_lnk = make_shared_string("lnk"); +  str_type_chr = make_shared_string("chr"); +  str_type_blk = make_shared_string("blk"); +  str_type_fifo = make_shared_string("fifo"); +  str_type_sock = make_shared_string( "sock"); +  str_type_unknown = make_shared_string( "unknown"); +  +  stat_map=allocate_mapping(1); +  push_int(0); +  for( n=0; n<sizeof(__indices)/sizeof(__indices[0]); n++ ) +  { +  struct pike_string *s = make_shared_string(__indices[n].name); +  stat_index_strs[__indices[n].id]=s; +  sp[-1].u.integer = __indices[n].id; +  mapping_string_insert( stat_map, s, sp-1); +  s->refs++; +  }    sp--;    dmalloc_touch_svalue(sp);       START_NEW_PROGRAM_ID(STDIO_STAT);    ADD_STORAGE(struct stat_storage);       ADD_FUNCTION ("create", stat_create,    tFunc(tOr5(tVoid,tObjImpl_STDIO_STAT,tPrg(tObj),tMapping,tArr(tInt)),    tVoid), ID_PROTECTED);