prevent any2many from overwriting an input file. At the some additional bug fixing of any2many has be carried out.
This commit is contained in:
parent
5088c2873c
commit
f04dd5a283
@ -9,6 +9,8 @@ changes since 0.11.0
|
||||
NEW 2012-04-24 added a first version for negative muon fitting. At the same
|
||||
time substaintial bug fixing has been carried out (mainly the
|
||||
logx/logy handling).
|
||||
CHANGED 2012-05-10 prevent any2many from overwriting an input file. At the
|
||||
some additional bug fixing of any2many has be carried out.
|
||||
CHANGED 2012-05-08 updating docu
|
||||
|
||||
changes since 0.10.0
|
||||
|
@ -202,8 +202,7 @@ int main(int argc, char *argv[])
|
||||
Int_t ival;
|
||||
for (int i=1; i<argc; i++) {
|
||||
|
||||
// handle year option
|
||||
if (!strcmp(argv[i], "-y")) {
|
||||
if (!strcmp(argv[i], "-y")) { // handle year option
|
||||
if (i+1 < argc) {
|
||||
ival=0;
|
||||
status = sscanf(argv[i+1], "%d", &ival);
|
||||
@ -219,14 +218,9 @@ int main(int argc, char *argv[])
|
||||
show_syntax = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// handle standard output option '-s'
|
||||
if (!strcmp(argv[i], "-s"))
|
||||
} else if (!strcmp(argv[i], "-s")) { // handle standard output option '-s'
|
||||
info.useStandardOutput = true;
|
||||
|
||||
// set input option tag
|
||||
if (!strcmp(argv[i], "-f")) {
|
||||
} else if (!strcmp(argv[i], "-f")) { // set input option tag
|
||||
if (i+1 < argc) {
|
||||
bool done = false;
|
||||
int j = i+1;
|
||||
@ -238,18 +232,15 @@ int main(int argc, char *argv[])
|
||||
j++; // shift input to the proper place
|
||||
}
|
||||
} while (!done && (j<argc));
|
||||
i = j;
|
||||
if (i >= argc) // make sure that counter is still in range
|
||||
i = j-1;
|
||||
if (j >= argc) // make sure that counter is still in range
|
||||
break;
|
||||
} else {
|
||||
cerr << endl << ">> any2many **ERROR** found input option '-f' without any arguments" << endl;
|
||||
show_syntax = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// handle output file name option '-o'
|
||||
if (!strcmp(argv[i], "-o")) {
|
||||
} else if (!strcmp(argv[i], "-o")) { // handle output file name option '-o'
|
||||
if (i+1 < argc) {
|
||||
outputFileName = argv[i+1];
|
||||
i++;
|
||||
@ -258,9 +249,7 @@ int main(int argc, char *argv[])
|
||||
show_syntax = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(argv[i], "-r")) {
|
||||
} else if (!strcmp(argv[i], "-r")) {
|
||||
if (i+1 < argc) {
|
||||
// first check for run list sequence of the form <runStartNo>-<runEndNo>
|
||||
int startNo, endNo;
|
||||
@ -273,7 +262,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
for (int j=startNo; j<=endNo; j++)
|
||||
info.runList.push_back(j);
|
||||
i += 2;
|
||||
i++;
|
||||
} else { // check for run list of the form <run1> <run2> ... <runN>
|
||||
bool done = false;
|
||||
int j = i+1;
|
||||
@ -286,8 +275,8 @@ int main(int argc, char *argv[])
|
||||
done = true;
|
||||
}
|
||||
} while (!done && (j<argc));
|
||||
i = j;
|
||||
if (i >= argc) // make sure that counter is still in range
|
||||
i = j-1;
|
||||
if (j >= argc) // make sure that counter is still in range
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -302,10 +291,7 @@ int main(int argc, char *argv[])
|
||||
show_syntax = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// set convert option tag
|
||||
if (!strcmp(argv[i], "-c")) {
|
||||
} else if (!strcmp(argv[i], "-c")) { // set convert option tag
|
||||
bool found = false;
|
||||
string sval;
|
||||
if (i+2 < argc) {
|
||||
@ -343,10 +329,7 @@ int main(int argc, char *argv[])
|
||||
show_syntax = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// filter output path name flag
|
||||
if (!strcmp(argv[i], "-p")) {
|
||||
} else if (!strcmp(argv[i], "-p")) { // filter output path name flag
|
||||
if (i+1 < argc) {
|
||||
info.outPath = argv[i+1];
|
||||
if (!info.outPath.EndsWith("/"))
|
||||
@ -357,14 +340,12 @@ int main(int argc, char *argv[])
|
||||
show_syntax = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// filter out rebinning option
|
||||
if (!strcmp(argv[i], "-rebin")) {
|
||||
} else if (!strcmp(argv[i], "-rebin")) { // filter out rebinning option
|
||||
if (i+1 < argc) {
|
||||
status = sscanf(argv[i+1], "%d", &ival);
|
||||
if (status == 1) {
|
||||
info.rebin = ival;
|
||||
i++;
|
||||
} else {
|
||||
cerr << endl << ">> any2many **ERROR** found in option '-rebin " << argv[i+1] << "' which doesn't make any sense." << endl;
|
||||
show_syntax = true;
|
||||
@ -375,10 +356,7 @@ int main(int argc, char *argv[])
|
||||
show_syntax = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// filter out the input/output file template
|
||||
if (!strcmp(argv[i], "-t")) {
|
||||
} else if (!strcmp(argv[i], "-t")) { // filter out the input/output file template
|
||||
if (i+2 < argc) {
|
||||
if ((argv[i+1][0] == '-') || (argv[i+2][0] == '-')) {
|
||||
cerr << endl << ">> any2many **ERROR** found invalid template in option '-t'" << endl;
|
||||
@ -393,10 +371,7 @@ int main(int argc, char *argv[])
|
||||
show_syntax = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// filter out if compression is whished
|
||||
if (!strcmp(argv[i], "-z")) {
|
||||
} else if (!strcmp(argv[i], "-z")) { // filter out if compression is whished
|
||||
if (i+2 < argc) {
|
||||
if ((argv[i+1][0] == '-') || (argv[i+2][0] == '-')) {
|
||||
cerr << endl << ">> any2many **ERROR** found invalid template in option '-t'" << endl;
|
||||
@ -419,6 +394,10 @@ int main(int argc, char *argv[])
|
||||
show_syntax = true;
|
||||
break;
|
||||
}
|
||||
} else { // unrecognized command
|
||||
cerr << endl << ">> any2many **ERROR** found unrecognized option " << argv[i] << endl;
|
||||
show_syntax = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,9 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
@ -298,6 +301,8 @@ Bool_t PRunDataHandler::ReadWriteFilesList()
|
||||
Int_t inTag = A2M_UNDEFINED;
|
||||
if (!fAny2ManyInfo->inFormat.CompareTo("root", TString::kIgnoreCase))
|
||||
inTag = A2M_ROOT;
|
||||
else if (!fAny2ManyInfo->inFormat.CompareTo("musrroot", TString::kIgnoreCase))
|
||||
inTag = A2M_MUSR_ROOT;
|
||||
else if (!fAny2ManyInfo->inFormat.CompareTo("psi-bin", TString::kIgnoreCase))
|
||||
inTag = A2M_PSIBIN;
|
||||
else if (!fAny2ManyInfo->inFormat.CompareTo("psi-mdu", TString::kIgnoreCase))
|
||||
@ -353,6 +358,7 @@ Bool_t PRunDataHandler::ReadWriteFilesList()
|
||||
Bool_t success = false;
|
||||
switch (inTag) {
|
||||
case A2M_ROOT:
|
||||
case A2M_MUSR_ROOT:
|
||||
success = ReadRootFile();
|
||||
break;
|
||||
case A2M_PSIBIN:
|
||||
@ -455,6 +461,7 @@ Bool_t PRunDataHandler::ReadWriteFilesList()
|
||||
Bool_t success = false;
|
||||
switch (inTag) {
|
||||
case A2M_ROOT:
|
||||
case A2M_MUSR_ROOT:
|
||||
success = ReadRootFile();
|
||||
break;
|
||||
case A2M_PSIBIN:
|
||||
@ -537,7 +544,7 @@ Bool_t PRunDataHandler::ReadWriteFilesList()
|
||||
|
||||
// check if compression is wished
|
||||
if (fAny2ManyInfo->compressionTag > 0) {
|
||||
TString fln = fAny2ManyInfo->compressFileName;
|
||||
TString fln = fAny2ManyInfo->outPath + fAny2ManyInfo->compressFileName;
|
||||
|
||||
// currently system call is used, which means this is only running under Linux and Mac OS X but not under Windows
|
||||
char cmd[256];
|
||||
@ -3961,21 +3968,10 @@ Bool_t PRunDataHandler::ReadDBFile()
|
||||
*/
|
||||
Bool_t PRunDataHandler::WriteMusrRootFile(TString fln)
|
||||
{
|
||||
// generate output file name if needed
|
||||
if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) {
|
||||
if (fln.Length() == 0) {
|
||||
Bool_t ok = false;
|
||||
fln = GetFileName(".root", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
} else {
|
||||
fln.Prepend(fAny2ManyInfo->outPath);
|
||||
}
|
||||
// keep the file name if compression is whished
|
||||
fAny2ManyInfo->outPathFileName.push_back(fln);
|
||||
} else {
|
||||
fln = fAny2ManyInfo->outPath + TString("__tmp.root");
|
||||
}
|
||||
Bool_t ok = false;
|
||||
fln = GenerateOutputFileName(fln, ".root", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
if (!fAny2ManyInfo->useStandardOutput)
|
||||
cout << endl << ">> PRunDataHandler::WriteMusrRootFile(): writing a root data file (" << fln.Data() << ") ... " << endl;
|
||||
@ -4214,21 +4210,11 @@ Bool_t PRunDataHandler::WriteMusrRootFile(TString fln)
|
||||
*/
|
||||
Bool_t PRunDataHandler::WriteRootFile(TString fln)
|
||||
{
|
||||
// generate output file name if needed
|
||||
if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) {
|
||||
if (fln.Length() == 0) {
|
||||
Bool_t ok = false;
|
||||
fln = GetFileName(".root", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
} else {
|
||||
fln.Prepend(fAny2ManyInfo->outPath);
|
||||
}
|
||||
// keep the file name if compression is whished
|
||||
fAny2ManyInfo->outPathFileName.push_back(fln);
|
||||
} else {
|
||||
fln = fAny2ManyInfo->outPath + TString("__tmp.root");
|
||||
}
|
||||
Bool_t ok = false;
|
||||
fln = GenerateOutputFileName(fln, ".root", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
|
||||
if (!fAny2ManyInfo->useStandardOutput)
|
||||
cout << endl << ">> PRunDataHandler::WriteRootFile(): writing a root data file (" << fln.Data() << ") ... " << endl;
|
||||
@ -4409,17 +4395,10 @@ Bool_t PRunDataHandler::WriteRootFile(TString fln)
|
||||
Bool_t PRunDataHandler::WriteNexusFile(TString fln)
|
||||
{
|
||||
#ifdef PNEXUS_ENABLED
|
||||
// generate output file name
|
||||
if (fln.Length() == 0) {
|
||||
Bool_t ok = false;
|
||||
fln = GetFileName(".nxs", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
} else {
|
||||
fln.Prepend(fAny2ManyInfo->outPath);
|
||||
}
|
||||
// keep the file name if compression is whished
|
||||
fAny2ManyInfo->outPathFileName.push_back(fln);
|
||||
Bool_t ok = false;
|
||||
fln = GenerateOutputFileName(fln, ".nxs", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
if (!fAny2ManyInfo->useStandardOutput)
|
||||
cout << endl << ">> PRunDataHandler::WriteNexusFile(): writing a NeXus data file (" << fln.Data() << ") ... " << endl;
|
||||
@ -4765,22 +4744,16 @@ Bool_t PRunDataHandler::WriteWkmFile(TString fln)
|
||||
if (!fAny2ManyInfo->inFormat.CompareTo("ROOT"))
|
||||
lem_wkm_style = true;
|
||||
|
||||
// generate output file name
|
||||
TString fileName("");
|
||||
if (fln.Length() == 0) {
|
||||
Bool_t ok = false;
|
||||
if (lem_wkm_style)
|
||||
fln = GetFileName(".nemu", ok);
|
||||
else
|
||||
fln = GetFileName(".wkm", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
fileName = fln;
|
||||
} else {
|
||||
fln.Prepend(fAny2ManyInfo->outPath);
|
||||
}
|
||||
// keep the file name if compression is whished
|
||||
fAny2ManyInfo->outPathFileName.push_back(fln);
|
||||
Bool_t ok = false;
|
||||
if (lem_wkm_style)
|
||||
fln = GenerateOutputFileName(fln, ".nemu", ok);
|
||||
else
|
||||
fln = GenerateOutputFileName(fln, ".wkm", ok);
|
||||
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
TString fileName = fln;
|
||||
|
||||
if (!fAny2ManyInfo->useStandardOutput)
|
||||
cout << endl << ">> PRunDataHandler::WriteWkmFile(): writing a wkm data file (" << fln.Data() << ") ... " << endl;
|
||||
@ -4842,16 +4815,20 @@ Bool_t PRunDataHandler::WriteWkmFile(TString fln)
|
||||
UInt_t no_of_bins_per_line = 16;
|
||||
if (lem_wkm_style)
|
||||
no_of_bins_per_line = 10;
|
||||
|
||||
PRawRunDataSet *dataSet;
|
||||
|
||||
if (fAny2ManyInfo->rebin == 1) {
|
||||
for (UInt_t i=0; i<fData[0].GetNoOfHistos(); i++) {
|
||||
cout << endl << endl;
|
||||
for (UInt_t j=0; j<fData[0].GetDataBin(i)->size(); j++) {
|
||||
dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
|
||||
for (UInt_t j=0; j<dataSet->GetData()->size(); j++) {
|
||||
if ((j > 0) && (j % no_of_bins_per_line == 0))
|
||||
cout << endl;
|
||||
if (lem_wkm_style)
|
||||
cout << setw(8) << static_cast<Int_t>(fData[0].GetDataBin(i)->at(j));
|
||||
cout << setw(8) << static_cast<Int_t>(dataSet->GetData()->at(j));
|
||||
else
|
||||
cout << static_cast<Int_t>(fData[0].GetDataBin(i)->at(j)) << " ";
|
||||
cout << static_cast<Int_t>(dataSet->GetData()->at(j)) << " ";
|
||||
}
|
||||
}
|
||||
} else { // rebin > 1
|
||||
@ -4861,7 +4838,8 @@ Bool_t PRunDataHandler::WriteWkmFile(TString fln)
|
||||
cout << endl << endl;
|
||||
count = 0;
|
||||
dataRebin = 0; // reset rebin
|
||||
for (UInt_t j=0; j<fData[0].GetDataBin(i)->size(); j++) {
|
||||
dataSet = fData[0].GetDataSet(i, false); // i.e. the false means, that i is the index and NOT the histo number
|
||||
for (UInt_t j=0; j<dataSet->GetData()->size(); j++) {
|
||||
if ((j > 0) && (j % fAny2ManyInfo->rebin == 0)) {
|
||||
if (lem_wkm_style)
|
||||
cout << setw(8) << dataRebin;
|
||||
@ -4872,7 +4850,7 @@ Bool_t PRunDataHandler::WriteWkmFile(TString fln)
|
||||
if ((count > 0) && (count % no_of_bins_per_line == 0))
|
||||
cout << endl;
|
||||
} else {
|
||||
dataRebin += static_cast<Int_t>(fData[0].GetDataBin(i)->at(j));
|
||||
dataRebin += static_cast<Int_t>(dataSet->GetData()->at(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4902,21 +4880,10 @@ Bool_t PRunDataHandler::WriteWkmFile(TString fln)
|
||||
*/
|
||||
Bool_t PRunDataHandler::WritePsiBinFile(TString fln)
|
||||
{
|
||||
// generate output file name if needed
|
||||
if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) {
|
||||
if (fln.Length() == 0) {
|
||||
Bool_t ok = false;
|
||||
fln = GetFileName(".bin", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
} else {
|
||||
fln.Prepend(fAny2ManyInfo->outPath);
|
||||
}
|
||||
// keep the file name if compression is whished
|
||||
fAny2ManyInfo->outPathFileName.push_back(fln);
|
||||
} else {
|
||||
fln = fAny2ManyInfo->outPath + TString("__tmp.bin");
|
||||
}
|
||||
Bool_t ok = false;
|
||||
fln = GenerateOutputFileName(fln, ".bin", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
if (!fAny2ManyInfo->useStandardOutput)
|
||||
cout << endl << ">> PRunDataHandler::WritePsiBinFile(): writing a psi-bin data file (" << fln.Data() << ") ... " << endl;
|
||||
@ -5134,21 +5101,10 @@ Bool_t PRunDataHandler::WritePsiBinFile(TString fln)
|
||||
*/
|
||||
Bool_t PRunDataHandler::WriteMudFile(TString fln)
|
||||
{
|
||||
// generate output file name if needed
|
||||
if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) {
|
||||
if (fln.Length() == 0) {
|
||||
Bool_t ok = false;
|
||||
fln = GetFileName(".msr", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
} else {
|
||||
fln.Prepend(fAny2ManyInfo->outPath);
|
||||
}
|
||||
// keep the file name if compression is whished
|
||||
fAny2ManyInfo->outPathFileName.push_back(fln);
|
||||
} else {
|
||||
fln = TString("__tmp.msr");
|
||||
}
|
||||
Bool_t ok = false;
|
||||
fln = GenerateOutputFileName(fln, ".msr", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
if (!fAny2ManyInfo->useStandardOutput)
|
||||
cout << endl << ">> PRunDataHandler::WriteMudFile(): writing a mud data file (" << fln.Data() << ") ... " << endl;
|
||||
@ -5305,19 +5261,12 @@ Bool_t PRunDataHandler::WriteMudFile(TString fln)
|
||||
*/
|
||||
Bool_t PRunDataHandler::WriteAsciiFile(TString fln)
|
||||
{
|
||||
// generate output file name
|
||||
TString fileName("");
|
||||
if (fln.Length() == 0) {
|
||||
Bool_t ok = false;
|
||||
fln = GetFileName(".ascii", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
fileName = fln;
|
||||
} else {
|
||||
fln.Prepend(fAny2ManyInfo->outPath);
|
||||
}
|
||||
// keep the file name if compression is whished
|
||||
fAny2ManyInfo->outPathFileName.push_back(fln);
|
||||
Bool_t ok = false;
|
||||
fln = GenerateOutputFileName(fln, ".ascii", ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
TString fileName = fln;
|
||||
|
||||
if (!fAny2ManyInfo->useStandardOutput)
|
||||
cout << endl << ">> PRunDataHandler::WriteAsciiFile(): writing an ascii data file (" << fln.Data() << ") ... " << endl;
|
||||
@ -5668,6 +5617,62 @@ Int_t PRunDataHandler::GetDataTagIndex(TString &str, const PStringVector* dataTa
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// GenerateOutputFileName (private)
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
* <p>Generates the output file name (any2many). It also makes sure that the
|
||||
* generated output file name does not coincidentally is identical to an already
|
||||
* existing file.
|
||||
*
|
||||
* <b>return:</b>
|
||||
* - constructed file name
|
||||
* - empty string
|
||||
*
|
||||
* \param fileName
|
||||
* \param extension if the file name to be constructed
|
||||
* \param ok flag which is 'true' if the file name could be constructed, 'false' otherwise
|
||||
*/
|
||||
TString PRunDataHandler::GenerateOutputFileName(const TString fileName, const TString extension, Bool_t &ok)
|
||||
{
|
||||
TString fln = fileName;
|
||||
ok = true;
|
||||
|
||||
// generate output file name if needed
|
||||
if (!fAny2ManyInfo->useStandardOutput || (fAny2ManyInfo->compressionTag > 0)) {
|
||||
if (fln.Length() == 0) {
|
||||
ok = false;
|
||||
fln = GetFileName(extension, ok);
|
||||
if (!ok) {
|
||||
fln = "";
|
||||
return fln;
|
||||
}
|
||||
} else {
|
||||
fln.Prepend(fAny2ManyInfo->outPath);
|
||||
}
|
||||
|
||||
// make sure that the file name doesn't already exist as a real file
|
||||
if (!gSystem->AccessPathName(fln)) { // file name already exists!!
|
||||
Int_t count = 1;
|
||||
TString newFln;
|
||||
do {
|
||||
newFln = fln;
|
||||
newFln.Insert(newFln.Last('.'), TString::Format(".%d", count++));
|
||||
} while (!gSystem->AccessPathName(newFln));
|
||||
cerr << endl << ">> PRunDataHandler::GenerateOutputFileName **WARNING** needed to modify output filename to " << newFln << ",";
|
||||
cerr << endl << ">> due to potential conflict with already existing files." << endl << endl;
|
||||
fln = newFln;
|
||||
}
|
||||
|
||||
// keep the file name if compression is whished
|
||||
fAny2ManyInfo->outPathFileName.push_back(fln);
|
||||
} else {
|
||||
fln = fAny2ManyInfo->outPath + TString("__tmp.") + extension;
|
||||
}
|
||||
|
||||
return fln;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// GetFileName (private)
|
||||
//--------------------------------------------------------------------------
|
||||
|
@ -94,6 +94,7 @@ class PRunDataHandler
|
||||
virtual Int_t ToInt(TString &str, Bool_t &ok);
|
||||
virtual Int_t GetDataTagIndex(TString &str, const PStringVector* fLabels);
|
||||
|
||||
virtual TString GenerateOutputFileName(const TString fileName, const TString extension, Bool_t &ok);
|
||||
virtual TString GetFileName(const TString extension, Bool_t &ok);
|
||||
virtual TString FileNameFromTemplate(TString &fileNameTemplate, Int_t run, TString &year, Bool_t &ok);
|
||||
virtual bool DateToISO8601(string inDate, string &iso8601Date);
|
||||
|
Loading…
x
Reference in New Issue
Block a user