void aliasexpand(char *cmd, int maxlen) { char *cp; unsigned m; unsigned len; short expanded; TAlias *ptr; assert(cmd); if (++useFlag == 0) /* (int) overflow */ { /* The useFlag specifies, if the particular ALIAS is used by the _current_ expand. To avoid to clear the flag each time when to expand a string a different flag value is used each time. */ if((ptr = first) != NULL) /* reset all values to be sure we hit no old one */ do ptr->used = 0; while((ptr = ptr->next) != NULL); useFlag = 1; } cp = ltrim(cmd); /* skip leading whitespaces */ /* Check if the user disabled alias expansion */ if (*cp == '*') { cp = ltrim(cp + 1); memmove(cmd, cp, strlen(cp) + 1); return; } /* this allows to case-sensitively compare strings, which is much faster */ partstrlower(cp); /* to simplify the loop below */ memmove(cmd, cp, strlen(cp) + 1); /* substitution loop */ /* Empty alias list --> no loop */ if(first) do { expanded = 0; ptr = first; do { assert(ptr); assert(ptr->name); assert(ptr->subst); len = strlen(ptr->name); if ((isspace(cmd[len]) || cmd[len] == '\0') /* end of word */ && !strncmp(cmd, ptr->name, len) /* line begins with alias */ && ptr->used != useFlag) /* this alias unused */ { m = strlen(ptr->subst); if (strlen(cmd) - len + m > maxlen) { error_command_too_long(); cmd[0] = '\0'; /* the parser won't cause any problems with an empty line */ return; } else { /* adjust the remaining part within the command line */ memmove(&cmd[m], &cmd[len], strlen(&cmd[len]) + 1); /* prepend the alias substitution */ memcpy(&cmd[0], &ptr->subst[0], m); ptr->used = useFlag; expanded = 1; } } } while((ptr = ptr->next) != NULL); } while(expanded); }
void aliasexpand(char * const cmd, const int maxlen) { char *hbuf; /* work buffer */ char *cp, *p; unsigned ofs, *expanded, *he; int i, numExpanded; assert(cmd); assert(strlen(cmd) < maxlen); if((hbuf = malloc(maxlen)) == 0) { error_out_of_memory(); return; } numExpanded = 0; expanded = 0; redo: /* iteration to expand all aliases */ cp = ltrimcl(cmd); /* skip leading whitespaces */ /* Check if the user disabled alias expansion */ if(*cp == '*') { memmove(cmd, cp + 1, strlen(cp)); goto errRet; } /* Get the name of this command */ for(p = hbuf; is_fnchar(*cp) || *cp == '.';) *p++ = *cp++; if(p == hbuf || is_pathdelim(*cp) || is_quote(*cp)) /* no name || part of path -> no alias */ goto errRet; *p = 0; StrFUpr(hbuf); /* all aliases are uppercased */ if((ofs = env_findVar(ctxtAlias, hbuf)) == (unsigned)-1) /* not found -> no alias */ goto errRet; /* Prevent recursion by recording the offset of the found variable */ for(i = 0; i < numExpanded; ++i) if(expanded[i] == ofs) /* already used -> ignore */ goto errRet; if((he = realloc(expanded, ++numExpanded)) == 0) { error_out_of_memory(); goto errRet; } expanded = he; expanded[numExpanded - 1] = ofs; /************ Expand the command line "cp" with the alias at MK_FP(ctxtAlias, ofs) ***********************/ ofs += strlen(hbuf) + 1; /* advance to value */ if(_fstrlen(MK_FP(ctxtAlias, ofs)) < maxlen - strlen(cp)) { /* prepend alias value to remaining command line */ _fstrcpy(TO_FP(hbuf), MK_FP(ctxtAlias, ofs)); strcat(hbuf, cp); assert(strlen(hbuf) < maxlen); strcpy(cmd, hbuf); goto redo; /* next expansion */ } error_command_too_long(); errRet: /* return to caller */ free(expanded); free(hbuf); }