📄 xcsubs.c
字号:
/* xcsubs.c -- subroutines for XC This file uses 4-character tabstops*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h>#include <sys/timeb.h>#include <sys/stat.h>#include <ctype.h>#include <signal.h>#include <termcap.h>#include <setjmp.h>#include "xc.h"extern jmp_buf erret;char line[SM_BUFF], /* Input line */ word[LG_BUFF], /* Parsed word */ *wptr, *lptr, /* Word and line pointers */ *tgetstr(), *tgoto();int LI, /* One less than screen length in termcap entry */ CO; /* Screen width */speed_t ospeed; /* Used by termcap lib */static char tc[LG_BUFF]; /* termcap buffer */static char tbuf[LG_BUFF], *CD, *CF, *CL, *CM, *CN, *AE, *SE, *SO, *ME;char *CE, PC; /* used by termcap -- padding character */#define Tgetstr(code) ((s = tgetstr(code,&p)) ? s : "")#if !_POSIX_SOURCE#if !HAVE_STRSTR /* For those that do not have strstr() *//* Find first occurence of str2 in str1 and return a pointer to it */char *strstr(str1, str2)char *str1, *str2;{ register char *Sptr, *Tptr; int len = strlen(str1) -strlen(str2) + 1; if (*str2) for (; len > 0; len--, str1++){ if (*str1 != *str2) continue; for (Sptr = str1, Tptr = str2; *Tptr != '\0'; Sptr++, Tptr++) if (*Sptr != *Tptr) break; if (*Tptr == '\0') return str1; } return NIL(char);}#endif#if !HAVE_DUP2 /* For those that do not have dup2() */#include <fcntl.h>intdup2(oldfd, newfd)int oldfd, newfd;{ if (fcntl(oldfd, F_GETFL, 0) == -1) /* Valid file descriptor? */ return (-1); /* No, return an error */ close(newfd); /* Ensure newfd is closed */ return (fcntl(oldfd, F_DUPFD, newfd)); /* Dup oldfd into newfd */}#endif /* !DUP2 Thanks to Bill Allie CIS: 76703,2061 */#if !HAVE_MEMSET /* For those that do not have memset() */void *memset(dst, chr, len)char *dst;register chr, len;{ char *d; for (d = dst; --len >= 0; *d++ = chr) ; return dst;}#endif#endif /* not _POSIX_SOURCE */char *xc_strdup(const char *s){ return strcpy((char *) malloc(strlen(s) + 1), s);}time_tmtime(){ struct timeb tb; ftime(&tb); return 1000 * tb.time + tb.millitm;}voidmsecs(t)time_t t;{ time_t start; start = mtime(); while (mtime()-start < t) ;}/* Do the fork call, packaging the error return so that the caller need not have code for it.*/intforkem(){ int i; if ((i = fork()) < 0){ S1("XC: Fork failed"); longjmp(erret,1); } return i;}#if RLINEstatic char prmt_buf[SM_BUFF]; /* buffer used to build prompt */char *luxptr = NULL ; /* global used in editline library */#endifvoidprompt_user(const char *prmp_msg){#if RLINE sprintf(prmt_buf, "%s%s%s ", SO, prmp_msg , SE);#else fputc('\r', tfp); fputc('\n', tfp); show(-1, prmp_msg ); fputc(' ', tfp);#endif}/* Line input routine to be used when the raw terminal mode is in effect. */void getline(){ memset(line, 0, SM_BUFF);#if RLINE { const int scroll = FALSE ; lptr = readline( prmt_buf, scroll ) ; strcpy( line, lptr ); add_history( lptr); free( lptr) ; lptr = line ; }#else { char *ptr; int c, i = 0; lptr = line; while ((c = getchar()) != '\r' && c != '\n'){ if (c == BS){ if (i > 0){ ptr = unctrl(line[--i]); line[i] = '\0'; while (*ptr++ != '\0') fputs("\b \b",tfp); } else beep(); continue; } if (c == LK){ while (i > 0){ ptr = unctrl(line[--i]); while (*ptr++ != '\0') fputs("\b \b",tfp); } memset(line, 0, SM_BUFF); continue; } if (c == ('v' & 0x1f)) c = getchar(); line[i++] = c; fputs(unctrl(c), tfp); } }#endif}/* Parse the "line" array for a word */void getword(){ char quote, *ptr = word; short carat = FALSE, backslash = FALSE; wptr = lptr; memset(word, 0, SM_BUFF); while (isspace(*lptr)) lptr++; if (*lptr == '\0') return; if (*lptr == '\'' || *lptr == '\"') quote = *lptr++; else quote = '\0'; for (; *lptr != '\0'; lptr++){ if (quote){ if (*lptr == '\0'){ word[0] = '\0'; sprintf(Msg,"Unmatched quote: %s", line); S; s_exit(0); } if (*lptr == quote) break; } else if (!backslash && isspace(*lptr)) break; if (carat) *ptr++ = *lptr & 0x1f, carat = FALSE; else if (backslash) *ptr++ = *lptr, backslash = FALSE; else if (*lptr == '^') carat = TRUE; else if (*lptr == '\\') backslash = TRUE; else *ptr++ = *lptr; } lptr++;}/* Make the specified word all lower case */void lc_word(ptr)char *ptr;{ while (*ptr){ *ptr = tolower(*ptr); ptr++; }}/* Make the specified word all upper case */void uc_word(ptr)char *ptr;{ while (*ptr){ *ptr = toupper(*ptr); ptr++; }}void mode(flag)int flag;{ if (flag == NEWMODE) tcsetattr(0, TCSANOW, &newmode); else if (flag == SIGMODE) tcsetattr(0, TCSANOW, &sigmode); else if (flag == OLDMODE) tcsetattr(0, TCSANOW, &oldmode);}intbeep(){ putc(BEL,tfp); return SUCCESS;}/* initialize termcap stuff */void get_ttype(){ char *ttytype; char *Lines; char *Columns; char *p = tbuf; char *s; if (!(ttytype = getenv("TERM"))){ S1("TERM not set"); exit(6); } if (tgetent(tc, ttytype) != 1){ sprintf(Msg,"Can't load %s", ttytype); S; exit(7); } ospeed = cfgetospeed(&newmode); if (NULL != (Lines= getenv("LINES"))) LI = atoi(Lines); else LI = tgetnum("li"); if (LI == -1) LI = 24; LI--; if (NULL != (Columns= getenv("COLUMNS"))) CO = atoi(Columns); else CO = tgetnum("co"); if (CO == -1) CO = 80; if (!(s=Tgetstr("pc"))) PC = '\0'; else PC = *s; CD = Tgetstr("cd"); CE = Tgetstr("ce"); CL = Tgetstr("cl"); CM = Tgetstr("cm"); SE = Tgetstr("se"); SO = Tgetstr("so"); CF = Tgetstr("vi"); /* C[ursor of]F */ CN = Tgetstr("ve"); /* C[ursor o]N */ ME = Tgetstr("me"); /* all attributes off including alternate char set */ AE = Tgetstr("ae"); /* turn off alternate character set */#if HAVE_VT102 if(!strcmp(AE,"")) AE = "\017" ;#endif if(!strcmp(ME,"")) ME = SE ; if (CF && ! CN) CN = Tgetstr("CO");}/* putchr() is a routine to pass to tputs() */static intputchr(c) int c; { return putc(c,tfp); }voidreset_crt() { tputs(AE,1,putchr); tputs(ME,1,putchr); }voidcls() { tputs(CL,LI,putchr); }voidcur_on() { tputs(CN,1,putchr); }voidcur_off() { tputs(CF,1,putchr); }voidcl_line() { tputs(CE,1,putchr); }voidcl_end() { tputs(CD,LI,putchr); }void ttgoto(row, col) int row, col; { tputs(tgoto(CM, col, row),1,putchr); }void drawline(row, col, len)int row, col, len;{ ttgoto(row, col); while (len--) fputc('-', tfp);}void show(flag, str)short flag;char *str;{ if (!flag){ beep(); ttgoto(LI,0), cl_line(), ttgoto(LI,(CO-strlen(str))/2 -1); } if (flag == 2) putc('\n',tfp), putc('\r',tfp); tputs(SO,1,putchr); putc(' ',tfp); fputs(str, tfp); putc(' ',tfp); tputs(SE,1,putchr); if (flag > 0) putc('\n',tfp), putc('\r',tfp);}void show_abort() { S2("USER ABORT"); }FILE *isregfile(pathname)char *pathname;{ struct stat statbuf; if (stat(pathname,&statbuf) || (statbuf.st_mode & S_IFMT) != S_IFREG) return NIL(FILE); return fopen(pathname, "r");}FILE *openfile(name)char *name;{ FILE *fp = NIL(FILE); char *home, fullname[SM_BUFF], *path, *pathend; int pathlen; if ((path = getenv("XC_PATH"))){ while (!fp){ if (!(pathend = strchr(path, ':'))) pathlen = strlen(path); else pathlen = pathend - path; sprintf(fullname, "%.*s/%s", pathlen, path, name); fp = isregfile(fullname); path += pathlen; if (*path == '\0') break; path++; } } if (!fp) fp = isregfile(name); if (!fp){ if ((home = getenv("HOME"))) sprintf(fullname, "%s/%s", home, name); fp = isregfile(fullname); } if (!fp){ sprintf(fullname, "%s/%s", LIBDIR, name); fp = isregfile(fullname); } return fp;}/* Translate the character specified by 'c' to its ASCII display name. Note: This routine is specific to the ASCII character set.*/char *unctrl(c)int c;{ static char buffer[3], buf1[2]; memset(buffer, 0, 3); memset(buf1, 0, 2); if (c == 0x7f) strcpy(buffer, "^?"); else { if (iscntrl(c)) strcpy(buffer, "^"), c += '@'; buf1[0] = c; strcat(buffer, buf1); } return buffer;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -