static void displayTag2(int string, Context_Tag tag) { ctxt_info_t *info; info = &CTXT_INFO_STRUCT(tag); displayString(string, info->c_sizecur); }
static void displayTag1(int string, Context_Tag tag) { ctxt_info_t *info; info = &CTXT_INFO_STRUCT(tag); displayString(string, info->c_sizecur , info->c_nummin < info->c_nummax ? info->c_nummax - info->c_nummin : 0); }
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); }
static int scan (void * arg, word segm, word ofs) { Context_Tag tag; ctxt_info_t *info; (void)arg; assert(segm); assert(ofs != (word)-1); redo: if((tag = peekb(segm, ofs), ctxtIsInfoTag(tag))) { info = &CTXT_INFO_STRUCT(tag); if(peekb(segm, ofs + 1) == '=' && peekb(segm, ofs + 4) == 0) { /* status entry */ info->c_sizemax = peekw(segm, ofs + 2) & ~0x8001; } else { /* normal entry */ char far *p = MK_FP(segm, ofs + 1); unsigned num; for(num = 0; isxdigit(*p); ++p) { num <<= 8; if(isdigit(*p)) num |= *p & 0xf; else { assert(islower(*p)); num |= *p - 'a' + 10; } } if(*p == '=') { info->c_sizecur += env_varlen(segm, ofs); if(num < info->c_nummin) info->c_nummin = num; if(num > info->c_nummax) info->c_nummax = num; } else { /* Invalid entry -> remove to make room for useful stuff */ env_subVarOffset(segm, ofs); goto redo; } } } else if(tag > ' ') { /* Alias */ CTXT_INFO(CTXT_TAG_ALIAS, sizecur) += env_varlen(segm ,ofs); } return 0; /* proceed */ }
int ctxtPush(const Context_Tag tag, const char * const buf) { ctxt_info_t *info; ctxtCheckInfoTag(tag); assert(buf); info = &CTXT_INFO_STRUCT(tag); if(info->c_nummax == (unsigned)-1) { /* numbers will wrap -> recalculate them */ ctxtRenumberItems(tag); if(info->c_nummax == (unsigned)-1) return E_NoItems; } if(ctxtSet(tag, info->c_nummax + 1, buf) == E_None) return E_None; return E_NoMem; }
int ctxtPop(const Context_Tag tag, char ** const Xbuf) { ctxt_info_t *info; char *buf; ctxtCheckInfoTag(tag); assert(Xbuf); info = &CTXT_INFO_STRUCT(tag); while(info->c_nummax > info->c_nummin) switch(ctxtGet(1, tag, info->c_nummax--, &buf)) { case 0: /* OK */ *Xbuf = buf; return 1; case 1: /* no such entry */ break; /* --> ifgnore silently */ case 2: /* out of memory */ error_out_of_memory(); return 0; /* will case "context empty" message */ } /* Nothing in the stack ==> make sure it's consistent */ ctxtClear(tag); return 0; }
void displayPrompt(const char *pr) { #ifdef FEATURE_ENVVARS_IN_PROMPT char *buf = strdup(pr); char *expanded = malloc(MAX_INTERNAL_COMMAND_SIZE + sizeof(errorlevel) * 8); if(buf && expanded) { if(!expandEnvVars(buf, expanded)) error_line_too_long(); else pr = expanded; } free(buf); #endif while (*pr) { if(*pr != '$') { outc(*pr); } else { switch (toupper(*++pr)) { case 'A': outc('&'); break; case 'B': outc('|'); break; case 'C': outc('('); break; /* case 'D': see below */ case 'E': outc(27); break; /* Decimal 27 */ case 'F': outc(')'); break; case 'G': outc('>'); break; case 'H': outc(8); break; /* Decimal 8 */ case 'L': outc('<'); break; /* case 'M': outc('<'); break; remote name of current drive */ /* case 'N': see below */ /* case 'P': see below */ case 'Q': outc('='); break; case 'S': outc(' '); break; /* case 'T': see below */ /* case 'V': see below */ case '$': outc('$'); break; case '_': outc('\n'); break; /* case '+': see below */ case 'D': { char *p; if((p = curDateLong()) != 0) { outs(p); free(p); } break; } case 'N': { outc( ( getdisk() + 'A' ) ); break; } case 'P': { #ifdef FEATURE_LONG_FILENAMES char pathname[MAXDIR]; IREGS r; printf("%c:\\", getdisk() + 'A'); r.r_ax = 0x7147; r.r_dx = 0; r.r_si = FP_OFF(pathname); r.r_ds = FP_SEG(pathname); intrpt(0x21, &r); if(r.r_flags & 1 || r.r_ax == 0x7100) { r.r_ax = 0x4700; intrpt(0x21, &r); } if(r.r_flags & 1) break; outs(pathname); #else char *p; if((p = cwd(0)) != 0) { outs(p); free(p); } #endif break; } case 'T': { char *p; if((p = curTime()) != 0) { outs(p); free(p); } break; } case 'V': { /* #1776 fputs(shellname, stdout); */ printf("%s v%s", shellname, shellver); break; } case '+': /* Levels of PUSHD */ { #ifdef INCLUDE_CMD_PUSHD ctxt_info_t *info; int i; info = &CTXT_INFO_STRUCT(CTXT_TAG_DIRSTACK); assert(info); if((i = info->c_nummax) > 0) do { outc('+'); } while(--i); #endif } } } pr++; } #ifdef FEATURE_ENVVARS_IN_PROMPT free(expanded); #endif }
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; } }