ファイル名:edit.rc
#include <windows.h>
#include "edit.h"
editmenu MENU
BEGIN
POPUP "ファイル(\036F\037フ)"
BEGIN
MENUITEM "新規作成(\036N\037サ)", IDM_NEW
MENUITEM "開く(\036O\037ヒ)...", IDM_OPEN
MENUITEM "上書き保存(\036S\037セ)", IDM_SAVE
MENUITEM "名前をつけて保存(\036A\037ナ)...", IDM_NAME
MENUITEM SEPARATOR
MENUITEM "終了(\036X\037シ)", IDM_EXIT
END
POPUP "編集(\036E\037ヘ)"
BEGIN
MENUITEM "元に戻す(\036U\037モ) Ctrl+Z", IDM_UNDO
MENUITEM SEPARATOR
MENUITEM "切り取り(\036T\037キ) Ctrl+X", IDM_CUT
MENUITEM "コピー(\036C\037コ) Ctrl+C", IDM_COPY
MENUITEM "貼り付け(\036P\037ハ) Ctrl+V", IDM_PASTE
MENUITEM "削除(\036L\037サ) DEL", IDM_DEL
MENUITEM "すべての範囲を選択(\036L\037ス) Ctrl+A", IDM_ALL
MENUITEM SEPARATOR
MENUITEM "右端で折り返す(\036W\037ミ)", IDM_FOLD
END
POPUP "検索(\036S\037ケ)"
BEGIN
MENUITEM "文字列の検索(\036F\037ケ)...", IDM_FIND
MENUITEM "次を検索(\036N\037ツ) F3", IDM_NEXT
MENUITEM "文字列の置換(\036R\037チ)...", IDM_REP
END
POPUP "ヘルプ(\036H\037ヘ)"
BEGIN
MENUITEM "ヘルプの表示(\036H\037ヘ)... F1", IDM_HELP
MENUITEM "バージョン情報(\036A\037シ)...", IDM_ABOUT
END
END
editaccel ACCELERATORS
BEGIN
VK_F3, IDM_NEXT, VIRTKEY
VK_F1, IDM_HELP, VIRTKEY
"^A", IDM_ALL
END
#include "edit.dlg"
#include "search.dlg"
#include "replace.dlg"
ファイル名:edit.c
#pragma resource "edit.res"
#define STRICT
#include <windows.h>
#include <windowsx.h>
#include "edit.h"
#include <commdlg.h>
#include <shellapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>/*filelength()*/
#ifdef WIN32
#define fmalloc(size) malloc(size)
#define ffree(ptr) free(ptr)
#define MAXPATH 260
#define MAXNAME 256
#define Edit_GetSelEnd(hCtl, end) (SendMessage((hCtl), EM_GETSEL, 0, (LPARAM)&(end)))
#else
#define fmalloc(size) MAKELONG(0,GlobalAlloc(GMEM_FIXED,size))
#define ffree(ptr) GlobalFree((HGLOBAL)HIWORD(ptr))
#define MAXPATH 80
#define MAXNAME 13
#define Edit_GetSelEnd(hCtl, end) ((end)=HIWORD(SendMessage((hCtl), EM_GETSEL, 0, 0L)))
#endif
unsigned int MAXTEXTSIZE;
DLGPROC lpSearch, lpReplace;
HWND hDlgMain, hDlgSearch, hDlgReplace;
HINSTANCE hInstApp;
char searchstr[256], replacestr[256];
int nocheck;
char buf[512];
#define ARGCMAX 16
/*static*/ int argc=16;
/*static*/ char *argv[ARGCMAX];
void cmdlinesprit(LPSTR CmdLin);
void pathsplit(const char *path, char *dir, char*name);
WORD Version(void){
WORD version = LOWORD(GetVersion());
version = (WORD)((LOBYTE(version)<<8) + HIBYTE(version));
#ifndef WIN32
if (version==0x35f) { /* Win16ではWin95と98で同じバージョン番号が返る */
WORD DosVersion = HIWORD(GetVersion());
if (DosVersion >=0x70a) version+=3;
}
#endif
return version;
}
int isNT32(void){
#ifdef WIN32
WORD DosVersion = HIWORD(GetVersion());
if (DosVersion & 0x8000) return FALSE; else return TRUE;
#else
return FALSE;
#endif
}
void foldchange(HWND hDlg){
RECT rc; LPSTR p; UINT writesize;
HWND hwndCtl=GetDlgItem(hDlg,IDEDIT);
LONG ws =GetWindowLong(hwndCtl, GWL_STYLE );
LONG wsex=GetWindowLong(hwndCtl, GWL_EXSTYLE);
int modify=SendDlgItemMessage(hDlg, IDEDIT, EM_GETMODIFY, 0, 0);
if (ws&WS_HSCROLL) ws=ws&(~WS_HSCROLL), CheckMenuItem(GetMenu(hDlg), IDM_FOLD, MF_CHECKED);
else ws=ws|( WS_HSCROLL), CheckMenuItem(GetMenu(hDlg), IDM_FOLD, MF_UNCHECKED);
GetClientRect (hDlg, &rc);
p=(LPSTR)fmalloc(MAXTEXTSIZE+1);
writesize=SendMessage(hwndCtl, WM_GETTEXT, MAXTEXTSIZE, (DWORD)p);
p[writesize]=0;
DestroyWindow(hwndCtl);
CreateWindowEx(wsex, "edit", p, ws, 0, 0, rc.right, rc.bottom, hDlg, (HMENU)IDEDIT, hInstApp, NULL);
SetFocus(GetDlgItem(hDlg,IDEDIT));
SendDlgItemMessage(hDlg, IDEDIT, EM_SETMODIFY, modify, 0);
UpdateWindow(GetDlgItem(hDlg,IDEDIT));
ffree(p);
}
void SetTitleBar(HWND hwnd, char *name){
char buf[14+MAXNAME];
if (name==NULL) sprintf(buf, "簡易テキストエディタ:(無題)");
else sprintf(buf, "簡易テキストエディタ:%s", name);
SetWindowText(hwnd, buf);
}
void readtext(HWND hwnd, char *path, char *name){
LPSTR p; UINT readsize; LONG textsize;
HFILE hfile=_lopen(path, OF_READ | OF_SHARE_DENY_WRITE);
if (hfile==HFILE_ERROR) {
MessageBox(hwnd, "オープンできません", "簡易テキストエディタ", MB_OK);
return;
}
#ifdef WIN32
{
WIN32_FIND_DATA ffd; HANDLE h;
h=FindFirstFile(path, &ffd);
if (h==INVALID_HANDLE_VALUE) {
MessageBox(hwnd, "ファイルが見つからない", "簡易テキストエディタ", MB_OK);
return;
}
FindClose(h);
textsize=ffd.nFileSizeLow+ffd.nFileSizeHigh*65536;
}
#else
textsize=filelength(hfile);
#endif
if (textsize>MAXTEXTSIZE){
int res;
if (Version()<0x035f)strcpy(buf, "ファイルが大きすぎます。\nライトで開きますか?");
else strcpy(buf, "ファイルが大きすぎます。ワードパットで開きますか?");
res=MessageBox(hwnd, buf, "簡易テキストエディタ", MB_YESNOCANCEL);
if (res==IDYES || res==IDCANCEL) _lclose(hfile);
if (res==IDYES) {
UINT exe;
if (Version()<0x035f) sprintf(buf, "write %s", path);
else sprintf(buf, "wordpad %s", path);
exe=WinExec(buf, SW_SHOW);
if (exe<32 && Version()>=0x035f){
sprintf(buf, "\"c:\\program files\\accessories\\wordpad\" %s", path);
exe=WinExec(buf, SW_SHOW);
}
if (exe<32) MessageBox(hwnd, "起動できません", "簡易テキストエディタ", MB_OK);
}
if (res==IDYES || res==IDCANCEL) return;
}
p=(LPSTR)fmalloc(MAXTEXTSIZE+1);
if (p==NULL) {
MessageBox(hwnd, "メモリ不足", "簡易テキストエディタ", MB_OK);
return;
}
readsize=_lread(hfile, p, MAXTEXTSIZE);
if (readsize>MAXTEXTSIZE) p[0]=0; /* HFILE_ERROR */
else p[readsize]=0;
SetDlgItemText(hwnd, IDEDIT, p);
ffree(p);
_lclose(hfile);
SetTitleBar(hwnd, name);
SendDlgItemMessage(hwnd, IDEDIT, EM_SETMODIFY , FALSE, 0);
}
void writetext(HWND hwnd, char *path, char *name){
LPSTR p; UINT writesize;
HFILE hfile=_lcreat(path, 0);
if (hfile==HFILE_ERROR) {
MessageBox(hwnd, "オープンできません", "簡易テキストエディタ", MB_OK);
return;
}
writesize=(UINT)SendDlgItemMessage(hwnd, IDEDIT, WM_GETTEXTLENGTH, 0, 0L);
p=(LPSTR)fmalloc(writesize+1);
if (p==NULL) {
int result=
MessageBox(hwnd, "メモリ不足です。一行ずつ書き込みますか?", "簡易テキストエディタ", MB_YESNO);
if (result==IDYES) {
UINT i, maxlin;
SendDlgItemMessage(hwnd, IDEDIT, EM_FMTLINES, TRUE, 0);
maxlin=SendDlgItemMessage(hwnd, IDEDIT, EM_GETLINECOUNT, 0, 0L);
for(i=0; i<maxlin; ++i){
*(WORD *)buf = sizeof(buf);
writesize = SendDlgItemMessage(hwnd, IDEDIT, EM_GETLINE, i, (DWORD)(LPSTR)buf);
buf[writesize]='\r';
buf[writesize+1]='\n';
_lwrite(hfile, buf, writesize+2);
}
_lclose(hfile);
}
return;
}
writesize=SendDlgItemMessage(hwnd, IDEDIT, WM_GETTEXT, writesize+1, (DWORD)p);
//writesize=GetDlgItemText(hwnd, IDEDIT, p, writesize+1);
_lwrite(hfile, p, writesize);
_lclose(hfile);
ffree(p);
SendDlgItemMessage(hwnd, IDEDIT, EM_SETMODIFY , FALSE, 0);
SetTitleBar(hwnd, name);
}
/*ダイアログ関数(Windowsからコールバックされる)*/
#ifdef __cplusplus
extern "C"
#endif
BOOL FAR PASCAL replacedlg(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
switch (msg) {
case WM_CLOSE:
DestroyWindow(hDlg); hDlgReplace=NULL;
return TRUE;
case WM_COMMAND:
switch((WORD)wParam){
case IDOK:
GetDlgItemText(hDlg, IDS_EDIT, searchstr, sizeof(searchstr));
GetDlgItemText(hDlg, IDR_EDIT, replacestr, sizeof(replacestr));
if (IsDlgButtonChecked(hDlg, IDCHECK)) nocheck=1; else nocheck=0;
SendMessage(hDlgMain, WM_COMMAND, IDM_REP2, 0L);
return TRUE;
case IDCANCEL:
DestroyWindow(hDlg); hDlgReplace=NULL;
return TRUE;
}
return TRUE;
case WM_INITDIALOG:
SetDlgItemText(hDlg, IDS_EDIT, searchstr);
SetDlgItemText(hDlg, IDR_EDIT, replacestr);
return TRUE;/* SetFocusしたらfalse */
}
return FALSE;
}
#ifdef __cplusplus
extern "C"
#endif
BOOL FAR PASCAL searchdlg(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
switch (msg) {
case WM_CLOSE:
DestroyWindow(hDlg); hDlgSearch=NULL;
return TRUE;
case WM_COMMAND:
switch((WORD)wParam){
case IDOK:
GetDlgItemText(hDlg, IDS_EDIT, searchstr, sizeof(searchstr));
SendMessage(hDlgMain, WM_COMMAND, IDM_NEXT, 0L);
return TRUE;
case IDCANCEL:
DestroyWindow(hDlg); hDlgSearch=NULL;
return TRUE;
}
return TRUE;
case WM_INITDIALOG:
EnableWindow(GetDlgItem(hDlg, IDCHECK), FALSE);
/* ↑ 大文字小文字の同一視はサポートしない */
SetDlgItemText(hDlg, IDS_EDIT, searchstr);
return TRUE;/* SetFocusしたらfalse */
}
return FALSE;
}
int changesave(HWND hDlg, char *achFilePath, char *achFileTitle){
int ans;
if (SendDlgItemMessage(hDlg, IDEDIT, EM_GETMODIFY, 0, 0)) {
sprintf(buf, "%sは変更されています。保存しますか?", achFilePath[0]?achFileTitle:"無題");
ans=MessageBox(hDlg, buf, "簡易テキストエディタ", MB_YESNOCANCEL);
if (ans==IDCANCEL) return TRUE;
if (ans==IDYES) SendMessage(hDlg, WM_COMMAND, IDM_SAVE, 0L);
}
return FALSE;
}
#ifdef __cplusplus
extern "C"
#endif
BOOL FAR PASCAL dlgproc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
RECT rc;
static OPENFILENAME ofn;
static char achFilePath[MAXPATH], achFileTitle[MAXNAME];
int end, lin, maxlin, i;
HFONT hfont;
switch(msg){
case WM_COMMAND:
switch((WORD)wParam) {/*コントロールID*/
case IDM_NEW:
if (changesave(hDlg, achFilePath, achFileTitle)) break;
SetDlgItemText(hDlg, IDEDIT, "");
achFilePath[0]=achFileTitle[0]=0;
SetTitleBar(hDlg, NULL);
SendDlgItemMessage(hDlg, IDEDIT, EM_SETMODIFY, FALSE, 0);
break;
case IDM_SAVE:
if (achFilePath[0]==0) SendMessage(hDlg, WM_COMMAND, IDM_NAME, 0L);
else writetext(hDlg, achFilePath, achFileTitle);
break;
case IDM_OPEN:
if (changesave(hDlg, achFilePath, achFileTitle)) break;
/*NO BREAK*/
case IDM_NAME:
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hDlg;
ofn.lpstrFilter = "テキスト(*.TXT)\0*.TXT\0全ファイル(*.*)\0*.*\0";
ofn.lpstrCustomFilter = NULL;
ofn.nFilterIndex = 1;
if ((WORD)wParam==IDM_OPEN) achFilePath[0] = 0;
else strcpy(achFilePath,achFileTitle);
ofn.lpstrFile = (LPSTR)achFilePath;
ofn.nMaxFile = sizeof(achFilePath);
ofn.lpstrFileTitle = (LPSTR)achFileTitle;
ofn.nMaxFileTitle = sizeof(achFileTitle);
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = NULL; //ofn.lpstrTitle = "ファイルを開く";
ofn.lpstrDefExt = NULL;
if ((WORD)wParam==IDM_OPEN) ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
else ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
if ((WORD)wParam==IDM_OPEN) {
if(GetOpenFileName((LPOPENFILENAME)&ofn))
readtext(hDlg, achFilePath, achFileTitle);
}else{
if (GetSaveFileName((LPOPENFILENAME)&ofn))
writetext(hDlg, achFilePath, achFileTitle);
}
break;
case IDCANCEL: case IDM_EXIT:
SendMessage(hDlg, WM_CLOSE, 0, 0L);
break;
case IDM_ABOUT:
MessageBox(hDlg, "簡易エディタ\nバージョン 0.03\nCopyright (c)のぐー",
"バージョン情報", MB_OK);
break;
case IDM_FIND:
if (hDlgSearch) SetActiveWindow(hDlgSearch);
else hDlgSearch=CreateDialog(hInstApp, "searchdlg", hDlg, lpSearch);
break;
case IDM_NEXT:
if (searchstr[0]==0) {
PostMessage(hDlg, WM_COMMAND, IDM_FIND, 0L);
break;
}
maxlin=SendDlgItemMessage(hDlg, IDEDIT, EM_GETLINECOUNT, 0, 0L);
Edit_GetSelEnd(GetDlgItem(hDlg, IDEDIT), end);
lin=SendDlgItemMessage(hDlg, IDEDIT, EM_LINEFROMCHAR, end, 0L);
end=end-SendDlgItemMessage(hDlg, IDEDIT, EM_LINEINDEX, lin, 0L);
for(;;){
int cbText; char *p;
*(WORD *) buf = sizeof(buf) - 1;
cbText = (int) SendDlgItemMessage(hDlg, IDEDIT, EM_GETLINE, lin, (DWORD) (LPSTR) buf);
buf[cbText] = '\0';
if ((p=strstr(buf+end, searchstr))!=NULL) {
int sta=SendDlgItemMessage(hDlg, IDEDIT, EM_LINEINDEX, lin, 0L)+(p-buf);
Edit_SetSel(GetDlgItem(hDlg, IDEDIT), sta, sta+strlen(searchstr));
break;
}
lin++; end=0;
if (lin>maxlin) {
MessageBox(hDlg, "見つかりません", "簡易エディタ", MB_OK);
break;
}
}
break;
case IDM_REP:
if (hDlgReplace) SetActiveWindow(hDlgReplace);
else hDlgReplace=CreateDialog(hInstApp, "replacedlg", hDlg, lpReplace);
break;
case IDM_REP2:
if (searchstr[0]==0) break;
maxlin=SendDlgItemMessage(hDlg, IDEDIT, EM_GETLINECOUNT, 0, 0L);
lin=end=0;
for(;;){
int cbText; char *p;
*(WORD *) buf = sizeof(buf) - 1;
cbText = (int) SendDlgItemMessage(hDlg, IDEDIT, EM_GETLINE, lin, (DWORD) (LPSTR) buf);
buf[cbText] = '\0';
if ((p=strstr(buf+end, searchstr))!=NULL) {
int answer;
int sta=SendDlgItemMessage(hDlg, IDEDIT, EM_LINEINDEX, lin, 0L)+(p-buf);
Edit_SetSel(GetDlgItem(hDlg, IDEDIT), sta, sta+strlen(searchstr));
if (nocheck) answer=IDYES;
else answer=MessageBox(hDlg, "置換しますか?", "簡易エディタ", MB_YESNOCANCEL);
if (answer==IDYES)
SendDlgItemMessage(hDlg, IDEDIT, EM_REPLACESEL, 0, (LPARAM)(LPSTR)replacestr);
if (answer==IDCANCEL) break;
Edit_GetSelEnd(GetDlgItem(hDlg, IDEDIT), end);
lin=SendDlgItemMessage(hDlg, IDEDIT, EM_LINEFROMCHAR, end, 0L);
end=end-SendDlgItemMessage(hDlg, IDEDIT, EM_LINEINDEX, lin, 0L);
}else
lin++, end=0;
if (lin>maxlin) {
MessageBox(hDlg, "置換が終了しました", "簡易エディタ", MB_OK);
break;
}
}
break;
case IDM_DEL : SendDlgItemMessage(hDlg, IDEDIT, EM_REPLACESEL, 0, (LPARAM)(LPSTR)""); break;
case IDM_CUT : SendDlgItemMessage(hDlg, IDEDIT, WM_CUT , 0, 0); break;
case IDM_UNDO : SendDlgItemMessage(hDlg, IDEDIT, EM_UNDO , 0, 0); break;
case IDM_COPY : SendDlgItemMessage(hDlg, IDEDIT, WM_COPY , 0, 0); break;
case IDM_PASTE: SendDlgItemMessage(hDlg, IDEDIT, WM_PASTE, 0, 0); break;
case IDM_ALL: Edit_SetSel(GetDlgItem(hDlg, IDEDIT), 0, -1); break;
case IDM_FOLD:
foldchange(hDlg);
break;
case IDM_HELP:
WinHelp(hDlg, "notepad.hlp", HELP_CONTENTS, 0L);
break;
}
break;
case WM_QUERYENDSESSION:
if (changesave(hDlg, achFilePath, achFileTitle))
return TRUE;/*TRUEを返すとWindowsが終了しない(一般のウィンドウと逆)*/
return FALSE;
case WM_CLOSE:
if (changesave(hDlg, achFilePath, achFileTitle))
return TRUE; /*メッセージを握りつぶす(デフォルト処理を実行しない)*/
DestroyWindow(hDlg);
return TRUE; /* FALSEだとエラー */
case WM_DROPFILES: {
UINT cFiles, a;
if (changesave(hDlg, achFilePath, achFileTitle)) break;
cFiles = DragQueryFile((HDROP) wParam, (UINT)-1, (LPSTR) NULL, 0U);
if (cFiles>1) cFiles=1; /* 最初の一個だけ */
for(a = 0; a < cFiles; a++) {
DragQueryFile((HDROP) wParam, a, achFilePath, sizeof(achFilePath));
pathsplit(achFilePath, buf, achFileTitle);
readtext(hDlg, achFilePath, achFileTitle);
}
DragFinish((HDROP) wParam);
break;
}
case WM_DESTROY:
DragAcceptFiles(hDlg, FALSE);
PostQuitMessage(0);
break;
case WM_SIZE:
MoveWindow(GetDlgItem(hDlg, IDEDIT) , 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
break;
case WM_INITDIALOG:
hfont = (HFONT)GetStockObject(OEM_FIXED_FONT);
SendDlgItemMessage(hDlg, IDEDIT ,WM_SETFONT, (WPARAM)hfont, MAKELONG(TRUE,0));
SetTitleBar(hDlg, NULL);
GetClientRect (hDlg, &rc);
MoveWindow(GetDlgItem(hDlg, IDEDIT) , 0, 0, rc.right, rc.bottom, TRUE);
CheckMenuItem(GetMenu(hDlg), IDM_FOLD, MF_CHECKED);
if (Version()<0x035f) MAXTEXTSIZE=64470U;//49153U;
else MAXTEXTSIZE=64474U;//16bit//61473U;
#ifdef WIN32
if (isNT32()) MAXTEXTSIZE=1024U*1024U*16U
#endif
SendDlgItemMessage(hDlg, IDEDIT, EM_LIMITTEXT , MAXTEXTSIZE, 0);
DragAcceptFiles(hDlg, TRUE);
for (i=1; i<argc; ++i) {
if (argv[i][0]!='/' && argv[i][0]!='\0') {
strcpy(achFilePath, argv[i]);
pathsplit(achFilePath, buf, achFileTitle);
readtext(hDlg, achFilePath, achFileTitle);
break;
}
}
SetFocus(GetDlgItem(hDlg,IDEDIT));
return FALSE;/* SetFocusしたらFALSE */
default:
return FALSE; /*メッセージを処理しなかった*/
}
return TRUE; /*メッセージを処理した*/
}
/*メイン関数*/
int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int cmdshow){
DLGPROC lpProc = (DLGPROC)MakeProcInstance((FARPROC)dlgproc, hinst);
MSG msg;
HACCEL hAccel=LoadAccelerators(hinst, "editaccel");
lpSearch = (DLGPROC)MakeProcInstance((FARPROC)searchdlg, hinst);
lpReplace = (DLGPROC)MakeProcInstance((FARPROC)replacedlg, hinst);
hInstApp=hinst;
#ifdef WIN32
cmdlinesprit(GetCommandLine());
#else
cmdlinesprit(cmdline);
#endif
hDlgMain=CreateDialog(hinst, "editdlg", NULL, lpProc);/*ここでダイアログボックスを作成*/
while (GetMessage(&msg, NULL, 0, 0)) {
if (!TranslateAccelerator(hDlgMain, hAccel, &msg)) {
if ((hDlgSearch ==NULL || !IsDialogMessage(hDlgSearch, &msg)) &&
(hDlgReplace==NULL || !IsDialogMessage(hDlgReplace, &msg))){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
FreeProcInstance((FARPROC)lpSearch);
FreeProcInstance((FARPROC)lpReplace);
FreeProcInstance((FARPROC)lpProc);
return 0;
}
/*********************************************************************************
日本語処理
*********************************************************************************/
#if defined(__TURBOC__) && __TURBOC__ <= 0x452
#include <jctype.h>
#else
#if _MSC_VER == 600
#include <jstring.h>
#else
#include <mbstring.h>
#include <mbctype.h>
#define nthctype _mbsbtype
#define _fnthctype _fmbsbtype
#define CT_ANK _MBC_SINGLE
#define CT_KJ2 _MBC_TRAIL
#endif
#include <sys/types.h>
#endif
#ifdef __LCC__
#define U(c) ((unsigned char)(c))
#define iskanji(c) ((0x81 <=U(c) && U(c)<= 0x9F) || (0xE0 <=U(c) && U(c)<= 0xFC))
#define iskanji2(c) ((0x40 <=U(c) && U(c)<= 0x7E) || (0x80 <=U(c) && U(c)<= 0xFC))
/*以下の二つの関数は、松田晋氏によるC MAGAZINE 92年5月号掲載のものである*/
/* nth_kanjiの非再帰版プログラム */
/* 文字列sのn文字目が漢字1バイト目か? */
int nth_kanji(const char *s, int n) {
int k;
if (! iskanji(s[n])) return 0;
k = n;
while (--k >= 0 && iskanji(s[k]))
;
return (n - k) & 1;
}
/* 高速版nthctype */
int nthctype(const char *s, int n){
if (n > 0 && nth_kanji(s, n - 1)) {/* 左隣が漢字1バイト目である場合 */
if (iskanji2(s[n])) /* 漢字2バイト目か? */
return CT_KJ2;
return CT_ILGL;
} else if (iskanji(s[n]))
return CT_KJ1;
else
return CT_ANK;
}
#endif
/*********************************************************************************
jstrrpbrk(s, t):文字列を末尾から検索し、特定の文字集合が見つかったら検索を打ち切る
sには全角を含む文字列を指定できるが、tにはできない(手抜きモード)
*********************************************************************************/
const char *jstrrpbrk(const char *s, const char *t){
int n; const char *q;
if (s==NULL || *s==0) return NULL;
if (t==NULL || *t==0) return NULL;
n = strlen(s) - 1;
for (; n >= 0; --n) {
for (q=t; *q!='\0'; ++q) {
if (s[n] == *q)
if (nthctype(s, n)==CT_ANK) return &s[n];
}
}
return NULL;
}
/**********************************************************************
pathsplit(): フルパスをファイル名とそれ以外に分離します。
**********************************************************************/
void pathsplit(const char *path, char *dir, char*name){
const char *p; int i;
if (path[0]==0) {dir[0]=0; name[0]=0; return;}
p=jstrrpbrk(path, "\\/:"); //p=strrchr(path,'\\');
if (p==NULL) dir[0]=0;
else {
for(i=0;i<=p-path;++i)
dir[i]=path[i];
dir[p-path+1]=0;
path=p+1;
}
strcpy(name,path);
}
/************************************************************************************
コマンドライン分割処理
************************************************************************************/
#ifdef WIN32
#undef _fnthctype
#define _fnthctype nthctype
#endif
void qu_strncpy(char *dst, char far *src, int n){
int i, j;
for (; n>0; ){
if (src[n-1]!=' ')break;
n--;
}
for(i=0,j=0; i<n; j++){
if (src[j]=='"' && (j==0 || (src[j-1]!='\\' || _fnthctype(src, j-1)==CT_KJ2)))
n--;
else if (src[j]=='\\' && _fnthctype(src, j)!=CT_KJ2 && src[j+1]=='"')
n--;
else dst[i]=src[j], i++;
if (src[j]==0) break;
}
dst[n]=0;
}
void cmdlinesprit(LPSTR CmdLin){
int i=0, p=0, inflag=0;
#ifdef WIN32
argc=0;
#else
argc=1;
#endif
for(;;){
if (CmdLin[i]=='\0'){
argv[argc]=(char*)malloc(i-p+1);
if (argv[argc]==NULL) break;
qu_strncpy(argv[argc],&CmdLin[p],i-p);
break;
}
if (CmdLin[i]=='"' && (i==0 ||
(CmdLin[i-1]!='\\' || _fnthctype(CmdLin, i-1)==CT_KJ2))) inflag=!inflag;
if (inflag==0 && (CmdLin[i]=='/' || (CmdLin[i]==' ' && (argc==0 || CmdLin[p]=='/')))){
argv[argc]=(char*)malloc(i-p+1);
if (argv[argc]==NULL) break;
qu_strncpy(argv[argc],&CmdLin[p],i-p);
argc++;if (argc>=ARGCMAX-1) break;
do{
p=i;i++;
}while (CmdLin[p]==' ');
}else i++;
}
argc++;
}
他のファイルはEDIT 0.02と共通。
戻る