figlet.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,077 行 · 第 1/4 页
C
2,077 行
****************************************************************************/void splitline(){ int i,gotspace,lastspace,len1,len2; inchr *part1,*part2; part1 = (inchr*)myalloc(sizeof(inchr)*(inchrlinelen+1)); part2 = (inchr*)myalloc(sizeof(inchr)*(inchrlinelen+1)); gotspace = 0; for (i=inchrlinelen-1;i>=0;i--) { if (!gotspace && inchrline[i]==' ') { gotspace = 1; lastspace = i; } if (gotspace && inchrline[i]!=' ') { break; } } len1 = i+1; len2 = inchrlinelen-lastspace-1; for (i=0;i<len1;i++) { part1[i] = inchrline[i]; } for (i=0;i<len2;i++) { part2[i] = inchrline[lastspace+1+i]; } clearline(); for (i=0;i<len1;i++) { addchar(part1[i]); } printline(); for (i=0;i<len2;i++) { addchar(part2[i]); } free(part1); free(part2);}/**************************************************************************** handlemapping Given an input character (type inchr), executes re-mapping commands read from control files. Returns re-mapped character (inchr).****************************************************************************/inchr handlemapping(c)inchr c;{ comnode *cmptr; cmptr=commandlist; while (cmptr!=NULL) { if (cmptr->thecommand ? (c >= cmptr->rangelo && c <= cmptr->rangehi) : 0) { c += cmptr->offset; while(cmptr!=NULL ? cmptr->thecommand : 0) { cmptr=cmptr->next; } } else { cmptr=cmptr->next; } } return c;}/**************************************************************************** Agetchar Replacement to getchar(). Acts exactly like getchar if -A is NOT specified, else obtains input from All remaining command line words.****************************************************************************/int Agetchar(){ extern int optind; /* current argv[] element under study */ static AgetMode = 0; /* >= 0 for displacement into argv[n], <0 EOF */ char *arg; /* pointer to active character */ int c; /* current character */ if ( ! cmdinput ) /* is -A active? */ return( getchar() ); /* no: return stdin character */ if ( AgetMode < 0 || optind >= Myargc ) /* EOF is sticky: */ return( EOF ); /* **ensure it now and forever more */ /* find next character */ arg = Myargv[optind]; /* pointer to active arg */ c = arg[AgetMode++]&0xFF; /* get appropriate char of arg */ if ( ! c ) /* at '\0' that terminates word? */ { /* at end of word: return ' ' if normal word, '\n' if empty */ c = ' '; /* suppose normal word and return blank */ if ( AgetMode == 1 ) /* if ran out in very 1st char, force \n */ c = '\n'; /* (allows "hello '' world" to do \n at '') */ AgetMode = 0; /* return to char 0 in NEXT word */ if ( ++optind >= Myargc ) /* run up word count and check if at "EOF" */ { /* just ran out of arguments */ c = EOF; /* return EOF */ AgetMode = -1; /* ensure all future returns return EOF */ } } return( c ); /* return appropriate character */} /* end: Agetchar() *//**************************************************************************** iso2022 Called by getinchr. Interprets ISO 2022 sequences******************************************************************************/inchr iso2022(){ inchr ch; inchr ch2; int save_gl; int save_gr; ch = Agetchar(); if (ch == EOF) return ch; if (ch == 27) ch = Agetchar() + 0x100; /* ESC x */ if (ch == 0x100 + '$') ch = Agetchar() + 0x200; /* ESC $ x */ switch (ch) { case 14: /* invoke G0 into GL */ gl = 0; return iso2022(); case 15: /* invoke G1 into GL */ gl = 1; return iso2022(); case 142: case 'N' + 0x100: /* invoke G2 into GL for next char */ save_gl = gl; save_gr = gr; gl = gr = 2; ch = iso2022(); gl = save_gl; gr = save_gr; return ch; case 143: case 'O' + 0x100: /* invoke G3 into GL for next char */ save_gl = gl; save_gr = gr; gl = gr = 3; ch = iso2022(); gl = save_gl; gr = save_gr; return ch; case 'n' + 0x100: /* invoke G2 into GL */ gl = 2; return iso2022(); case 'o' + 0x100: /* invoke G3 into GL */ gl = 3; return iso2022(); case '~' + 0x100: /* invoke G1 into GR */ gr = 1; return iso2022(); case '}' + 0x100: /* invoke G2 into GR */ gr = 2; return iso2022(); case '|' + 0x100: /* invoke G3 into GR */ gr = 3; return iso2022(); case '(' + 0x100: /* set G0 to 94-char set */ ch = Agetchar(); if (ch == 'B') ch = 0; /* ASCII */ gn[0] = ch << 16; gndbl[0] = 0; return iso2022(); case ')' + 0x100: /* set G1 to 94-char set */ ch = Agetchar(); if (ch == 'B') ch = 0; gn[1] = ch << 16; gndbl[1] = 0; return iso2022(); case '*' + 0x100: /* set G2 to 94-char set */ ch = Agetchar(); if (ch == 'B') ch = 0; gn[2] = ch << 16; gndbl[2] = 0; return iso2022(); case '+' + 0x100: /* set G3 to 94-char set */ ch = Agetchar(); if (ch == 'B') ch = 0; gn[3] = ch << 16; gndbl[3] = 0; return iso2022(); case '-' + 0x100: /* set G1 to 96-char set */ ch = Agetchar(); if (ch == 'A') ch = 0; /* Latin-1 top half */ gn[1] = (ch << 16) | 0x80; gndbl[1] = 0; return iso2022(); case '.' + 0x100: /* set G2 to 96-char set */ ch = Agetchar(); if (ch == 'A') ch = 0; gn[2] = (ch << 16) | 0x80; gndbl[2] = 0; return iso2022(); case '/' + 0x100: /* set G3 to 96-char set */ ch = Agetchar(); if (ch == 'A') ch = 0; gn[3] = (ch << 16) | 0x80; gndbl[3] = 0; return iso2022(); case '(' + 0x200: /* set G0 to 94 x 94 char set */ ch = Agetchar(); gn[0] = ch << 16; gndbl[0] = 1; return iso2022(); case ')' + 0x200: /* set G1 to 94 x 94 char set */ ch = Agetchar(); gn[1] = ch << 16; gndbl[1] = 1; return iso2022(); case '*' + 0x200: /* set G2 to 94 x 94 char set */ ch = Agetchar(); gn[2] = ch << 16; gndbl[2] = 1; return iso2022(); case '+' + 0x200: /* set G3 to 94 x 94 char set */ ch = Agetchar(); gn[3] = ch << 16; gndbl[3] = 1; return iso2022(); default: if (ch & 0x200) { /* set G0 to 94 x 94 char set (deprecated) */ gn[0] = (ch & ~0x200) << 16; gndbl[0] = 1; return iso2022(); } } if (ch >= 0x21 && ch <= 0x7E) { /* process GL */ if (gndbl[gl]) { ch2 = Agetchar(); return gn[gl] | (ch << 8) | ch2; } else return gn[gl] | ch; } else if (ch >= 0xA0 && ch <= 0xFF) { /* process GR */ if (gndbl[gr]) { ch2 = Agetchar(); return gn[gr] | (ch << 8) | ch2; } else return gn[gr] | (ch & ~0x80); } else return ch; }/**************************************************************************** ungetinchr Called by main. Pushes back an "inchr" to be read by getinchr on the next call.******************************************************************************/inchr getinchr_buffer;int getinchr_flag;inchr ungetinchr(c)inchr c;{ getinchr_buffer = c; getinchr_flag = 1; return c;}/***************************************************************************** getinchr Called by main. Processes multibyte characters. Invokes Agetchar. If multibyte = 0, ISO 2022 mode (see iso2022 routine). If multibyte = 1, double-byte mode (0x00-0x7f bytes are characters, 0x80-0xFF bytes are first byte of a double-byte character). If multibyte = 2, Unicode UTF-8 mode (0x00-0x7F bytes are characters, 0x80-0xBF bytes are nonfirst byte of a multibyte character, 0xC0-0xFD bytes are first byte of a multibyte character, 0xFE-0xFF bytes are errors (all errors return code 0x0080)). If multibyte = 3, HZ mode ("~{" starts double-byte mode, "}~" ends it, "~~" is a tilde, "~x" for all other x is ignored). If multibyte = 4, Shift-JIS mode (0x80-0x9F and 0xE0-0xEF are first byte of a double-byte character, all other bytes are characters). *****************************************************************************/inchr getinchr(){ int ch, ch2, ch3, ch4, ch5, ch6; if (getinchr_flag) { getinchr_flag = 0; return getinchr_buffer; } switch(multibyte) { case 0: /* single-byte */ return iso2022(); case 1: /* DBCS */ ch = Agetchar(); if ((ch >= 0x80 && ch <= 0x9F) || (ch >= 0xE0 && ch <= 0xEF)) { ch = (ch << 8) + Agetchar(); } return ch; case 2: /* UTF-8 */ ch = Agetchar(); if (ch < 0x80) return ch; /* handles EOF, too */ if (ch < 0xC0 || ch > 0xFD) return 0x0080; /* illegal first character */ ch2 = Agetchar() & 0x3F; if (ch < 0xE0) return ((ch & 0x1F) << 6) + ch2; ch3 = Agetchar() & 0x3F; if (ch < 0xF0) return ((ch & 0x0F) << 12) + (ch2 << 6) + ch3; ch4 = Agetchar() & 0x3F; if (ch < 0xF8) return ((ch & 0x07) << 18) + (ch2 << 12) + (ch3 << 6) + ch4; ch5 = Agetchar() & 0x3F; if (ch < 0xFC) return ((ch & 0x03) << 24) + (ch2 << 18) + (ch3 << 12) + (ch4 << 6) + ch5; ch6 = Agetchar() & 0x3F; return ((ch & 0x01) << 30) + (ch2 << 24) + (ch3 << 18) + (ch4 << 12) + (ch5 << 6) + ch6; case 3: /* HZ */ ch = Agetchar(); if (ch == EOF) return ch; if (hzmode) { ch = (ch << 8) + Agetchar(); if (ch == ('}' << 8) + '~') { hzmode = 0; return getinchr(); } return ch; } else if (ch == '~') { ch = Agetchar(); if (ch == '{') { hzmode = 1; return getinchr(); } else if (ch == '~') { return ch; } else { return getinchr(); } } else return ch; case 4: /* Shift-JIS */ ch = Agetchar(); if ((ch >= 0x80 && ch <= 0x9F) || (ch >= 0xE0 && ch <= 0xEF)) { ch = (ch << 8) + Agetchar(); } return ch; default: return 0x80; } }/**************************************************************************** main The main program, of course. Reads characters 1 by 1 from stdin, and makes lines out of them using addchar. Handles line breaking, (which accounts for most of the complexity in this function).****************************************************************************/int main(argc,argv)int argc;char *argv[];{ inchr c,c2; int i; int last_was_eol_flag;/*--------------------------------------------------------------------------- wordbreakmode: -1: /^$/ and blanks are to be absorbed (when line break was forced by a blank or character larger than outlinelenlimit) 0: /^ *$/ and blanks are not to be absorbed 1: /[^ ]$/ no word break yet 2: /[^ ] *$/ 3: /[^ ]$/ had a word break---------------------------------------------------------------------------*/ int wordbreakmode; int char_not_added; Myargc = argc; Myargv = argv; getparams(); readcontrolfiles(); readfont(); linealloc(); wordbreakmode = 0; last_was_eol_flag = 0; while ((c = getinchr())!=EOF) { if (c=='\n'&¶graphflag&&!last_was_eol_flag) { ungetinchr(c2 = getinchr()); c = ((isascii(c2)&&isspace(c2))?'\n':' '); } last_was_eol_flag = (isascii(c)&&isspace(c)&&c!='\t'&&c!=' '); if (deutschflag) { if (c>='[' && c<=']') { c = deutsch[c-'[']; } else if (c >='{' && c <= '~') { c = deutsch[c-'{'+3]; } } c = handlemapping(c); if (isascii(c)&&isspace(c)) { c = (c=='\t'||c==' ') ? ' ' : '\n'; } if ((c>'\0' && c<' ' && c!='\n') || c==127) continue;/* Note: The following code is complex and thoroughly tested. Be careful when modifying!*/ do { char_not_added = 0; if (wordbreakmode== -1) { if (c==' ') { break; } else if (c=='\n') { wordbreakmode = 0; break; } wordbreakmode = 0; } if (c=='\n') { printline(); wordbreakmode = 0; } else if (addchar(c)) { if (c!=' ') { wordbreakmode = (wordbreakmode>=2)?3:1; } else { wordbreakmode = (wordbreakmode>0)?2:0; } } else if (outlinelen==0) { for (i=0;i<charheight;i++) { if (right2left && outputwidth>1) { putstring(currchar[i]+MYSTRLEN(currchar[i])-outlinelenlimit); } else { putstring(currchar[i]); } } wordbreakmode = -1; } else if (c==' ') { if (wordbreakmode==2) { splitline(); } else { printline(); } wordbreakmode = -1; } else { if (wordbreakmode>=2) { splitline(); } else { printline(); } wordbreakmode = (wordbreakmode==3)?1:0; char_not_added = 1; } } while (char_not_added); } if (outlinelen!=0) { printline(); } /* XXX Xen hack -- finish off the C macro output */ if ( nr_chars != 0 ) putchar('"'); putchar('\n'); exit(0);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?