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;
}
Example #3
0
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;
}
Example #4
0
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;
}