/**********************************************************************
 *
 *       *** HAPPy P-code Interpriter ***
 *
 *          ファイル関連の命令処理
 *
 *        void EOL(void)  void EoF(void)  void GET(void)  void PGE(void)
 *        void PUT(void)  void RLN(void)  void RDC(void)  void RDI(void)
 *        void RDR(void)  void RST(void)  void RWT(void)  void TGT(void)
 *        void TPT(void)  void TRS(void)  void TRW(void)  void WLN(void)
 *        void WRB(void)  void WRC(void)  void WRF(void)  void WRI(void)
 *        void WRR(void)  void WRS(void)
 *        void T_get(short fileno, _store *filebuf, FILE *fp,char *name)
 *
 *            Copyright (c) H.Asano 1992-1994.
 **********************************************************************/

#define EXTERN extern

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hapai.h"

extern void prerr(short,char*) ;        /* Run-timeエラー出力         */

extern _store store[] ;                 /* 記憶装置                   */

extern _store *sp ;                     /* Stack Pointer              */
extern _code  cd  ;                     /* p-code                     */

extern boolean readlnflag ;             /* inputにreadlnをした時 及び
                                           起動時には真               */


/**************************************************/
/* searchfile() : fileadrに対応するファイルを探す *
/**************************************************/
static fileinfo *searchfile(void)
{
   register fileinfo *finf = fi -1 ;
   short fileadr ;

     fileadr = (sp--)->va ;
     while((*(++finf)).fileadr != fileadr) ;
     return(finf) ;
}

/**************************************************/
/* fileerrmsg() : file関係のエラーメッセージ出力  */
/**************************************************/
static void fileerrmsg(short msgno,char *pname,fileinfo *fiadr,char *msg)
{
  char buf[160] ;

     sprintf(buf,"%s: %s(実ファイル=%s)%s", pname,
                  (*fiadr).filename, (*fiadr).rfname, msg) ;
     prerr(msgno,buf) ;
}

/******************************************/
/* checkgeneration() : 生成モードチェック */
/******************************************/
static void checkgeneration(char *pname,fileinfo *fiadr)
{
     if((*fiadr).mode != generation)
      fileerrmsg(9,pname,fiadr,"が生成モードでない") ;
}

/******************************************/
/* checkinspection() : 検査モードチェック */
/******************************************/
static void checkinspection(char *pname,fileinfo *fiadr)
{
     if((*fiadr).mode != inspection)
      fileerrmsg(14,pname,fiadr,"が検査モードでない") ;
}

/*************************************************/
/* err131() : ファイル書き込み障害メッセージ出力 */
/*************************************************/
static void err131(char *pname,fileinfo *fiadr)
{
      fileerrmsg(131,pname,fiadr,"で障害が発生した") ;
}

/*****************************************/
/* T_get() : textファイルからの1文字読込 */
/*****************************************/
void T_get(fileinfo *fiadr, _store *filebuf, char *name)
{

     if(feof(fiadr->fp))
      fileerrmsg(42,name,fiadr,"がEOFとなっている") ;

     filebuf->vc = getc(fiadr->fp);     /* 1文字先読み                */

     if(ferror(fiadr->fp))
      fileerrmsg(181,name,fiadr,"で障害が発生した") ;

     if(fiadr->eolnflag=(filebuf->vc=='\n') )      /* 改行を読んだ 真 */
      filebuf->vc = ' ' ;               /* 空白に置き換え             */
}

/******************* 各P-codeの処理 ***********************************/

/***************************************/
/* EOL() : eol標準関数                 */
/***************************************/
void EOL(void)
{
  fileinfo *fiadr   ;
  _store   *filebuf ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     filebuf = (*fiadr).filebuf       ;

     if((*fiadr).mode == undefined)
      fileerrmsg(41,"eoln",fiadr,"が不定である") ;

     if(feof((*fiadr).fp))
      fileerrmsg(42,"eoln",fiadr,"がEOFとなっている") ;

     if((cd.p==0) && readlnflag) {      /* inputファイルで直前がreadln*/
      T_get(fiadr,filebuf,"eoln") ;
                                        /* 次の文字を読込             */
      readlnflag = false ;
     }
     (++sp)->vb = (*fiadr).eolnflag ;
}

/***************************************/
/* EoF() : eof標準関数                 */
/***************************************/
void EoF(void)
{
  fileinfo *fiadr   ;
  _store   *filebuf ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     filebuf = (*fiadr).filebuf       ;

     sp++ ;

     if((cd.p==0) && readlnflag) {      /* inputファイルで直前がreadln*/
      T_get(fiadr,filebuf,"eof") ;
                                        /* 次の文字を読込             */
      readlnflag = false ;
      sp->vb = feof((*fiadr).fp) ;
     }
     else {                             /* 通常のeof                  */
      if((*fiadr).mode == undefined)
       fileerrmsg(40,"eof",fiadr,"が不定である") ;

      sp->vb = ((*fiadr).mode == generation)      /* 生成モードは真   */
                    ?  true : feof((*fiadr).fp) ;
     }
}

/**************************************/
/* GET() : テキストファイル以外のget  */
/**************************************/
void GET(void)
{
  short    fileadr ;
  fileinfo *fiadr  ;
  FILE     *fp     ;

     fileadr = (*sp).va ;
     fiadr   = searchfile() ;
     fp      = (*fiadr).fp ;

     checkinspection("get",fiadr) ;

     if(feof(fp))
      fileerrmsg(16,"get",fiadr,"がEOFとなっている") ;

     fread(store+fileadr, (*fiadr).filesize*sizeof(_store),1,fp);

     if(ferror(fp)) err131("get",fiadr) ;
}

/**************************************/
/* PGE() : page標準手続き             */
/**************************************/
void PGE(void)
{
  fileinfo *fiadr ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */

     checkgeneration("page",fiadr) ;

     if(!(*fiadr).writelnflag)        /* 最後が改行でない時         */
      if(fputc('\n',(*fiadr).fp) == EOF) err131("page",fiadr) ;
     if(fputc('\f',(*fiadr).fp)  == EOF) err131("page",fiadr) ;
     (*fiadr).writelnflag = false ;
}

/**************************************/
/* PUT() : テキストファイル以外のput  */
/**************************************/
void PUT(void)
{
  short    fileadr ;
  fileinfo *fiadr  ;
  FILE     *fp     ;

     fileadr = (*sp).va ;
     fiadr   = searchfile() ;
     fp      = (*fiadr).fp  ;

     checkgeneration("put",fiadr) ;

     fwrite(store+fileadr, (*fiadr).filesize*sizeof(_store),1,fp) ;

     if(ferror(fp))
      fileerrmsg(182,"put",fiadr,"で障害が発生した") ;
}

/**************************************/
/* RLN() : テキストファイルのreadln   */
/**************************************/
void RLN(void)
{
  _store   *filebuf ;
  fileinfo *fiadr   ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     filebuf = (*fiadr).filebuf       ;

     checkinspection("read",fiadr)  ;

     if((cd.p==0) && readlnflag)
      T_get(fiadr,filebuf,"readln") ;

     while(!(*fiadr).eolnflag)
      T_get(fiadr,filebuf,"readln") ;   /* 改行文字を読み飛ばす       */
     if(fiadr == fi) readlnflag = true ;/* inputファイルの時          */
     else
      T_get(fiadr,filebuf,"readln") ;   /* 次の文字を読込             */
}

/*****************************************/
/* RDC() : テキストファイルからの文字読込*/
/*****************************************/
void RDC(void)
{
  _store   *filebuf ;
  fileinfo *fiadr   ;
  short    ad       ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     filebuf = (*fiadr).filebuf       ;

     checkinspection("read",fiadr) ;

     if(feof((*fiadr).fp))
      fileerrmsg(16,"read",fiadr,"がEOFとなっている") ;

     if((cd.p==0) && readlnflag) {      /* inputファイルで直前がreadln*/
      T_get(fiadr,filebuf,"read") ;     /* 次の文字を読込             */
      readlnflag = false ;
     }

     ad = (sp--)->va ;
     store[ad].vc = (*filebuf).vc  ;    /* バッファ変数から変数へ代入 */

     T_get(fiadr,filebuf,"read") ;      /* 次の文字を読込             */
}

/*****************************************/
/* RDI() : テキストファイルからの整数読込*/
/*****************************************/
void RDI(void)
{
  FILE     *fp      ;
  _store   *filebuf ;
  fileinfo *fiadr   ;
  short    ad       ;
  short    lch      ;
  integer  ival = 0 ;
  short    sign = 1 ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     filebuf = fiadr->filebuf   ;
     fp      = fiadr->fp        ;
     ad      = (sp--)->va       ;

     checkinspection("read",fiadr)  ;

     if((cd.p==0) && readlnflag) {     /* inputファイルで直前がreadln*/
      T_get(fiadr,filebuf,"read") ;    /* 次の文字を読込             */
      readlnflag = false ;
     }

     while((*filebuf).vc == ' ')        /* 空白読み飛ばし             */
      T_get(fiadr,filebuf,"read");
     if(((*filebuf).vc=='+') || ((*filebuf).vc=='-')) { /* 符号の時   */
      sign = ((*filebuf).vc=='+') ? 1 : -1  ; /* 符号に応じた正負     */
      T_get(fiadr,filebuf,"read");
     }

     if(((*filebuf).vc >= '0') && ((*filebuf).vc <= '9')) { /* 数字   */
      do {
       lch = (*filebuf).vc - '0' ;
       if(ival <= (Maxint-lch/10))      /* 上限チェック               */
        ival = ival*10 + lch ;
       else
        fileerrmsg(54,"read",fiadr,
                   "から符号付き整数の形式でないものを読もうとした") ;
       T_get(fiadr,filebuf,"read");
       if(feof(fp)) break ;             /* eofだったら終わり          */
      } while(('0' <= (*filebuf).vc ) && ((*filebuf).vc <= '9')) ;

      store[ad].vi = sign * ival ;
     }
     else {                             /* 最初に数字がこなかった時   */
      if(feof(fp)) fileerrmsg(16,"read",fiadr,"がEOFとなっている") ;
      fileerrmsg(54,"read",fiadr,
                 "から符号付き整数の形式でないものを読もうとした") ;
     }
}

/*****************************************/
/* RDR() : テキストファイルからの実数読込*/
/*****************************************/
void RDR(void)
{
  FILE   *fp       ;
  _store *filebuf  ;
  fileinfo *fiadr  ;
  char buf[80]     ;
  char *stopstring ;
  short  i         ;
  integer ival = 0 ;                    /* 整数部の値                 */

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     filebuf = fiadr->filebuf   ;
     fp      = fiadr->fp        ;

     checkinspection("read",fiadr) ;

     if((cd.p==0) && readlnflag) {     /* inputファイルで直前がreadln*/
      T_get(fiadr,filebuf,"read") ;    /* 次の文字を読込             */
      readlnflag = false ;
     }

     for(i=0;i<80;i++) *(buf+i) = '\0'; /* バッファクリア             */
     i = 0 ;

     while((*filebuf).vc == ' ')        /* 空白読み飛ばし             */
      T_get(fiadr,filebuf,"read");
     if(((*filebuf).vc=='+') || ((*filebuf).vc=='-')) { /* 符号の時   */
      buf[i++] = (char)(*filebuf).vc ;
      T_get(fiadr,filebuf,"read");
     }

     if(((*filebuf).vc >= '0') && ((*filebuf).vc <= '9')) { /* 数字   */
      do {
       buf[i++] = (char)(*filebuf).vc ;
       ival = ival*10 + (*filebuf).vc - '0';
       T_get(fiadr,filebuf,"read");
       if(feof(fp)) break ;             /* eofだったら終わり          */
      } while(('0' <= (*filebuf).vc ) && ((*filebuf).vc <= '9')) ;

      if((*filebuf).vc == '.') {        /* 小数点                     */
       buf[i++] = (char)(*filebuf).vc ;
       T_get(fiadr,filebuf,"read");     /* 小数点を読み飛ばす         */
       if(((*filebuf).vc >= '0') && ((*filebuf).vc <= '9')) { /* 数字 */
        do {
         buf[i++] = (char)(*filebuf).vc ;
         T_get(fiadr,filebuf,"read");
         if(feof(fp)) break ;           /* eofだったら終わり          */
        } while(('0' <= (*filebuf).vc ) && ((*filebuf).vc <= '9')) ;
       }
       else goto error ;                /* . の次が数字でない時       */
      }

      if(((*filebuf).vc == 'e') || ((*filebuf).vc == 'E')) {    /*指数*/
       buf[i++] = (char)(*filebuf).vc ;
       T_get(fiadr,filebuf,"read") ;    /* eまたはEを読み飛ばす       */
       if(((*filebuf).vc=='+') || ((*filebuf).vc=='-')) {  /* 符号の時*/
        buf[i++] = (char)(*filebuf).vc ;
        T_get(fiadr,filebuf,"read") ;
       }
       if(((*filebuf).vc >= '0') && ((*filebuf).vc <= '9')) {  /* 数字*/
        do {
         buf[i++] = (char)(*filebuf).vc ;
         T_get(fiadr,filebuf,"read");
         if(feof(fp)) break ;           /* eofだったら終わり          */
        } while(('0' <= (*filebuf).vc ) && ((*filebuf).vc <= '9')) ;
       }
       else goto error ;                /* 指数部の最初が数字でない   */
      }
     }
     else goto error ;                  /* 最初に数字がこなかった時   */

     store[(sp--)->va].vr = (float)strtod(buf,&stopstring) ;

     return ;

 error :                                /* 符号つき数字でない時       */
     if(feof(fp)) fileerrmsg(16,"read",fiadr,"がEOFとなっている") ;
     fileerrmsg(56,"read",fiadr,
                "から符号付き数の形式でないものを読もうとした") ;
}

/****************************************/
/* RST() : テキストファイル以外のreset  */
/****************************************/
void RST(void)
{
   short    fileadr ;
   fileinfo *fiadr  ;
   FILE     *fp     ;

     fileadr = (*sp).va ;
     fiadr   = searchfile() ;

     fclose((*fiadr).fp) ;            /*まずクローズ(エラーでも良い)*/
     fp = fopen((*fiadr).rfname,"rb") ;
     if(fp == NULL)
      fileerrmsg(13,"reset",fiadr,"が不定である") ;

     (*fiadr).mode = inspection ;     /* 検査モード                 */
     (*fiadr).fp   = fp ;
     fread(store+fileadr, (*fiadr).filesize*sizeof(_store),1,fp) ;
                                        /* 最初の要素をバッファ変数に */
}

/******************************************/
/* RWT() : テキストファイル以外のrewrite  */
/******************************************/
void RWT(void)
{
  fileinfo *fiadr ;

     fiadr  = searchfile() ;

     fclose((*fiadr).fp) ;            /*まずクローズ(エラーでも良い)*/
     (*fiadr).fp = fopen((*fiadr).rfname,"wb") ;
     if((*fiadr).fp == NULL)
      fileerrmsg(132,"rewrite",fiadr,"のオープンができない") ;

     (*fiadr).mode = generation ;     /* 生成モード                 */
}

/***************************************/
/* TGT() : テキストファイルのget       */
/***************************************/
void TGT(void)
{
  _store *filebuf ;
  fileinfo *fiadr ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     filebuf = (*fiadr).filebuf   ;

     checkinspection("get",fiadr) ;

     if((cd.p==0) && readlnflag) {      /* inputファイルで直前がreadln*/
      T_get(fiadr,filebuf,"get") ;      /* 次の文字を読込             */
      readlnflag = false ;
     }

     if(feof((*fiadr).fp))
      fileerrmsg(16,"get",fiadr,"がEOFとなっている") ;

     T_get(fiadr,filebuf,"get") ;       /* 次の文字を読込             */
}

/***************************************/
/* TPT() : テキストファイルへのput     */
/***************************************/
void TPT(void)
{
  FILE *fp        ;
  fileinfo *fiadr ;
  _store *filebuf ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     fp      = fiadr->fp        ;
     filebuf = fiadr->filebuf   ;

     checkgeneration("put",fiadr) ;

     if(fputc(filebuf->vc,fp) == EOF)   /* 文字出力                   */
      err131("put",fiadr) ;
     (*fiadr).writelnflag = false ;
}

/***************************************/
/* TRS() : テキストファイルへのreset   */
/***************************************/
void TRS(void)
{
  FILE *fp ;
  fileinfo *fiadr ;
  _store *filebuf ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */

     if((fiadr==fi) || (fiadr==fi+1))   /* input,outputファイル       */
      fileerrmsg(81,"reset",fiadr,"に対してresetはできない") ;

     filebuf = (*fiadr).filebuf         ;

     if((*fiadr).mode == generation)    /* 今が生成モードの時         */
      if(! (*fiadr).writelnflag)        /* 最後が改行マークでない時   */
       if(fputc('\n',(*fiadr).fp) == EOF)    /* 改行を書き込む        */
        err131("reset",fiadr) ;
     fclose((*fiadr).fp) ;              /* ファイルクローズ           */
     fp = fopen((*fiadr).rfname,"rt") ;   /* テキストモードオープン   */
     if(fp == NULL)
      fileerrmsg(13,"reset",fiadr,"が不定である") ;
     (*fiadr).fp   = fp ;
     (*fiadr).mode = inspection ;       /* 検査モード                 */
     (*fiadr).textfile = true   ;       /* テキストファイル           */

     T_get(fiadr,filebuf,"reset") ;     /* 最初の文字を読む           */
}

/***************************************/
/* TRW() : テキストファイルへのrewrite */
/***************************************/
void TRW(void)
{
  fileinfo *fiadr ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */

     if((fiadr==fi) || (fiadr==fi+1))   /* input,outputファイル       */
      fileerrmsg(82,"rewrite",fiadr,"に対してrewriteはできない") ;

     fclose((*fiadr).fp) ;              /*まずクローズ(エラーでも良い)*/
     (*fiadr).fp = fopen((*fiadr).rfname,"wt") ;
     if((*fiadr).fp == NULL)
      fileerrmsg(132,"rewrite",fiadr,"のオープンができない") ;

     (*fiadr).mode = generation ;       /* 生成モード                 */
     (*fiadr).textfile = true   ;       /* テキストファイル           */
     (*fiadr).writelnflag = true;       /* rewrite直後には改行いらない*/
}

/***************************************/
/* WLN() : writeln標準手続き           */
/***************************************/
void WLN(void)
{
  fileinfo *fiadr ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */

     checkgeneration("writeln",fiadr) ;

     if(fputc('\n',(*fiadr).fp) == EOF) err131("writeln",fiadr) ;
     (*fiadr).writelnflag = true ;
}

/***************************************/
/* WRB() : boolean型の出力             */
/***************************************/
void WRB(void)
{
  fileinfo *fiadr ;
  char *put ;
  short i,j,k ;
  FILE *fp  ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     fp = (*fiadr).fp ;

     checkgeneration("write",fiadr) ;

     put = ((*(sp-1)).vb) ?  "TRUE" : "FALSE" ;
     j   = strlen(put) ;                /* 出力文字長                 */
     k   = (short)(*sp).vi ;            /* 出力幅                     */

     if(k>j) {                          /* 空白をつける必要のある時   */
      for(i=1;i<=(k-j);i++)
       if(fputc(' ',fp) == EOF) err131("write",fiadr) ;
     }
     else j= k ;
     for(i=0;i<j;i++)
      if(fputc((short)put[i], fp) == EOF) err131("write",fiadr) ;

     (*fiadr).writelnflag = false ;

     sp-=2;
}

/***************************************/
/* WRC() : テキストファイルに文字出力  */
/***************************************/
void WRC(void)
{
  fileinfo *fiadr ;
  short i   ;
  FILE *fp  ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     fp = (*fiadr).fp ;

     checkgeneration("write",fiadr) ;

     for(i=1;i<(short)(*sp).vi;i++)
      if(fputc(' ',fp) == EOF) err131("write",fiadr) ;
     if(fputc((*(sp-1)).vc,fp) == EOF) err131("write",fiadr) ;

     (*fiadr).writelnflag = false ;

     sp-=2 ;
}

/*************************************************/
/* WRF() : テキストファイルに固定小数点実数出力  */
/*************************************************/
void WRF(void)
{
  fileinfo *fiadr ;
  FILE *fp  ;
  char buf1[80] ;
  char buf2[80] ;
  short width ;
  short i ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */

     fp = (*fiadr).fp ;

     checkgeneration("write",fiadr) ;

     *buf1 = '%' ;                      /*  %1.xfという形を生成       */
     sprintf(buf1+1,"1.%df",(short)sp->vi) ;       /* 少数点以下の桁数*/
     width = sprintf(buf2,buf1,(*(sp-2)).vr);      /* 固定小数点変換  */
     for(i=width;i<(short)(*(sp-1)).vi;i++)
      if(fputc(' ',fp) == EOF)          /* 前に空白を出力する         */
       err131("write",fiadr) ;
     if(fputs(buf2,fp) != 0) err131("write",fiadr) ;

     (*fiadr).writelnflag = false ;

     sp-=3 ;
}

/***************************************/
/* WRI() : テキストファイルに整数出力  */
/***************************************/
void WRI(void)
{
  char buf[12];
  fileinfo *fiadr ;
  FILE *fp  ;
  short i,len ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     fp = (*fiadr).fp ;

     checkgeneration("write",fiadr) ;

      len=sprintf(buf,"%ld",(*(sp-1)).vi); /* 数字出力に必要な桁      */
      for(i=(short)(*(sp)).vi;i>len;i--)
       if(fputc(' ',fp) == EOF)         /* 数字の前に空白を出力する   */
        err131("write",fiadr) ;
      if(fputs(buf,fp) != 0) err131("write",fiadr) ;

     (*fiadr).writelnflag = false ;

     sp -= 2 ;
}

/*************************************************/
/* WRR() : テキストファイルに浮動小数点実数出力  */
/*************************************************/
void WRR(void)
{
  char     buf[15] ;
  short    keta    ;
  short    width   ;
  short    point   ;
  fileinfo *fiadr  ;
  FILE     *fp     ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     fp = (*fiadr).fp ;

     checkgeneration("write",fiadr) ;

     keta  = (short)(*sp).vi    ;       /* 出力桁                     */
     width = (keta >= 9) ? keta : 9 ;   /* 必要出力桁                 */
     point = width - 8 ;
     *buf = '%' ;                       /* %x.xEの形に変換            */
     sprintf(buf+1,"%d.%dE",width,point);
     fprintf(fp,buf,(*(sp-1)).vr) ;

     (*fiadr).writelnflag = false ;

     sp -= 2 ;
}

/***************************************/
/* WRS() : テキストファイルに文字列出力*/
/***************************************/
void WRS(void)
{
  fileinfo *fiadr ;
  FILE     *fp    ;
  short    i,j,k  ;
  short    ad     ;

     if(cd.p==2) fiadr = searchfile() ;
     else        fiadr = fi + cd.p    ; /* input,outputファイル       */
     fp = (*fiadr).fp ;

     checkgeneration("write",fiadr) ;

     k = (short)(*(sp--)).vi ;          /* k=出力幅                   */
     ad=        (*(sp--)).va ;
     j = cd.q                ;          /* 文字列長                   */

     if(k>j) {                          /* 空白をつける必要のある時   */
      for(i=0;i<(k-j);i++)
       if(fputc(' ',fp) == EOF) err131("write",fiadr) ;
     }
     else j= k ;
     for(i=0;i<j;i++)
      if(fputc(store[ad+i].vc,fp) == EOF) err131("write",fiadr) ;

     (*fiadr).writelnflag = false ;
}
