/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 【機能概要】 : C++言語関連で使用する共通関数群 本アプリで実装している共通関数は、以下の通り 使用方法については、各関数の実装部で記述 【作成日】 : 2021.04.23 【実装関数】 : getLocalTimeString # 現在時刻の取得と指定フォーマット化 : strnumber # int型数値を文字列に変換 : ExpandEnvironmentStrings # 文字列中から環境変数定義部を展開して結果を返却 : getEnvString # 環境変数char型返却(初期値設定付き) : getEnvLong # 環境変数Long型返却(初期値設定付き) : strtokEX # strtokの拡張版、["],['],[()]による区切り保護が可能 : strTrim # 文字列の前後半角スペースをトリムする : strLTrim # 文字列の前部半角スペースをトリムする : startLock # 排他ロックを開始する : endLock # 排他ロックを解除する : initLock # 排他ロックを初期化する _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */ #include "compatible_function.h" #ifndef WIN32 pthread_mutex_t mutex [ maxMutexLock ] ; // mutexロック(unix) #else HANDLE hMutex [ maxMutexLock ] ; // mutexロック(win・但し、windowsは未実装箇所あり) #endif int mutexCount = 0 ; // mutexロック数 //******************************************************************************* //* getLocalTimeString関数 * //******************************************************************************* //* 現在のローカル時刻を取得し指定フォーマットにあわせて文字列に変換する //* parameter O cOutputString :出力バッファ //* I maxStringSize :出力バッファ長 //* I cFormatString :書式 //* return 0以上 :文字列変換成功(文字列長) //* 0 :文字列変換失敗 //* -1 :時刻取得失敗 //* 備考:使用できるフォーマット指定コードは以下の通り //* %Y :10進数で表す4桁の西暦 //* %y :10進数で表す西暦の下 2 桁 (00〜99) //* %m :10進数で表す月 (01〜12) //* %d :10進数で表す月の日付 (01〜31) //* %p :現在のロケールの am/pm (小文字) //* %P :現在のロケールの AM/PM (大文字) //* %H :24時間表記の時間 (00〜23) //* %h :12時間表記の時間 (00〜11) //* %M :10進数で表す分 (00〜59) //* %S :10進数で表す秒 (00〜59) //* %u :10進数で表すミリ秒(000〜999) //* %U :10進数で表すマイクロ秒(000000〜999999) //* %% :%記号 long getLocalTimeString( char * cOutputString, size_t maxStringSize, const char * cFormatString) { //変数定義 #ifdef WIN32 struct timeb tp; //システム時刻格納用 #else struct timeval tp; //システム時刻格納用 #endif struct tm *tmc; //時刻情報取得用 struct tm tmc_r; //時刻情報取得用(実体) long iMicroSec; //マイクロ秒格納 size_t szLeft; //未使用の出力バッファ長 int iTmp; // //現在時刻取得 // #ifdef WIN32 ftime(&tp); tmc = localtime_r ( &tp.time , &tmc_r ); iMicroSec = tp.millitm*1000; #else (void)gettimeofday( &tp,NULL ); tmc = localtime_r ( &tp.tv_sec , &tmc_r); iMicroSec = tp.tv_usec; #endif if(tmc == NULL){ return -1; } // //現在時刻文字列変換 // szLeft = maxStringSize; //未使用出力バッファ長に引数の出力バッファ長を入れて初期化 while (szLeft > 0) { switch (*cFormatString){ case '\0': //書式終了時は文字列変換終了 goto done; case '%': //書式の先頭文字の場合は書式にあわせて文字列変換 cFormatString++; switch (*cFormatString){ case 'd': strnumber(tmc->tm_mday,2,&cOutputString,&szLeft); break; case 'H': strnumber(tmc->tm_hour,2,&cOutputString,&szLeft); break; case 'h': if(tmc->tm_hour < 12){ strnumber(tmc->tm_hour,2,&cOutputString,&szLeft); } else{ strnumber(tmc->tm_hour-12,2,&cOutputString,&szLeft); } break; case 'p': if(tmc->tm_hour < 12){ * cOutputString = 'a'; *(cOutputString + 1) = 'm'; } else{ * cOutputString = 'p'; *(cOutputString + 1) = 'm'; } cOutputString += 2; break; case 'P': if(tmc->tm_hour < 12){ * cOutputString = 'A'; *(cOutputString + 1) = 'M'; } else{ * cOutputString = 'P'; *(cOutputString + 1) = 'M'; } cOutputString += 2; szLeft -= 2; break; case 'm': strnumber(tmc->tm_mon+1,2,&cOutputString,&szLeft); break; case 'M': strnumber(tmc->tm_min,2,&cOutputString,&szLeft); break; case 'S': strnumber(tmc->tm_sec,2,&cOutputString,&szLeft); break; case 'U': strnumber(iMicroSec,6,&cOutputString,&szLeft); break; case 'u': strnumber(iMicroSec / 1000,3,&cOutputString,&szLeft); break; case 'y': strnumber(tmc->tm_year % 100,2,&cOutputString,&szLeft); break; case 'Y': iTmp = (tmc->tm_year / 100 + 19) * 100 + tmc->tm_year % 100; strnumber(iTmp,4,&cOutputString,&szLeft); break; case '%': *cOutputString = '%'; cOutputString++; szLeft--; break; default : break; } cFormatString++; break; default: //その他の文字はそのまま出力 *cOutputString = *cFormatString; cOutputString++; cFormatString++; szLeft--; } } done: if(szLeft > 0){ *cOutputString = '\0'; return (long)maxStringSize - (long)szLeft; } return 0; } //******************************************************************************* //* strnumber関数 * //******************************************************************************* //* 数値文字列変換関数(getLocalTimeStringでのみ使用) //* parameter I num :入力数値 //* I digits :出力桁数 //* O out :出力バッファ //* I/O count :出力バッファ容量(残バッファ容量) static void strnumber( int num, const int digits, char ** out, size_t * count) { int i; if(digits < (int)*count){ for (i = 1;(int)(digits - i) >=0 ; i++) { *(*out + digits - i) = '0' + num % 10; num = (num - num % 10) / 10; } count = count - digits; *out = *out + digits; } else{ *count = 0; } } #ifndef WIN32 //******************************************************************************* //* ExpandEnvironmentStrings関数 * //******************************************************************************* //* 文字列中の環境変数を展開する(win32APIをUNIXでエミュレート) //* parameter I szInputBuffer :入力文字列バッファ //* O szOutputBuffer :出力文字列バッファ //* I nSize :出力バッファ長 //* return 0以上 :文字列変換成功(文字列長) //* 0 :文字列変換失敗 int ExpandEnvironmentStrings( const char * szInputBuffer, char * szOutputBuffer, int nSize) { char * pszInputBuffer; char * pszTmpL; char * pszTmpR; char * pszEnv; //使用変数の初期化 pszInputBuffer = (char *)malloc(strlen(szInputBuffer)+1); strcpy(pszInputBuffer,szInputBuffer); *szOutputBuffer = '\0'; pszTmpL = pszInputBuffer; pszTmpR = strchr(pszTmpL,'$'); //環境変数が発見されなくなるまでループ while(pszTmpR != NULL){ //環境変数開始位置で文字列を切り離す *pszTmpR = '\0'; //環境変数より左側を出力バッファに追加する strncat(szOutputBuffer,pszTmpL,nSize); nSize -= strlen(pszTmpL); pszTmpR++; //$の後ろが括弧の場合は括弧の中の文字列を環境変数名とする if(*pszTmpR=='('){ //環境変数名を抜き出す pszTmpR++; pszTmpL = strchr(pszTmpR,')')+1; *(pszTmpL - 1) = '\0'; //環境変数から文字列を取得 pszEnv = getenv(pszTmpR); if(pszEnv != NULL){ strncat(szOutputBuffer,pszEnv,nSize); nSize -= strlen(pszEnv); } } else{ //$の後ろが括弧でない場合は/の直前までを環境変数名とする pszTmpL = strchr(pszTmpR,'/'); if(pszTmpL != NULL){ *pszTmpL = '\0'; *pszTmpL++; pszEnv = getenv(pszTmpR); if(pszEnv != NULL){ strncat(szOutputBuffer,pszEnv,nSize); nSize -= strlen(pszEnv); } strncat(szOutputBuffer,"/",nSize); nSize -= strlen("/"); } else{ //'/'が文字列中にない場合は文字列全体を環境変数名とする pszEnv = getenv(pszTmpR); if(pszEnv != NULL){ strncat(szOutputBuffer,pszEnv,nSize); nSize -= strlen(pszEnv); } //終了処理 free(pszInputBuffer); return strlen(szOutputBuffer); } } //次の環境変数を検索する pszTmpR = strchr(pszTmpL,'$'); } //残文字列を出力バッファに追加する strncat(szOutputBuffer,pszTmpL,nSize); free(pszInputBuffer); return strlen(szOutputBuffer); } #endif //******************************************************************************* //* getEnvString関数 * //******************************************************************************* //* 環境変数を取得する。取得できない場合は初期値を出力する //* parameter O outputBuffer :出力バッファ //* I inputEnvName :入力環境変数名 //* I DefaultString :初期値 //* I maxOutputSize :出力バッファのサイズ(NULL込み) //* return 0以上 :文字列変換成功(文字列長) //* 0 :文字列変換失敗 int getEnvString( char * outputBuffer, const char * inputEnvName, const char * DefaultString, int maxOutputSize) { char * pszEnv; //環境変数 pszEnv = getenv(inputEnvName); //環境変数より文字列を取得 if(pszEnv != NULL){ return ExpandEnvironmentStrings(pszEnv,outputBuffer,maxOutputSize); } else{ //取得できなかった場合は初期値を出力 return ExpandEnvironmentStrings(DefaultString,outputBuffer,maxOutputSize); } } //******************************************************************************* //* getEnvLong関数 * //******************************************************************************* //* 環境変数を取得する。取得できない場合は初期値を出力する //* parameter I inputEnvName :入力環境変数名 //* I DefaultString :初期値 //* return :取得した数値 long getEnvLong( const char * inputEnvName, const long DefaultData) { char * pszEnv; //環境変数 pszEnv = getenv(inputEnvName); //環境変数より文字列を取得 if(pszEnv != NULL){ return strtol(pszEnv,NULL,0); } else{ //取得できなかった場合は初期値を出力 return DefaultData; } } //******************************************************************************* //* strtokEX関数 * //******************************************************************************* //* 文字列を指定された文字で区切り、トークンを切り出す //* parameter I/O pcStartString :入力文字列バッファ(切り出し後の残りバッファ) //* I pcTokenSep :初期値 //* I iOption :オプション(オプション同士をANDで組み合わせ可能) //* return :切り出した文字列 //* 備考:オプションは以下の通り //* 1 :"〜"の部分を1つの文字列として認識しその中で区切らないようにする //* 2 :'〜'の部分を1つの文字列として認識しその中で区切らないようにする //* 4 :(〜)の部分を1つの文字列として認識しその中で区切らないようにする char * strtokEX( char ** pcStartString, const char * pcTokenSep, int iOption) { char * pcToken; int i,j; char cSectionStack[50]; //待避スタックバッファ memset(cSectionStack,'\0',sizeof(cSectionStack)); //区切り文字を検索する pcToken=*pcStartString+strspn(*pcStartString,pcTokenSep); for(i=0,j=0;((strchr(pcTokenSep,*(pcToken+i))==NULL)&&(j==0))||j>0;i++){ if(*(pcToken+i)=='\0'){ break; } switch (*(pcToken+i)){ case '"': case '\'': if(((iOption&0x01) != 0)&&(*(pcToken+i)=='"')){ break; } if(((iOption&0x02) != 0)&&(*(pcToken+i)=='\'')){ break; } if(j>0){ if(*(cSectionStack+j-1)==*(pcToken+i)){ *(cSectionStack+j-1)='\0'; j--; } else{ *(cSectionStack+j)=*(pcToken+i); j++; } } else{ *(cSectionStack+j)=*(pcToken+i); j++; } break; case '(': if((iOption & 0x04) != 0){ break; } *(cSectionStack+j)='('; j++; break; case ')': if((iOption & 0x04) != 0){ break; } if(j==0){ j--; break; } if(*(cSectionStack+j-1)=='('){ *(cSectionStack+j-1)='\0'; j--; } break; } if(j<0){ break; } } if(*(pcToken+i)!='\0'){ *(pcToken+i)='\0'; *pcStartString = pcToken+i+1; } else{ *pcStartString = NULL; } return pcToken; } //******************************************************************************* //* strTrim関数 * //******************************************************************************* //* 文字列の前後の空白を除去する //* parameter I/O inputBuffer :入出力バッファ //* return :空白除去後の文字列の先頭アドレス char * strTrim(char * inputBuffer){ long i; while(*inputBuffer == ' '){ inputBuffer++; } for(i=(long)strlen(inputBuffer)-1;*(inputBuffer+i)==' ';i--){ *(inputBuffer+i)='\0'; } return inputBuffer; } char * strLTrim(char * inputBuffer){ while(*inputBuffer == ' '){ inputBuffer++; } return inputBuffer; } //******************************************************************************* //* 排他ロック開始関数 * //******************************************************************************* //* 排他ロックを行う //* parameter I mutexNo :ロック番号 int startLock(int mutexNo){ if ( mutexNo < 0 || mutexNo >= mutexCount ) return ( -1 ) ; #ifndef WIN32 pthread_mutex_lock( &mutex[mutexNo] ); #else WaitForSingleObject(hMutex[mutexNo],INFINITE); #endif return ( 0 ) ; } //******************************************************************************* //* 排他ロック解除関数 * //******************************************************************************* //* 排他ロックを解除する //* parameter I mutexNo :ロック番号 int endLock(int mutexNo){ if ( mutexNo < 0 || mutexNo >= mutexCount ) return ( -1 ) ; #ifndef WIN32 pthread_mutex_unlock( &mutex[mutexNo] ) ; #else ReleaseMutex( hMutex[mutexNo] ); #endif return ( 0 ) ; } //******************************************************************************* //* 排他ロック初期化関数 * //******************************************************************************* //* 排他ロックを初期化する //* parameter I mutexNum :ロック数(最大10) int initLock(int mutexNum){ if ( mutexCount != 0 ) return ( -2 ) ; if ( mutexNum < 1 || mutexNum > maxMutexLock ) return ( -1 ) ; for ( int i = 0 ; i < mutexNum ;i++ ) { #ifndef WIN32 pthread_mutex_init ( &mutex[i],NULL ) ; #else hMutex[i] = CreateMutex(NULL,FALSE,NULL); #endif } mutexCount = mutexNum ; return ( 0 ) ; }