00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00068 #include "arts.h"
00069 #include "array.h"
00070 #include "file.h"
00071 #include "methods.h"
00072 #include "workspace_ng.h"
00073 #include "agenda_record.h"
00074
00075
00076 void align(ofstream& ofs, bool& is_first_parameter, const String& indent)
00077 {
00078
00079 if (is_first_parameter)
00080 is_first_parameter = false;
00081 else
00082 {
00083 ofs << ",\n";
00084
00085 ofs << indent;
00086 }
00087 }
00088
00090
00094 void write_method_header_documentation (ofstream& ofs, const MdRecord& mdd)
00095 {
00096 const Array<WsvRecord>& wsv_data = Workspace::wsv_data;
00097
00098 String fullname = mdd.Name();
00099
00100
00101
00102 bool is_first_parameter = true;
00103
00104
00105
00106 String indent(" ");
00107
00108
00109
00110 bool pass_workspace = false;
00111
00112
00113
00114 ArrayOfIndex vo=mdd.Out();
00115 const ArrayOfIndex &vi = mdd.InOnly();
00116 ArrayOfIndex vgo=mdd.GOutType();
00117 ArrayOfIndex vgi=mdd.GInType();
00118
00119
00120
00121
00122
00123 for (Index j = 0; !pass_workspace && j < mdd.In().nelem(); j++)
00124 {
00125 if (wsv_data[mdd.In()[j]].Group() == get_wsv_group_id ("Agenda"))
00126 {
00127 pass_workspace = true;
00128 }
00129 }
00130
00131
00132
00133 for (Index j = 0; !pass_workspace && j < mdd.GInType().nelem(); j++)
00134 {
00135 if (mdd.GInType()[j] == get_wsv_group_id ("Agenda"))
00136 {
00137 pass_workspace = true;
00138 }
00139 }
00140
00141
00142 ofs << "//! WORKSPACE METHOD: " << fullname << ".\n";
00143
00144 ofs << "/*!\n";
00145
00146 String DoxyDescription = mdd.Description();
00147 size_t start_pos = 0;
00148
00149 while (start_pos != string::npos)
00150 {
00151 start_pos = DoxyDescription.find ("\n ", start_pos);
00152 if (start_pos && start_pos != string::npos
00153 && DoxyDescription[start_pos]-1 != '\n')
00154 {
00155 DoxyDescription.insert (start_pos + 1, "<br>");
00156 start_pos += 5;
00157 }
00158 }
00159
00160
00161
00162 DoxyDescription.insert_substr ("<", "\\");
00163 DoxyDescription.insert_substr (">", "\\");
00164
00165 ofs << DoxyDescription << "\n";
00166
00167
00168 for (Index j=0; j<mdd.Authors().nelem(); ++j)
00169 {
00170 ofs << indent << "\\author " << mdd.Authors ()[j] << "\n";
00171 }
00172
00173 ofs << "\n";
00174
00175 if (pass_workspace || mdd.PassWorkspace() || mdd.AgendaMethod())
00176 {
00177 ofs << indent << "\\param[in,out] " << "ws Workspace\n";
00178 }
00179
00180
00181 for (Index j=0; j<vo.nelem(); ++j)
00182 {
00183 ofs << indent << "\\param[out] "
00184 << wsv_data[vo[j]].Name() << " WS Output\n";
00185 }
00186
00187
00188 for (Index j=0; j<vgo.nelem(); ++j)
00189 {
00190 ofs << indent << "\\param[out] ";
00191
00192 if (mdd.GOut()[j].length())
00193 ofs << mdd.GOut()[j];
00194 else
00195 ofs << "genericoutput" << j+1;
00196
00197 if (mdd.Supergeneric ()) ofs << " Supergeneric output\n";
00198 else ofs << " Generic output\n";
00199 }
00200
00201
00202 if (mdd.PassWsvNames())
00203 {
00204 for (Index j=0; j<vgo.nelem(); ++j)
00205 {
00206 ofs << indent << "\\param[in] ";
00207 if (mdd.GOut()[j].length())
00208 ofs << mdd.GOut()[j] << "_wsvname";
00209 else
00210 ofs << "genericoutput" << j+1 << "_wsvname";
00211
00212 ofs << " Generic Output Name" << endl;
00213 }
00214 }
00215
00216
00217 for (Index j=0; j<vi.nelem(); ++j)
00218 {
00219 ofs << indent << "\\param[in] "
00220 << wsv_data[vi[j]].Name() << " WS Input\n";
00221 }
00222
00223
00224 for (Index j=0; j<vgi.nelem(); ++j)
00225 {
00226 ofs << indent << "\\param[in] ";
00227 if (mdd.GIn()[j] != "")
00228 ofs << mdd.GIn()[j];
00229 else
00230 ofs << "genericinput" << j+1;
00231
00232 ofs << " Generic Input";
00233
00234 if (mdd.GInDefault()[j] != NODEF)
00235 {
00236 ofs << " (Default: \"" << mdd.GInDefault()[j] << "\")";
00237 }
00238 ofs << endl;
00239 }
00240
00241
00242 if (mdd.PassWsvNames())
00243 {
00244 for (Index j=0; j<vgi.nelem(); ++j)
00245 {
00246 ofs << indent << "\\param[in] ";
00247 if (mdd.GIn()[j].length())
00248 ofs << mdd.GIn()[j] << "_wsvname";
00249 else
00250 ofs << "genericinput" << j+1 << "_wsvname";
00251
00252 ofs << " Generic Input Name" << endl;
00253 }
00254 }
00255
00256
00257
00258 if ( mdd.AgendaMethod() )
00259 {
00260 align(ofs,is_first_parameter,indent);
00261 ofs << indent << "\\param[in] " << "input_agenda Agenda from controlfile\n";
00262 }
00263
00264 ofs << "*/\n";
00265 }
00266
00268
00272 void write_method_header( ofstream& ofs,
00273 const MdRecord& mdd )
00274 {
00275 extern const ArrayOfString wsv_group_names;
00276 const Array<WsvRecord>& wsv_data = Workspace::wsv_data;
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 String fullname = mdd.Name();
00287
00288
00289
00290 bool is_first_parameter = true;
00291
00292
00293
00294 String indent(fullname.nelem()+6,' ');
00295
00296
00297
00298 bool pass_workspace = false;
00299
00300
00301
00302 ArrayOfIndex vo=mdd.Out();
00303 const ArrayOfIndex &vi = mdd.InOnly();
00304 ArrayOfIndex vgo=mdd.GOutType();
00305 ArrayOfIndex vgi=mdd.GInType();
00306
00307
00308
00309
00310
00311 for (Index j = 0; !pass_workspace && j < mdd.In().nelem(); j++)
00312 {
00313 if (wsv_data[mdd.In()[j]].Group() == get_wsv_group_id ("Agenda"))
00314 {
00315 pass_workspace = true;
00316 }
00317 }
00318
00319
00320
00321 for (Index j = 0; !pass_workspace && j < mdd.GInType().nelem(); j++)
00322 {
00323 if (mdd.GInType()[j] == get_wsv_group_id ("Agenda"))
00324 {
00325 pass_workspace = true;
00326 }
00327 }
00328
00329
00330
00331
00332
00333
00334
00335 if (mdd.Supergeneric ())
00336 {
00337 ofs << "template <typename T>" << endl;
00338 }
00339
00340
00341 ofs << "void " << fullname << "(";
00342
00343 if (pass_workspace || mdd.PassWorkspace() || mdd.AgendaMethod())
00344 {
00345 ofs << "// Workspace reference:\n";
00346 ofs << indent << "Workspace& ws";
00347 is_first_parameter = false;
00348 }
00349
00350
00351 {
00352
00353 bool is_first_of_these = true;
00354
00355 for (Index j=0; j<vo.nelem(); ++j)
00356 {
00357
00358 align(ofs,is_first_parameter,indent);
00359
00360
00361 if (is_first_of_these)
00362 {
00363 ofs << "// WS Output:\n";
00364 ofs << indent;
00365 is_first_of_these = false;
00366 }
00367
00368 ofs << wsv_group_names[Workspace::wsv_data[vo[j]].Group()] << "& "
00369 << Workspace::wsv_data[vo[j]].Name();
00370 }
00371 }
00372
00373
00374 {
00375
00376 bool is_first_of_these = true;
00377
00378 for (Index j=0; j<vgo.nelem(); ++j)
00379 {
00380
00381 align(ofs,is_first_parameter,indent);
00382
00383
00384 if (is_first_of_these)
00385 {
00386 ofs << "// WS Generic Output:\n";
00387 ofs << indent;
00388 is_first_of_these = false;
00389 }
00390
00391 if (wsv_group_names[mdd.GOutType()[j]] == "Any") ofs << "T& ";
00392 else ofs << wsv_group_names[mdd.GOutType()[j]] << "& ";
00393
00394 if (mdd.GOut()[j].length()) ofs << mdd.GOut()[j];
00395 else ofs << "genericoutput" << j+1;
00396 }
00397 }
00398
00399
00400 if (mdd.PassWsvNames())
00401 {
00402
00403 bool is_first_of_these = true;
00404
00405 for (Index j=0; j<vgo.nelem(); ++j)
00406 {
00407
00408 align(ofs,is_first_parameter,indent);
00409
00410
00411 if (is_first_of_these)
00412 {
00413 ofs << "// WS Generic Output Names:\n";
00414 ofs << indent;
00415 is_first_of_these = false;
00416 }
00417
00418 ofs << "const String& ";
00419 if (mdd.GOut()[j].length())
00420 ofs << mdd.GOut()[j] << "_wsvname";
00421 else
00422 ofs << "genericoutput" << j+1 << "_wsvname";
00423 }
00424 }
00425
00426
00427 {
00428
00429 bool is_first_of_these = true;
00430
00431 for (Index j=0; j<vi.nelem(); ++j)
00432 {
00433
00434 align(ofs,is_first_parameter,indent);
00435
00436
00437 if (is_first_of_these)
00438 {
00439 ofs << "// WS Input:\n";
00440 ofs << indent;
00441 is_first_of_these = false;
00442 }
00443
00444 ofs << "const "
00445 << wsv_group_names[Workspace::wsv_data[vi[j]].Group()] << "& "
00446 << Workspace::wsv_data[vi[j]].Name();
00447 }
00448 }
00449
00450
00451 {
00452
00453 bool is_first_of_these = true;
00454
00455 for (Index j=0; j<vgi.nelem(); ++j)
00456 {
00457
00458 align(ofs,is_first_parameter,indent);
00459
00460
00461 if (is_first_of_these)
00462 {
00463 ofs << "// WS Generic Input:\n";
00464 ofs << indent;
00465 is_first_of_these = false;
00466 }
00467
00468 if (wsv_group_names[mdd.GInType()[j]] == "Any")
00469 {
00470 ofs << "const T& ";
00471 if (mdd.GIn()[j].length()) ofs << mdd.GIn()[j];
00472 else ofs << "genericinput" << j+1;
00473 }
00474 else
00475 {
00476 ofs << "const " << wsv_group_names[mdd.GInType()[j]] << "& ";
00477 if (mdd.GIn()[j].length()) ofs << mdd.GIn()[j];
00478 else ofs << "genericinput" << j+1;
00479 }
00480 }
00481 }
00482
00483
00484 if (mdd.PassWsvNames())
00485 {
00486
00487 bool is_first_of_these = true;
00488
00489 for (Index j=0; j<vgi.nelem(); ++j)
00490 {
00491
00492 align(ofs,is_first_parameter,indent);
00493
00494
00495 if (is_first_of_these)
00496 {
00497 ofs << "// WS Generic Input Names:\n";
00498 ofs << indent;
00499 is_first_of_these = false;
00500 }
00501
00502 ofs << "const String& ";
00503 if (mdd.GIn()[j].length())
00504 ofs << mdd.GIn()[j] << "_wsvname";
00505 else
00506 ofs << "genericinput" << j+1 << "_wsvname";
00507 }
00508 }
00509
00510
00511 if ( mdd.AgendaMethod() )
00512 {
00513 align(ofs,is_first_parameter,indent);
00514 ofs << "// Agenda from controlfile:\n";
00515 ofs << indent;
00516 ofs << "const Agenda& input_agenda";
00517 }
00518
00519 ofs << ");\n\n";
00520 }
00521
00522
00523 bool md_sanity_checks (const Array<MdRecord>& md_data)
00524 {
00525 ostringstream os;
00526
00527 bool is_sane = true;
00528 for (Array<MdRecord>::const_iterator i = md_data.begin ();
00529 i < md_data.end (); ++i)
00530 {
00531 bool invalid_author = false;
00532 for (ArrayOfString::const_iterator j = i->Authors ().begin ();
00533 !invalid_author && j < i->Authors ().end (); ++j)
00534 {
00535 if (*j == "" || *j == "unknown")
00536 invalid_author = true;
00537 }
00538
00539 if (invalid_author)
00540 {
00541 os << i->Name () << ": Missing or invalid author.\n";
00542 is_sane = false;
00543 }
00544
00545 switch (check_newline (i->Description ())) {
00546 case 1:
00547 os << i->Name () << ": Empty description.\n";
00548 is_sane = false;
00549 break;
00550 case 2:
00551 os << i->Name () << ": Missing newline at the end of description.\n";
00552 is_sane = false;
00553 break;
00554 case 3:
00555 os << i->Name () << ": Extra newline at the end of description.\n";
00556 is_sane = false;
00557 break;
00558 }
00559 }
00560
00561 if (!is_sane)
00562 {
00563 cerr << "Error(s) found in workspace method documentation (check methods.cc):\n"
00564 << os.str ();
00565 }
00566
00567 return is_sane;
00568 }
00569
00570
00571 int main()
00572 {
00573 try
00574 {
00575
00576 extern Array<MdRecord> md_data_raw;
00577 extern Array<MdRecord> md_data;
00578
00579
00580 define_wsv_group_names();
00581
00582
00583 Workspace::define_wsv_data();
00584
00585
00586 Workspace::define_wsv_map();
00587
00588
00589 define_md_data_raw();
00590
00591
00592 expand_md_data_raw_to_md_data();
00593
00594 if (!md_sanity_checks (md_data))
00595 return 1;
00596
00597 const Index n_md = md_data.nelem();
00598
00599
00600
00601 ofstream ofs;
00602 open_output_file(ofs,"auto_md.h");
00603
00604 ofs << "// This file was generated automatically by make_auto_md_h.cc.\n";
00605 ofs << "// DO NOT EDIT !\n";
00606 ofs << "// Generated: "
00607 << __DATE__ << ", "
00608 << __TIME__ << "\n\n";
00609
00610 ofs << "#ifndef auto_md_h\n";
00611 ofs << "#define auto_md_h\n\n";
00612
00613 ofs << "#include \"matpackI.h\"\n"
00614 << "#include \"matpackII.h\"\n"
00615 << "#include \"abs_species_tags.h\"\n"
00616 << "#include \"gas_abs_lookup.h\"\n"
00617 << "#include \"gridded_fields.h\"\n"
00618 << "#include \"optproperties.h\"\n"
00619 << "#include \"jacobian.h\"\n"
00620 << "#include \"mc_antenna.h\"\n"
00621 << "#include \"m_general.h\"\n"
00622 << "#include \"parser.h\"\n"
00623 << "#include \"workspace_ng.h\"\n"
00624 << "\n";
00625
00626 ofs << "// This is only used for a consistency check. You can get the\n"
00627 << "// number of WSMs from md_data.nelem().\n"
00628 << "#define N_MD " << n_md << "\n\n";
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 ofs << "// Method function declarations:\n\n";
00643 for (Index i=0; i<n_md; ++i)
00644 {
00645 const MdRecord& mdd = md_data[i];
00646 if ( !mdd.SuppressHeader() )
00647 {
00648 write_method_header_documentation( ofs, mdd );
00649 write_method_header( ofs, mdd );
00650 }
00651 }
00652
00653
00654 ofs << "// Supergeneric template function declarations:\n\n";
00655 for (Index i=0; i<md_data_raw.nelem (); ++i)
00656 {
00657 const MdRecord& mdd = md_data_raw[i];
00658 if ( mdd.Supergeneric() )
00659 {
00660 write_method_header_documentation( ofs, mdd );
00661 write_method_header( ofs, mdd );
00662 }
00663 }
00664
00665
00666 ofs << "// Get-away function declarations:\n\n";
00667 for (Index i=0; i<n_md; ++i)
00668 {
00669 const MdRecord& mdd = md_data[i];
00670 if ( mdd.Supergeneric() )
00671 {
00672 ofs << "void " << mdd.Name()
00673 << "_sg_" << mdd.ActualGroups()
00674 << "_g(Workspace& ws, const MRecord& mr);\n";
00675 }
00676 else
00677 {
00678 ofs << "void " << mdd.Name()
00679 << "_g(Workspace& ws, const MRecord& mr);\n";
00680 }
00681 }
00682
00683 ofs << "\n";
00684
00685
00686
00687
00688 Workspace::define_wsv_map ();
00689 define_agenda_data ();
00690
00691 extern const Array<AgRecord> agenda_data;
00692 for (Index i = 0; i < agenda_data.nelem (); i++)
00693 {
00694 write_agenda_wrapper_header (ofs, agenda_data[i]);
00695
00696 ofs << ";\n\n";
00697 }
00698
00699 ofs << "\n#endif // auto_md_h\n";
00700
00701
00702 ofs.close();
00703
00704 }
00705 catch (runtime_error x)
00706 {
00707 cout << "Something went wrong. Message text:\n";
00708 cout << x.what() << '\n';
00709 return 1;
00710 }
00711
00712 return 0;
00713 }