root/lib.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. g_log
  2. g_cstr_compare
  3. g_rm_recursive
  4. g_cstring2file
  5. g_file2cstring
  6. g_fcreate
  7. g_connect_process
  8. g_cstr2cstra
  9. g_cstr2cstra_ex
  10. g_cstra2cstr
  11. g_cstra_getsize
  12. g_file2cstra
  13. g_cstra2file
  14. g_getfs
  15. g_get_min_num
  16. g_cstra_getpart
  17. g_is_there
  18. g_ma
  19. g_getfield
  20. g_gen_msgid
  21. g_cstr_chop
  22. g_cstr_chop2
  23. g_cstr_rvs_find
  24. g_get_tmp_file
  25. g_delete_directory
  26. g_logfont_copy
  27. g_get_tzoffset_from_tzname
  28. g_strip_part
  29. g_is_hankana

/*
 * Copyright (C) 2002-2003 chik, s.hiranaka
 * For license terms, see the file COPYING in this directory.
 */

#include "stdafx.h"
#include "Pochy.h"
#include "MainFrm.h"
#include "SummaryView.h"
#include "HeaderInfo.h"
#include "CodeConvert.h"
#include "direct.h"
#include "lib.h"
#include "_regex.h" // 正規表現関数
#include "process.h" // getpid()

void g_log(CString path, CString log)
{
        CPochyApp *app = (CPochyApp*)AfxGetApp();
        FILE* file;
        if((file = fopen(app->m_app_path+"\\"+path, "ab"))==NULL){
                AfxMessageBox("fopen: error at g_log");
                return;
        }
        fwrite(log, sizeof(char), log.GetLength(), file);
        fclose(file);
}

// 文字列cとdを比較する関数
BOOL g_cstr_compare(LPCTSTR c, LPCTSTR d)
{
        regex_t reg; // 正規表現格納用
        regmatch_t pmatch[2]; // regexecの結果が格納される

        CString regex;
        regex.Format("^%s$", c);
        regcomp(&reg, regex.GetBuffer(0), REG_EXTENDED | REG_NEWLINE | REG_ICASE |REG_NOSUB );
        if(0 == regexec(&reg, d, 2, pmatch, 0)){
                regfree(&reg);
                return TRUE;
        }
        regfree(&reg);
        return FALSE;
}

BOOL g_rm_recursive(CString path)
{
        CFileFind ff;
        BOOL b_Find;
        CString cPath = path + "\\*.*";

        b_Find = ff.FindFile(cPath);
        while(b_Find){
                b_Find = ff.FindNextFile();
                if(ff.IsDots())
                        continue;
                if(ff.IsDirectory()){
                        if(!g_rm_recursive(path + "\\" + ff.GetFileName()))
                                return FALSE;
                }else{
                        if(!DeleteFile(path + "\\" +ff.GetFileName()))
                                return FALSE;
                }
        }
        ff.FindFile(cPath + "\\.."); // カレントディレクトリ変更しておかないとrmdirできない
        if(_rmdir(path))
                return FALSE;
        return TRUE;
}

// CStringからファイルへテキストを書き出す関数
BOOL g_cstring2file(/*CString& buf*/LPCTSTR buf, LPCTSTR file_name)
{
/*      HANDLE hTmp;
        DWORD len;
        hTmp = CreateFile(filename,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
*/
//      WriteFile(hTmp, buf, /*buf.GetLength()*/strlen(buf), &len, 0);
/*      if(!CloseHandle(hTmp)){
                AfxMessageBox("CloseHandle");
                return FALSE;
        }
        return TRUE;*/

        FILE *fp;

        fp = fopen(file_name, "wb");
        if(0 > fwrite(buf, sizeof(char), strlen(buf), fp)){
                AfxMessageBox("g_cstring2file error");
                fclose(fp);
                return FALSE;
        }

        fclose(fp);
        return TRUE;
}

// ファイルからCStringにテキストを書き出す関数
BOOL g_file2cstring(LPCTSTR filename,CString& buf)
{
        CFile file;
        if(!file.Open(filename,CFile::modeRead)){
                return FALSE;
        }
        LPSTR pbuf;
        pbuf = buf.GetBuffer(file.GetLength()+1);
        file.Read(pbuf,file.GetLength());
        pbuf[file.GetLength()]=0;
        buf.ReleaseBuffer();
        file.Close();
        return TRUE;
}

// ファイルを作成する関数
BOOL g_fcreate(LPCTSTR path)
{
        HANDLE h = CreateFile(
                path,
                GENERIC_WRITE,
                FILE_SHARE_READ,
                0,      // これはNTや2000だと多分だめ、要修正
                OPEN_ALWAYS,
                FILE_ATTRIBUTE_NORMAL,
                NULL);  
        if(h == NULL){
                CloseHandle(h);
                return FALSE;
        }       
        CloseHandle(h);
        return TRUE;
}

// プロセスへ接続する関数
BOOL g_connect_process(CStringArray &comline, CString &out1, CString &out2)
{
        HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
        HANDLE hInputWriteTmp,hInputRead,hInputWrite;
        HANDLE hErrorReadTmp,hErrorRead,hErrorWrite;
        SECURITY_ATTRIBUTES sa;
        sa.nLength = sizeof(SECURITY_ATTRIBUTES);
        sa.lpSecurityDescriptor = NULL;
        sa.bInheritHandle = TRUE;

        // Create the child output pipe.
        if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
                AfxMessageBox("CreatePipe");
        if (!CreatePipe(&hErrorReadTmp,&hErrorWrite,&sa,0))
                AfxMessageBox("CreatePipe");
        if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
                AfxMessageBox("CreatePipe");

        if (!DuplicateHandle(GetCurrentProcess(),hErrorReadTmp,
                GetCurrentProcess(),&hErrorRead,0,TRUE,DUPLICATE_SAME_ACCESS))
                AfxMessageBox("DuplicateHandle");
        if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
                GetCurrentProcess(),&hOutputRead,0,FALSE,DUPLICATE_SAME_ACCESS))
                AfxMessageBox("DuplicateHandle");
        if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
                GetCurrentProcess(),&hInputWrite,0,FALSE,DUPLICATE_SAME_ACCESS))
                AfxMessageBox("DuplicateHandle");

        // Close inheritable copies of the handles you do not want to be 
        // inherited.
        if (!CloseHandle(hOutputReadTmp)) AfxMessageBox("CloseHandle");
        if (!CloseHandle(hInputWriteTmp)) AfxMessageBox("CloseHandle");
        if (!CloseHandle(hErrorReadTmp)) AfxMessageBox("CloseHandle");

        // プロセス起動
        STARTUPINFO siStartInfo;
        PROCESS_INFORMATION pi;
        ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
        siStartInfo.hStdError = hErrorWrite;
        siStartInfo.hStdOutput = hOutputWrite;
        siStartInfo.hStdInput = hInputRead;
        siStartInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
        siStartInfo.wShowWindow = SW_HIDE;
        siStartInfo.cb = sizeof(STARTUPINFO);
        LPSTR lps = comline[0].GetBuffer(0);
        if(!CreateProcess(NULL,lps,
                NULL,NULL,TRUE,CREATE_NEW_CONSOLE/*NORMAL_PRIORITY_CLASS|DETACHED_PROCESS*/,NULL,NULL,&siStartInfo,&pi)){ //CREATE_NEW_CONSOLE
                if(!CloseHandle(hInputWrite)) AfxMessageBox("CloseHandle");
                if(!CloseHandle(hOutputRead)) AfxMessageBox("CloseHandle");
                if(!CloseHandle(hErrorRead)) AfxMessageBox("CloseHandle");
                return FALSE;
        }

        // 入力する
        for(int i=1;i<comline.GetSize();i++){
                DWORD len;
                WaitForInputIdle(pi.hProcess,INFINITE);
                WriteFile(hInputWrite,comline[i],comline[i].GetLength(),&len,NULL);
        }

        DWORD BytesAvail;
        DWORD ret;
        out1.Empty();
        out2.Empty();
        CString buf;
    // プロセス起動中のパイプ内容受け取り処理
        while((ret = WaitForSingleObject(pi.hProcess,0)) != WAIT_ABANDONED){
                PeekNamedPipe(hOutputRead,NULL,0,NULL,&BytesAvail,NULL);
                if(BytesAvail>0){
                        LPSTR pout1;
                        DWORD len;
                        pout1 = buf.GetBuffer(65536);
                        ReadFile(hOutputRead,pout1,65536,&len,NULL);
                        pout1[len]=0;
                        buf.ReleaseBuffer();
                        out1 += buf;
                        buf.Empty();
                }
                PeekNamedPipe(hErrorRead,NULL,0,NULL,&BytesAvail,NULL);
                if(BytesAvail>0){
                        LPSTR pout2;
                        DWORD len;
                        pout2 = buf.GetBuffer(65536);
                        ReadFile(hErrorRead,pout2,65536,&len,NULL);
                        pout2[len]=0;
                        buf.ReleaseBuffer();
                        out2 += buf;
                        buf.Empty();
                }
                // メッセージキューを取得し、存在すれば、処理を促す
/*              MSG msg;
                if(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
                        ::TranslateMessage(&msg);
                        ::DispatchMessage(&msg);
                }*/
                // プロセス終了なら、ループを抜ける
                if(ret == WAIT_OBJECT_0)
                        break;
        }
    GetExitCodeProcess(pi.hProcess, &ret);
        if(!CloseHandle(hInputWrite)) AfxMessageBox("CloseHandle");
        if(!CloseHandle(hOutputRead)) AfxMessageBox("CloseHandle");
        if(!CloseHandle(hErrorRead)) AfxMessageBox("CloseHandle");

        return TRUE;
}

/*
int g_get_icon_index(const CString& csFileName)
{
        SHFILEINFO sfi;

        SHGetFileInfo(
                (LPCTSTR)csFileName, 
                0,
                &sfi, 
                sizeof(SHFILEINFO), 
                SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_SMALLICON);

        return sfi.iIcon;
}
*/

// CStringを各行毎にCStringArrayに格納する(sepも含める)
void g_cstr2cstra(CString& cstr, CStringArray& cstra, LPCTSTR sep)
{
        int a;
        cstra.RemoveAll();
        a = cstr.Find(sep);
        while(a!=-1){
                cstra.Add(cstr.Left(a+strlen(sep)));
                cstr = cstr.Mid(a+strlen(sep));
                a = cstr.Find(sep);
        }
        cstra.Add(cstr);
}

// CStringを各行毎にCStringArrayに格納する(sepは含めない)
void g_cstr2cstra_ex(CString& cstr, CStringArray& cstra, LPCTSTR sep)
{
        CString buf;
        int a;
        cstra.RemoveAll();
        a = cstr.Find(sep);
        while(a!=-1){
                buf = cstr.Left(a);
                cstra.Add(buf);
                cstr = cstr.Mid(a+strlen(sep));
                a = cstr.Find(sep);
        }
        cstra.Add(cstr);
}

// CStringArrayに各行毎格納したものをCStringに書き出す
void g_cstra2cstr(CStringArray& cstra, CString& cstr, int size)
{
        int i;
        cstr.Empty();

        char *p = cstr.GetBuffer(size);
        for(i=0;i<cstra.GetSize();i++){
                strcpy(p, cstra.GetAt(i).GetBuffer(0));
                p += cstra.GetAt(i).GetLength();
        }
        cstr.ReleaseBuffer();
}

// CStringArrayに格納されたCString全部のサイズ
int g_cstra_getsize(CStringArray& cstra)
{
        int i;
        int n;

        i = n = 0;
        while(i < cstra.GetSize()){
                n += cstra.GetAt(i).GetLength();
                i++;
        }
        return n;
}

// テキストファイルの各行をCStringArrayに読み込む
BOOL g_file2cstra(LPCTSTR path, CStringArray &cstra)
{
        CString buf;
        CStdioFile file;

        if(!file.Open(path, CFile::modeRead | CFile::typeText))
                return FALSE;
        while(file.ReadString(buf)){
                buf += "\r\n";
                cstra.Add(buf);
        }
        buf.Empty();
        file.Close();
        return TRUE;
}

// CStringArrayに各行毎格納されたテキストをファイルへ書き出す
BOOL g_cstra2file(LPCTSTR path, CStringArray &cstra)
{
        int n = 0;
        FILE *file;

        file = fopen(path, "wb");
        if(file == NULL){
                AfxMessageBox("fopen: error");
                return FALSE;
        }
        while(n < cstra.GetSize()){
                fwrite(cstra.GetAt(n), sizeof(char), cstra.GetAt(n).GetLength(), file);
                n++;
        }
        fclose(file);

        return TRUE;
}

// ファイルの大きさを返す
long g_getfs(LPCTSTR path)
{
        FILE *file;
        long size = 0;

        if((file = fopen(path, "rt"))){
                fseek(file, 0, SEEK_END);
                size = ftell(file);
                fclose(file);
                return size;
        }

        return -1;
}

// ファイル名を番号として見たとき、
// 引数(num)以上でまだ存在しない最小の番号を返す関数
int g_get_min_num(CString path)
{
/*      CString cNum;
        CString tmp;
        HANDLE hFile;
        WIN32_FIND_DATA wfd;

        while(1){
                tmp = path;
                cNum.Format("\\%d", num);
                tmp += cNum;
                cNum.Empty();
                hFile = FindFirstFile(tmp.GetBuffer(0), &wfd);
                tmp.Empty();
                if(hFile == INVALID_HANDLE_VALUE) break;
                num++;
        }
        FindClose(hFile);

        cNum.Format("%d", num);
        return num;*/

        int i=0;
        CFileFind ff;
        BOOL b = ff.FindFile(path+"\\*.*");
        while(b){
                b = ff.FindNextFile();
                if(     !ff.IsDirectory() &&
                        !ff.IsDots() &&
                        ff.GetFileName().SpanExcluding("0123456789").IsEmpty())
                {
                        if(i<atoi(ff.GetFileName()))
                                i=atoi(ff.GetFileName());
                }
        }
        ff.Close();
        return ++i;
}

// CStringArayの部分を取り出す関数
void g_cstra_getpart(CStringArray &org, CStringArray &dst, int start, int end)
{
        dst.RemoveAll();

        while(/*start < org.GetSize() || */start < end+1){
                dst.Add(org.GetAt(start));
                start++;
        }
}

// ファイルが存在しているかどうかを返す関数
BOOL g_is_there(LPCTSTR path)
{
        WIN32_FIND_DATA wfd;

        HANDLE handle = FindFirstFile(path, &wfd);
        if(handle == INVALID_HANDLE_VALUE){
                FindClose(handle);
                return FALSE;
        }else{
                FindClose(handle);
                return TRUE;
        }
}

// <>の中の文字列を返す関数
CString g_ma(CString& to)
{
        CString res;
        int p,p2,q,q2;
        p = to.Find("<")+1;
        q = to.Find(">")+1;
        p2 = to.Find("<",p)+1;
        q2 = to.Find(">",q)+1;

        if(p && q && !p2 && !q2)
                return to.Mid(p,q-p-1);
        if(p || q || p2 || q2)
                AfxMessageBox(to+"\r\nは変なアドレスです。");
        return to;
}

CString g_getfield(CString& body,LPCTSTR name)
{
        CString res;
        int a,b;
        a = body.Find(name);
        if(a==-1){
                res.Empty();
                return res;
        }
        if(a==0 || body[a-1]==10){
                b = body.Find("\r\n",a);
                if(b == -1)
                        b = body.GetLength();
                a += strlen(name);
                res = body.Mid(a,b-a);
        }
        res.TrimLeft();
        res.TrimRight();
        return res;
}

// Message-IDを生成する関数
CString g_gen_msgid(CString from)
{
        CString message_id;
        CTime t = CTime::GetCurrentTime();
        message_id.Format("<%d%02d%02d.%02d%02d%02d.%d.%s>",
                        t.GetYear(),
                        t.GetMonth(),
                        t.GetDay(),
                        t.GetHour(),
                        t.GetMinute(),
                        t.GetSecond(),
                        getpid(),
                        g_ma(from)); // fromはちゃんとメールアドレスだけを引っ掛ける必要がある
        return message_id;
}

void g_cstr_chop(CString &buf)
{
        if(buf.IsEmpty()) return;
        buf.TrimRight("\r\n");
        buf.TrimLeft("\t ");
}

CString g_cstr_chop2(CString buf)
{
        if(buf.IsEmpty()) return buf;
        buf.TrimRight("\r\n");
        buf.TrimLeft("\t ");
        return buf;
}

int g_cstr_rvs_find(CString org, LPCTSTR key, int start)
{
        int i=start;

        if(i >= org.GetLength())
                return -1;

        while(i > 0){
                if(org.GetAt(i) == (TCHAR)key)
                        return i;

                i--;
        }
        return -1;
}

// テンポラリーファイルを作成し、そのファイルへのパスを返す
CString g_get_tmp_file()
{
        // テンポラリーファイルのディレクトリを取得
        TCHAR tmp_path[MAX_PATH];
        DWORD d_result = GetTempPath(MAX_PATH, tmp_path);
        ASSERT(d_result);
        // ファイルの作成
        TCHAR tmp_file[MAX_PATH];
        UINT u_result = GetTempFileName(tmp_path, _T("~ex"), 0, tmp_file);
        ASSERT(u_result);

        return tmp_file;
}

// directoryを削除する関数(中にあるファイルも全て)
BOOL g_delete_directory(LPCTSTR dir_path)
{
        CFileFind ff;
        CString path = dir_path;
        path.TrimRight('\\');
        BOOL r;

        r = ff.FindFile(path+"\\*.*");
        while(r){
                r = ff.FindNextFile();
                if(ff.IsDots())
                        continue;
                if(ff.IsDirectory())
                        g_delete_directory(path+"\\"+ff.GetFileName());
                else
                        DeleteFile(path+"\\"+ff.GetFileName());
        }
        ff.Close();

        return RemoveDirectory(dir_path);
}

// logfontをコピーする関数
void g_logfont_copy(LOGFONT *dst, LOGFONT *org)
{
        dst->lfCharSet                          = org->lfCharSet;
        dst->lfClipPrecision                            = org->lfClipPrecision;
        dst->lfEscapement                               = org->lfEscapement;
        strcpy(dst->lfFaceName, org->lfFaceName);
        dst->lfHeight                           = org->lfHeight;
        dst->lfItalic                           = org->lfItalic;
        dst->lfOrientation                      = org->lfOrientation;
        dst->lfOutPrecision                     = org->lfOutPrecision;
        dst->lfPitchAndFamily           = org->lfPitchAndFamily;
        dst->lfQuality                          = org->lfQuality;
        dst->lfStrikeOut                        = org->lfStrikeOut;
        dst->lfUnderline                        = org->lfUnderline;
        dst->lfWeight                           = org->lfWeight;
        dst->lfWidth                            = org->lfWidth;
}

// timezone name を与えると、timezone offsetを返す関数
CString g_get_tzoffset_from_tzname(CString name)
{

        name.MakeUpper();

        CMapStringToString map;

        map.SetAt("NZDT",       "+1300");       // New Zealand Daylight Time (ニュージーランド夏時間)
        map.SetAt("IDLE",       "+1200");       // International Date Line, East (国際日付変更線、東側)
        map.SetAt("NZST",       "+1200");       // New Zealand Std Time (ニュージーランド標準時間)
        map.SetAt("NZT",        "+1200");       // New Zealand Time (ニュージーランド時間)
        map.SetAt("AESST",      "+1100");       // Australia Eastern Summer Std Time (オーストラリア標準夏時間)
        map.SetAt("ACSST",      "+1030");       // Central Australia Summer Std Time (オーストラリア中部標準夏時間)
        map.SetAt("CADT",       "+1030");       // Central Australia Daylight Savings Time (オーストラリア中部夏時間)
        map.SetAt("SADT",       "+1030");       // South Australian Daylight Time (オーストラリア南部夏時間)
        map.SetAt("AEST",       "+1000");       // Australia Eastern Std Time (オーストラリア東部標準時間)
        map.SetAt("EAST",       "+1000");       // East Australian Std Time (オーストラリア東部標準時間)
        map.SetAt("GST",        "+1000");       // Guam Std Time, USSR Zone 9 (グアム標準時間、ソビエトタイムゾーン 9)
        map.SetAt("LIGT",       "+1000");       // Melbourne, Australia (オーストラリア、メルボルン時間)
        map.SetAt("ACST",       "+0930");       // Central Australia Std Time (オーストラリア中部標準時間)
        map.SetAt("CAST",       "+0930");       // Central Australia Std Time (オーストラリア中部標準時間)
        map.SetAt("SAT",        "+0930");       // South Australian Std Time (オーストラリア南部標準時間)
        map.SetAt("AWSST",      "+0900");       // Australia Western Summer Std Time (オーストラリア西部標準時間)
        map.SetAt("JST",        "+0900");       // Japan Std Time, USSR Zone 8 (日本標準時間、ソビエトタイムゾーン 8)
        map.SetAt("KST",        "+0900");       // Korea Standard Time (韓国標準時間)
        map.SetAt("WDT",        "+0900");       // West Australian Daylight Time (オーストラリア西部夏時間)
        map.SetAt("MT",         "+0830");       // Moluccas Time (モルッカ諸島時間)
        map.SetAt("AWST",       "+0800");       // Australia Western Std Time (オーストラリア西部標準時間)
        map.SetAt("CCT",        "+0800");       // China Coastal Time (中国湾岸時間)
        map.SetAt("WADT",       "+0800");       // West Australian Daylight Time (西部アーストラリア夏時間)
        map.SetAt("WST",        "+0800");       // West Australian Std Time (西部オーストラリア標準時間)
        map.SetAt("JT",         "+0730");       // Java Time (Java 時間)
        map.SetAt("WAST",       "+0700");       // West Australian Std Time (西部オーストラリア標準時間)
        map.SetAt("IT",         "+0330");       // Iran Time (イラン時間)
        map.SetAt("BT",         "+0300");       // Baghdad Time (バグダッド時間)
        map.SetAt("EETDST",     "+0300");       // Eastern Europe Daylight Savings Time (東ヨーロッパ夏時間)
        map.SetAt("CETDST",     "+0200");       // Central European Daylight Savings Time (中央ヨーロッパ夏時間)
        map.SetAt("EET",        "+0200");       // Eastern Europe, USSR Zone 1 (東ヨーロッパ時間、ソビエトタイムゾーン 1)
        map.SetAt("FWT",        "+0200");       // French Winter Time (フランス冬時間)
        map.SetAt("IST",        "+0200");       // Israel Std Time (イスラエル標準時間)
        map.SetAt("MEST",       "+0200");       // Middle Europe Summer Time (中央ヨーロッパ夏時間)
        map.SetAt("METDST",     "+0200");       // Middle Europe Daylight Time (中央ヨーロッパ夏時間)
        map.SetAt("SST",        "+0200");       // Swedish Summer Time (スウェーデン夏時間)
        map.SetAt("BST",        "+0100");       // British Summer Time (イギリス夏時間)
        map.SetAt("CET",        "+0100");       // Central European Time (中央ヨーロッパ時間)
        map.SetAt("DNT",        "+0100");       // Dansk Normal Tid (デンマーク標準時間)
        map.SetAt("DST",        "+0100");       // Dansk Standard Time (?) (デンマーク標準時間 (?))
        map.SetAt("FST",        "+0100");       // French Summer Time (フランス夏時間)
        map.SetAt("MET",        "+0100");       // Middle Europe Time (中央ヨーロッパ時間)
        map.SetAt("MEWT",       "+0100");       // Middle Europe Winter Time (中央ヨーロッパ冬時間)
        map.SetAt("MEZ",        "+0100");       // Middle Europe Zone (中央ヨーロッパ時間)
        map.SetAt("NOR",        "+0100");       // Norway Standard Time (ノルウェー標準時間)
        map.SetAt("SET",        "+0100");       // Seychelles Time (セイシェル時間)
        map.SetAt("SWT",        "+0100");       // Swedish Winter Time (スウェーデン冬時間)
        map.SetAt("WETDST",     "+0100");       // Western Europe Daylight Savings Time (西ヨーロッパ夏時間)
        map.SetAt("GMT",        "+0000");       // Greenwish Mean Time (グリニッジ標準時)
        map.SetAt("WET",        "+0000");       // Western Europe (西ヨーロッパ)
        map.SetAt("WAT",        "-0100");       // West Africa Time (西アフリカ時間)
        map.SetAt("NDT",        "-0230");       // Newfoundland Daylight Time (ニューファンドランド夏時間)
        map.SetAt("ADT",        "-0300");       // Atlantic Daylight Time (大西洋夏時間)
        map.SetAt("NFT",        "-0330");       // Newfoundland Standard Time (ニューファンドランド標準時間)
        map.SetAt("NST",        "-0330");       // Newfoundland Standard Time (ニューファンドランド標準時間)
        map.SetAt("AST",        "-0400");       // Atlantic Std Time (Canada) (大西洋標準時間 (カナダ))
        map.SetAt("EDT",        "-0400");       // Eastern Daylight Time (アメリカ東部夏時間)
        map.SetAt("ZP4",        "-0400");       // GMT +4 時間
        map.SetAt("CDT",        "-0500");       // Central Daylight Time (アメリカ中部夏時間)
        map.SetAt("EST",        "-0500");       // Eastern Standard Time (アメリカ東部標準時間)
        map.SetAt("ZP5",        "-0500");       // GMT +5 時間
        map.SetAt("CST",        "-0600");       // Central Std Time (アメリカ中部標準時間)
        map.SetAt("MDT",        "-0600");       // Mountain Daylight Time (アメリカ山岳部夏時間)
        map.SetAt("ZP6",        "-0600");       // GMT +6 hours (グリニッジ標準時 +6 時間)
        map.SetAt("MST",        "-0700");       // Mountain Standard Time (アメリカ山岳部標準時間)
        map.SetAt("PDT",        "-0700");       // Pacific Daylight Time (アメリカ太平洋夏時間)
        map.SetAt("PST",        "-0800");       // Pacific Std Time (アメリカ太平洋標準時間)
        map.SetAt("YDT",        "-0800");       // Yukon Daylight Time (ユーコン夏時間)
        map.SetAt("HDT",        "-0900");       // Hawaii/Alaska Daylight Time (ハワイ/アラスカ夏時間)
        map.SetAt("YST",        "-0900");       // Yukon Standard Time (ユーコン標準時間)
        map.SetAt("AHST",       "-1000");       // Alaska-Hawaii Std Time (アラスカ-ハワイ標準時間)
        map.SetAt("CAT",        "-1000");       // Central Alaska Time (アラスカ中央時間)
        map.SetAt("NT",         "-1100");       // Nome Time (ノーム時間)
        map.SetAt("IDLW",       "-1200");       // International Date Line, West (国際日付変更線、西側)

        CString value;
        map.Lookup(name, value);
        return value;
}

// cstringからmarkで囲まれた部分を排除する
void g_strip_part(CString &buf, char *mark)
{
        int start = 0;
        int end;
        while((start = buf.Find(mark, start)) != -1){
                end = buf.Find(mark, start+1);
                buf = buf.Left(start)+buf.Mid(end+1);
                start = start+1;
        }
}

// 文字列に半角カナが含まれているかどうか確かめる
BOOL g_is_hankana(unsigned char *buf)
{
        unsigned char c = *buf;
        while(c != NULL){
                // 0xa0 -> 0xdf 
                if(c >= 0xa0 && c <= 0xdf){
                        return TRUE;
                }
                c = *(++buf);
        }
        return FALSE;
}

/* [<][>][^][v][top][bottom][index][help] */