Mail Archives: djgpp/2004/09/25/06:01:31
> Probably. So the way to unlock this mystery would be to find the
> shortest subset of the OP's original program that still exhibits this
> behavior, then post the source here.
I tried to reduce the program, what I noticed was, when I comment this
function it works as expected. The function and one more associated
function is as
follows, but I dont know whether it is still too big to post.
size_t getCmdLine (char *cmdLine, int leftMargin, int *hIndex)
{
int icmd = 0; /* Index of command line i.e current
cursor
position. 0 indicates first char
after the
left margin */
BOOL inInsMode = FALSE; /* Flag to indicate that INSERT
pressed */
int cmdLen = 0; /* Length of command line */
int key = 0; /* The key pressed */
int i;
char startRow; /* The starting row number */
int upArrowCnt = 0; /* Number of times Up arrow is pressed
*/
int tmp;
_setcursortype (_NORMALCURSOR); /* Initially normal cursor */
startRow = wherey () - 1; /* Wherey returns the current row -
starts
from 1, but the setCursor func
requires 0
based row */
/* In this function the current Row is not kept track, instead the
ScreenSetCursor function is used to position the cursor by
starting from
the start row, it can handle the case when the column is greater
than
NUM_COLS(defined as 80).*/
for (;;)
{
switch (key = getKey ()) /* getKey returns an integer value for
the key pressed */
{
case ENTER:
cmdLine[cmdLen] = '\0'; /* Nul terminate */
/* Move cursor to the end of cmd line, as editing may have
occured
somewhere inbetween */
i = ceil ((double) cmdLen / NUM_COLS);
ScreenSetCursor (startRow + i, 0);
return strlen (cmdLine);
case ARROWLEFT:
if (icmd)
icmd--; /* cannot go negative */
else
{
beep ();
break;
}
ScreenSetCursor (startRow, icmd + leftMargin);
break;
case ARROWRIGHT:
if (icmd < cmdLen)
icmd++; /* cannot move past the end of command
line */
else
{
beep ();
break;
}
ScreenSetCursor (startRow, icmd + leftMargin);
break;
case INSERT:
/* Change the cursor and set a flag */
if (inInsMode == TRUE)
{
_setcursortype (_NORMALCURSOR);
inInsMode = FALSE;
}
else
{
_setcursortype (_SOLIDCURSOR);
inInsMode = TRUE;
}
break;
case DELETE:
/* Start deleting from the cur pos of cursor */
for (i = icmd; i < cmdLen; i++)
cmdLine[i] = cmdLine[i + 1]; /* Move left by 1 */
cmdLine[cmdLen - 1] = '\0';
clearAndDispCmdLine (cmdLine, cmdLen, startRow, leftMargin);
/* Deletion doesn't change the index(icmd), but reduces len
*/
cmdLen--;
ScreenSetCursor (startRow, leftMargin + icmd);
break;
case HOME:
/* Move to the beginning of cmd line */
ScreenSetCursor (startRow, leftMargin);
icmd = 0;
break;
case END:
/* Move to the end of cmd line */
ScreenSetCursor (startRow, leftMargin + cmdLen);
icmd = cmdLen;
break;
case BACKSPACE:
/* At the beginning of the command cannot press BACKSPACE */
if (icmd == 0)
{
beep ();
break;
}
for (i = icmd - 1; i < cmdLen; i++)
cmdLine[i] = cmdLine[i + 1]; /* Move left by 1 */
cmdLine[cmdLen - 1] = '\0';
/* The len is reduced only after the display function is
called as
it should remove other trailing chars from screen */
clearAndDispCmdLine (cmdLine, cmdLen, startRow, leftMargin);
icmd--;
cmdLen--;
ScreenSetCursor (startRow, leftMargin + icmd);
break;
default:
/* Make place for the cur key by moving others(after cur
cursor pos)
to the right */
if (inInsMode == FALSE)
{
/* If editing somewhere in between the command, move
other
characters after cursor to the right */
if (icmd < cmdLen)
{
for (i = cmdLen + 1; i > icmd; i--)
cmdLine[i] = cmdLine[i - 1]; /* From end
copy prev
char */
}
cmdLine[icmd++] = key;
cmdLen++;
cmdLine[cmdLen] = '\0';
}
else
{
/* If inside insert mode - rewrite Don't change cmd len
if
cursor in between the string */
cmdLine[icmd++] = key;
/* if insertion at the end of string - len increases */
if (icmd > cmdLen)
cmdLen++;
cmdLine[cmdLen] = '\0';
}
clearAndDispCmdLine (cmdLine, cmdLen, startRow, leftMargin);
ScreenSetCursor (startRow, leftMargin + icmd);
break;
case ARROWUP:
/* Display prev command from cmd history */
tmp = *hIndex; /* Display the cmd at cur Index */
/* Can go UP MAX_HISTORY times */
if (tmp < 0 || upArrowCnt == MAX_HISTORY)
{
beep ();
break;
}
*hIndex = (*hIndex + MAX_HISTORY - 1) % MAX_HISTORY;
strcpy (cmdLine, cmdHistory[tmp]);
/* Send prev cmdLen to clear&disp func */
clearAndDispCmdLine (cmdLine, cmdLen, startRow, leftMargin);
cmdLen = strlen (cmdHistory[tmp]); /* Set the length,
after
display */
icmd = cmdLen;
upArrowCnt++;
break;
case ARROWDOWN:
/* Display next command from cmd history */
if (upArrowCnt)
{
tmp = (*hIndex + 1) % MAX_HISTORY;
strcpy (cmdLine, cmdHistory[tmp + 1]);
/* Prev command len is sent to the clr&disp func */
clearAndDispCmdLine (cmdLine, cmdLen, startRow,
leftMargin);
cmdLen = strlen (cmdHistory[tmp + 1]); /* Set the
length */
icmd = cmdLen;
*hIndex = tmp;
upArrowCnt--;
}
else
beep ();
break;
} /* end switch */
} /* end for (;;) */
} /* end function {getCmdLine} */
void clearAndDispCmdLine (char *cmdLine, int cmdLen, int startRow,
int leftMargin)
{
int i;
/* The length passed to this function is that before the editing is
done so
that if len number of spaces are put, it is ensured to clear the
whole
command line. */
ScreenSetCursor (startRow, leftMargin); /* move to start */
for (i = leftMargin; i < cmdLen + leftMargin; i++)
putchar (' '); /* clear the cur command line */
fflush (stdout);
ScreenSetCursor (startRow, leftMargin); /* move back */
printf ("%s", cmdLine);
}
I call this function like:
int i;
int hIndex = -1;
char cmd[160]={0};
i=printf ("command>");
getCmdLine (cmd,i,&hIndex);
Thanks.
- Raw text -