Obj operator()(const std::string& s) const { Obj o; const char* c = s.c_str(); C_NEW_STRING_DYN(o, c); return o; }
Obj FuncSTRING_DIGITS_MACFLOAT( Obj self, Obj gapprec, Obj f) { Char buf[50]; Obj str; int prec = INT_INTOBJ(gapprec); if (prec > 40) /* too much anyways, and would risk buffer overrun */ prec = 40; snprintf(buf, sizeof(buf), "%.*" PRINTFFORMAT, prec, (TOPRINTFFORMAT)VAL_MACFLOAT(f)); C_NEW_STRING_DYN(str, buf); return str; }
Obj FuncALL_RNAMES ( Obj self ) { Obj copy, s; UInt i; Char* name; copy = NEW_PLIST( T_PLIST+IMMUTABLE, CountRNam ); for ( i = 1; i <= CountRNam; i++ ) { name = NAME_RNAM( i ); C_NEW_STRING_DYN(s, name); SET_ELM_PLIST( copy, i, s ); } SET_LEN_PLIST( copy, CountRNam ); return copy; }
Obj NameRNamHandler ( Obj self, Obj rnam ) { Obj name; Char *cname; while ( ! IS_INTOBJ(rnam) || INT_INTOBJ(rnam) <= 0 || CountRNam < INT_INTOBJ(rnam) ) { rnam = ErrorReturnObj( "NameRName: <rnam> must be a record name (not a %s)", (Int)TNAM_OBJ(rnam), 0L, "you can replace <rnam> via 'return <rnam>;'" ); } cname = NAME_RNAM( INT_INTOBJ(rnam) ); C_NEW_STRING_DYN( name, cname); return name; }
UInt RNamName ( const Char * name ) { Obj rnam; /* record name (as imm intobj) */ UInt pos; /* hash position */ UInt len; /* length of name */ 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> */ const Char * p; /* loop variable */ UInt i; /* loop variable */ /* start looking in the table at the following hash position */ pos = 0; len = 0; for ( p = name; *p != '\0'; p++ ) { pos = 65599 * pos + *p; len++; } pos = (pos % SizeRNam) + 1; if(len >= 1023) { // Note: We can't pass 'name' here, as it might get moved by garbage collection ErrorQuit("Record names must consist of less than 1023 characters", 0, 0); } /* look through the table until we find a free slot or the global */ while ( (rnam = ELM_PLIST( HashRNam, pos )) != 0 && strncmp( NAME_RNAM( INT_INTOBJ(rnam) ), name, 1023 ) ) { pos = (pos % SizeRNam) + 1; } /* 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) */ if ( rnam == 0 ) { CountRNam++; rnam = INTOBJ_INT(CountRNam); SET_ELM_PLIST( HashRNam, pos, rnam ); strlcpy( namx, name, sizeof(namx) ); C_NEW_STRING_DYN(string, namx); GROW_PLIST( NamesRNam, CountRNam ); SET_LEN_PLIST( NamesRNam, CountRNam ); SET_ELM_PLIST( NamesRNam, CountRNam, string ); CHANGED_BAG( NamesRNam ); } /* if the table is too crowed, 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 ); for ( i = 1; i <= (SizeRNam-1)/2; i++ ) { rnam2 = ELM_PLIST( table, i ); if ( rnam2 == 0 ) continue; pos = 0; for ( p = NAME_RNAM( INT_INTOBJ(rnam2) ); *p != '\0'; p++ ) { pos = 65599 * pos + *p; } pos = (pos % SizeRNam) + 1; while ( ELM_PLIST( HashRNam, pos ) != 0 ) { pos = (pos % SizeRNam) + 1; } SET_ELM_PLIST( HashRNam, pos, rnam2 ); } } /* return the record name */ return INT_INTOBJ(rnam); }