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); }
char *aliasexpand(const char * const Xcmd) { char *cmd; /* work buffer */ char *cp, *name, *alias; unsigned ofs, *expanded, *he; int i, numExpanded, newlen, len; assert(Xcmd); if((cmd = estrdup(Xcmd)) == 0) return (char*)Xcmd; numExpanded = 0; expanded = 0; name = 0; redo: /* iteration to expand all aliases */ cp = ltrimcl(cmd); /* skip leading whitespaces */ /* Check if the user disabled alias expansion */ if(*cp == '*') { *cp = ' '; goto errRet; } myfree(name); /* Get the name of this command */ if((name = getCmdName(&(const char*)cp)) == 0 || is_pathdelim(*cp)) goto errRet; StrFUpr(name); /* all aliases are uppercased */ if((ofs = env_findVar(ctxtAlias, name)) == (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) ***********************/ alias = ctxtP(ctxtAlias, ofs + strlen(name) + 1); /* Check that the total command line won't overflow MAX_INT */ if((newlen = strlen(alias)) >= 0 && (len = strlen(cp)) >= 0 && ++len > 0 && newlen + len > 0) { int dst = cp - cmd; /* destination index within cmd[] */ if(newlen > dst) { /* need to increase the buffer */ char *p; if((p = realloc(cmd, newlen + len)) == 0) goto errRet1; cmd = p; } /* else ignore to shrink the buffer; it will be done automatically with the next ALIAS expansion or when this function returns */ assert(len); if(newlen != dst) /* need to move the command tail */ memmove(&cmd[newlen], &cmd[dst], len); /* prepend alias value to remaining command line */ memcpy(cmd, alias, newlen); goto redo; /* next expansion */ } errRet1: error_long_internal_line(); errRet: /* return to caller */ myfree(expanded); myfree(name); return StrTrim(cmd); }