pike.git / src / pike_types.c

version» Context lines:

pike.git/src/pike_types.c:1:   /*\   ||| This file a part of Pike, and is copyright by Fredrik Hubinette   ||| Pike is distributed as GPL (General Public License)   ||| See the files COPYING and DISCLAIMER for more information.   \*/   #include "global.h" - RCSID("$Id: pike_types.c,v 1.33 1998/02/24 23:01:31 hubbe Exp $"); + RCSID("$Id: pike_types.c,v 1.34 1998/03/01 11:40:47 hubbe Exp $");   #include <ctype.h>   #include "svalue.h"   #include "pike_types.h"   #include "stralloc.h"   #include "stuff.h"   #include "array.h"   #include "program.h"   #include "constants.h"   #include "object.h"   #include "multiset.h"
pike.git/src/pike_types.c:54:   struct pike_string *function_type_string;   struct pike_string *object_type_string;   struct pike_string *program_type_string;   struct pike_string *array_type_string;   struct pike_string *multiset_type_string;   struct pike_string *mapping_type_string;   struct pike_string *mixed_type_string;   struct pike_string *void_type_string;   struct pike_string *any_type_string;    + static char *a_markers[10],*b_markers[10]; +  + static void clear_markers() + { +  unsigned int e; +  for(e=0;e<NELEM(a_markers);e++) a_markers[e]=b_markers[e]=0; + } +    #ifdef DEBUG   static void CHECK_TYPE(struct pike_string *s)   {    if(debug_findstring(s) != s)    fatal("Type string not shared.\n");       if(type_length(s->str) != s->len) -  +  { +  stupid_describe_type(s->str,s->len);    fatal("Length of type is wrong.\n");    } -  + }   #else   #define CHECK_TYPE(X)   #endif      void init_types(void)   {    string_type_string=parse_type("string");    int_type_string=parse_type("int");    object_type_string=parse_type("object");    program_type_string=parse_type("program");
pike.git/src/pike_types.c:93:   static int type_length(char *t)   {    char *q=t;       switch(EXTRACT_UCHAR(t++))    {    default:    fatal("error in type string.\n");    /*NOTREACHED*/    +  break; +  +  case T_ASSIGN: +  t++; +  t+=type_length(t); +  break; +     case T_FUNCTION:    while(EXTRACT_UCHAR(t)!=T_MANY) t+=type_length(t); /* skip arguments */    t++;       case T_MAPPING:    case T_OR:    case T_AND:    t+=type_length(t);       case T_ARRAY:    case T_MULTISET:    case T_NOT:    t+=type_length(t);    -  +  case '0': +  case '1': +  case '2': +  case '3': +  case '4': +  case '5': +  case '6': +  case '7': +  case '8': +  case '9':    case T_INT:    case T_FLOAT:    case T_STRING:    case T_PROGRAM:    case T_MIXED:    case T_VOID:    case T_UNKNOWN:    break;       case T_OBJECT:
pike.git/src/pike_types.c:198:    push_type(((unsigned char *)&i)[e]);   }      void push_unfinished_type(char *s)   {    int e;    e=type_length(s);    for(e--;e>=0;e--) push_type(s[e]);   }    + static void push_unfinished_type_with_markers(char *s, char **am) + { +  int e; +  e=type_length(s); +  for(e--;e>=0;e--) +  { +  if(s[e]>='0' && s[e]<='9') +  { +  if(am[s[e]-'0']) +  { +  push_unfinished_type(am[s[e]-'0']); +  }else{ +  push_type(T_MIXED); +  } +  }else{ +  push_type(s[e]); +  } +  } + } +    void push_finished_type(struct pike_string *type)   {    int e;    CHECK_TYPE(type);    for(e=type->len-1;e>=0;e--) push_type(type->str[e]);   }      struct pike_string *debug_pop_unfinished_type(void)   {    int len,e;
pike.git/src/pike_types.c:362:    {    ++*s;    internal_parse_type(_s);    if(**s != ')') error("Expecting ')'.\n");    ++*s;    }else{    push_type(T_MIXED);    }    push_type(T_MULTISET);    } +  else if(buf[0]>='0' && buf[0]<='9' && atoi(buf)<10) +  { +  while(ISSPACE(**s)) ++*s; +  if(**s=='=') +  { +  ++*s; +  internal_parse_type(_s); +  push_type(buf[0]); +  push_type(T_ASSIGN); +  }else{ +  push_type(buf[0]); +  } +  }    else    error("Couldn't parse type. (%s)\n",buf);       while(ISSPACE(**s)) ++*s;   }         static void internal_parse_typeB(char **s)   {    while(ISSPACE(**((unsigned char **)s))) ++*s;
pike.git/src/pike_types.c:469: Inside #if defined(DEBUG)
     #ifdef DEBUG   void stupid_describe_type(char *a,INT32 len)   {    INT32 e;    for(e=0;e<len;e++)    {    if(e) printf(" ");    switch(EXTRACT_UCHAR(a+e))    { +  case '0': case '1': case '2': case '3': case '4': +  case '5': case '6': case '7': case '8': case '9': +  printf("%c",EXTRACT_UCHAR(a+e)); +  break; +  +  case T_ASSIGN: printf("="); break;    case T_INT: printf("int"); break;    case T_FLOAT: printf("float"); break;    case T_STRING: printf("string"); break;    case T_PROGRAM: printf("program"); break;    case T_OBJECT:    printf("object(%ld)",(long)EXTRACT_INT(a+e+1));    e+=sizeof(INT32);    break;    case T_FUNCTION: printf("function"); break;    case T_ARRAY: printf("array"); break;
pike.git/src/pike_types.c:506: Inside #if defined(DEBUG)
  void simple_describe_type(struct pike_string *s)   {    stupid_describe_type(s->str,s->len);   }   #endif      char *low_describe_type(char *t)   {    switch(EXTRACT_UCHAR(t++))    { +  case '0': case '1': case '2': case '3': case '4': +  case '5': case '6': case '7': case '8': case '9': +  my_putchar(EXTRACT_UCHAR(t-1)); +  break; +  +  case T_ASSIGN: +  my_putchar('('); +  my_putchar(EXTRACT_UCHAR(t++)); +  my_putchar('='); +  t=low_describe_type(t); +  my_putchar(')'); +  break; +     case T_VOID: my_strcat("void"); break;    case T_MIXED: my_strcat("mixed"); break;    case T_UNKNOWN: my_strcat("unknown"); break;    case T_INT: my_strcat("int"); break;    case T_FLOAT: my_strcat("float"); break;    case T_PROGRAM: my_strcat("program"); break;    case T_OBJECT:    my_strcat("object");    t+=4;    /* Prog id */
pike.git/src/pike_types.c:609:   }      struct pike_string *describe_type(struct pike_string *type)   {    if(!type) return make_shared_string("mixed");    init_buf();    low_describe_type(type->str);    return free_buf();   }    + static int low_is_same_type(char *a, char *b) + { +  if(type_length(a) != type_length(b)) return 0; +  return !MEMCMP(a,b,type_length(a)); + } +    static TYPE_T low_compile_type_to_runtime_type(char *t)   {    TYPE_T tmp;    switch(EXTRACT_UCHAR(t))    {    case T_OR:    t++;    tmp=low_compile_type_to_runtime_type(t);    if(tmp == low_compile_type_to_runtime_type(t+type_length(t)))    return tmp;    -  case T_MANY: -  case T_UNKNOWN: -  case T_AND: -  case T_NOT: +  default:    return T_MIXED;    -  default: +  case T_ARRAY: +  case T_MAPPING: +  case T_MULTISET: +  +  case T_OBJECT: +  case T_PROGRAM: +  case T_FUNCTION: +  +  case T_STRING: +  case T_INT: +  case T_FLOAT:    return EXTRACT_UCHAR(t);    }   }      TYPE_T compile_type_to_runtime_type(struct pike_string *s)   {    return low_compile_type_to_runtime_type(s->str);   }      #define A_EXACT 1
pike.git/src/pike_types.c:667:    return low_match_types(a,b,flags);       case T_OR:    a++;    ret=low_match_types(a,b,flags);    if(ret) return ret;    a+=type_length(a);    return low_match_types(a,b,flags);       case T_NOT: -  if(low_match_types(a+1,b,flags | B_EXACT | NO_MAX_ARGS)) +  if(low_match_types(a+1,b,(flags ^ B_EXACT ) | NO_MAX_ARGS))    return 0;    return a; -  +  +  case T_ASSIGN: +  ret=low_match_types(a+2,b,flags); +  if(ret) +  { +  int m=EXTRACT_UCHAR(a+1)-'0'; +  if(!a_markers[m]) +  a_markers[m]=b; +  else if(!low_is_same_type(a_markers[m], b)) +  a_markers[m]=mixed_type_string->str;    } -  +  return ret;    -  +  case '0': case '1': case '2': case '3': case '4': +  case '5': case '6': case '7': case '8': case '9': +  { +  int m=EXTRACT_UCHAR(a)-'0'; +  if(a_markers[m]) +  return low_match_types(a_markers[m], b, flags); +  else +  return low_match_types(mixed_type_string->str, b, flags); +  } +  } +     switch(EXTRACT_UCHAR(b))    {    case T_AND:    b++;    ret=low_match_types(a,b,flags);    if(!ret) return 0;    b+=type_length(b);    return low_match_types(a,b,flags);       case T_OR:    b++;    ret=low_match_types(a,b,flags);    if(ret) return ret;    b+=type_length(b);    return low_match_types(a,b,flags);       case T_NOT: -  if(low_match_types(a,b+1, flags | A_EXACT | NO_MAX_ARGS)) +  if(low_match_types(a,b+1, (flags ^ A_EXACT ) | NO_MAX_ARGS))    return 0;    return a; -  +  +  case T_ASSIGN: +  ret=low_match_types(a,b+2,flags); +  if(ret) +  { +  int m=EXTRACT_UCHAR(b+1)-'0'; +  if(!b_markers[m]) +  b_markers[m]=a; +  else if(!low_is_same_type(b_markers[m], a)) +  b_markers[m]=mixed_type_string->str;    } -  +  return ret;    -  +  case '0': case '1': case '2': case '3': case '4': +  case '5': case '6': case '7': case '8': case '9': +  { +  int m=EXTRACT_UCHAR(b)-'0'; +  if(b_markers[m]) +  return low_match_types(a, b_markers[m], flags); +  else +  return low_match_types(a, mixed_type_string->str, flags); +  } +  } +     /* 'mixed' matches anything */    if(EXTRACT_UCHAR(a) == T_MIXED && !(flags & A_EXACT)) return a;    if(EXTRACT_UCHAR(b) == T_MIXED && !(flags & B_EXACT)) return a;       /* Special cases (tm) */    switch(EXTRACT_TWOT(a,b))    {    case TWOT(T_PROGRAM, T_FUNCTION):    case TWOT(T_FUNCTION, T_PROGRAM):    return a;
pike.git/src/pike_types.c:886:    a=low_match_types(a,b,0);    if(a)    {    switch(EXTRACT_UCHAR(a))    {    case T_FUNCTION:    a++;    while(EXTRACT_UCHAR(a)!=T_MANY) a+=type_length(a);    a++;    a+=type_length(a); -  push_unfinished_type(a); +  push_unfinished_type_with_markers(a, a_markers );    return 1;       case T_PROGRAM:    push_type_int(0);    push_type(T_OBJECT);    return 1;       default:    push_type(T_MIXED);    return 1;    }    }    return 0;   }         int match_types(struct pike_string *a,struct pike_string *b)   {    CHECK_TYPE(a);    CHECK_TYPE(b); -  +  clear_markers();    return 0!=low_match_types(a->str, b->str,0);   }         #ifdef DEBUG_MALLOC   #define low_index_type(X,Y) ((struct pike_string *)debug_malloc_touch(debug_low_index_type((X),(Y))))   #else   #define low_index_type debug_low_index_type   #endif   
pike.git/src/pike_types.c:1015:    return pop_unfinished_type();    }else{    return make_shared_binary_string(t, type_length(t));    }    }   }      struct pike_string *index_type(struct pike_string *type, node *n)   {    struct pike_string *t; +  clear_markers();    t=low_index_type(type->str,n);    if(!t) copy_shared_string(t,mixed_type_string);    return t;   }      static int low_check_indexing(char *type, char *index_type, node *n)   {    switch(EXTRACT_UCHAR(type++))    {    case T_OR:
pike.git/src/pike_types.c:1137:    CHECK_TYPE(s);       return low_count_arguments(s->str);   }      struct pike_string *check_call(struct pike_string *args,    struct pike_string *type)   {    CHECK_TYPE(args);    CHECK_TYPE(type); +  clear_markers();    type_stack_mark();    max_correct_args=0;       if(low_get_return_type(type->str,args->str))    {    return pop_unfinished_type();    }else{    pop_stack_mark();    return 0;    }   }      INT32 get_max_args(struct pike_string *type)   {    INT32 ret,tmp=max_correct_args;    CHECK_TYPE(type); -  +  clear_markers();    type=check_call(function_type_string, type);    if(type) free_string(type);    ret=max_correct_args;    max_correct_args=tmp;    return tmp;   }      struct pike_string *get_type_of_svalue(struct svalue *s)   {    struct pike_string *ret;