00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 #include <pwd.h>
00032 #include <fcntl.h>
00033 #include <unistd.h>
00034 #include <sys/stat.h>
00035 #include <cstdlib>
00036 #include <cstdio>
00037 #include "GTools.hpp"
00038 #include "GException.hpp"
00039 #include "GFilename.hpp"
00040 #include "GApplicationPars.hpp"
00041
00042
00043 #define G_ACCESS "GApplicationPars::operator[](std::string&)"
00044 #define G_AT "GApplicationPar& GApplicationPars::at(int&)"
00045 #define G_APPEND "GApplicationPars::append(GApplicationPar&)"
00046 #define G_INSERT1 "GApplicationPar& GApplicationPars::insert(int&, "\
00047 "GApplicationPar&)"
00048 #define G_INSERT2 "GApplicationPar& GApplicationPars::insert(std::string&, "\
00049 "GApplicationPar&)"
00050 #define G_REMOVE1 "GApplicationPars::remove(int&)"
00051 #define G_REMOVE2 "GApplicationPars::remove(std::string&)"
00052 #define G_EXTEND "GApplicationPars::extend(GApplicationPars&)"
00053 #define G_LOAD1 "GApplicationPars::load(GFilename&)"
00054 #define G_LOAD2 "GApplicationPars::load(GFilename&, "\
00055 "std::vector<std::string>&)"
00056 #define G_SAVE "GApplicationPars::save(GFilename&)"
00057 #define G_OUTPATH "GApplicationPars::outpath(std::string&)"
00058 #define G_READ "GApplicationPars::read(std::string&)"
00059 #define G_WRITE "GApplicationPars::write(std::string&)"
00060 #define G_PARSE "GApplicationPars::parse()"
00061
00062
00063
00064
00065 #define G_LOCK_PARFILE
00066 //#define G_CHECK_LOCK_PARFILE
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 GApplicationPars::GApplicationPars(void)
00081 {
00082
00083 init_members();
00084
00085
00086 return;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095 GApplicationPars::GApplicationPars(const GFilename& filename)
00096 {
00097
00098 init_members();
00099
00100
00101 load(filename);
00102
00103
00104 return;
00105 }
00106
00107
00108
00109
00110
00111
00112
00113 GApplicationPars::GApplicationPars(const GFilename& filename,
00114 const std::vector<std::string>& args)
00115 {
00116
00117 init_members();
00118
00119
00120 load(filename, args);
00121
00122
00123 return;
00124 }
00125
00126
00127
00128
00129
00130
00131
00132 GApplicationPars::GApplicationPars(const GApplicationPars& pars)
00133 {
00134
00135 init_members();
00136
00137
00138 copy_members(pars);
00139
00140
00141 return;
00142 }
00143
00144
00145
00146
00147
00148 GApplicationPars::~GApplicationPars(void)
00149 {
00150
00151 free_members();
00152
00153
00154 return;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 GApplicationPars& GApplicationPars::operator=(const GApplicationPars& pars)
00171 {
00172
00173 if (this != &pars) {
00174
00175
00176 free_members();
00177
00178
00179 init_members();
00180
00181
00182 copy_members(pars);
00183
00184 }
00185
00186
00187 return *this;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 GApplicationPar& GApplicationPars::operator[](const std::string& name)
00201 {
00202
00203 int index = get_index(name);
00204
00205
00206 if (index == -1) {
00207 std::string msg = "Parameter \""+name+"\" has not been found in "
00208 "parameter file. Please specify a valid parameter "
00209 "name.";
00210 throw GException::invalid_argument(G_ACCESS, msg);
00211 }
00212
00213
00214 return (m_pars[index]);
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 const GApplicationPar& GApplicationPars::operator[](const std::string& name) const
00228 {
00229
00230 int index = get_index(name);
00231
00232
00233 if (index == -1) {
00234 std::string msg = "Parameter \""+name+"\" has not been found in "
00235 "parameter file. Please specify a valid parameter "
00236 "name.";
00237 throw GException::invalid_argument(G_ACCESS, msg);
00238 }
00239
00240
00241 return (m_pars[index]);
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 void GApplicationPars::clear(void)
00255 {
00256
00257 free_members();
00258
00259
00260 init_members();
00261
00262
00263 return;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272 GApplicationPars* GApplicationPars::clone(void) const
00273 {
00274 return (new GApplicationPars(*this));
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 GApplicationPar& GApplicationPars::at(const int& index)
00287 {
00288
00289 #if defined(G_RANGE_CHECK)
00290 if (index < 0 || index >= size()) {
00291 throw GException::out_of_range(G_AT, "Parameter index", index, size());
00292 }
00293 #endif
00294
00295
00296 return (m_pars[index]);
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 const GApplicationPar& GApplicationPars::at(const int& index) const
00309 {
00310
00311 #if defined(G_RANGE_CHECK)
00312 if (index < 0 || index >= size()) {
00313 throw GException::out_of_range(G_AT, "Parameter index", index, size());
00314 }
00315 #endif
00316
00317
00318 return (m_pars[index]);
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 GApplicationPar& GApplicationPars::append(const GApplicationPar& par)
00335 {
00336
00337 int inx = get_index(par.name());
00338 if (inx != -1) {
00339 std::string msg =
00340 "Attempt to append parameter with name \""+par.name()+"\" in"
00341 " parameter container, but a parameter with the same name exists"
00342 " already at index "+gammalib::str(inx)+" in the container.\n"
00343 "Every parameter in the parameter container needs a unique name.";
00344 throw GException::invalid_value(G_APPEND, msg);
00345 }
00346
00347
00348 m_pars.push_back(par);
00349
00350
00351 GApplicationPar& parameter = m_pars[m_pars.size()-1];
00352
00353
00354 size_t start = 0;
00355 size_t stop = 0;
00356 std::string line = parline(parameter, &start, &stop);
00357
00358
00359 m_line.push_back(m_parfile.size());
00360 m_parfile.push_back(line);
00361 m_vstart.push_back(start);
00362 m_vstop.push_back(stop);
00363
00364
00365 return parameter;
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375 void GApplicationPars::append_standard(void)
00376 {
00377
00378 append(GApplicationPar("chatter","i","h","2","0","4","Chattiness of output"));
00379 append(GApplicationPar("clobber","b","h","yes","","","Overwrite existing output files with new output files?"));
00380 append(GApplicationPar("debug","b","h","no","","","Debugging mode activated"));
00381 append(GApplicationPar("mode","s","h","ql","","","Mode of automatic parameters"));
00382
00383
00384 return;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 GApplicationPar& GApplicationPars::insert(const int& index, const GApplicationPar& par)
00399 {
00400
00401 #if defined(G_RANGE_CHECK)
00402 if (is_empty()) {
00403 if (index > 0) {
00404 throw GException::out_of_range(G_INSERT1, "Parameter index", index, size());
00405 }
00406 }
00407 else {
00408 if (index < 0 || index >= size()) {
00409 throw GException::out_of_range(G_INSERT1, "Parameter index", index, size());
00410 }
00411 }
00412 #endif
00413
00414
00415 int inx = get_index(par.name());
00416 if (inx != -1) {
00417 std::string msg =
00418 "Attempt to insert parameter with name \""+par.name()+"\" in"
00419 " parameter container before index "+gammalib::str(index)+
00420 ", but a parameter with the same name exists already at index "+
00421 gammalib::str(inx)+" in the container.\n"
00422 "Every parameter in the parameter container needs a unique name.";
00423 throw GException::invalid_value(G_INSERT1, msg);
00424 }
00425
00426
00427 m_pars.insert(m_pars.begin()+index, par);
00428
00429
00430 GApplicationPar& parameter = m_pars[m_pars.size()-1];
00431
00432
00433 size_t start = 0;
00434 size_t stop = 0;
00435 std::string line = parline(parameter, &start, &stop);
00436
00437
00438
00439 int line_number = m_line[index];
00440
00441
00442 m_parfile.insert(m_parfile.begin()+line_number, line);
00443 m_line.insert(m_line.begin()+index, line_number);
00444 m_vstart.insert(m_vstart.begin()+index, start);
00445 m_vstop.insert(m_vstop.begin()+index, stop);
00446
00447
00448 for (int i = index+1; i < size(); ++i) {
00449 m_line[i]++;
00450 }
00451
00452
00453 return parameter;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 GApplicationPar& GApplicationPars::insert(const std::string& name, const GApplicationPar& par)
00473 {
00474
00475 int index = get_index(name);
00476
00477
00478 if (index == -1) {
00479 std::string msg = "Parameter \""+name+"\" has not been found in"
00480 " parameter file.\n"
00481 "Please specify a valid parameter name.";
00482 throw GException::invalid_argument(G_INSERT2, msg);
00483 }
00484
00485
00486 return (insert(index, par));
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 void GApplicationPars::remove(const int& index)
00501 {
00502
00503 #if defined(G_RANGE_CHECK)
00504 if (index < 0 || index >= size()) {
00505 throw GException::out_of_range(G_REMOVE1, "Parameter index", index, size());
00506 }
00507 #endif
00508
00509
00510 m_pars.erase(m_pars.begin() + index);
00511
00512
00513 m_parfile.erase(m_parfile.begin() + m_line[index]);
00514 m_line.erase(m_line.begin() + index);
00515 m_vstart.erase(m_vstart.begin() + index);
00516 m_vstop.erase(m_vstop.begin() + index);
00517
00518
00519 for (int i = index; i < size(); ++i) {
00520 m_line[i]--;
00521 }
00522
00523
00524 return;
00525 }
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 void GApplicationPars::remove(const std::string& name)
00539 {
00540
00541 int index = get_index(name);
00542
00543
00544 if (index == -1) {
00545 std::string msg = "Parameter \""+name+"\" has not been found in"
00546 " parameter file.\n"
00547 "Please specify a valid parameter name.";
00548 throw GException::invalid_argument(G_REMOVE2, msg);
00549 }
00550
00551
00552 remove(index);
00553
00554
00555 return;
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 void GApplicationPars::extend(const GApplicationPars& pars)
00567 {
00568
00569 if (!pars.is_empty()) {
00570
00571
00572
00573
00574 int num = pars.size();
00575
00576
00577 reserve(size() + num);
00578
00579
00580 for (int i = 0; i < num; ++i) {
00581
00582
00583 int inx = get_index(pars[i].name());
00584 if (inx != -1) {
00585 std::string msg =
00586 "Attempt to append parameter with name \""+pars[i].name()+
00587 "\" to parameter container, but a parameter with the same name"
00588 " exists already at index "+gammalib::str(inx)+" in the"
00589 " container.\n"
00590 "Every parameter in the parameter container needs a unique"
00591 " name.";
00592 throw GException::invalid_value(G_EXTEND, msg);
00593 }
00594
00595
00596 append(pars[i]);
00597
00598 }
00599
00600 }
00601
00602
00603 return;
00604 }
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 bool GApplicationPars::contains(const std::string& name) const
00617 {
00618
00619 int inx = get_index(name);
00620
00621
00622 return (inx != -1);
00623 }
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636 void GApplicationPars::load(const GFilename& filename)
00637 {
00638
00639 m_parfile.clear();
00640
00641
00642 std::string path = inpath(filename.url());
00643 if (path.length() == 0) {
00644 throw GException::par_file_not_found(G_LOAD1, filename.url());
00645 }
00646
00647
00648 read(path);
00649
00650
00651 parse();
00652
00653
00654 return;
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672 void GApplicationPars::load(const GFilename& filename,
00673 const std::vector<std::string>& args)
00674 {
00675
00676 m_parfile.clear();
00677
00678
00679 std::string path = inpath(filename.url());
00680 if (path.length() == 0) {
00681 throw GException::par_file_not_found(G_LOAD2, filename.url());
00682 }
00683
00684
00685 read(path);
00686
00687
00688 parse();
00689
00690
00691 for (int i = 1; i < args.size(); ++i) {
00692
00693
00694 size_t pos = args[i].find("=");
00695 if (pos == std::string::npos) {
00696 throw GException::bad_cmdline_argument(G_LOAD2, args[i],
00697 "no \"=\" specified");
00698 }
00699 std::string name = args[i].substr(0, pos);
00700 std::string value = args[i].substr(pos+1);
00701 if (name.length() < 1) {
00702 throw GException::bad_cmdline_argument(G_LOAD2, args[i],
00703 "no parameter name before \"=\"");
00704 }
00705
00706
00707 if (!contains(name)) {
00708 throw GException::bad_cmdline_argument(G_LOAD2, args[i],
00709 "invalid parameter name \""+name+"\"");
00710 }
00711
00712
00713 try {
00714 (*this)[name].value(value);
00715 }
00716 catch (GException::par_error &e) {
00717 throw GException::bad_cmdline_argument(G_LOAD2, args[i]);
00718 }
00719
00720
00721 if ((*this)[name].mode() == "q") {
00722 (*this)[name].mode("h");
00723 }
00724 else if ((*this)[name].mode() == "ql") {
00725 (*this)[name].mode("hl");
00726 }
00727 else if ((*this)[name].mode() == "lq") {
00728 (*this)[name].mode("lh");
00729 }
00730
00731 }
00732
00733
00734 return;
00735 }
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746 void GApplicationPars::save(const GFilename& filename)
00747 {
00748
00749 std::string path = outpath(filename.url());
00750 if (path.size() == 0) {
00751 throw GException::par_file_not_found(G_SAVE, filename.url());
00752 }
00753
00754
00755 update();
00756
00757
00758 write(path);
00759
00760
00761 return;
00762 }
00763
00764
00765
00766
00767
00768
00769
00770
00771 std::string GApplicationPars::print(const GChatter& chatter) const
00772 {
00773
00774 std::string result;
00775
00776
00777 if (chatter != SILENT) {
00778
00779
00780 result.append("=== GApplicationPars ===");
00781
00782
00783 for (int i = 0; i < size(); ++i) {
00784 result.append("\n"+m_pars[i].print(chatter));
00785 }
00786
00787 }
00788
00789
00790 return result;
00791 }
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803 void GApplicationPars::init_members(void)
00804 {
00805
00806 m_parfile.clear();
00807 m_pars.clear();
00808 m_line.clear();
00809 m_vstart.clear();
00810 m_vstop.clear();
00811 m_mode = "h";
00812
00813
00814 return;
00815 }
00816
00817
00818
00819
00820
00821
00822
00823 void GApplicationPars::copy_members(const GApplicationPars& pars)
00824 {
00825
00826 m_parfile = pars.m_parfile;
00827 m_pars = pars.m_pars;
00828 m_line = pars.m_line;
00829 m_vstart = pars.m_vstart;
00830 m_vstop = pars.m_vstop;
00831 m_mode = pars.m_mode;
00832
00833
00834 return;
00835 }
00836
00837
00838
00839
00840
00841 void GApplicationPars::free_members(void)
00842 {
00843
00844 return;
00845 }
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 std::string GApplicationPars::inpath(const std::string& filename) const
00866 {
00867
00868 std::string path;
00869
00870
00871
00872 char* ptr = std::getenv("PFILES");
00873 if (ptr != NULL) {
00874
00875
00876 std::string pfiles = ptr;
00877 std::vector<std::string> dirs = gammalib::split(pfiles, ":;");
00878
00879
00880 for (int i = 0; i < dirs.size(); ++i) {
00881
00882
00883 std::string fname = dirs[i] + "/" + filename;
00884
00885
00886 if (access(fname.c_str(), R_OK) == 0) {
00887 path = fname;
00888 break;
00889 }
00890
00891 }
00892
00893 }
00894
00895
00896
00897 else {
00898 uid_t uid = geteuid();
00899 struct passwd* pw = getpwuid(uid);
00900 if (pw != NULL) {
00901 std::string fname = std::string(pw->pw_dir) + "/pfiles/" + filename;
00902 if (access(fname.c_str(), R_OK) == 0) {
00903 path = fname;
00904 }
00905 }
00906 }
00907
00908
00909
00910 if (path.size() == 0) {
00911 ptr = std::getenv("GAMMALIB");
00912 if (ptr != NULL) {
00913 std::string fname = std::string(ptr) + "/syspfiles/" + filename;
00914 if (access(fname.c_str(), R_OK) == 0) {
00915 path = fname;
00916 }
00917 }
00918 }
00919
00920
00921
00922 #ifdef PACKAGE_PREFIX
00923 if (path.size() == 0) {
00924 std::string fname = std::string(PACKAGE_PREFIX) + "/syspfiles/" +
00925 filename;
00926 if (access(fname.c_str(), R_OK) == 0) {
00927 path = fname;
00928 }
00929 }
00930 #endif
00931
00932
00933
00934
00935 return path;
00936 }
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956 std::string GApplicationPars::outpath(const std::string& filename) const
00957 {
00958
00959 std::string path;
00960
00961
00962 char* ptr = std::getenv("PFILES");
00963 if (ptr != NULL) {
00964
00965
00966 std::string pfiles = ptr;
00967 std::vector<std::string> dirs = gammalib::split(pfiles, ":;");
00968
00969
00970 for (int i = 0; i < dirs.size(); ++i) {
00971
00972
00973 if (access(dirs[i].c_str(), W_OK) == 0) {
00974 path = dirs[i] + "/" + filename;
00975 break;
00976 }
00977
00978 }
00979 }
00980
00981
00982
00983 if (path.size() == 0) {
00984
00985
00986 uid_t uid = geteuid();
00987 gid_t gid = getegid();
00988 struct passwd* pw = getpwuid(uid);
00989 if (pw == NULL) {
00990 throw GException::home_not_found(G_OUTPATH);
00991 }
00992
00993
00994 path = std::string(pw->pw_dir) + "/pfiles";
00995
00996
00997 if (access(path.c_str(), F_OK) != 0) {
00998 if (mkdir(path.c_str(),
00999 S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) {
01000 throw GException::could_not_create_pfiles(G_OUTPATH, path);
01001 }
01002 }
01003
01004
01005 else if (access(path.c_str(), W_OK) != 0) {
01006 if (chown(path.c_str(), uid, gid) != 0 ||
01007 chmod(path.c_str(),
01008 S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) {
01009 throw GException::pfiles_not_accessible(G_OUTPATH, path);
01010 }
01011 }
01012
01013
01014 path = path + "/" + filename;
01015
01016 }
01017
01018
01019 return path;
01020 }
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035 void GApplicationPars::read(const std::string& filename)
01036 {
01037
01038 const int n = 1000;
01039 char line[n];
01040
01041
01042 #if defined(G_LOCK_PARFILE)
01043 struct flock lock;
01044 lock.l_type = F_RDLCK;
01045 lock.l_whence = SEEK_SET;
01046 lock.l_start = 0;
01047 lock.l_len = 0;
01048 lock.l_pid = getpid();
01049 int fd;
01050 if ((fd = open(filename.c_str(), O_RDONLY)) == -1) {
01051 throw GException::par_file_open_error(G_READ, filename,
01052 "Could not open file for locking.");
01053 }
01054 #if defined(G_CHECK_LOCK_PARFILE)
01055 if (fcntl(fd, F_SETLKW, &lock) == -1) {
01056 throw GException::par_file_open_error(G_READ, filename,
01057 "Could not get a lock on the file.");
01058 }
01059 #else
01060 fcntl(fd, F_SETLKW, &lock);
01061 #endif
01062 #endif
01063
01064
01065 FILE* fptr = fopen(filename.c_str(), "r");
01066 if (fptr == NULL) {
01067 throw GException::par_file_open_error(G_READ, filename);
01068 }
01069
01070
01071 while (fgets(line, n, fptr) != NULL) {
01072 m_parfile.push_back(std::string(line));
01073 }
01074
01075
01076 fclose(fptr);
01077
01078
01079 #if defined(G_LOCK_PARFILE)
01080 if (fd != -1) {
01081 lock.l_type = F_UNLCK;
01082 #if defined(G_CHECK_LOCK_PARFILE)
01083 if (fcntl(fd, F_SETLK, &lock) == -1) {
01084 throw GException::par_file_open_error(G_READ, filename,
01085 "Could not unlock the file.");
01086 }
01087 #else
01088 fcntl(fd, F_SETLK, &lock);
01089 #endif
01090 close(fd);
01091 }
01092 #endif
01093
01094
01095 return;
01096 }
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110 void GApplicationPars::write(const std::string& filename) const
01111 {
01112
01113
01114
01115 #if defined(G_LOCK_PARFILE)
01116 struct flock lock;
01117 lock.l_type = F_WRLCK;
01118 lock.l_whence = SEEK_SET;
01119 lock.l_start = 0;
01120 lock.l_len = 0;
01121 lock.l_pid = getpid();
01122 int fd;
01123 if ((fd = open(filename.c_str(), O_WRONLY)) != -1) {
01124 #if defined(G_CHECK_LOCK_PARFILE)
01125 if (fcntl(fd, F_SETLKW, &lock) == -1) {
01126 throw GException::par_file_open_error(G_WRITE, filename,
01127 "Could not get a lock on the file.");
01128 }
01129 #else
01130 fcntl(fd, F_SETLKW, &lock);
01131 #endif
01132 }
01133 #endif
01134
01135
01136 FILE* fptr = fopen(filename.c_str(), "w");
01137 if (fptr == NULL) {
01138 throw GException::par_file_open_error(G_WRITE, filename);
01139 }
01140
01141
01142 #if defined(G_LOCK_PARFILE)
01143 if (fd == -1) {
01144 if ((fd = open(filename.c_str(), O_WRONLY)) != -1) {
01145 #if defined(G_CHECK_LOCK_PARFILE)
01146 if (fcntl(fd, F_SETLKW, &lock) == -1) {
01147 fclose(fptr);
01148 throw GException::par_file_open_error(G_WRITE, filename,
01149 "Could not get a lock on the file.");
01150 }
01151 #else
01152 fcntl(fd, F_SETLKW, &lock);
01153 #endif
01154 }
01155 }
01156 #endif
01157
01158
01159 for (int i = 0; i < m_parfile.size(); ++i) {
01160 fprintf(fptr, "%s", m_parfile[i].c_str());
01161 }
01162
01163
01164 fclose(fptr);
01165
01166
01167 #if defined(G_LOCK_PARFILE)
01168 if (fd != -1) {
01169 lock.l_type = F_UNLCK;
01170 #if defined(G_CHECK_LOCK_PARFILE)
01171 if (fcntl(fd, F_SETLK, &lock) == -1) {
01172 throw GException::par_file_open_error(G_WRITE, filename,
01173 "Could not unlock the file.");
01174 }
01175 #else
01176 fcntl(fd, F_SETLK, &lock);
01177 #endif
01178 close(fd);
01179 }
01180 #endif
01181
01182
01183 return;
01184 }
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201 void GApplicationPars::parse(void)
01202 {
01203
01204 m_mode = "h";
01205
01206
01207 for (int i = 0; i < m_parfile.size(); ++i) {
01208
01209
01210 std::string line = gammalib::strip_whitespace(m_parfile[i]);
01211
01212
01213 if (line.length() == 1 && line[0] == '\n')
01214 continue;
01215
01216
01217 if (line.length() == 0 || line[0] == '#') {
01218 continue;
01219 }
01220
01221
01222 std::string fields[7];
01223 int quotes = 0;
01224 size_t start = 0;
01225 size_t end = line.length() - 1;
01226 int index = 0;
01227 size_t vstart = 0;
01228 size_t vstop = 0;
01229 for (size_t pos = 0; pos < line.length(); ++pos) {
01230
01231
01232 if (line[pos] == '"') {
01233 quotes = 1-quotes;
01234 }
01235
01236
01237
01238
01239
01240 if (quotes == 0) {
01241 if (line[pos] == ',' || pos == end) {
01242 if (index < 7) {
01243 fields[index] =
01244 gammalib::strip_chars(gammalib::strip_whitespace(line.substr(start,
01245 pos-start)), "\"");
01246 if (index == 3) {
01247 vstart = start;
01248 vstop = pos;
01249 }
01250 start = pos + 1;
01251 }
01252 index++;
01253 }
01254 }
01255
01256 }
01257
01258
01259 if (quotes != 0) {
01260 throw GException::par_file_syntax_error(G_PARSE,
01261 gammalib::strip_chars(line,"\n"),
01262 "quotes are not balanced");
01263 }
01264
01265
01266 if (index != 7) {
01267 throw GException::par_file_syntax_error(G_PARSE,
01268 gammalib::strip_chars(line,"\n"),
01269 "found "+gammalib::str(index)+" fields, require 7");
01270 }
01271
01272
01273 if (contains(fields[0])) {
01274 throw GException::par_file_syntax_error(G_PARSE,
01275 gammalib::strip_chars(line,"\n"),
01276 "redefinition of parameter name \""+fields[0]+"\"");
01277 }
01278
01279
01280 try {
01281 m_pars.push_back(GApplicationPar(fields[0], fields[1], fields[2],
01282 fields[3], fields[4], fields[5],
01283 fields[6]));
01284 m_line.push_back(i);
01285 m_vstart.push_back(vstart);
01286 m_vstop.push_back(vstop);
01287 }
01288 catch (GException::par_error &e) {
01289 throw GException::par_file_syntax_error(G_PARSE,
01290 gammalib::strip_chars(line,"\n"),
01291 e.what());
01292 }
01293
01294
01295 if (fields[0] == "mode") {
01296 if (fields[3] != "h" && fields[3] != "q" &&
01297 fields[3] != "hl" && fields[3] != "ql" &&
01298 fields[3] != "lh" && fields[3] != "lq") {
01299 throw GException::par_file_syntax_error(G_PARSE,
01300 gammalib::strip_chars(line,"\n"),
01301 "mode parameter has invalid value \""+fields[3]+"\"");
01302 }
01303 m_mode = fields[3];
01304 }
01305
01306 }
01307
01308
01309 for (int i = 0; i < m_pars.size(); ++i) {
01310 if (m_pars[i].mode() == "a") {
01311 m_pars[i].mode(m_mode);
01312 }
01313 }
01314
01315
01316 return;
01317 }
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329 void GApplicationPars::update(void)
01330 {
01331
01332 for (int i = 0; i < m_pars.size(); ++i) {
01333
01334
01335 if (m_pars[i].m_update && m_pars[i].is_learn()) {
01336 m_parfile[m_line[i]] = m_parfile[m_line[i]].substr(0, m_vstart[i]) +
01337 m_pars[i].m_value +
01338 m_parfile[m_line[i]].substr(m_vstop[i]);
01339 m_vstop[i] = m_vstart[i] + m_pars[i].m_value.length();
01340 }
01341
01342 }
01343
01344
01345 return;
01346 }
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358 int GApplicationPars::get_index(const std::string& name) const
01359 {
01360
01361 int index = -1;
01362
01363
01364 for (int i = 0; i < size(); ++i) {
01365 if (m_pars[i].name() == name) {
01366 index = i;
01367 break;
01368 }
01369 }
01370
01371
01372 return index;
01373 }
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387 std::string GApplicationPars::parline(GApplicationPar& par, size_t* start, size_t* stop) const
01388 {
01389
01390 std::string line;
01391
01392
01393 line.append(par.name()+", ");
01394 line.append(par.type()+ ", ");
01395 line.append(par.mode()+ ",");
01396 *start = line.length();
01397 line.append(par.value()+ ",");
01398 *stop = line.length();
01399 line.append(par.min()+ ",");
01400 line.append(par.max()+ ",");
01401 line.append("\""+par.prompt()+"\"\n");
01402
01403
01404 return line;
01405 }