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'&&paragraphflag&&!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 + -
显示快捷键?