void ctxtRenumberItems(const Context_Tag tag) { ctxtCheckInfoTag(tag); assert(ctxtFromTag(tag) != CTXT_INVALID); CTXT_INFO(tag, nummin) = CTXT_INFO(tag, nummax) = 0; env_forAll(ctxtFromTag(tag), renumber, (void*)tag); }
int ctxtClear(const Context_Tag tag) { ctxt_info_t *info; ctxtCheckInfoTag(tag); assert(ctxtFromTag(tag) != CTXT_INVALID); /* Clear the useage information */ info = &CTXT_INFO_STRUCT(tag); info->c_sizecur = 0; info->c_nummax = info->c_nummin= 0; /* Clear the items within the context */ return env_forAll(ctxtFromTag(tag), clear, (void*)tag); }
char far*ctxtAddress(const Context_Tag tag, const unsigned num) { char name[CTXT_ITEMNAME_LENGTH]; word ofs, segm; ctxtMkItemName(name, tag, num); segm = ctxtFromTag(tag); assert(segm && segm != CTXT_INVALID); if((ofs = env_findVar(segm, name)) != (word)-1) return MK_FP(segm, ofs + strlen(name) + 1); return 0; }
int chgCtxt(const Context_Tag tag, const char * const name, const char * const value) { word segm, ofs; int newlen; assert(name); ctxtCheckInfoTag(tag); segm = ctxtFromTag(tag); assert(segm); newlen = value? strlen(name) + strlen(value) + 2: 0; if((ofs = env_findVar(segm, name)) != (word)-1) newlen -= env_varlen(segm, ofs); /* Make sure the context has enough room to add the value to */ if(newlen > 0) { /* contents size will grow */ ctxt_info_t *hinfo, *dinfo; /* aliases may not exceed sizemax */ if(tag == CTXT_TAG_ALIAS) { if(CTXT_INFO(CTXT_TAG_ALIAS, sizemax) - CTXT_INFO(CTXT_TAG_ALIAS, sizecur) < newlen) { error_alias_out_of_memory(); return E_NoMem; } } /* Otherwise a removeable entry is removed; those are: oldest item of history oldest item of dirstack */ hinfo = segm == ctxtFromTag(CTXT_TAG_HISTORY) ? &CTXT_INFO_STRUCT(CTXT_TAG_HISTORY): 0; dinfo = segm == ctxtFromTag(CTXT_TAG_DIRSTACK) ? &CTXT_INFO_STRUCT(CTXT_TAG_DIRSTACK): 0; while(env_freeCount(segm) < newlen) { /* There are two structures that can shrink: history & dirstack */ if(hinfo && (hinfo->c_sizecur <= hinfo->c_sizemax /* inconsitency of redundant info */ || hinfo->c_nummin >= hinfo->c_nummax)) /* in range -> ignore */ hinfo = 0; if(dinfo && (dinfo->c_sizecur <= dinfo->c_sizemax /* inconsitency of redundant info */ || dinfo->c_nummin >= dinfo->c_nummax)) /* in range -> ignore */ dinfo = 0; if(hinfo && dinfo) { /* Choose one */ if(weight(hinfo) < weight(dinfo)) ctxtGet(1, CTXT_TAG_DIRSTACK, ++dinfo->c_nummin, 0); else ctxtGet(1, CTXT_TAG_HISTORY, ++hinfo->c_nummin, 0); } else if(dinfo) ctxtGet(1, CTXT_TAG_DIRSTACK, ++dinfo->c_nummin, 0); else if(hinfo) ctxtGet(1, CTXT_TAG_HISTORY, ++hinfo->c_nummin, 0); else { /* no space left */ error_context_out_of_memory(); return E_NoMem; } } } /* return values 1 and 3 are OK */ switch(env_change(segm, name, value)) { case 2: /* variable to delete not found <-> no problem */ case 1: case 3: /* var replaced | deleted | inserted ==> OK */ CTXT_INFO(tag, sizecur) += newlen; return 0; case 0: /* Cannot insert */ dprintf(("chgCtxt(): out-of-mem shouldn't occure here!\n")); error_context_out_of_memory(); return E_NoMem; default: return E_Syntax; } }