📄 ledlib.c
字号:
int led_id, /* ID returned by ledOpen */ int inFd, /* new input fd (NONE = no change) */ int outFd, /* new output fd (NONE = no change) */ int histSize /* new history list size (NONE = no change), (0 = display) */ ) { FAST LED_ID ledId = (LED_ID)led_id; if (inFd >= 0) ledId->inFd = inFd; if (outFd >= 0) ledId->outFd = outFd; if (histSize == 0) histAll (ledId); if (histSize > 0) histInit (ledId, histSize); }/********************************************************************************* setPreempt - set function to use next*/LOCAL void setPreempt ( FAST FUNCPTR *catchFunc, FAST FUNCPTR func ) { *catchFunc = func; }/********************************************************************************* preempt - perform preempt function if set** If <catchFunc> is non-NULL then it is called using the* remaining arguments.** RETURNS:* result of preempt function, or* 1 if no function called*/LOCAL int preempt ( FAST FUNCPTR *catchFunc, /* preempting function */ char ch, /* arguments to be */ char *curLn, /* passed to th */ int *curPs, /* routine ... */ int *number, LED_ID ledId ) { FUNCPTR tmpFunc = *catchFunc; if (*catchFunc == (FUNCPTR)NULL) return (1); /* no function called */ /* clear the catch */ *catchFunc = (FUNCPTR) NULL; return ((*tmpFunc) (ch, curLn, curPs, number, ledId)); }/********************************************************************************* redraw - redraw line** From the previous line and position (oldLn & lastPs) redraw line to* reflect reality (curLn & curPs).** Operation: compare new line with previous line,* optimize the number of characters redrawn and cursor motion.*/LOCAL void redraw ( int outFd, char *oldLn, int lastPs, char *curLn, int *curPs ) { FAST int ok1Ps; /* line is the same up to this position */ FAST int ok2Ps; /* line is the same from the far end to here */ /* find first difference */ for (ok1Ps = 0; curLn [ok1Ps] == oldLn [ok1Ps] && curLn [ok1Ps] != EOS; ok1Ps++) ; /* find first difference from the far end if same length */ if (strlen (curLn) == strlen (oldLn)) { for (ok2Ps = strlen (curLn); curLn [ok2Ps] == oldLn [ok2Ps] && ok2Ps > 0; ok2Ps--) ; if (ok2Ps < strlen (curLn)) ok2Ps++; } else ok2Ps = strlen (curLn); /* line is bad before cursor position */ if (ok1Ps < lastPs) { /* back up */ (void)writen (outFd, '\b', lastPs - ok1Ps); /* redraw line from ok1Ps to the good portion */ (void)writex (outFd, &curLn [ok1Ps], ok2Ps - ok1Ps); lastPs = ok2Ps; } /* line is bad after cursor position */ else if (ok2Ps > lastPs) { /* draw line from lastPs to the good portion */ (void)writex (outFd, &curLn [lastPs], ok2Ps - lastPs); lastPs = ok2Ps; } /* line is bad at cursor position */ else if (ok2Ps == lastPs && lastPs < strlen (curLn)) { /* draw single character */ (void)writex (outFd, &curLn [lastPs], 1); lastPs++; } /* blank out remaining junk if we're at the end of the line */ if (lastPs == strlen (curLn)) { int i = strlen (oldLn) - strlen (curLn); if (i > 0) { (void)writen (outFd, ' ', i); (void)writen (outFd, '\b', i); } } /* now get cursor right */ if (lastPs > *curPs) (void)writen (outFd, '\b', lastPs - *curPs); else (void)writex (outFd, &curLn [lastPs], *curPs - lastPs); }/* * Definitions used through remaining routines. */#define CUR (curLn [*curPs])#define PREV (curLn [*curPs-dir])#define NEXT (curLn [*curPs+dir])#define INC (*curPs+=dir)#define ispunct_nospc(c) (ispunct(c) && !isspace(c))#define igpunct(c) (ignorePunct ? ispunct_nospc(c) : FALSE)#define isword(c) (isalpha(c) || isdigit(c) || index("*?_-.[]~=",c))/********************************************************************************* completeName - complete partial symbol name at current position** RETURNS: TRUE if symbol name is completed in any way, otherwise FALSE.*/LOCAL BOOL completeName ( FAST char *curLn, int *curPs ) { CMP_ARG arg; char saveLn [LINE_LEN+1]; char string [100]; int count; int dir = FORWARD; int startPs = *curPs; int endPs = *curPs; /* operation: * isolate begin and end of string at current position, * if begin and end are equal then no string - return error, * call support routine to see if string is in symbol table, * if not then - return error * otherwise determine symbol up to the last unambiguous character, * then insert extra characters - return ok. */ while (isalpha((int)curLn [startPs-1]) || isdigit((int)curLn[startPs-1]) || curLn [startPs-1] == '_') { startPs--; } while (isalpha ((int)curLn [endPs]) || isdigit ((int)curLn [endPs]) || curLn [endPs] == '_') { endPs++; } if (endPs == startPs) return (FALSE); if (curLn [startPs] == '_') startPs++; /* ignore leading underscore */ strncpy (string, &curLn [startPs], endPs - startPs); string [endPs - startPs] = EOS; arg.name = string; /* search string */ arg.nameLen = strlen (string); /* optimization */ arg.count = 0; /* reset to zero */ symEach (sysSymTbl, (FUNCPTR)findName, (int)&arg); count = arg.count; /* keep looking while match is ambiguous */ while (arg.count > 1 && count == arg.count) { if (strcmp (arg.name, arg.match) == 0) { /* just in case more than one entry with same name, * but hope this first match is different, oh well. */ count = 1; break; } arg.count = 0; /* reset to zero */ arg.nameLen++; /* optimization */ strncpy (arg.name, arg.match, arg.nameLen); symEach (sysSymTbl, (FUNCPTR)findName, (int)&arg); } /* have to admit we didn't find anything */ if (count == 0) return (FALSE); if (count > 1) { /* ambiguous match up 'til second last position */ arg.name [arg.nameLen - 1] = EOS; arg.match = arg.name; } /* insert new string, don't forget to save original line */ if ((endPs - startPs) + strlen (curLn) + strlen (arg.match) < LINE_LEN) { strcpy (saveLn, curLn); strcpy (&curLn [startPs], arg.match); strcat (curLn, &saveLn [endPs]); if (isalpha((int)CUR) || isdigit((int)CUR) || CUR == '_') { while (isalpha((int)NEXT) || isdigit((int)NEXT) || NEXT == '_') { INC; } } } return (TRUE); }/********************************************************************************* findName - support routine for completeName** This routine is called for each string in the symbol table.** RETURNS: TRUE always.** ARGSUSED*/LOCAL BOOL findName ( char *name, /* name of this entry */ char *value, /* symbol table junk */ SYM_TYPE type, /* symbol table junk */ CMP_ARG *arg /* what to match, etc. */ ) { if (name[0] == '_') name++; /* ignore leading underscore */ if (strncmp (name, arg->name, arg->nameLen) == 0) { if (++arg->count == 1 || strlen (name) > strlen (arg->match)) arg->match = name; } return (TRUE); }/********************************************************************************* search - move from current position to matched character position** RETURNS: new ptr to current position.*/LOCAL void search ( FAST BOOL ignorePunct, /* ignore punctuation or not */ FAST BOOL endOfWord, /* stop at end of word, or when BACKWARD stop at beginning */ char *curLn, int *curPs, int dir /* direction to search */ ) { /* make sure we're not already at limits */ if (CUR == EOS || NEXT == EOS) return; if (isspace ((int)CUR)) { /* just get to a non-space */ while (NEXT != EOS && isspace ((int)CUR)) INC; } else if (ispunct ((int)CUR)) { /* just get to the next/previous word */ while (NEXT != EOS && !isalnum ((int)CUR)) INC; } else if (endOfWord || dir == BACKWARD) { /* while space coming */ while (isspace((int)NEXT)) INC; /* maybe we've got to punctuation */ if (ispunct_nospc ((int)NEXT)) { do { INC; } while (NEXT != EOS && ispunct_nospc ((int)NEXT)); /* while we're on a space advance/retreat */ while (NEXT != EOS && isspace ((int)CUR)) INC; return; } /* get to end/beginning of word but not past */ while (NEXT != EOS && (isalnum ((int)NEXT) || igpunct(((int)NEXT)))) INC; } else { /* get past end/beginning of word */ do { INC; } while (NEXT != EOS && (isalnum ((int)CUR) || igpunct((int)CUR))); /* while we're on a space advance/retreat */ while (NEXT != EOS && isspace ((int)CUR)) INC; } }/********************************************************************************* find - a particualar character** RETURNS:* TRUE if `ch' found, or* FALSE if end of line reached first.*/LOCAL BOOL find ( char ch, /* what to find */ char *curLn, int *curPs, int dir /* direction to search */ ) { if (CUR == EOS || NEXT == EOS) return (FALSE); do { INC; } while (CUR != ch && NEXT != EOS); return (CUR == ch); }/********************************************************************************* findFwd - find <ch> some <number> of times looking forwards*/LOCAL STATUS findFwd ( FAST char ch, char *curLn, int *curPs, int *number ) { while (find (ch, curLn, curPs, FORWARD) && --*number > 0) ; *number = 0; return (OK); }/********************************************************************************* findBwd - find <ch> some <number> of times looking backwards*/LOCAL STATUS findBwd ( char ch, char *curLn, int *curPs, int *number ) { while (find (ch, curLn, curPs, BACKWARD) && --*number > 0) ; *number = 0; return (OK); }/********************************************************************************* change - change as specified by (w/W/e/E/sp/l/h/c/$/0)*/LOCAL STATUS change ( FAST char ch, char *curLn, int *curPs, int *number, LED_ID ledId ) { STATUS status = OK; switch (ch) { case '0': case ' ': case 'l': case 'h': case 'w': case 'W': case 'e': case 'E': case 'b': case 'B': ledId->cmdMode = FALSE; status = deletec (ch, curLn, curPs, number, ledId); break; case 'c': *curPs = 0; /* drop through */ case '$': ledId->cmdMode = FALSE; CUR = EOS; break; default: status = ERROR; break; } return (status); }/********************************************************************************* deletec - delete as specified by (w/W/e/E/b/B/sp/l/h/d/$/0) <number> of times** RETURNS: OK or ERROR*/LOCAL STATUS deletec ( FAST char ch, char *curLn, int *curPs, int *number, LED_ID ledId ) { STATUS status = OK; FAST int tmp = *curPs; FAST int i = 0; int dir = (ch == 'b' || ch == 'B' || ch == 'h') ? BACKWARD : FORWARD; BOOL endOfWord = ch != 'w' && ch != 'W'; int fudge; /* fudge factor? */ do { switch (ch) { case 'w': case 'W': /* ignore punctuation */ case 'e': case 'E': /* ignore punctuation */ case 'b':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -