memmove(ecp->cp, ecp->cp + ecp->o_clen, ecp->o_clen);
memcpy(ecp->cp, ecp->cp + ecp->o_clen, ecp->o_clen);
ex_load(sp)	SCR *sp;{	GS *gp;	EXCMD *ecp;	RANGE *rp;	F_CLR(sp, SC_EX_GLOBAL);	/*	 * Lose any exhausted commands.  We know that the first command	 * can't be an AGV command, which makes things a bit easier.	 */	for (gp = sp->gp;;) {		/*		 * If we're back to the original structure, leave it around,		 * but discard any allocated source name, we've returned to		 * the beginning of the command stack.		 */		if ((ecp = gp->ecq.lh_first) == &gp->excmd) {			if (F_ISSET(ecp, E_NAMEDISCARD)) {				free(ecp->if_name);				ecp->if_name = NULL;			}			return (0);		}		/*		 * ecp->clen will be 0 for the first discarded command, but		 * may not be 0 for subsequent ones, e.g. if the original		 * command was ":g/xx/@a|s/b/c/", then when we discard the		 * command pushed on the stack by the @a, we have to resume		 * the global command which included the substitute command.		 */		if (ecp->clen != 0)			return (0);		/*		 * If it's an @, global or v command, we may need to continue		 * the command on a different line.		 */		if (FL_ISSET(ecp->agv_flags, AGV_ALL)) {			/* Discard any exhausted ranges. */			while ((rp = ecp->rq.cqh_first) != (void *)&ecp->rq)				if (rp->start > rp->stop) {					CIRCLEQ_REMOVE(&ecp->rq, rp, q);					free(rp);				} else					break;			/* If there's another range, continue with it. */			if (rp != (void *)&ecp->rq)				break;			/* If it's a global/v command, fix up the last line. */			if (FL_ISSET(ecp->agv_flags,			    AGV_GLOBAL | AGV_V) && ecp->range_lno != OOBLNO)				if (db_exist(sp, ecp->range_lno))					sp->lno = ecp->range_lno;				else {					if (db_last(sp, &sp->lno))						return (1);					if (sp->lno == 0)						sp->lno = 1;				}			free(ecp->o_cp);		}		/* Discard the EXCMD. */		LIST_REMOVE(ecp, q);		free(ecp);	}	/*	 * We only get here if it's an active @, global or v command.  Set	 * the current line number, and get a new copy of the command for	 * the parser.  Note, the original pointer almost certainly moved,	 * so we have play games.	 */	ecp->cp = ecp->o_cp;	memmove(ecp->cp, ecp->cp + ecp->o_clen, ecp->o_clen);	ecp->clen = ecp->o_clen;	ecp->range_lno = sp->lno = rp->start++;	if (FL_ISSET(ecp->agv_flags, AGV_GLOBAL | AGV_V))		F_SET(sp, SC_EX_GLOBAL);	return (0);}