static int make_adjective(char *English_word) { /* Returns adjective number of the English word supplied, creating a new adjective number if need be. Note that (partly for historical reasons) adjectives are numbered from 0xff downwards. (And partly to make them stand out as tokens.) This routine is used only in grammar version 1: the corresponding table is left empty in GV2. */ int i; uchar new_sort_code[MAX_DICT_WORD_BYTES]; if (no_adjectives >= MAX_ADJECTIVES) memoryerror("MAX_ADJECTIVES", MAX_ADJECTIVES); dictionary_prepare(English_word, new_sort_code); for (i=0; i<no_adjectives; i++) if (compare_sorts(new_sort_code, adjective_sort_code+i*DICT_WORD_BYTES) == 0) return(0xff-i); adjectives[no_adjectives] = dictionary_add(English_word,8,0,0xff-no_adjectives); copy_sorts(adjective_sort_code+no_adjectives*DICT_WORD_BYTES, new_sort_code); return(0xff-no_adjectives++); }
boolean debugcopyhandle (char * filename, unsigned long linenumber, unsigned long threadid, Handle horig, Handle *hcopy) { register Handle h; register long ct; if (horig == nil) /*easy to copy a nil handle*/ h = nil; else { ct = gethandlesize (horig); h = debuggetnewhandle (filename, linenumber, threadid, ct, false); if (h == nil) { memoryerror (); return (false); } moveleft (*horig, *h, ct); } *hcopy = h; return (true); } /*copyhandle*/
boolean copyhandle (Handle horig, Handle *hcopy) { register Handle h; register long ct; if (horig == nil) /*easy to copy a nil handle*/ h = nil; else { ct = gethandlesize (horig); h = getnewhandle (ct, false); if (h == nil) { memoryerror (); return (false); } moveleft (*horig, *h, ct); } *hcopy = h; return (true); } /*copyhandle*/
boolean debugnewtexthandle (char * filename, unsigned long linenumber, unsigned long threadid, const bigstring bs, Handle *htext) { /* create a new handle to hold the text of the string. if the string is "\pABC" -- you get a handle of size 3. */ register long len = stringlength (bs); register Handle h; h = debuggetnewhandle (filename, linenumber, threadid, len, false); if (h == nil) { memoryerror (); return (false); } if (len > 0) moveleft ((ptrstring) stringbaseaddress (bs), *h, len); *htext = h; /*pass handle back to caller*/ return (true); } /*newtexthandle*/
void disposehandle (Handle h) { if (h != nil) { #ifdef WIN95VERSION DisposeHandle (h); #endif #ifdef MACVERSION #if (MEMTRACKER == 1) debugremovememhandle(h); #endif #ifdef fldebug if (HandleZone (h) == tempzone) --cttemphandles; #endif DisposeHandle (h); #ifdef fldebug if (MemError ()) memoryerror (); #endif #endif } } /*disposehandle*/
boolean debugnewhandle (char * filename, unsigned long linenumber, unsigned long threadid, long size, Handle *h) { *h = debuggetnewhandle (filename, linenumber, threadid, size, false); if (*h == nil) { memoryerror (); return (false); } return (true); } /*newhandle*/
boolean newhandle (long size, Handle *h) { *h = getnewhandle (size, false); if (*h == nil) { memoryerror (); return (false); } return (true); } /*newhandle*/
boolean sethandlesize (Handle h, long size) { if (h == nil) /*defensive driving*/ return (false); if (!resizehandle (h, size)) { memoryerror (); return (false); } return (true); } /*sethandlesize*/
boolean menewmenubar (hdloutlinerecord houtline, hdlmenubarstack *hstack) { /* create a new, empty menubar data structure, linked into menubarlist. 4.1b2 dmb: xxx - create stack in the (client) application zone */ register hdlmenubarstack hs; #if 0 THz savezone = GetZone (); SetZone (ApplicationZone ()); *hstack = (hdlmenubarstack) NewHandleClear (sizeof (tymenubarstack)); SetZone (savezone); hs = *hstack; /*move into register*/ if (hs == nil) { memoryerror (); return (false); } #else if (!newclearhandle (sizeof (tymenubarstack), (Handle *) hstack)) return (false); hs = *hstack; /*move into register*/ #endif (**hs).menubaroutline = houtline; (**hs).ixdeletedmenu = -1; /*no halfway deleted menu*/ /* if (pushmenubarlist (hs)) /%add it to the end of our list%/ (**hs).flactive = (**menubarlist).flactive; */ return (true); } /*menewmenubar*/
boolean testheapspace (long size) { /* see if there's enough space in the heap to allocate a handle of the given size. if not, generate an error, and return false. */ if (haveheapspace (size)) return (true); memoryerror (); return (false); } /*testheapspace*/
extern assembly_operand action_of_name(char *name) { /* Returns the action number of the given name, creating it as a new action name if it isn't already known as such. */ char action_sub[MAX_IDENTIFIER_LENGTH+4]; int j; assembly_operand AO; sprintf(action_sub, "%s__A", name); j = symbol_index(action_sub, -1); if (stypes[j] == FAKE_ACTION_T) { AO.value = svals[j]; AO.marker = 0; if (!glulx_mode) AO.type = LONG_CONSTANT_OT; else set_constant_ot(&AO); sflags[j] |= USED_SFLAG; return AO; } if (sflags[j] & UNKNOWN_SFLAG) { if (no_actions>=MAX_ACTIONS) memoryerror("MAX_ACTIONS",MAX_ACTIONS); new_action(name, no_actions); action_symbol[no_actions] = j; assign_symbol(j, no_actions++, CONSTANT_T); sflags[j] |= ACTION_SFLAG; } sflags[j] |= USED_SFLAG; AO.value = svals[j]; AO.marker = ACTION_MV; if (!glulx_mode) { AO.type = (module_switch)?LONG_CONSTANT_OT:SHORT_CONSTANT_OT; if (svals[j] >= 256) AO.type = LONG_CONSTANT_OT; } else { AO.type = CONSTANT_OT; } return AO; }
static void register_verb(char *English_verb, int number) { /* Registers a new English verb as referring to the given Inform-verb number. (See comments above for format of the list.) */ if (find_or_renumber_verb(English_verb, NULL) != -1) { error_named("Two different verb definitions refer to", English_verb); return; } English_verb_list_size += strlen(English_verb)+4; if (English_verb_list_size >= MAX_VERBSPACE) memoryerror("MAX_VERBSPACE", MAX_VERBSPACE); English_verb_list_top[0] = 4+strlen(English_verb); English_verb_list_top[1] = number/256; English_verb_list_top[2] = number%256; strcpy(English_verb_list_top+3, English_verb); English_verb_list_top += English_verb_list_top[0]; }
boolean debugconcathandles (char * filename, unsigned long linenumber, unsigned long threadid, Handle h1, Handle h2, Handle *hmerged) { /* create a new handle which is the concatenation of two handles. */ register Handle h; long sizefirsthandle; long sizesecondhandle; register ptrbyte p; *hmerged = nil; /*default return value*/ sizefirsthandle = gethandlesize (h1); sizesecondhandle = gethandlesize (h2); h = debuggetnewhandle (filename, linenumber, threadid, sizefirsthandle + sizesecondhandle, false); if (h == nil) { memoryerror (); return (false); } p = (ptrbyte) *h; moveleft (*h1, p, sizefirsthandle); p += sizefirsthandle; moveleft (*h2, p, sizesecondhandle); *hmerged = h; return (true); } /*concathandles*/
boolean loadfromhandletohandle (Handle hload, long *ixload, long ctload, boolean fltemp, Handle *hnew) { /* load from the source handle, creating a new handle to hold the loaded stuff. 6/8/91 dmb: fixed memory leak if loadfromhandle fails 11/27/91 dmb: reject ctload < 0 2.1b3 dmb: added fltemp parameter to determine whether caller is going to dispose the result soon. */ Handle h; if (ctload < 0) return (false); h = getnewhandle (ctload, fltemp); if (h == nil) { memoryerror (); return (false); } if (!loadfromhandle (hload, ixload, ctload, *h)) { disposehandle (h); return (false); } *hnew = h; return (true); } /*loadfromhandletohandle*/
boolean concathandles (Handle h1, Handle h2, Handle *hmerged) { /* create a new handle which is the concatenation of two handles. */ register Handle h; long sizefirsthandle; long sizesecondhandle; register ptrbyte p; *hmerged = nil; /*default return value*/ sizefirsthandle = gethandlesize (h1); sizesecondhandle = gethandlesize (h2); h = getnewhandle (sizefirsthandle + sizesecondhandle, false); if (h == nil) { memoryerror (); return (false); } p = (ptrbyte) *h; moveleft (*h1, p, sizefirsthandle); p += sizefirsthandle; moveleft (*h2, p, sizesecondhandle); *hmerged = h; return (true); } /*concathandles*/
boolean newfilledhandle (ptrvoid pdata, long size, Handle *hreturned) { register Handle h; register long ctbytes; ctbytes = size; h = getnewhandle (ctbytes, false); if (h == nil) { *hreturned = nil; memoryerror (); return (false); } moveleft (pdata, *h, ctbytes); *hreturned = h; return (true); } /*newfilledhandle*/
boolean newclearhandle (long size, Handle *hreturned) { register Handle h; register long ctbytes; ctbytes = size; /*copy into a register*/ h = getnewhandle (ctbytes, false); if (h == nil) { *hreturned = nil; memoryerror (); return (false); } clearhandle (h); *hreturned = h; return (true); } /*newclearhandle*/
boolean debugnewfilledhandle (char * filename, unsigned long linenumber, unsigned long threadid, ptrvoid pdata, long size, Handle *hreturned) { register Handle h; register long ctbytes; ctbytes = size; h = debuggetnewhandle (filename, linenumber, threadid, ctbytes, false); if (h == nil) { *hreturned = nil; memoryerror (); return (false); } moveleft (pdata, *h, ctbytes); *hreturned = h; return (true); } /*newfilledhandle*/
boolean debugnewclearhandle (char * filename, unsigned long linenumber, unsigned long threadid, long size, Handle *hreturned) { register Handle h; register long ctbytes; ctbytes = size; /*copy into a register*/ h = debuggetnewhandle (filename, linenumber, threadid, ctbytes, false); if (h == nil) { *hreturned = nil; memoryerror (); return (false); } clearhandle (h); *hreturned = h; return (true); } /*newclearhandle*/
extern int symbol_index(char *p, int hashcode) { /* Return the index in the symbs/svals/sflags/stypes arrays of symbol "p", creating a new symbol with that name if it isn't already there. New symbols are created with fundamental type UNKNOWN_CONSTANT_FT, value 0x100 (a 2-byte quantity in Z-machine terms) and type CONSTANT_T. The string "p" is undamaged. */ int32 new_entry, this, last; char *r; if (hashcode == -1) hashcode = hash_code_from_string(p); this = start_of_list[hashcode]; last = -1; do { if (this == -1) break; r = (char *)symbs[this]; new_entry = strcmpcis(r, p); if (new_entry == 0) return this; if (new_entry > 0) break; last = this; this = next_entry[this]; } while (this != -1); if (no_symbols >= MAX_SYMBOLS) memoryerror("MAX_SYMBOLS", MAX_SYMBOLS); if (last == -1) { next_entry[no_symbols]=start_of_list[hashcode]; start_of_list[hashcode]=no_symbols; } else { next_entry[no_symbols]=this; next_entry[last]=no_symbols; } if (symbols_free_space+strlen(p)+1 >= symbols_ceiling) { symbols_free_space = my_malloc(SYMBOLS_CHUNK_SIZE, "symbol names chunk"); symbols_ceiling = symbols_free_space + SYMBOLS_CHUNK_SIZE; /* If we've passed MAX_SYMBOL_CHUNKS chunks, we print an error message telling the user to increase SYMBOLS_CHUNK_SIZE. That is the correct cure, even though the error comes out worded inaccurately. */ if (no_symbol_name_space_chunks >= MAX_SYMBOL_CHUNKS) memoryerror("SYMBOLS_CHUNK_SIZE", SYMBOLS_CHUNK_SIZE); symbol_name_space_chunks[no_symbol_name_space_chunks++] = (char *) symbols_free_space; } strcpy((char *) symbols_free_space, p); symbs[no_symbols] = (int32 *) symbols_free_space; symbols_free_space += strlen((char *)symbols_free_space) + 1; svals[no_symbols] = 0x100; /* ###-wrong? Would this fix the unbound-symbol-causes-asm-error? */ sflags[no_symbols] = UNKNOWN_SFLAG; stypes[no_symbols] = CONSTANT_T; slines[no_symbols] = ErrorReport.line_number + 0x10000*ErrorReport.file_number; return(no_symbols++); }
boolean mergehandles (Handle h1, Handle h2, Handle *hmerged) { /* create a new handle which is the concatenation of two handles. the first four bytes of the new handle store the size of the first handle so the merged handle can be easily unpacked. 6/8/90 DW: modified so it could deal with nil handles. 10/7/91 dmb: try to merge result into the larger of the original handles, so that our memory overhead can be almost cut in half. 2.1b3 dmb: in the unusual case the we allocated a new handle, go ahead and use temporary memory if available. this might not always be ideal, but more often than not it will be best -- we're likely Saving, and tossing the merged handle soon. */ register Handle h; long sizefirsthandle; long sizesecondhandle; long sizemergedhandle; long storesizefirsthandle; register ptrbyte p; *hmerged = nil; /*default return value*/ sizefirsthandle = gethandlesize (h1); storesizefirsthandle = conditionallongswap (sizefirsthandle); sizesecondhandle = gethandlesize (h2); sizemergedhandle = sizeof (long) + sizefirsthandle + sizesecondhandle; if (sizefirsthandle > sizesecondhandle) { /*try using h1 for result*/ if (resizehandle (h1, sizemergedhandle)) { p = (ptrbyte) *h1; moveright (p, p + sizeof (long), sizefirsthandle); moveleft (&storesizefirsthandle, p, sizeof (long)); if (h2 != nil) moveleft (*h2, p + sizeof (long) + sizefirsthandle, sizesecondhandle); *hmerged = h1; disposehandle (h2); return (true); } } else if (h2 != nil) { /*try using h2 for result*/ if (resizehandle (h2, sizemergedhandle)) { p = (ptrbyte) *h2; moveright (p, p + sizeof (long) + sizefirsthandle, sizesecondhandle); moveleft (&storesizefirsthandle, p, sizeof (long)); if (h1 != nil) moveleft (*h1, p + sizeof (long), sizefirsthandle); *hmerged = h2; disposehandle (h1); return (true); } } /*resizing didn't work; try it the old way, using a newly-allocated handle*/ h = getnewhandle (sizemergedhandle, true); if (h == nil) { memoryerror (); disposehandle (h1); disposehandle (h2); return (false); } p = (ptrbyte) *h; moveleft (&storesizefirsthandle, p, sizeof (long)); p += sizeof (long); if (h1 != nil) moveleft (*h1, p, sizefirsthandle); if (h2 != nil) moveleft (*h2, p + sizefirsthandle, sizesecondhandle); *hmerged = h; disposehandle (h1); disposehandle (h2); return (true); } /*mergehandles*/
boolean unmergehandles (Handle hmerged, Handle *hfirst, Handle *hsecond) { /* split up a handle created by mergehandle. 3/12/91 dmb: rewrote so that we own hmerged; caller no longer diposes it. this allows us to reuse the handle to greatly reduce memory requirements. we could further optimize by reusing hmerged for the larger handle instead of always hsecond. also, avoid locking handles when we're trying to allocate potentially large chunks of memory. 2.1b3 dmb: newly-created handle is always ok as temporary memory */ register Handle h1 = nil, h2 = nil; register Handle h = hmerged; long ix; long sizefirsthandle, sizesecondhandle; *hfirst = *hsecond = nil; /*default return values*/ moveleft (*h, &sizefirsthandle, sizeof (long)); #ifdef PACKFLIPPED longswap (sizefirsthandle); #endif ix = sizeof (long); if (sizefirsthandle == 0) h1 = nil; else { h1 = getnewhandle (sizefirsthandle, true); if (h1 == nil) goto error; moveleft (*h + ix, *h1, sizefirsthandle); } ix += sizefirsthandle; sizesecondhandle = gethandlesize (h) - sizefirsthandle - sizeof (long); if (sizesecondhandle == 0) { h2 = nil; disposehandle (h); } else { h2 = h; /*second handle can safely re-use merged handle*/ moveleft (*h2 + ix, *h2, sizesecondhandle); sethandlesize (h2, sizesecondhandle); } *hfirst = h1; /*return handles to caller*/ *hsecond = h2; return (true); error: disposehandle (h); disposehandle (h1); disposehandle (h2); memoryerror (); return (false); } /*unmergehandles*/