示例#1
0
UInt            completion_rnam (
    Char *              name,
    UInt                len )
{
    const Char *        curr;
    const Char *        next;
    UInt                i, k;
    const UInt          countRNam = LEN_PLIST(NamesRNam);

    next = 0;
    for ( i = 1; i <= countRNam; i++ ) {
        curr = CONST_CSTR_STRING( NAME_RNAM( i ) );
        for ( k = 0; name[k] != 0 && curr[k] == name[k]; k++ ) ;
        if ( k < len || curr[k] <= name[k] )  continue;
        if ( next != 0 ) {
            for ( k = 0; curr[k] != '\0' && curr[k] == next[k]; k++ ) ;
            if ( k < len || next[k] < curr[k] )  continue;
        }
        next = curr;
    }

    if ( next != 0 ) {
        for ( k = 0; next[k] != '\0'; k++ )
            name[k] = next[k];
        name[k] = '\0';
    }

    return next != 0;
}
示例#2
0
文件: serialize.c 项目: dimpase/gap
static void ReadBytesNativeString(void * addr, UInt size)
{
    Obj  str = MODULE_STATE(Serialize).obj;
    UInt max = GET_LEN_STRING(str);
    UInt off = MODULE_STATE(Serialize).index;
    if (off + size > max)
        DeserializationError();
    memcpy(addr, CONST_CSTR_STRING(str) + off, size);
    MODULE_STATE(Serialize).index += size;
}
示例#3
0
/****************************************************************************
**
*F  iscomplete( <name>, <len> ) . . . . . . . .  find the completions of name
*F  completion( <name>, <len> ) . . . . . . . .  find the completions of name
*/
UInt            iscomplete_rnam (
    Char *              name,
    UInt                len )
{
    const Char *        curr;
    UInt                i, k;
    const UInt          countRNam = LEN_PLIST(NamesRNam);

    for ( i = 1; i <= countRNam; i++ ) {
        curr = CONST_CSTR_STRING( NAME_RNAM( i ) );
        for ( k = 0; name[k] != 0 && curr[k] == name[k]; k++ ) ;
        if ( k == len && curr[k] == '\0' )  return 1;
    }
    return 0;
}
示例#4
0
/****************************************************************************
**
*F  RNamObj(<obj>)  . . . . . . . . . . .  convert an object to a record name
**
**  'RNamObj' returns the record name  corresponding  to  the  object  <obj>,
**  which currently must be a string or an integer.
*/
UInt            RNamObj (
    Obj                 obj )
{
    /* convert integer object                                              */
    if ( IS_INTOBJ(obj) ) {
        return RNamIntg( INT_INTOBJ(obj) );
    }

    /* convert string object (empty string may have type T_PLIST)          */
    else if ( IsStringConv(obj) && IS_STRING_REP(obj) ) {
        return RNamName( CONST_CSTR_STRING(obj) );
    }

    /* otherwise fail                                                      */
    else {
        Obj err;
        err = ErrorReturnObj(
            "Record: '<rec>.(<obj>)' <obj> must be a string or an integer",
            0L, 0L,
            "you can replace <obj> via 'return <obj>;'" );
        return RNamObj( err );
    }
}
示例#5
0
文件: scanner.c 项目: cdwensley/gap
static UInt GetNumber(Int readDecimalPoint)
{
  UInt symbol = S_ILLEGAL;
  UInt i = 0;
  Char c;
  UInt seenADigit = 0;
  UInt seenExp = 0;
  UInt seenExpDigit = 0;

  STATE(ValueObj) = 0;

  c = PEEK_CURR_CHAR();
  if (readDecimalPoint) {
    STATE(Value)[i++] = '.';
  }
  else {
    // read initial sequence of digits into 'Value'
    while (IsDigit(c)) {
      i = AddCharToValue(i, c);
      seenADigit = 1;
      c = GET_NEXT_CHAR();
    }

    // maybe we saw an identifier character and realised that this is an
    // identifier we are reading
    if (IsIdent(c) || c == '\\') {
      // if necessary, copy back from STATE(ValueObj) to STATE(Value)
      if (STATE(ValueObj)) {
        i = GET_LEN_STRING(STATE(ValueObj));
        GAP_ASSERT(i >= MAX_VALUE_LEN - 1);
        memcpy(STATE(Value), CONST_CSTR_STRING(STATE(ValueObj)), MAX_VALUE_LEN);
        STATE(ValueObj) = 0;
      }
      // this looks like an identifier, scan the rest of it
      return GetIdent(i);
    }

    // Or maybe we saw a '.' which could indicate one of two things: a
    // float literal or S_DOT, i.e., '.' used to access a record entry.
    if (c == '.') {
      GAP_ASSERT(i < MAX_VALUE_LEN - 1);

      // If the symbol before this integer was S_DOT then we must be in
      // a nested record element expression, so don't look for a float.
      // This is a bit fragile
      if (STATE(Symbol) == S_DOT || STATE(Symbol) == S_BDOT) {
        symbol = S_INT;
        goto finish;
      }

      // peek ahead to decide which
      if (PEEK_NEXT_CHAR() == '.') {
        // It was '.', so this looks like '..' and we are probably
        // inside a range expression.
        symbol = S_INT;
        goto finish;
      }

      // Now the '.' must be part of our number; store it and move on
      i = AddCharToValue(i, '.');
      c = GET_NEXT_CHAR();
    }

    else {
      // Anything else we see tells us that the token is done
      symbol = S_INT;
      goto finish;
    }
  }


  // When we get here we have read possibly some digits, a . and possibly
  // some more digits, but not an e,E,d,D,q or Q

    // read digits
    while (IsDigit(c)) {
      i = AddCharToValue(i, c);
      seenADigit = 1;
      c = GET_NEXT_CHAR();
    }
    if (!seenADigit)
      SyntaxError("Badly formed number: need a digit before or after the "
                  "decimal point");
    if (c == '\\')
      SyntaxError("Badly formed number");

    // If we found an identifier type character in this context could be an
    // error or the start of one of the allowed trailing marker sequences
    if (IsIdent(c) && c != 'e' && c != 'E' && c != 'd' && c != 'D' &&
        c != 'q' && c != 'Q') {

      // Allow one letter on the end of the numbers -- could be an i, C99
      // style
      if (IsAlpha(c)) {
        i = AddCharToValue(i, c);
        c = GET_NEXT_CHAR();
      }
      // independently of that, we allow an _ signalling immediate conversion
      if (c == '_') {
        i = AddCharToValue(i, c);
        c = GET_NEXT_CHAR();
        // After which there may be one character signifying the
        // conversion style
        if (IsAlpha(c)) {
          i = AddCharToValue(i, c);
          c = GET_NEXT_CHAR();
        }
      }
      // Now if the next character is alphanumerical, or an identifier type
      // symbol then we really do have an error, otherwise we return a result
      if (IsIdent(c) || IsDigit(c)) {
        SyntaxError("Badly formed number");
      }
      else {
        symbol = S_FLOAT;
        goto finish;
      }
    }

    // If the next thing is the start of the exponential notation, read it now.

    if (IsAlpha(c)) {
      if (!seenADigit)
        SyntaxError("Badly formed number: need a digit before or after "
                    "the decimal point");
      seenExp = 1;
      i = AddCharToValue(i, c);
      c = GET_NEXT_CHAR();
      if (c == '+' || c == '-') {
        i = AddCharToValue(i, c);
        c = GET_NEXT_CHAR();
      }
    }

    // Either we saw an exponent indicator, or we hit end of token deal with
    // the end of token case
    if (!seenExp) {
      if (!seenADigit)
        SyntaxError("Badly formed number: need a digit before or after "
                    "the decimal point");
      // Might be a conversion marker
      if (IsAlpha(c) && c != 'e' && c != 'E' && c != 'd' && c != 'D' &&
          c != 'q' && c != 'Q') {
        i = AddCharToValue(i, c);
        c = GET_NEXT_CHAR();
      }
      // independently of that, we allow an _ signalling immediate conversion
      if (c == '_') {
        i = AddCharToValue(i, c);
        c = GET_NEXT_CHAR();
        // After which there may be one character signifying the
        // conversion style
        if (IsAlpha(c))
          i = AddCharToValue(i, c);
        c = GET_NEXT_CHAR();
      }
      // Now if the next character is alphanumerical, or an identifier type
      // symbol then we really do have an error, otherwise we return a result
      if (!IsIdent(c) && !IsDigit(c)) {
        symbol = S_FLOAT;
        goto finish;
      }
      SyntaxError("Badly formed number");
    }

  // Here we are into the unsigned exponent of a number in scientific
  // notation, so we just read digits

  while (IsDigit(c)) {
    i = AddCharToValue(i, c);
    seenExpDigit = 1;
    c = GET_NEXT_CHAR();
  }

  // Look out for a single alphabetic character on the end
  // which could be a conversion marker
  if (seenExpDigit) {
    if (IsAlpha(c)) {
      i = AddCharToValue(i, c);
      c = GET_NEXT_CHAR();
      symbol = S_FLOAT;
      goto finish;
    }
    if (c == '_') {
      i = AddCharToValue(i, c);
      c = GET_NEXT_CHAR();
      // After which there may be one character signifying the
      // conversion style
      if (IsAlpha(c)) {
        i = AddCharToValue(i, c);
        c = GET_NEXT_CHAR();
      }
      symbol = S_FLOAT;
      goto finish;
    }
  }

  // Otherwise this is the end of the token
  if (!seenExpDigit)
    SyntaxError(
        "Badly formed number: need at least one digit in the exponent");
  symbol = S_FLOAT;

finish:
  i = AddCharToValue(i, '\0');
  if (STATE(ValueObj)) {
    // flush buffer
    AppendBufToString(STATE(ValueObj), STATE(Value), i - 1);
  }
  return symbol;
}
示例#6
0
UInt RNamNameWithLen(const Char * name, UInt len)
{
    Obj                 rnam;           /* record name (as imm intobj)     */
    UInt                pos;            /* hash position                   */
    Char                namx [1024];    /* temporary copy of <name>        */
    Obj                 string;         /* temporary string object <name>  */
    Obj                 table;          /* temporary copy of <HashRNam>    */
    Obj                 rnam2;          /* one element of <table>          */
    UInt                i;              /* loop variable                   */
    UInt                sizeRNam;

    if (len > 1023) {
        // Note: We can't pass 'name' here, as it might get moved by garbage collection
        ErrorQuit("Record names must consist of at most 1023 characters", 0, 0);
    }

    /* start looking in the table at the following hash position           */
    const UInt hash = HashString( name, len );

#ifdef HPCGAP
    HPC_LockNames(0); /* try a read lock first */
#endif

    /* look through the table until we find a free slot or the global      */
    sizeRNam = LEN_PLIST(HashRNam);
    pos = (hash % sizeRNam) + 1;
    while ( (rnam = ELM_PLIST( HashRNam, pos )) != 0
         && !EqString( NAME_RNAM( INT_INTOBJ(rnam) ), name, len ) ) {
        pos = (pos % sizeRNam) + 1;
    }
    if (rnam != 0) {
#ifdef HPCGAP
      HPC_UnlockNames();
#endif
      return INT_INTOBJ(rnam);
    }
#ifdef HPCGAP
    if (!PreThreadCreation) {
      HPC_UnlockNames(); /* switch to a write lock */
      HPC_LockNames(1);
      /* look through the table until we find a free slot or the global      */
      sizeRNam = LEN_PLIST(HashRNam);
      pos = (hash % sizeRNam) + 1;
      while ( (rnam = ELM_PLIST( HashRNam, pos )) != 0
           && !EqString( NAME_RNAM( INT_INTOBJ(rnam) ), name, len ) ) {
          pos = (pos % sizeRNam) + 1;
      }
    }
    if (rnam != 0) {
      HPC_UnlockNames();
      return INT_INTOBJ(rnam);
    }
#endif

    /* if we did not find the global variable, make a new one and enter it */
    /* (copy the name first, to avoid a stale pointer in case of a GC)     */
    memcpy( namx, name, len );
    namx[len] = 0;
    string = MakeImmString(namx);

    const UInt countRNam = PushPlist(NamesRNam, string);
    rnam = INTOBJ_INT(countRNam);
    SET_ELM_PLIST( HashRNam, pos, rnam );

    /* if the table is too crowded, make a larger one, rehash the names     */
    if ( sizeRNam < 3 * countRNam / 2 ) {
        table = HashRNam;
        sizeRNam = 2 * sizeRNam + 1;
        HashRNam = NEW_PLIST( T_PLIST, sizeRNam );
        SET_LEN_PLIST( HashRNam, sizeRNam );
#ifdef HPCGAP
        /* The list is briefly non-public, but this is safe, because
         * the mutex protects it from being accessed by other threads.
         */
        MakeBagPublic(HashRNam);
#endif
        for ( i = 1; i <= (sizeRNam-1)/2; i++ ) {
            rnam2 = ELM_PLIST( table, i );
            if ( rnam2 == 0 )  continue;
            string = NAME_RNAM( INT_INTOBJ(rnam2) );
            pos = HashString( CONST_CSTR_STRING( string ), GET_LEN_STRING( string) );
            pos = (pos % sizeRNam) + 1;
            while ( ELM_PLIST( HashRNam, pos ) != 0 ) {
                pos = (pos % sizeRNam) + 1;
            }
            SET_ELM_PLIST( HashRNam, pos, rnam2 );
        }
    }
#ifdef HPCGAP
    HPC_UnlockNames();
#endif

    /* return the record name                                              */
    return INT_INTOBJ(rnam);
}
示例#7
0
static inline int EqString(Obj str, const Char * name, UInt len)
{
    if (GET_LEN_STRING(str) != len)
        return 0;
    return memcmp(CONST_CSTR_STRING(str), name, len) == 0;
}