static size_t skip_bytes(char c) { if (is_ascii(c)) { return 1; } else if (is_kanji(c) || is_hankana(c)) { return 2; } else if (is_hojyo(c)) { return 3; } return 0; }
static size_t eucjp_iconv(iconv_t cd, char **srcbuf, size_t *srclen, char **outbuf, size_t *outlen) { unsigned char *tmpbuf, *tmp; unsigned char *src; unsigned char ch, cl; size_t ret; if (! (srcbuf && srclen && outbuf && outlen)) return 0; /* translate EUC-JP into SJIS */ src = (unsigned char *)*srcbuf; tmp = tmpbuf = malloc(*srclen+2); while (*src && ((tmp - tmpbuf) < *srclen)) { ch = *src++; if (is_ascii(ch)) { *tmp++ = ch; } else { cl = *src++; if (is_kanji(ch)) { *tmp++ = ((ch-0x5f)/2) ^ 0xA0; if (!(ch&1)) *tmp++ = cl - 0x02; else if (cl < 0xE0) *tmp++ = cl - 0x61; else *tmp++ = cl - 0x60; } else if (is_hankana(ch)) { if (cl < 0xA0 || cl > 0xDF) { *srcbuf=(char *)(src-2); errno=EILSEQ; return -1; } *tmp++ = cl; } else { /* We don't support JIS X 0212 */ *srcbuf=(char *)(src-2); errno=EILSEQ; return -1; } } } *tmp='\0'; ret = mssjis_iconv(cd, (char **) &tmpbuf, srclen, outbuf, outlen); free(tmpbuf); *srcbuf += *src; *srclen = 0; return ret; }
char * putkchar(char *str, int *x, int *y) { if(is_kanji(*str)) { if(*x == term_width - 1) { putchar(' '); (*y) ++; (*x) = 0; return str; } putchar(*str++); (*x) ++; putchar(*str++); (*x) ++; } else { putchar(*str++); (*x) ++; } if(*x >= term_width) { (*x) -= term_width; (*y) ++; } return str; }
Token nextTkn(void) /* 次のトークン */ { Token tkn = {NulKind, "", 0}; int errF = FALSE, num, ct, n; char *p = tkn.text, *p_end31 = p+ID_SIZ; char lite[100+1], *lite_end = lite+100; static int ch = ' '; /* 前回文字を保持するためstatic */ while (isspace(ch)) { ch = nextCh(); } /* 空白読み捨て */ if (ch == EOF) { tkn.kind = EofTkn; return tkn; } /* EOF */ switch (ctyp[ch]) { case Letter: for ( ; ctyp[ch]==Letter || ctyp[ch]==Digit; ch = nextCh()) { if (p < p_end31) *p++ = ch; /* 識別子は最大31文字まで有効 */ } *p = '\0'; break; case Digit: /* 数値定数 */ for (num=0; ctyp[ch]==Digit; ch = nextCh()) { num = num*10 + (ch-'0'); } tkn.kind = IntNum; tkn.intVal = num; /* 値格納 */ sprintf(tkn.text, "%d", num); /* エラー表示用 */ break; case SngQ: /* 文字定数 */ for (ct=0,ch=nextCh(); ch!=EOF && ch!='\n' && ch!='\''; ch=nextCh()) { if (ch == '\\') { if ((ch=nextCh()) == 'n') ch = '\n'; } /* \nの処理 */ if (++ct == 1) tkn.intVal = ch; /* 文字定数値格納 */ } if (ct != 1) errF = TRUE; if (ch == '\'') ch = nextCh(); else errF = TRUE; if (errF) err_s("不正な文字定数"); tkn.kind = IntNum; /* 以降は整数定数として扱う */ sprintf(tkn.text, "'%c'", tkn.intVal); /* エラー表示用 */ break; case DblQ: /* 文字列定数 */ p = lite; ch = nextCh(); while (ch!=EOF && ch!='\n' && ch!='"') { if (errF) { ch = nextCh(); continue; } if ((n=is_kanji(ch)) > 0) { while (n--) { if (p < lite_end) P_SET(); else errF = TRUE; } continue; } if (ch == '\\') { if ((ch=nextCh()) == 'n') ch = '\n'; } /* \nの処理 */ if (p < lite_end) P_SET(); else errF = TRUE; } *p = '\0'; if (errF) err_s("文字列リテラルが長すぎる"); if (ch == '"') ch = nextCh(); else err_s("文字列リテラルが閉じていない"); tkn.kind = String; tkn.intVal = mallocS(lite); /* 文字列をメモリに確保し番地を格納 */ tkn.text[0] = '\"'; /*以下エラー表示用に文字列確保*/ strncat(tkn.text+1, lite, 29); if (strlen(tkn.text) <= 29) strcat(tkn.text, "\""); break; default: /* 記号 */ if (ch<0 || 127<ch) err_s("不正な文字が使われている"); if ((n=is_kanji(ch)) > 0) { while (n--) P_SET(); } else P_SET(); if (is_ope2(*(p-1), ch)) P_SET(); /* == など */ *p = '\0'; } if (tkn.kind == NulKind) tkn = set_kind(tkn); /* 種別設定 */ if (tkn.kind == Others) err_ss("不正なトークン", tkn.text); return tkn; }