『Cプログラミング診断室』目次次(第2章 これでもプロ 「超」基本的問題点)

第2章 これでもプロ

プログラムの紹介


次に紹介する記念する汚いプログラムは、作者不詳です。某ソフト開発グループメンバー(ア ルバイトを含む)の誰かであることまでは分かっているのですが、そのうちの誰(もしかすると複 数人)であるかは不明です。こんな馬鹿なとお思いでしょうが、結構世の中には、そういう程度の 開発体制でやっているところが多いのです。

ソフト全体では5万行程度あり、複数のディレクトリに整理分散して入れています。全体のソー スファイル構成の下手さ加減は並大抵ではないので、それを記事にしたいのですが、ソースの量が あまりに多く、とても単行本1冊程度では書き切れないありさまなので、どんなに努力してもその 概念的なことしか書けません(残念!)。全体構成が汚いから、当然各ファイルも十分汚かったの で、その中から単独でも分かりやすそうなものを1つ取り上げました(リスト2−1)。取り上げ たファイルは、全体の中では中程度の汚さです。もっと汚いのがいっぱいあったのですが、単独の ファイルとしては説明しづらいとか、汚過ぎてとても説明できないなどの理由でやめました。

内容は、キー入力に関連するものです。では、さっそく解剖していきましょう。

リスト2−1 オリジナルプログラム

     1  #include <stdio.h>
     2  #include <draw.h>
     3  #include <kernel.h>
     4  #include <data.ext>
     5  #include <mes.h>
     6  #include <tags.h>
     7  
     8  #define ASTA            0x2a
     9  #define UNDER_line      0x5f
    10  #define MAXBLINK        50
    11  #define KSHIFTJ         0x8140
    12  #define KSHIFTJE        0xeefc
    13  #define KKI             0x004b
    14  #define KKO             0x0048
    15  #define MASK            0xff00
    16  #define MASKLOW         0x00ff
    17  #define MOUSE_LEFT      1
    18  #define MOUSE_RIGHT     4
    19  #define BUFMAX          60
    20  
    21  extern  unsigned char   Cursor;
    22  extern  char    kbbuf[BUFMAX];
    23  extern  char    parameter[10][10];
    24  
    25  int     EXIT_CHAR;
    26  static int      keyin_cx;
    27  static int      keyin_cy;
    28  static int      keyin_noc;
    29  
    30  keyinput_main(fs,pkt)
    31  int     fs;
    32  int pkt[4];
    33  {
    34          int     i, rets, col,kflag;
    35  
    36          col     = pkt[0];
    37          keyin_cx   = pkt[1];
    38          keyin_cy   = pkt[2];
    39          keyin_noc  = pkt[3];
    40          kflag      = fs;
    41  
    42          if (keyin_noc >= BUFMAX)
    43                  keyin_noc = BUFMAX - 1;
    44  
    45          for(i = 0; i <= keyin_noc; i++)
    46                  kbbuf[i]=0;
    47  
    48          rets = GET_OK;
    49          if (keyinput_sub(col,kflag) == TOPF)    rets = TOPF;
    50          return (rets);
    51  }
    52  
    53  get_str(fs, col, x, y, size, type)
    54  int     fs, col, x, y, size, type;
    55  {
    56          int     pkt[4];
    57  
    58          Cursor = type;
    59          pkt[0] = col;
    60          pkt[1] = x;
    61          pkt[2] = y;
    62          pkt[3] = size;
    63          return (keyinput_main(fs, pkt));
    64  }
    65  
    66  SetNumber(ptr)
    67  char    *ptr;
    68  {
    69          char    buf[100];
    70          int     i, j, num;
    71  
    72          buf[0] = '\0';
    73          for (i = 0, j = 0; ptr[i] != '\0'; i++, j++) {
    74                  if (ptr[i] == '$') {
    75                          if ((num = atoi(&ptr[i] + 1)) < 0 || num >  9) {
    76                                  beep();
    77                                  return (GET_ERR);
    78                          }
    79                          strcat(buf, &parameter[num][0]);
    80                          i++;
    81                          j = strlen(buf) - 1;
    82                  }
    83                  else {
    84                          buf[j] = ptr[i];
    85                          buf[j + 1] = '\0';
    86                  }
    87          }
    88          strcpy(ptr, buf);
    89          return (NO_GET);
    90  }
    91  
    92  keyinput_num(col, x, y, size)
    93  int     col, x, y, size;
    94  {
    95  again:
    96          if (get_str(11, col, x, y, size, UNDER_line) == TOPF) return (TOPF);
    97          if (keyin_stat != -2 && keyin_stat != -3) {
    98                  if (SetNumber(kbbuf) == GET_ERR) {
    99                          beep();
   100                          goto again;
   101                  }
   102                  if (realchk(kbbuf)){
   103                          beep();
   104                          goto again;
   105                  }
   106          }
   107          return (GET_OK);
   108  }
   109  
   110  get_chr()
   111  {
   112          int     mi, CC;
   113  
   114          mi = 0;
   115          while ((CC = io_conin()) == '\0') {
   116                  if (mskb_flg == 1) {
   117                          mi = io_mouse(0) ;
   118                          if (mi != 0)
   119                                  break;
   120                  }
   121          }
   122          if (mi == MOUSE_LEFT) {
   123                  CC = KRTN;
   124                  outputc(CC);
   125          }
   126          else if (mi == MOUSE_RIGHT || mi == 2 || mi == 3) {
   127                  CC = ' ';
   128                  outputc(CC);
   129          }
   130          return (CC);
   131  }
   132  
   133  static
   134  keyinput_sub(col,fs)
   135  int     col;
   136  int     fs;
   137  {
   138          static int      as[2]={
   139                  0,0                                             };
   140          int     chr_conv;
   141          char    *keybuf;
   142          int     xx, yy, i;
   143          int     wrdbuf[60];
   144          int     zen_su, han_su;
   145          int     chr_pnt;
   146          int     zen_flg;
   147  
   148  again:
   149          keyin_stat = 0;
   150          if (keyin_noc == 0)  return (GET_OK);
   151  
   152          keybuf = &kbbuf[0];
   153          zen_flg = zen_su = han_su = chr_pnt = 0;
   154          if (fs == 14) zen_flg = 1;
   155          if (fs == 15) zen_flg = 2;
   156  
   157          xx = keyin_cx;
   158          yy = keyin_cy;
   159          color(col);
   160          locate(xx, yy);
   161          for (i = 1; i <= keyin_noc; i++ )
   162                  io_cout(Cursor);
   163  
   164  next:
   165          *as = get_chr();
   166  
   167  get:
   168          if ((*as & 0xff00) == B_PFKEY) {
   169                  beep();
   170                  goto next;
   171          }
   172  
   173          switch (*as) {
   174          case KDEL:
   175                  kbbuf[0] = '\0';
   176                  goto again;
   177  
   178          case KESC:
   179                  wrdbuf[chr_pnt++] = *as;
   180                  goto next;
   181  
   182          case KBS:
   183                  keyin_stat = -2;
   184                  locate(keyin_cx, keyin_cy);
   185                  for (i = 1; i <= keyin_noc; i++)
   186                          io_cout(Cursor);
   187                  return (GET_OK);
   188  
   189          case KRTN:
   190                  if (EXIT_CHAR != 0 && wrdbuf[chr_pnt-1] == EXIT_CHAR) {
   191                          delng_flg = 0;
   192                          kpf = 0;
   193                          return (TOPF);
   194                  }
   195                  if (chr_pnt == 0 && kbbuf[0] == '\0') {
   196                          keyin_stat = -3;
   197                          locate(keyin_cx, keyin_cy);
   198                          io_cout(' ');
   199                          *keybuf= '\0';
   200                  }
   201                  storedata(wrdbuf, chr_pnt, keybuf);
   202                  return (GET_OK);
   203  
   204          case UPA:
   205          case DOWNA:
   206          case RIGHTA:
   207          case KHOME:
   208          case KCLR:
   209                  beep();
   210                  goto next;
   211  
   212          case LEFTA:
   213                  if (chr_pnt == 0) {
   214                          kbbuf[0] = '\0';
   215                          goto again;
   216                  }
   217                  else {
   218                          chr_pnt--;
   219                          if ((((char)wrdbuf[chr_pnt -1]) >= 0xff82 &&
   220                              ((char)wrdbuf[chr_pnt]) >= 0x3f) &&
   221                              (((char)wrdbuf[chr_pnt -1]) <= 0xff9f &&
   222                              ((char)wrdbuf[chr_pnt]) <= 0xfc)){
   223                                  xx -= 2;
   224                                  zen_su -= 2;
   225                                  chr_pnt --;
   226                                  locate(xx, yy);
   227                                  io_cout(Cursor);
   228                                  io_cout(Cursor);
   229  
   230                          }
   231                          else{
   232                                  xx--;
   233                                  han_su--;
   234                                  locate(xx, yy);
   235                                  io_cout(Cursor);
   236                          }
   237                  }
   238                  goto next;
   239          }
   240  
   241          if (0 < *as && *as < 0x20) {
   242                  beep();
   243                  goto next;
   244          }
   245  
   246          if (*as >= KSHIFTJ && *as <= KSHIFTJE ){
   247                  chr_conv = *as;
   248                  if (zen_flg) {
   249                          wrdbuf[chr_pnt++] = ((chr_conv & MASK) >> 8) & MASKLOW;
   250                          wrdbuf[chr_pnt++] =  chr_conv & MASKLOW;
   251                          locate(xx,yy);
   252                          io_cout(wrdbuf[chr_pnt-2]);
   253                          io_cout(wrdbuf[chr_pnt-1]);
   254                          xx +=2;
   255                          zen_su += 2;
   256                  }
   257                  else {
   258                          beep();
   259                          goto next;
   260                  }
   261          }
   262          else{
   263                  if (zen_flg == 1) {
   264                          beep();
   265                          goto next;
   266                  }
   267                  else {
   268                          locate(xx, yy);
   269                          io_cout(*as);
   270                          wrdbuf[chr_pnt++] = *as;
   271                          xx++;
   272                          han_su++;
   273                  }
   274          }
   275          if ((zen_su + han_su) < keyin_noc)  goto next;
   276          else
   277                  storedata(wrdbuf, chr_pnt, keybuf);
   278          return (GET_OK);
   279  }
   280  
   281  storedata(wrdbuf, chr_pnt, keybuf)
   282  int     wrdbuf[], chr_pnt;
   283  char    *keybuf;
   284  {
   285          int     i, s, scount, zen_flg;
   286          int     codeh;
   287          char    codeb;
   288  
   289          scount = zen_flg = 0;
   290          for (i = 0; i < chr_pnt; i++){
   291                  if (wrdbuf[i] & MASK){
   292                          if (zen_flg == 0){
   293                                  zen_flg = 1;
   294                                  *(keybuf + scount++) = KESC;
   295                                  *(keybuf + scount++) = KKI;
   296                          }
   297                          if (zen_flg == 1){
   298                                  codeh = wrdbuf[i];
   299                                  codeh >>= 8;
   300                                  codeb = codeh;
   301                                  *(keybuf + scount++) = codeb;
   302                                  codeb = wrdbuf[i];
   303                                  *(keybuf + scount++) = codeb;
   304                          }
   305                  }
   306                  else if(zen_flg == 1){
   307                          zen_flg = 0;
   308                          *(keybuf + scount++) = KESC;
   309                          *(keybuf + scount++) = KKO;
   310                          *(keybuf + scount++) = wrdbuf[i];
   311                  }
   312                  else 
   313                          *(keybuf + scount++) = wrdbuf[i];
   314  
   315                  *(keybuf + scount) = '\0';
   316          }
   317  
   318          conv_chr_val(kbbuf);
   319  
   320          s = keyin_noc - strlen(keybuf);
   321          if (s < 0)      s = 0;
   322  
   323          locate(keyin_cx + strlen(kbbuf),keyin_cy);
   324          for (i = 0; i < s; i++)
   325                  printf(" ");
   326  }
   327  
   328  keyinput_yn(mes)
   329  int mes;
   330  {
   331          int     flag;
   332  
   333          dsp_str(SKYBLUE, 0, 0, "OK[Y/N]= *");
   334          flag  = get_yn();
   335          clear_guide();
   336          return (flag);
   337  }
   338  
   339  get_yn()
   340  {
   341          int     c, n;
   342  loop:
   343          c = get_chr();
   344          if (c == 'y' || c == 'Y' || c == 13)
   345                  n = 0;
   346          else if (c == 'n' || c == 'N' || c == ' ')
   347                  n = 1;
   348          else {
   349                  beep();
   350                  goto loop;
   351          }
   352          return (n);
   353  }
   354  
   355  wait_5()
   356  {
   357          long i;
   358  
   359          for (i = 0; i < 50000; i++) ;
   360  }
   361  
   362  static
   363  realchk(s)
   364  char s[];
   365  {
   366          int i,periodsw;
   367  
   368          periodsw = 0;
   369          if (s[0] == '+' || s[0] == '-')
   370                  i = 1;
   371          else
   372                  i = 0;
   373          while(s[i] != '\0') {
   374                  if (!((s[i] == '.' && periodsw == 0)
   375                      || s[i] == '/' || (s[i] >= '0' && s[i] <= '9')))
   376                          return(1);
   377                  if (s[i] == '.')
   378                          periodsw = 1;
   379                  ++i;
   380          }
   381          return(0);
   382  }


Copyright1996 Hirofumi Fujiwara. No reproduction or republication without written permission
『Cプログラミング診断室』目次次(第2章 これでもプロ 「超」基本的問題点)