📄 my_sp.c
字号:
//$Id: MY_SP.C,v 1.3 2003/03/30 04:57:08 genta Exp $
/*! @file
@brief 引数を正しく無視するsplitpath
@author SUI
@date 2002.07.15 Initial release
$Revision: 1.3 $
*/
/*
Copyright (C) 2002, SUI
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
/* #define _USE_MS_DOS_FUNC_ /* */
/* ↑ファイルの属性取得に _dos_getfileattr (Dos function) を使用する場合に定義
しておく。未定義の場合は GetFileAttributes (Windows API) を使用する。
主に LSI-C 試食版で動作確認していたもので。 */
#ifdef LSI_C /* LSI-C なら絶対 _dos_getfileattr を使う */
#ifndef _USE_MS_DOS_FUNC_
#define _USE_MS_DOS_FUNC_
#endif
#endif /* LSI_C */
#include <io.h> /* access */
#include <string.h> /* strncpy strlen */
#include <stdlib.h> /* _MAX_PATH _MAX_DRIVE _MAX_DIR _MAX_FNAME _MAX_EXT */
/* LSI-C 試食版では↓この辺が無いので... */
#ifndef _MAX_PATH
#define _MAX_PATH 260 /* */
/*#define _MAX_PATH 28 /* for DEBUG */
/*#define _MAX_PATH 27 /* for DEBUG */
#endif
#ifndef _MAX_DRIVE
#define _MAX_DRIVE 3
#endif
#ifndef _MAX_DIR
#define _MAX_DIR 256
#endif
#ifndef _MAX_FNAME
#define _MAX_FNAME 256
#endif
#ifndef _MAX_EXT
#define _MAX_EXT 256
#endif
#ifdef _USE_MS_DOS_FUNC_
#include <dos.h> /* _dos_getfileattr _A_SUBDIR _dos_getvect _dos_setvect */
#else
#include <windows.h> /* GetFileAttributes FILE_ATTRIBUTE_DIRECTORY */
#endif
#include "MY_SP.h" // Feb. 12, 2003 MIK 抜けていた
/* ============================================================================
my_splitpath( const char *CommandLine, char *drive, char *dir, char *fname, char *ext );
★ 概要
CommandLine に与えられたコマンドライン文字列の先頭から、実在するファイル?ディ
レクトリの部分のみを抽出し、その抽出部分に対して _splitpath() と同等の処理をお
こないます。
先頭部分に実在するファイル?ディレクトリ名が無い場合は空文字列が返ります。
文字列中の日本語(Shift_JISコードのみ)に対応しています。
★ プログラム記述内容について(言い訳あれこれ)
文字列の split 処理部だけにでも _splitpath() を使えばもっと短くなったのですが、
そうやらずに全て自前で処理している理由は、
?コンパイラによっては _splitpath() が日本語に対応していない可能性もある。
?_splitpath() って、コンパイラによって、詳細動作が微妙に異なるかもしれないから
仕様をハッキリさせるためにもコンパイラに添付されている _splitpath() にあまり
頼りたくなかった。
?というか、主に動作確認に使用していた LSI-C試食版にはそもそも _splitpath() が
存在しないから、やらざるをえなかった。 :-(
という事によります。
あらかじめ _USE_MS_DOS_FUNC_ が #define されていると MS-DOS ファンクションの関
数(_dos_getfileattr)が使用されます。( LSI-C試食版なんか向け)
#define定義されていない場合、Windows の GetFileAttributes が使用されます。
( Windows ソフトウェア向け)
動作確認は主に LSI-C 試食版(+ LFN library Ver.1.1)にておこなっています。
注意点としては、DOS版コンパイラでコンパイルしたMS-DOS用.exe の場合、フロッピー
ディスクなどのリムーバブルディスクのドライブのパスが渡されて来た時、そのドライ
ブのディスクが用意できていない場合、
|準備ができていません 読み取り中 ドライブ X:
|中止(A), 再試行(R), 失敗(F)?
という、お馴染みのメッセージが登場してしまうという事です。
# Windows版の.exe では Windows API が使用されるので出ないはずです。
MS-DOSにて、このうっとうしいメッセージを出さないようにするには、割り込みベクタ
の設定をおこなわなくてはなりません。
( _dos_getvect (DOS func.35H) , _dos_setvect (DOS func.25H) で 24H の割り込み
ベクタをいじる)
が、これはかなりコンパイラに依存する記述になってしまいます。
ので、結局、今この部分(メッセージを出さない処理)は LSI-C のみ対応のプログラムに
なっています。
「 LSI-C でコンパイルした場合」または「 Windows版.exe を作成した場合」*以外* の
場合は上記メッセージが出てしまいます。
※ "LFN library" -> http://webs.to/ken/
★ 詳細動作
my_splitpath( CommandLine, drive, dir, fname, ext );
CommandLine に文字列として D:\Test.ext が与えられた場合、
├?D:\Test.ext というファイルが存在する場合
│ drive = "D:"
│ dir = "\"
│ fname = "Test"
│ ext = ".ext"
├?D:\Test.ext というディレクトリが存在する場合
│ drive = "D:"
│ dir = "\Test.ext\"
│ fname = ""
│ ext = ""
└?D:\Test.ext というファイル?ディレクトリが存在しない場合、
├?D:ドライブは有効
│ drive = "D:"
│ dir = "\"
│ fname = ""
│ ext = ""
└?D:ドライブは無効
drive = ""
dir = ""
fname = ""
ext = ""
)=========================================================================== */
/* ↓ Shift_JIS の漢字の1バイト目の判定 */
#define _IS_SJIS_1(ch) ( ( ( ch >=0x081 )&&( ch <=0x09F ) ) || ( ( ch >=0x0E0 )&&( ch <=0x0FC ) ) )
/* Shift_JIS 対応で検索対象文字を2個指定できる strrchr() みたいなもの。
/ 指定された2つの文字のうち、見つかった方(より後方の方)の位置を返す。
/ # strrchr( char *s , char c ) とは、文字列 s 中の最後尾の c を探し出す関数。
/ # 文字 c が見つかったら、その位置を返す。
/ # 文字 c が見つからない場合は NULL を返す。 */
char *sjis_strrchr2( unsigned char *pt , const unsigned char ch1 , const unsigned char ch2 ){
unsigned char *pf = NULL;
while( *pt != '\0' ){ /* 文字列の終端まで調べる。 */
if( ( *pt == ch1 ) || ( *pt == ch2 ) ) pf = pt; /* pf = 検索文字の位置 */
if( _IS_SJIS_1(*pt) ) pt++; /* Shift_JIS の1文字目なら、次の1文字をスキップ */
if( *pt != '\0' ) pt++; /* 次の文字へ */
}
return pf;
}
/* 文字列 pi 中の先頭にある有効なパス名(実在するファイル?ディレクトリ名)部分
のみを po に書き出す。po は char po[_MAX_PATH]; 確保しておく事。 */
#ifdef LSI_C /* LSI-C の場合。 */
void far _asm_void_( char * );
void far int_nop(){ _asm_void_( "IRET\n" ); }
#endif /* LSI_C */
#define GetExistPath_NO_DriveLetter 0 /* ドライブレターが無い */
#define GetExistPath_IV_Drive 1 /* ドライブが無効 */
#define GetExistPath_AV_Drive 2 /* ドライブが有効 */
void GetExistPath( char *po , const char *pi ) {
char *pw,*ps;
int cnt;
char drv[4] = "_:\\";
int dl; /* ドライブの状態 */
#ifdef LSI_C
void far *int24h;
#endif /* LSI_C */
/* pi の内容を
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -