Ejemplo n.º 1
0
static char *
CompletionFunction(const char *text, int state)
{
	char *cp;
	char *cmdstart;
	ArgvInfo ai;
	int bUsed;
	CommandPtr cmdp;
	static int flags;

	if (state == 0) {
		flags = -1;
		cmdstart = FindStartOfCurrentCommand();
		if (cmdstart == NULL)
			return NULL;
		if (HaveCommandNameOnly(cmdstart)) {
			flags = -2;	/* special case */
			cp = CommandCompletionFunction(text, state);
			return cp;
		}

		(void) memset(&ai, 0, sizeof(ai));
		bUsed = MakeArgv(cmdstart, &ai.cargc, ai.cargv,
			(int) (sizeof(ai.cargv) / sizeof(char *)),
			ai.argbuf, sizeof(ai.argbuf),
			ai.noglobargv, 1);
		if (bUsed <= 0)
			return NULL;
		if (ai.cargc == 0)
			return NULL;

		cmdp = GetCommandByName(ai.cargv[0], 0);
		if (cmdp == kAmbiguousCommand) {
			return NULL;
		} else if (cmdp == kNoCommand) {
			return NULL;
		}
		flags = cmdp->flags;
	}
	if (flags == (-2)) {
		cp = CommandCompletionFunction(text, state);
		return cp;
	}
	if (flags < 0)
		return NULL;
	if ((flags & (kCompleteLocalFile|kCompleteLocalDir)) != 0) {
		cp = gl_local_filename_completion_proc(text, state);
		return cp;
	} else if ((flags & kCompleteRemoteFile) != 0) {
		gl_filename_quoting_desired = 1;
		cp = RemoteFileCompletionFunction(text, state);
		return cp;
	} else if ((flags & kCompleteRemoteDir) != 0) {
		gl_filename_quoting_desired = 1;
		cp = RemoteDirCompletionFunction(text, state);
		return cp;
	} else if ((flags & kCompleteBookmark) != 0) {
		cp = BookmarkCompletionFunction(text, state);
		return cp;
	} else if ((flags & kCompletePrefOpt) != 0) {
		cp = PrefOptCompletionFunction(text, state);
		return cp;
	}
	return NULL;
}	/* CompletionFunction */
Ejemplo n.º 2
0
ZChatCmd* ZChatCmdManager::MakeArgv(char* szLine, ZChatCmdArgvInfo* pAI)
{
	int nLen = (int)strlen(szLine);
	if (nLen >= 2048) NULL;

	char szBuffer[2048];
	strcpy(szBuffer, szLine);

	// 문자열 끝의 스페이스 제거
	for (int pos = nLen-1; pos >= 0; pos--)
	{
		if (IsSpace(szBuffer[pos])) szBuffer[pos] = '\0';
		else break;
	}


	ZChatCmd* pCmd = NULL;

	int c;
	char* scp;
	char* dcp;
	char* dlim;
	char* arg;

	int nArgcMax, nCmdArgcMax;
	nCmdArgcMax = nArgcMax = (sizeof(pAI->cargv) / sizeof(char*));
	

	scp = szBuffer;
	dcp = pAI->argbuf;
	dlim = dcp + sizeof(pAI->argbuf) - 1;

	for (pAI->cargc = 0; pAI->cargc < nArgcMax; )
	{
		for ( ; ; scp++)
		{
			c = *scp;
			if (IsSpace(c)) continue;

			if ( (c == '\0') || (c == '\n') )
			{
				pAI->cargv[pAI->cargc] = NULL;
				return pCmd;
			}
			break;
		}
		arg = dcp;
		pAI->cargv[pAI->cargc] = arg;
		(pAI->cargc)++;

		for ( ; ; )
		{
			c = *scp;
			if ( (c == '\0') || (c == '\n')) break;

			// 마지막 인자는 무조건 문자열 마지막까지의 값이다.
			if (pAI->cargc != nCmdArgcMax)
			{
				if (IsSpace(c)) break;
			}
			scp++;

			// 작은 따옴표 처리
			if (c == '\'') 
			{
//				for ( ; ; ) 
//				{
//					c = *scp++;

					// 따옴표가 하나만 있으면 널 리턴
//					if (c == '\0') return NULL;

//					if (c == '\'') break;

					// 너무 길다
//					if (dcp >= dlim) return NULL;

					*dcp++ = c;
//				}
			} 
			else if (c == '"')	// 큰따옴표처리
			{	
//				for ( ; ; ) 
//				{
//					c = *scp++;
//					if (c == '\0') return NULL;
//					if (c == '"') break;

//					if (dcp >= dlim) return NULL;
					*dcp++ = c;
//				}
			}
            else 
			{
				if (dcp >= dlim) return NULL;
				*dcp++ = c;
			}
		}

		*dcp++ = '\0';

		if (pAI->cargc == 1)
		{
			pCmd = GetCommandByName(pAI->cargv[0]);
			if (pCmd != NULL) 
			{
				if (pCmd->GetMaxArgs() != ARGVNoMin)
				{
					nCmdArgcMax = pCmd->GetMaxArgs() + 1;
				}
			}
			else
			{
				return NULL;
			}
		}
	}
	
	return NULL;
}
Ejemplo n.º 3
0
/* Parse a command line into an array of arguments. */
int
MakeArgv(char *line, int *cargc, const char **cargv, int cargcmax, char *dbuf, size_t dbufsize, int *noglobargv, int readlineHacks)
{
	int c;
	int retval;
	char *dlim;
	char *dcp;
	char *scp;
	char *arg;

	*cargc = 0;
	scp = line;
	dlim = dbuf + dbufsize - 1;
	dcp = dbuf;

	for (*cargc = 0; *cargc < cargcmax; ) {
		/* Eat preceding junk. */
		for ( ; ; scp++) {
			c = *scp;
			if (c == '\0')
				goto done;
			if (isspace(c))
				continue;
			if ((c == ';') || (c == '\n')) {
				scp++;
				goto done;
			}
			break;
		}

		arg = dcp;
		cargv[*cargc] = arg;
		noglobargv[*cargc] = 0;
		(*cargc)++;

		/* Special hack so that "!cmd" is always split into "!" "cmd" */
		if ((*cargc == 1) && (*scp == '!')) {
			if (scp[1] == '!') {
				scp[1] = '\0';
			} else if ((scp[1] != '\0') && (!isspace((int) scp[1]))) {
				cargv[0] = "!";
				scp++;
				arg = dcp;
				cargv[*cargc] = arg;
				noglobargv[*cargc] = 0;
				(*cargc)++;
			}
		}

		/* Add characters to the new argument. */
		for ( ; ; ) {
			c = *scp;
			if (c == '\0')
				break;
			if (isspace(c))
				break;
			if ((c == ';') || (c == '\n')) {
				break;
			}

			scp++;

			if (c == '\'') {
				for ( ; ; ) {
					c = *scp++;
					if (c == '\0') {
						if (readlineHacks != 0)
							break;
						/* Syntax error */
						(void) fprintf(stderr, "Error: Unbalanced quotes.\n");
						return (-1);
					}
					if (c == '\'')
						break;

					/* Add char. */
					if (dcp >= dlim)
						goto toolong;
					*dcp++ = c;

					if (strchr(kGlobChars, c) != NULL) {
						/* User quoted glob characters,
						 * so mark this argument for
						 * noglob.
						 */
						noglobargv[*cargc - 1] = 1;
					}
				}
			} else if (c == '"') {
				for ( ; ; ) {
					c = *scp++;
					if (c == '\0') {
						if (readlineHacks != 0)
							break;
						/* Syntax error */
						(void) fprintf(stderr, "Error: Unbalanced quotes.\n");
						return (-1);
					}
					if (c == '"')
						break;

					/* Add char. */
					if (dcp >= dlim)
						goto toolong;
					*dcp++ = c;

					if (strchr(kGlobChars, c) != NULL) {
						/* User quoted glob characters,
						 * so mark this argument for
						 * noglob.
						 */
						noglobargv[*cargc - 1] = 1;
					}
				}
			} else
#if defined(WIN32) || defined(_WINDOWS)
				if (c == '|') {
#else
				if (c == '\\') {
#endif
				/* Add next character, verbatim. */
				c = *scp++;
				if (c == '\0')
					break;

				/* Add char. */
				if (dcp >= dlim)
					goto toolong;
				*dcp++ = c;
			} else {
				/* Add char. */
				if (dcp >= dlim)
					goto toolong;
				*dcp++ = c;
			}
		}

		*dcp++ = '\0';
	}

	(void) fprintf(stderr, "Error: Argument list too long.\n");
	*cargc = 0;
	cargv[*cargc] = NULL;
	return (-1);

done:
	retval = (int) (scp - line);
	cargv[*cargc] = NULL;
	return (retval);

toolong:
	(void) fprintf(stderr, "Error: Line too long.\n");
	*cargc = 0;
	cargv[*cargc] = NULL;
	return (-1);
}	/* MakeArgv */




static int
DoCommand(const ArgvInfoPtr aip)
{
	CommandPtr cmdp;
	int flags;
	int cargc, cargcm1;

	cmdp = GetCommandByName(aip->cargv[0], 0);
	if (cmdp == kAmbiguousCommand) {
		(void) printf("%s: ambiguous command name.\n", aip->cargv[0]);
		return (-1);
	} else if (cmdp == kNoCommand) {
		(void) printf("%s: no such command.\n", aip->cargv[0]);
		return (-1);
	}

	cargc = aip->cargc;
	cargcm1 = cargc - 1;
	flags = cmdp->flags;

	if (((flags & kCmdMustBeConnected) != 0) && (gConn.connected == 0)) {
		(void) printf("%s: must be connected to do that.\n", aip->cargv[0]);
	} else if (((flags & kCmdMustBeDisconnected) != 0) && (gConn.connected != 0)) {
		(void) printf("%s: must be disconnected to do that.\n", aip->cargv[0]);
	} else if ((cmdp->minargs != kNoMin) && (cmdp->minargs > cargcm1)) {
		PrintCmdUsage(cmdp);
	} else if ((cmdp->maxargs != kNoMax) && (cmdp->maxargs < cargcm1)) {
		PrintCmdUsage(cmdp);
	} else {
		(*cmdp->proc)(cargc, aip->cargv, cmdp, aip);
	}
	return (0);
}	/* DoCommand */