write_block(long v) /* 將 ddd 中內容拷至當前行指定位置 */
{ /* 參數 v 為拷貝後塊尾行號 */
int i,g;
char *b;
b=malloc(HC); /* 為 b 分配內存空間 */
strcpy(b,ss[ss_x]+yy); /* 將當前行光標後字符串暫放入 b 中 */
if(ss_max-ss_x>Q3+H3) wfp2(); /* 如編輯數組當前行後較多,存一些到 fp2 */
for(;;) { /* 建一個無限循環 */
write_prompt(0); /* 提示“請稍候...” */
if((g=v-xx)<QB-1-ss_max) { /* 如塊移入後編輯數組不會溢出 */
mov(ss_x+1,g); /* 將目標行後的編輯數組後移 */
ss_max+=g; /* 編輯數組已用最大行號增加 */
fp_rd+=g; /* fp 已讀出最大行號增加 */
ttl_x+=g; /* 文末行行號增加 */
while(*ddd) { /* *ddd 為真則循環 */
ss[ss_x][yy]=*ddd++; /* ddd 中字符讀入當前行 yy 處 */
ser++; /* 字序數加 1 */
if(ss[ss_x][yy++]==0x0A) { /* 如讀到一換行符後 */
ss[ss_x][yy]=0; /* 串尾加 '\0' 定界 */
ss_x++; xx++; /* 下移一行 */
yy=0; /* 至行首列 */
}
}
strcpy(ss[ss_x]+yy,b); /* b 中字串接到行尾 */
break; /* 跳出 for 循環 */
}
else { /* 如編輯數組裝不下 */
if(ss_x>Q1) wfp1(); /* 如當前行在後半數組,寫一部分到 fp1 */
else { /* 如當前行在前半數組 */
mov(ss_x+1,(g=QB-1-ss_max)); /* 將當前行後的編輯數組後移 */
ss_max=QB-1; /* 定數組已用最大行行號 */
for(i=0;i<g;i++) { /* ddd 中字塊讀入編輯數組共 g 行 */
while(*ddd) { /* *ddd 為真則循環 */
ss[ss_x][yy]=*ddd++; /* ddd 中內容讀入數組行當前列 */
ser++; /* 字序號加 1 */
if(ss[ss_x][yy++]==0x0A) { /* 如遇到換行符 */
ss[ss_x][yy]=0; /* 以'\0'結束本行 */
ss_x++; xx++; /* 行號增 1 */
yy=0; /* 至行首列 */
fp_rd++; /* fp 已讀出最大行號增 1 */
ttl_x++; /* 文末行行號加 1 */
break; /* 填完一行,跳出 while 循環 */
}
}
}
}
}
}
free(b); /* 釋放內存 */
clear_prompt(); /* 清提示區 */
}
del_block() /* 刪除塊 */
{
int j;
write_prompt(0); /* 提示“請稍候...” */
/* 以下計算刪除原塊後,原光標位置的變化 */
if(!(txx<ksx||(txx==ksx && tyy<=ksy))) {
if(txx>kwx) txx-=kwx-ksx;
else {
if(txx==kwx && tyy>kwy) tyy-=kwy-ksy;
else tyy=ksy;
txx=ksx;
}
}
Ctrl_F(0); /* 移到塊首,不顯示 */
if(ksx==kwx) strcpy(ss[ss_x]+yy,ss[ss_x]+kwy);
/* 如塊首塊尾在同一行,將塊尾後的字符串拷至塊首起 */
else { /* 如塊首塊尾不在同一行 */
Ctrl_T(0); /* 塊首行刪至行末,不顯示 */
ser+=2; /* 計算字序數 */
xx++; ss_x++; /* 至下行 */
y=0; yy=0; /* 至行首 */
while(xx<kwx) Ctrl_Y(0); /* 逐行刪除,不顯示 */
yy=kwy; /* 當前行已移至塊尾行,列號定為塊尾列號 */
ser+=yy; /* 計算塊尾列的字序號 */
Ctrl_E(0); /* 刪至行首,不顯示 */
delc(); /* 本行剩余部分接至塊前 */
}
ser+=tyy-yy; /* 計算字序數 */
if((j=ss_x+H3-x)>ss_max && j<ttl_x) tj();
/* 屏幕文本區底行超出數組,且未到文末,從 fp 或 fp2 讀入 */
mvto(txx); /* 重返原坐標 */
clear_prompt(); /* 清提示區 */
}
int read_block() /* 字塊讀入緩沖區 ddd */
{
int i,j;
write_prompt(0); /* 提示“請稍候...” */
txx=xx; /* 保存原文本行號 */
tyy=yy; /* 保存原文本列號 */
Ctrl_F(0); /* 移到塊首,不顯示 */
if(ksx==kwx) { /* 如塊首塊尾在同一行 */
j=kwy-ksy; /* 計算塊串長 */
ddd=malloc(j+2); /* 給 ddd 分配內存空間 */
dd=ddd; /* 保存 ddd 指針首址 */
for(i=0;i<j;i++) *ddd++=ss[ss_x][ksy+i]; /* 塊讀入 ddd */
*ddd++=0; /* ddd 以 '\0' 結尾 */
vv=i; /* 統計塊長字節數 */
yy+=i; /* 移至塊尾 */
}
else { /* 如塊首塊尾不在同一行 */
ddd=malloc(KK); /* 給 ddd 分配內存空間 */
dd=ddd; /* 保存 ddd 首指針 */
first=strlen(ss[ss_x])-ksy; /* 計算塊首行中塊串長 */
vv=first; /* 計算讀入字節數 */
for(i=0;i<first;i++) *ddd++=ss[ss_x][ksy+i]; /* 首行中塊串讀入 ddd */
xx++; ss_x++; /* 至下行 */
yy=0; /* 至行首 */
for(;;) { /* 為讀入字塊建的循環 */
tj(); /* 如當前行在數組後半部,寫 Q3 行到 fp1,
數組行數不足數組一半,從 fp1 或 fp2 補充之 */
if(kwx-xx<=ss_max-ss_x) { /* 如塊尾在當前編輯數組中 */
while(xx<kwx) /* 當前行在塊尾行前則循環 */
if(hb()) return 1; /* 讀入 ddd 中,如塊太大返回 1 */
break; /* 退出 for 循環 */
}
else /* 如塊尾不在編輯數組中 */
while(ss_x<ss_max) /* 數組中的字塊部分讀入ddd */
if(hb()) return 1; /* 計算字節數,讀入 ddd,如塊太大返回 1 */
}
for(i=0;i<kwy;i++) *ddd++=ss[ss_x][i]; /* 讀入塊末行的塊串 */
vv+=i; /* 計算讀入的字節數 */
yy=kwy; /* 到塊尾 */
*ddd=0; /* ddd 以 '\0' 結尾 */
}
ser+=vv; /* 計算字序數 */
ddd=dd; /* 返回指針頭 */
clear_prompt(); /* 清提示區 */
return 0; /* 正常讀完,返回 0 */
}
int hb() /* 計算塊的字節數,讀入 ddd 中 */
{
int i=0;
vv+=strlen(ss[ss_x]); /* 計算讀入的字節數 */
if(vv>=KK-255) { /* 如字節數超出 ddd 最大空間 */
mvto(txx); /* 重返原坐標 */
comp_disp(); /* 重顯原屏幕 */
write_prompt(2); /* 提示“塊太大!” */
clear_ques(); /* 清提問區 */
ddd=dd; /* 返回首指針 */
free(ddd); /* 釋放 ddd 占用內存空間 */
return 1; /* 返回 1 */
}
while(ss[ss_x][i]) *ddd++=ss[ss_x][i++]; /* 讀一行至 ddd */
ss_x++; xx++; /* 至下一行 */
return 0; /* 返回 0 */
}
int over(int g) /* 行超長處理,g 為當前行長度 */
{
if((kwx==ksx && vv+g>HC-4)||
(kwx!=ksx &&(tyy+first>HC-4 || g-tyy+kwy>HC-4))) {
mvto(txx); /* 重返原坐標 */
comp_disp(); /* 重顯原屏幕 */
ddd=dd; /* 返回指針頭 */
free(ddd); /* 釋放 ddd 占用的內存空間 */
write_prompt(3); /* 提示:行超長 */
return 1; /* 發生超長返回 1 */
}
return 0; /* 未發生行超長返回 0 */
}
Ctrl_W() /* 字塊存盤 */
{
long g;
if(blck==2) { /* 如已定義塊 */
g=ser; /* 保存字序號 */
write_ques(1); /* 提問存盤文件名 */
if(key_string(HH,25,hsz,PROM_COLOR)<=0) { /* 如為空串或按 ESC */
clear_ques(); /* 清提問區 */
return; /* 退出本功能 */
}
if(findfirst(hsz,pt,0)==0){ /* 如當前目錄中已有此文件 */
write_ques(2); /* 提問是否復蓋 */
if(key_yn(30)<1) { /* 輸入 Y 或 N,如按 ESC 鍵或輸入 N */
clear_ques(); /* 清提問區 */
return; /* 退出本功能 */
}
}
fp3=fopen(hsz,"wb+"); /* 以寫方式打開文件 hsz,文件指針放入 fp3 */
if(read_block()) { /* 讀塊到 ddd ,如失敗,跳出開關語句 */
ser=g; /* 恢復原參數 */
return; /* 退出本功能 */
}
write_prompt(0); /* 提示“請稍候...” */
fwrite(ddd,sizeof(char),vv,fp3); /* ddd 中內容寫入文件 fp3 */
fputc(0x1A,fp3); /* 加文件結束符 */
fclose(fp3); /* 關閉文件 fp3 */
free(ddd); /* 釋放 ddd 占用的內存 */
mvto(txx); /* 重返原坐標 */
ser=g; /* 恢復原參數 */
comp_disp(); /* 重顯屏幕 */
clear_prompt(); /* 清提示區 */
clear_ques(); /* 清提問區 */
}
else write_prompt(1); /* 提示:請先定義塊 */
}
Ctrl_R() /* 外部文件讀入光標處 */
{
int i,j,g,v;
write_ques(3); /* 提問外部文件名 */
if(key_string(HH,23,hsz,PROM_COLOR)<=0) { /* 輸入字符串,如為空串或按 ESC */
clear_ques(); /* 清提問區 */
return; /* 退出本功能 */
}
if((fp3=fopen(hsz,"rb"))==NULL){ /* 如文件不存在 */
clear_ques(); /* 清提問區 */
write_prompt(6); /* 提示文件未找到 */
return; /* 退出本功能 */
}
chg=1; /* 文件已修改標志置為真 */
txx=xx; /* 保存文本行號 */
tyy=yy; /* 保存文本列號 */
*hsz=0; /* 字符串置為空串 */
g=0; /* 累計讀入行數置初值 0 */
for(;;) { /* 分批讀入的循環 */
ddd=malloc(KK+1); /* 給 ddd 分配內存 */
dd=ddd; /* 保存 ddd 首指針 */
j=fread(ddd,sizeof(char),KK,fp3); /* 讀文件KK字節至ddd */
v=0; /* 本次讀入行數置初值 0 */
while(*ddd) { /* *ddd 為真則循環 */
if(*ddd==0x1A) { /* 以 '\0' 代替文件結束符 */
*ddd=0;
break; /* 退出循環 */
}
if(*ddd++==0x0A) { /* 計算讀入行數 */
++v; /* 本次循環讀入行數加 1 */
++g; /* 累計讀入行數加 1 */
}
}
ddd=dd; /* 恢復指針到指針頭 */
v+=xx; /* 計算本次拷入後光標行號 */
write_block(v); /* ddd 中內容拷入當前位置 */
ddd=dd; /* 恢復 ddd 指針到指針頭 */
free(ddd);
if(j<KK) break; /* 讀入字節數小於 KK 時,文件已讀完 */
}
if(txx<ksx) ksx+=g; /* 如當前行在塊首行前,塊首行號增加讀入文件行數 */
else { /* 如當前行不在塊首行前 */
if(txx==ksx && tyy<=ksy) { /* 如當前行為塊首行,當前列在塊首列前 */
ksx+=g; /* 塊首行行號增加 g */
ksy+=yy-tyy; /* 計算塊首列列號 */
}
}
if(txx<kwx) kwx+=g; /* 如當前行在塊尾行後,塊尾行行號增加 g */
else { /* 如當前行不在塊尾行後 */
if(txx==kwx && tyy<=kwy) { /* 如當前行在塊尾行,並在塊尾列前 */
kwx+=g; /* 塊尾行行號加 g */
kwy+=yy-tyy; /* 計算塊尾列列號 */
}
}
comp_disp(); /* 計算顯示參數,重顯當前屏幕 */
fclose(fp3); /* 關閉外部文件 */
clear_ques(); /* 清提問區 */
}
Ctrl_P() /* 當前編輯文本的打印 */
{
FILE *fpw,*fpr;
unsigned char prt[255];
int i,j,k,a,b=0,pg;
write_ques(8); /* 提問每頁打印行數 */
if((j=key_digit(22))<=0) { /* 輸入行數,如為空串或按 ESC 鍵 */
clear_ques(); /* 清提問區 */
return; /* 退出本功能 */
}
write_ques(12); /* 提問頁號位置 */
if((k=key_digit(20))<=0) { /* 輸入起始列號,如為空串或按 ESC 鍵 */
clear_ques(); /* 清提問區 */
return; /* 退出本功能 */
}
write_ques(13); /* 提問起始頁號 */
if((pg=key_digit(16))<=0) { /* 輸入起始頁號,如為空串或按 ESC 鍵 */
clear_ques(); /* 清提問區 */
return; /* 退出本功能 */
}
Shift_F1(); /* 存盤不退出 */
if((fpr=fopen(mfile,"rb"))==NULL) { /* 打開主文件,指針賦於 fpr,如失敗返回 */
clear_ques(); /* 清提問區 */
return; /* 退出本功能 */
}
fpw=fopen("PRN","w"); /* 打開設備文件(打印機),指針賦於 fpw */
while(1) { /* 為分頁打印設的循環 */
write_ques(10); /* 提示:調整好打印機,按一鍵開始打印 */
if(gett()==-1||tpt()==-1) { /* 測打印機,如按 Esc 鍵 */
fclose(fpr); /* 關閉 fpr */
clear_ques(); /* 清提問區 */
return; /* 返回 */
}
for(i=0;i<j;i++) { /* 為一頁內分行打印設的循環 */
if(fgets(prt,255,fpr)==NULL) { /* 從 fpr 讀入一行至 prt, 如失敗 */
while(i++<j) { /* 未打滿一頁則循環 */
fprintf(fpw,"\n"); /* 打印一空行 */
b=1; /* 文件結束標志置 1 */
}
break; /* 跳出 for 循環 */
}
for(a=0;prt[a];a++) { /* 去除字符串中的回車換行符 */
if(prt[a]==0x0D || prt[a]==0x8D) break;
}
prt[a]=0; /* 字符串以 '\0' 定界 */
fprintf(fpw,"%s\n",prt); /* 打印一行 */
}
fprintf(fpw,"\n"); /* 走紙一行 */
for(a=0;a<k;a++) fprintf(fpw," "); /* 打印頁號前空格 */
fprintf(fpw,"·%d·\n",pg++); /* 打印頁號 */
if(b) break; /* 如打印完全文,退出循環 */
}
clear_ques(); /* 清提問區 */
fclose(fpr); /* 關閉打印的文本文件 */
fclose(fpw); /* 關閉打印機文件 */
}
int tpt() /* 打印機狀態測試 */
{
while(1) { /* 為重復測試建的循環 */
if(inp(0x379)==0xDF) break; /* 取 0x379 端口值,如等於 0xDF, 跳出循環 */
else write_ques(9); /* 否則提示打印機未准備好 */
if(gett()==-1) { /* 等待按鍵,Esc 鍵返回 -1,否則繼續循環 */
clear_ques(); /* 清提問區 */
return -1; /* 返回 -1 */
}
}
write_ques(11); /* 提示“正在打印....” */
return 0; /* 返回 0 */
}
Esc() /* 放棄存盤,退出編輯 */
{
if(chg) { /* 如文本已修改過 */
write_ques(0); /* 提問:是否放棄並退出編輯 */
if(key_yn(26)<1) { /* 如輸入 N */
clear_ques(); /* 清提問區 */
return; /* 返回,繼續編輯 */
}
}
bk(); /* 退出程序,至 DOS 下 */
}
Chr() /* 輸入字符 */
{
static bb=0; /* 定義一個靜態變量作為全角一、三區字符標志 */
int j,g,k;
if(cc.ch[0]==0xF0 && cc.ch[1]==76) return; /* 屏蔽小鍵盤中間鍵 */
if(cc.ch[0]>31) { /* 屏蔽控制鍵 */
chg=1; /* 文件已修改標志置為真 */
qq=0; /* 全角制表符標志變量初始化 */
make_tab(); /* 如表線開關為開,產生表格線 */
AA: z2=cc.ch[0]; /* 將字符放入 z2 */
if(yy>=enq) { /* 如在排版寬度以後 */
if(vs(enq-1)==0) { /* 如排版長度處不為全角後半部 */
if(yy==enq) { /* 如寫在排版長度處 */
if(z2<160) { /* 如為半角字符 */
if(punc1(z2)) goto BB; /* 如為指定標點符號,轉寫入字符串 */
else k=enq; /* 如不是,在此處折斷 */
}
else { /* 如為全角字符 */
if(z2==161 || z2==163) { /* 如第一字節在一、三區 */
z1=z2; /* 輸入字符從 z2 移入 z1 暫存 */
bb=1; /* 全角一、三區標志置 1 */
goto BB; /* 先寫入字符串 */
}
else k=enq; /* 否則在此處折斷 */
}
}
else { /* 如在排版長度之後 */
if(bb && punc2(z1,z2)) goto BB;
/* 如為指定全角標點符號,寫入字符串 */
else { /* 否則檢查排版長處字符 */
bb=0; /* 全角一、三區標志 bb 恢復初值 */
a1=ss[ss_x][enq]; /* 排版長處取一字節,放入 a1 */
if(a1<160) { /* 如為半角字符 */
if(punc1(a1)) k=enq+1; /* 如為指定半角標點,折斷處後移一字節 */
else k=enq; /* 否則原處折斷 */
}
else { /* 如為全角字符 */
a2=ss[ss_x][enq+1]; /* 再取一字節放入 a2 */
if(punc2(a1,a2)) /* 如為指定全角標點*/
k=enq+2; /* 折斷處後移二字節 */
else k=enq; /* 否則原處折斷 */
}
}
}
}
else { /* 排版長度處為全角字符後半部 */
z1=ss[ss_x][enq-1]; /* 讀出全角前半部 */
if(yy==enq) { /* 如寫入處在排版長度處 */
if(punc2(z1,z2)) goto BB; /* 如為指定全角標點, 轉寫入字符串 */
else k=enq-1; /* 否則折斷處前移一字節 */
}
else { /* 如寫入在排版長之後 */
a2=ss[ss_x][enq]; /* 檢查應折斷處字符 */
if(punc2(z1,a2)) /* 如為指定全角標點 */
k=enq+1; /* 折斷處後移一字符 */
else k=enq-1; /* 否則,折斷處前移一字節 */
}
}
intercept(k); /* 折斷字符串換行 */
strcpy(ss[ss_x-1]+k,ra); /* 折斷處加軟回車符 0x8D0A */
yy-=k; /* 計算列號 */
comp_disp(); /* 計算參數,重顯當前屏幕 */
}
BB: g=string_lingth(); /* 計算行長(不包括回車換行符) */
if(ins || yy==g) { /* 如為插入狀態或寫在行末 */
if(g>HC-4) { /* 如行超長退回 */
write_prompt(3); /* 提示:行超長 */
return; /* 退出 */
}
if(xx==ksx && yy<ksy) ksy++; /* 計算塊坐標變化 */
if(xx==kwx && yy<kwy) kwy++;
for(j=g+3;j>yy;j--) ss[ss_x][j]=ss[ss_x][j-1];
} /* 插入字符後的字符依次後移 */
else { /* 如為非插入狀態 */
if(cc.ch[0]<127 && ss[ss_x][yy]>0xA0) ss[ss_x][yy+1]=32;
/* 如為半角復蓋全角,全角後半字填空格 */
if(vs(yy)==0 && cc.ch[0]>0xA0 && ss[ss_x][yy]<127
&& ss[ss_x][yy+1]>0xA0){ /* 如為全角復蓋一個半角和一個全角的前半部 */
ss[ss_x][yy+2]=32; /* 全角後半字節填空格 */
}
}