1 // 2 // aegis - project change supervisor 3 // Copyright (C) 1995-2009, 2011, 2012 Peter Miller 4 // Copyright (C) 2007, 2008 Walter Franzini 5 // 6 // This program is free software; you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation; either version 3 of the License, or (at 9 // your option) any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 // General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program. If not, see <http://www.gnu.org/licenses/>. 18 // 19 20 #ifndef LIBAEGIS_CHANGE_H 21 #define LIBAEGIS_CHANGE_H 22 23 #include <libaegis/cstate.fmtgen.h> 24 #include <libaegis/fstate.fmtgen.h> 25 #include <libaegis/pconf.fmtgen.h> 26 #include <libaegis/view_path.h> 27 #include <libaegis/zero.h> 28 29 class nstring_list; // forward 30 31 // 32 // Name of the project configuration file, 33 // relative to the baseline/devdir root. 34 // 35 #define THE_CONFIG_FILE_OLD "config" 36 #define THE_CONFIG_FILE_NEW "aegis.conf" 37 38 #include <libaegis/user.h> 39 40 // 41 // Define a magic number to represent the trunk transaction 42 // of the project. It has an exceptional file name. 43 // 44 #define TRUNK_CHANGE_NUMBER ((long)((~(unsigned long)0) >> 1)) 45 46 #define TIME_NOT_SET (time_t)0 47 #define UUID_NOT_SET (string_ty*)0 48 49 struct string_list_ty; // forward 50 struct sub_context_ty; // forward 51 struct symtab_ty; // forward 52 class project; // forward 53 54 class change 55 { 56 public: 57 /** 58 * The pointer typedef is provided so that clients of this 59 * interface may use change::pointer everywhere they need to point 60 * at a change instance, and only this typedef needs to be edited 61 * to use a variety of smart pointer instead. 62 */ 63 typedef change *pointer; 64 65 long reference_count; 66 project *pp; 67 long number; 68 cstate_ty *cstate_data; 69 string_ty *cstate_filename; 70 int cstate_is_a_new_file; 71 fstate_ty *fstate_data; 72 symtab_ty *fstate_stp; 73 symtab_ty *fstate_uuid_stp; 74 string_ty *fstate_filename; 75 fstate_ty *pfstate_data; 76 symtab_ty *pfstate_stp; 77 symtab_ty *pfstate_uuid_stp; 78 string_ty *pfstate_filename; 79 int fstate_is_a_new_file; 80 string_ty *top_path_unresolved; 81 string_ty *top_path_resolved; 82 string_ty *development_directory_unresolved; 83 string_ty *development_directory_resolved; 84 string_ty *integration_directory_unresolved; 85 string_ty *integration_directory_resolved; 86 string_ty *logfile; 87 pconf_ty *pconf_data; 88 long lock_magic; 89 int bogus; 90 string_ty *architecture_name; 91 string_list_ty *file_list[view_path_MAX]; 92 bool project_specific_setenv_performed; 93 94 // NOTE: methods are sorted alphabetically. To have methods 95 // grouped, make sure they change their suffix rather than their 96 // prefix. E.g. thingumy_get and thingumy_set rather than 97 // get_thingumy and set_thingumy. 98 99 // ---------- A ------------------------------------------------------ 100 101 /** 102 * The attributes_get method is used to obtain the value of an 103 * attribute of this change set. 104 * 105 * @param name 106 * The name of the attribute. 107 * Attribute names are not case sensitive. 108 * @returns 109 * the string value of the attribute, or the empty string 110 * if not found. 111 */ 112 nstring attributes_get(const nstring &name); 113 114 /** 115 * The attributes_get_boolean method is used to obtain the 116 * value of an attribute of this change set, as a true/false 117 * attribute. 118 * 119 * @param name 120 * The name of the attribute. 121 * Attribute names are not case sensitive. 122 * @returns 123 * the boolean value of the attribute, or false if the 124 * attribute is not found or is not interpretable as a 125 * boolean. 126 */ 127 bool attributes_get_boolean(const nstring &name); 128 129 // ---------- B ------------------------------------------------------ 130 131 /** 132 * The brief_description_get method is used to obtain the brief 133 * description of this change set. 134 */ 135 nstring brief_description_get(void); 136 137 // ---------- C ------------------------------------------------------ 138 139 /** 140 * The copyright_years_get_string is used to get a string 141 * containing the list fo copyrigth years, a union of the project's 142 * copyright years and this change set's copyright years. 143 */ 144 nstring copyright_years_get_string(void); 145 146 /** 147 * The completion_timestamp method is used to obtain the time that 148 * the change set completed integration, or "now" if it is not yet 149 * complete. use the #is_completed method to distinguish the two cases. 150 */ 151 time_t completion_timestamp(void); 152 153 /** 154 * The creator_name method is used to obtain the Unix name of the 155 * user that created this change. 156 * 157 * @returns 158 * The string value of the Unix name or NULL if not defined. 159 * DO NOT str_free it when you are done with it, it is cached. 160 */ 161 string_ty *creator_name(void); 162 163 /** 164 * The cstate_filename_get method is used to obtain the name of 165 * the file containing cstate meta-data of this change. 166 * 167 * @returns 168 * a string. DO NOT str_free it when you are done with it, 169 * it is cached. 170 */ 171 string_ty *cstate_filename_get(void); 172 173 /** 174 * The cstate_get method may be used to obtain the cstate meta-data 175 * of this change. 176 */ 177 cstate_ty *cstate_get(void); 178 179 /** 180 * THe cstate_write method may be used to write the cstate 181 * meta-data of this change 182 */ 183 void cstate_write(void); 184 185 // ---------- D ------------------------------------------------------ 186 187 /** 188 * The delta_number_get method is used to get the delta number of a 189 * change, or zero if the change is not yet completed. 190 */ 191 long delta_number_get(void); 192 193 /** 194 * The description_get method is used to obtain the long 195 * description of this change set. 196 */ 197 nstring description_get(void); 198 199 /** 200 * The developer_name method is used to obtain the Unix name of 201 * the developer of this change. 202 * 203 * @returns 204 * The string value of the Unix name or NULL if not defined. 205 * DO NOT str_free it when you are done with it, it is 206 * cached. 207 */ 208 string_ty *developer_name(void); 209 210 /** 211 * The developer_user_get method is used to obtain a user_ty 212 * instance representing the (most recent) developer of this change 213 * set. 214 */ 215 user_ty::pointer developer_user_get(void); 216 217 // ---------- E ------------------------------------------------------ 218 219 // ---------- F ------------------------------------------------------ 220 221 /** 222 * The file_exists method is used to determine whether or not a 223 * file exists in the change set. (view_path == view_path_first) 224 * 225 * @param filename 226 * The base-relative name of the file to search for. 227 */ 228 bool file_exists(const nstring &filename); 229 230 /** 231 * The file_find method is used to locate a change file similar to 232 * the file named. 233 * 234 * @param filename 235 * The name of the file to be found. 236 * @param vp 237 * The style of view path to be used. 238 */ 239 fstate_src_ty *file_find(const nstring &filename, view_path_ty vp); 240 241 /** 242 * The file_find method is used to locate a change file similar to 243 * the one indicated. If possible it uses the UUID otherwise (for 244 * backwards compatibility) it uses the file name. 245 * 246 * @param src 247 * The meta-data of the file to be found. 248 * @param vp 249 * The style of view path to be used. 250 */ 251 fstate_src_ty *file_find(fstate_src_ty *src, view_path_ty vp); 252 253 /** 254 * The file_find method is used to locate a change file similar to 255 * the one indicated. If possible it uses the UUID otherwise (for 256 * backwards compatibility) it uses the file name. 257 * 258 * @param src 259 * The meta-data of the file to be found. 260 * @param vp 261 * The style of view path to be used. 262 */ 263 fstate_src_ty *file_find(cstate_src_ty *src, view_path_ty vp); 264 265 /** 266 * The file_find method is used to locate a change file similar to 267 * the file named, in the change set itself 268 * (view_path == view_path_first). 269 * 270 * @param filename 271 * The name of the file to be found. 272 */ 273 fstate_src_ty *file_find(const nstring &filename); 274 275 /** 276 * The file_find_fuzzy method is used to locate a change file with 277 * a name similar to the one given. 278 * 279 * @param filename 280 * The name of the file to be found. 281 * @param vp 282 * The style of view path to be used. 283 */ 284 fstate_src_ty *file_find_fuzzy(const nstring &filename, view_path_ty vp); 285 286 /** 287 * The file_find_uuid method is used to find a source file given 288 * the UUID. 289 * 290 * @param uuid 291 * The UUID to search for. 292 * @param view_path 293 * The style and depth of search for the file. 294 * @returns 295 * a pointer to the file information, or NULL if no file has the 296 * specified UUID. 297 */ 298 fstate_src_ty *file_find_uuid(string_ty *uuid, view_path_ty view_path); 299 300 /** 301 * The file_find_uuid method is used to find a source file given 302 * the UUID. 303 * 304 * @param uuid 305 * The UUID to search for. 306 * @param view_path 307 * The style and depth of search for the file. 308 * @returns 309 * a pointer to the file information, or NULL if no file has the 310 * specified UUID. 311 */ 312 fstate_src_ty *file_find_uuid(const nstring &uuid, view_path_ty view_path); 313 314 /** 315 * The file_new method is used to add a new file to a change set's 316 * file manifest. No checking is poerformed, it is up to the caller 317 * to ensure that the name is unique. 318 * 319 * @param file_name 320 * The name of the file to be created. 321 * @returns 322 * A newly allocated file, with the name set, and everything 323 * else blank. 324 */ 325 fstate_src_ty *file_new(string_ty *file_name); 326 327 /** 328 * The file_new method is used to add a new file to a change 329 * set's file manifest. No checking is poerformed, it is up to 330 * the caller to ensure that the file name and UUID are unique. 331 * Typically this is used when adding a project file to a change 332 * set for modification or removal. 333 * 334 * @param meta 335 * The meta-data of the file to be created. 336 * @returns 337 * A newly allocated file, with the name set, and everything 338 * else blank. 339 */ 340 fstate_src_ty *file_new(fstate_src_ty *meta); 341 342 /** 343 * The file_path method is used to obtain the absolute path to 344 * the given change file. 345 * 346 * @param file_name 347 * The name of the file in question. 348 * @returns 349 * a string containing the absolute path, or NULL if the file is 350 * not a change source file. 351 */ 352 string_ty *file_path(string_ty *file_name); 353 354 /** 355 * The file_path method is used to obtain the absolute path to 356 * the given change file. 357 * 358 * @param file_name 359 * The name of the file in question. 360 * @returns 361 * a string containing the absolute path, or the empty string 362 * if the file is not a change source file. 363 */ 364 nstring file_path(const nstring &file_name); 365 366 /** 367 * The file_path method is used to obtain the absolute path to 368 * the given change file. 369 * 370 * @param src 371 * The meta-data of the file in question. 372 * @returns 373 * a string containing the absolute path, or NULL if the file is 374 * not a change source file. 375 */ 376 string_ty *file_path(fstate_src_ty *src); 377 378 /** 379 * The file_path_by_uuid method is used to obtain the absolute 380 * path to the given change file. 381 * 382 * @param uuid 383 * The UUID of the file in question. 384 * @returns 385 * a string containing the absolute path, or NULL if the file is 386 * not a change source file. 387 */ 388 string_ty *file_path_by_uuid(string_ty *uuid); 389 390 /** 391 * The file_path_by_uuid method is used to obtain the absolute 392 * path to the given change file. 393 * 394 * @param uuid 395 * The UUID of the file in question. 396 * @returns 397 * a string containing the absolute path, or NULL if the file is 398 * not a change source file. 399 */ 400 nstring file_path_by_uuid(const nstring &uuid); 401 402 /** 403 * The file_promote method is used to check whether or not recent 404 * integrations have change the actions the change files must 405 * perform. 406 * 407 * If two changes are creating the same file, the first one integrated 408 * means that the second one must update its action to "modify". 409 * 410 * If two changes are removing the same file, the first one integrated 411 * means that the second one needs to drop the file from its list. 412 * 413 * If one change is removing a file, and a second change is modifying 414 * the same file, after the first change is integrated, the second 415 * change must update its action to "create". 416 * 417 * @returns 418 * true if anything changed, false if nothing changed. 419 */ 420 bool file_promote(void); 421 422 /** 423 * The file_resolve_name method is used to resolve an arbitrary 424 * UNIX pathname (relative or absolute) into a base relative path 425 * within a change set's search path. 426 * 427 * @param up 428 * The user invoking the program. 429 * @param file_name 430 * The file name to be resolved. 431 * @returns 432 * The resolved base relative file name. Use str_free when you are 433 * done with it. 434 */ 435 string_ty *file_resolve_name(user_ty::pointer up, string_ty *file_name); 436 437 /** 438 * The file_resolve_name method is used to resolve an arbitrary 439 * UNIX pathname (relative or absolute) into a base relative path 440 * within a change set's search path. 441 * 442 * @param up 443 * The user invoking the program. 444 * @param file_name 445 * The file name to be resolved. 446 * @returns 447 * The resolved base relative file name. Use str_free when you are 448 * done with it. 449 */ 450 nstring file_resolve_name(user_ty::pointer up, const nstring &file_name); 451 452 /** 453 * The file_resolve_names method is used to resolve arbitrary UNIX 454 * pathnames (relative or absolute) into base relative paths within 455 * a change set's search path. 456 * 457 * @param up 458 * The user invoking the program. 459 * @param file_names 460 * The file names to be resolved. 461 * This parameter ISN'T const because this will be done in situ. 462 */ 463 void file_resolve_names(user_ty::pointer up, string_list_ty &file_names); 464 465 /** 466 * The file_unchanged method is used to determine whether a source 467 * file is unchanged compared to the file in the baseline. 468 * 469 * @param src_data 470 * The file in question. 471 * @param up 472 * The user to perform file actions as. 473 * @returns 474 * bool; true if the file is unchanged, false if the file has 475 * changed, and false if the comparison isn't meaningful. 476 */ 477 bool file_unchanged(fstate_src_ty *src_data, user_ty::pointer up); 478 479 /** 480 * The file_is_config method is used to determine whether or not 481 * the named file is a configuration file. 482 * 483 * @param name 484 * The name of the file of interest 485 * @returns 486 * true if it is a config file, false if not. 487 */ 488 bool file_is_config(string_ty *name); 489 490 /** 491 * The download_files_acessable method may be used to to determine 492 * whether or not the calling user has permission to access the 493 * change set's download files. This usually means read and search 494 * premission on the development directory and/or the integration 495 * director, unless the change set is in the completed state. 496 */ 497 bool download_files_accessable(void); 498 499 private: 500 /** 501 * The fimprove method is used to cope with previous versions 502 * of the file meta data, and rewrite them to conform to later 503 * expectations. 504 * 505 * @param fstate_data 506 * The file meta data to be massaged. 507 */ 508 void fimprove(fstate_ty *fstate_data); 509 510 public: 511 /** 512 * The fstate_get method is used to obtain a current value for the 513 * change file state symbol table. 514 * 515 * @note 516 * This would be static to aegis/change_file.c if only 517 * aegis/aer/value/fstate.c did not need it. No other place 518 * should access this directly. 519 */ 520 fstate_ty *fstate_get(void); 521 522 // ---------- G ------------------------------------------------------ 523 524 /** 525 * The gid_get method is used to obtain the Unix group id of the 526 * change owner. 527 */ 528 int gid_get() const; 529 530 // ---------- H ------------------------------------------------------ 531 532 // ---------- I ------------------------------------------------------ 533 534 /** 535 * The integration_directory_get method may be used to obtain the 536 * change's integration directory path. It is an error if the 537 * change is not in the 'being integrated' state. 538 * 539 * @param resolve 540 * whether or not to resolve symlinks in the path. 541 */ 542 nstring integration_directory_get(bool resolve); 543 544 /** 545 * The integrator_name method is used to obtain the Unix group 546 * name of the integrator. 547 * 548 * @returns 549 * The string value of the Unix name or NULL if not defined. 550 * DO NOT str_free it when you are done with it, it is 551 * cached. 552 */ 553 string_ty *integrator_name(void); 554 555 /** 556 * The is_a_branch method is used to determine whether or not this 557 * change set is an active branch. If you want to know if it was 558 * ever an active branch (e.g. now completed) use the #was_a_branch 559 * method. 560 */ 561 bool is_a_branch(void); 562 563 /** 564 * The is_awaiting_development method returns true if the given 565 * change is in the awaiting development state, and false if it is 566 * not. 567 */ 568 bool is_awaiting_development(void); 569 570 /** 571 * The is_being_developed method returns true if the given change 572 * is in the being developed state, and false if it is not. 573 */ 574 bool is_being_developed(void); 575 576 /** 577 * The is_being_integrated method is used to determine whether or 578 * not this is in the being integrated state. 579 * 580 * @returns 581 * bool; true if this is in the being integrated state, and 582 * false if it is not. 583 */ 584 bool is_being_integrated(void); 585 586 /** 587 * The change_is_completed function returns true (non-zero) if this 588 * change is in the completed state, and false (zero) if it is not. 589 */ 590 bool is_completed(void); 591 592 // ---------- J ------------------------------------------------------ 593 594 // ---------- K ------------------------------------------------------ 595 596 // ---------- L ------------------------------------------------------ 597 598 // ---------- M ------------------------------------------------------ 599 600 // ---------- N ------------------------------------------------------ 601 602 // ---------- O ------------------------------------------------------ 603 604 // ---------- P ------------------------------------------------------ 605 606 /** 607 * The pconf_attributes_get method is used to obtain the 608 * value of an attribute of the project, from the project 609 * configuration file. It could be in this change, or it could 610 * be in a baseline or an ancestor baseline. 611 * 612 * @param name 613 * The name of the attribute. 614 * Attribute names are not case sensitive. 615 * @returns 616 * the string value of the attribute, or the empty string 617 * if not found. 618 */ 619 nstring pconf_attributes_find(const nstring &name); 620 621 /** 622 * The pconf_attributes_get_boolean method is used to obtain the 623 * value of an attribute of the project, from the project 624 * configuration file. It could be in this change, or it could 625 * be in a baseline or an ancestor baseline. 626 * 627 * @param name 628 * The name of the attribute. 629 * Attribute names are not case sensitive. 630 * @param dflt 631 * The default value to return if no attribute available. 632 * @returns 633 * the string value of the attribute, or the empty string 634 * if not found. 635 */ 636 bool pconf_attributes_get_boolean(const nstring &name, bool dflt = false); 637 638 /** 639 * The pconf_copyright_owner_get method is used to obtain the 640 * name of the copyright holder of a project. 641 */ 642 nstring pconf_copyright_owner_get(void); 643 644 /** 645 * The pfstate_get method is used to obtain the project file state 646 * information for a change set. This is all of the project files, 647 * not just one. 648 */ 649 fstate_ty *pfstate_get(void); 650 651 /** 652 * The project_specific_setenv_performed_set method is used to 653 * remember if the environment variable(s), specified as 654 * project_specific attributes, has been already exported. 655 * 656 * @returns 657 * Void. 658 */ 659 void project_specific_setenv_performed_set(void); 660 661 /** 662 * The project_specific_setenv_performed_get method is used to 663 * know if the environment variable(s), specified as 664 * project_specific attributes, has been already exported. 665 * 666 * @returns 667 * True if the variables has been already exported, false 668 * otherwise. 669 */ 670 bool project_specific_setenv_performed_get() const; 671 672 // ---------- Q ------------------------------------------------------ 673 674 // ---------- R ------------------------------------------------------ 675 676 /** 677 * The reviewer_name method is used to determine the Unix name of 678 * the (last) reviewer. 679 * 680 * @returns 681 * The string representation of the Unix name or NULL if not 682 * defined. DO NOT str_free it when you are done with it, it 683 * is cached. 684 */ 685 string_ty *reviewer_name(void); 686 687 /** 688 * The run_project_file_command_needed method may be used to 689 * determine whether or not the project_file_command needstosed in 690 * recent integration history. 691 * 692 * @returns 693 * true if need to run it (see next method), false if not. 694 */ 695 bool run_project_file_command_needed(void); 696 697 /** 698 * The run_project_file_command method is used to run the command 699 * configured in the aegis.conf file's project_file_command field. 700 * 701 * @param up 702 * The user to run the command as. 703 * 704 * @note 705 * this method MUST be called outside the change set lock 706 */ 707 void run_project_file_command(const user_ty::pointer &up); 708 709 /** 710 * The run_project_file_command_done method is used to remember 711 * that the project_file comman has been (is about to be) called 712 * recently. 713 * 714 * @note 715 * this method MUST be called INSIDE the change set lock 716 */ 717 void run_project_file_command_done(void); 718 719 /** 720 * The run_new_file_command method is used to run the 721 * new_file_command field of the aegis.conf file. 722 * 723 * @param slp 724 * The list of new file names 725 * @param up 726 * Th euser to run the command as. 727 */ 728 void run_new_file_command(string_list_ty *slp, const user_ty::pointer &up); 729 730 /** 731 * The run_new_file_undo_command method is used to run the command 732 * in the new_file_undo_command field of the aegis.conf file. 733 * 734 * @param slp 735 * The list of filenames affected. 736 * @param up 737 * the user to run the program as 738 */ 739 void run_new_file_undo_command(string_list_ty *slp, 740 const user_ty::pointer &up); 741 742 /** 743 * The run_new_test_command method is used to run the command in 744 * the new_test_command field of the aegis.conf file. 745 * 746 * @param slp 747 * The list of filenames affected. 748 * @param up 749 * the user to run the program as 750 */ 751 void run_new_test_command(string_list_ty *slp, 752 const user_ty::pointer &up); 753 754 /** 755 * The run_new_test_undo_command method is used to run the command 756 * in the new_test_undo_command field of the aegis.conf file. 757 * 758 * @param slp 759 * The list of filenames affected. 760 * @param up 761 * the user to run the program as 762 */ 763 void run_new_test_undo_command(string_list_ty *slp, 764 const user_ty::pointer &up); 765 766 /** 767 * The run_copy_file_command method is used to run the command in 768 * the copy_file_command field of the aegis.conf file. 769 * 770 * @param slp 771 * The list of filenames affected. 772 * @param up 773 * the user to run the program as 774 */ 775 void run_copy_file_command(string_list_ty *slp, const user_ty::pointer &up); 776 777 /** 778 * The run_copy_file_undo_command method is used to run the command 779 * in the copy_file_undo_command field of the aegis.conf file. 780 * 781 * @param slp 782 * The list of filenames affected. 783 * @param up 784 * the user to run the program as 785 */ 786 void run_copy_file_undo_command(string_list_ty *slp, 787 const user_ty::pointer &up); 788 789 /** 790 * The run_remove_file_command method is used to run the command in 791 * the remove_file_command field of the aegis.conf file. 792 * 793 * @param slp 794 * The list of filenames affected. 795 * @param up 796 * the user to run the program as 797 */ 798 void run_remove_file_command(string_list_ty *slp, 799 const user_ty::pointer &up); 800 801 /** 802 * The run_remove_file_undo_command method is used to run the 803 * command in the remove_file_undo_command field of the aegis.conf 804 * file. 805 * 806 * @param slp 807 * The list of filenames affected. 808 * @param up 809 * the user to run the program as 810 */ 811 void run_remove_file_undo_command(string_list_ty *slp, 812 const user_ty::pointer &up); 813 814 /** 815 * The run_make_transparent_command method is used to run the 816 * command in the make_transparent_command field of the aegis.conf 817 * file. 818 * 819 * @param slp 820 * The list of filenames affected. 821 * @param up 822 * the user to run the program as 823 */ 824 void run_make_transparent_command(string_list_ty *slp, 825 const user_ty::pointer &up); 826 827 /** 828 * The run_make_transparent_undo_comman method is used to run 829 * the command in the make_transparent_undo_command field of the 830 * aegis.conf file. 831 * 832 * @param slp 833 * The list of filenames affected. 834 * @param up 835 * the user to run the program as 836 */ 837 void run_make_transparent_undo_command(string_list_ty *slp, 838 const user_ty::pointer &up); 839 840 /** 841 * The run_forced_develop_begin_notify_command method is used to 842 * run the command in the forced_develop_begin_notify_command field 843 * of the aegis.conf file. 844 * 845 * @param up 846 * the user to run the program as 847 */ 848 void run_forced_develop_begin_notify_command(const user_ty::pointer &up); 849 850 /** 851 * The run_develop_end_notify_command method is used to run 852 * the command in the develop_end_notify_command field of the 853 * aegis.conf file. 854 */ 855 void run_develop_end_notify_command(void); 856 857 /** 858 * The run_develop_end_undo_notify_command method is used to run 859 * the command in the develop_end_undo_notify_command field of the 860 * aegis.conf file. 861 */ 862 void run_develop_end_undo_notify_command(void); 863 864 /** 865 * The run_review_begin_notify_command method is used to run 866 * the command in the review_begin_notify_command field of the 867 * aegis.conf file. 868 */ 869 void run_review_begin_notify_command(void); 870 871 /** 872 * The run_review_begin_undo_notify_command method is used to run 873 * the command in the review_begin_undo_notify_command field of the 874 * aegis.conf file. 875 */ 876 void run_review_begin_undo_notify_command(void); 877 878 /** 879 * The run_review_pass_notify_command method is used to run 880 * the command in the review_pass_notify_command field of the 881 * aegis.conf file. 882 */ 883 void run_review_pass_notify_command(void); 884 885 /** 886 * The run_review_pass_undo_notify_command method is used to run 887 * the command in the review_pass_undo_notify_command field of the 888 * aegis.conf file. 889 */ 890 void run_review_pass_undo_notify_command(void); 891 892 /** 893 * The run_review_fail_notify_command method is used to run 894 * the command in the review_fail_notify_command field of the 895 * aegis.conf file. 896 */ 897 void run_review_fail_notify_command(void); 898 899 /** 900 * The run_integrate_pass_notify_command method is used to run 901 * the command in the integrate_pass_notify_command field of the 902 * aegis.conf file. 903 */ 904 void run_integrate_pass_notify_command(void); 905 906 /** 907 * The run_integrate_fail_notify_command method is used to run 908 * the command in the integrate_fail_notify_command field of the 909 * aegis.conf file. 910 */ 911 void run_integrate_fail_notify_command(void); 912 913 /** 914 * The run_develop_begin_early_command method is used to run the 915 * develop_begin_early_command from the project configuration file. 916 * This is used by the aedb command, just after the development 917 * directory has been created. 918 * 919 * @param up 920 * The user to run the command as. 921 */ 922 void run_develop_begin_early_command(user_ty::pointer up); 923 924 /** 925 * The run_develop_begin_command method is used to run the 926 * develop_begin_command from the projetc configuration file. This 927 * is used by the aedb command, just all other actions performed by 928 * aedb. 929 * 930 * @param up 931 * The user to run the command as. 932 */ 933 void run_develop_begin_command(user_ty::pointer up); 934 935 // ---------- S ------------------------------------------------------ 936 937 /** 938 * The search_path_get method may be used to obtain the search path 939 * (list of progressively more out-of-date ancestor branches) 940 * within which to search for files. 941 * 942 * @param result 943 * Where to append the additional directories. 944 * @param resolve 945 * Whether or not to expand synbolic links within paths. 946 */ 947 void search_path_get(string_list_ty *result, bool resolve); 948 949 /** 950 * The search_path_get method may be used to obtain the search path 951 * (list of progressively more out-of-date ancestor branches) 952 * within which to search for files. 953 * 954 * @param result 955 * Where to append the additional directories. 956 * @param resolve 957 * Whether or not to expand synbolic links within paths. 958 */ 959 void search_path_get(nstring_list &result, bool resolve); 960 961 // ---------- T ------------------------------------------------------ 962 963 time_t time_limit_get(void); 964 965 /** 966 * The umask method is used to obtain the umask for this change. 967 * 968 * @returns 969 * An int representing the umask value. 970 */ 971 int umask_get() const; 972 973 // ---------- U ------------------------------------------------------ 974 975 /** 976 * The uuid_get method is used to obtain the UUID of this change set. 977 * 978 * @returns 979 * The uuid of the change set, or the empty string of this 980 * change set doesn't have a UUID. 981 */ 982 nstring uuid_get(void); 983 984 /** 985 * The uuid_get_list method is used to obtain all of the UUIDs 986 * associated with this change set. This includes the change set's 987 * UUID, if it has one, and all of the aoriginal-uuid attributes. 988 * 989 * @param uuids 990 * Where to put all of the UUIDs associated with this change set. 991 */ 992 void uuid_get_list(nstring_list &uuids); 993 994 // ---------- V ------------------------------------------------------ 995 996 /** 997 * The version_debian_get method is used to get the version 998 * of this change set, in Debian format. In particular, it 999 * makes being-developed change sets look like they are "release 1000 * candidates" for the next project delta, otherwise business as 1001 * usual. 1002 */ 1003 nstring version_debian_get(void); 1004 1005 /** 1006 * The version_rpm_get method is used to get the version of 1007 * this change set, in RPM format. In particular, it makes 1008 * being-developed change sets look like they are "branched from" 1009 * for the current project delta, otherwise business as usual. 1010 */ 1011 nstring version_rpm_get(void); 1012 1013 /** 1014 * The version_get method is used to get the version of this change 1015 * set. This will consist of the branch name (1.2) combined with 1016 * ether a delta number (.D123) or, for incomplete changes, a 1017 * change number (.C123). 1018 */ 1019 nstring version_get(void); 1020 1021 // ---------- W ------------------------------------------------------ 1022 1023 /** 1024 * The was_a_branch method is used to determine whether or not this 1025 * change set is, or was ever, an active branch. If you want to 1026 * know if it is a currently active branch (beging_developed) use 1027 * the #is_a_branch method. 1028 */ 1029 bool was_a_branch(void); 1030 1031 // ---------- X ------------------------------------------------------ 1032 1033 // ---------- Y ------------------------------------------------------ 1034 1035 // ---------- Z ------------------------------------------------------ 1036 1037 // --------------------------------------------------------------------- 1038 // PLEASE keep the above method declarations in alphabetical order. 1039 1040 // 1041 // If you add instance variables to this class, don't forget to update 1042 // change_alloc() in libaegis/change/alloc.cc 1043 // change_free() in libaegis/change/free.cc 1044 // change_lock_sync() in libaegis/change/lock_sync.cc 1045 // 1046 }; 1047 1048 change::pointer change_alloc(project *, long); 1049 void change_free(change::pointer ); 1050 change::pointer change_copy(change::pointer ); 1051 void change_bind_existing(change::pointer ); 1052 int change_bind_existing_errok(change::pointer ); 1053 void change_bind_new(change::pointer ); 1054 change::pointer change_bogus(project *); 1055 1056 cstate_history_ty *change_history_new(change::pointer , user_ty::pointer ); 1057 1058 void change_top_path_set(change::pointer , string_ty *); 1059 void change_top_path_set(change::pointer , const nstring &); 1060 void change_development_directory_set(change::pointer , string_ty *); 1061 void change_integration_directory_set(change::pointer , string_ty *); 1062 string_ty *change_top_path_get(change::pointer , int); 1063 string_ty *change_development_directory_get(change::pointer , int); 1064 string_ty *change_integration_directory_get(change::pointer , int); 1065 string_ty *change_logfile_basename(void); 1066 string_ty *change_logfile_get(change::pointer ); 1067 void change_cstate_lock_prepare(change::pointer ); 1068 void change_error(change::pointer , sub_context_ty *, const char *); 1069 void change_fatal(change::pointer , sub_context_ty *, const char *) NORETURN; 1070 void change_verbose(change::pointer , sub_context_ty *, const char *); 1071 1072 /** 1073 * The change_warning function is used to issue a warning message 1074 * specific to a change. The message will be substituted accouring 1075 * to aesub(5) and any additional substitutions provided in the 1076 * substitution context. 1077 */ 1078 void change_warning(change::pointer , sub_context_ty *, const char *); 1079 1080 /** 1081 * The change_warning_obsolete_field function is used to warn about the 1082 * use of obsolete fields (in user suppied files, Aegis will take care 1083 * of quietly cleaning up the meta-data files all by itself). 1084 */ 1085 void change_warning_obsolete_field(change::pointer cp, string_ty *errpos, 1086 const char *old_field, const char *new_field); 1087 1088 pconf_ty *change_pconf_get(change::pointer , int); 1089 1090 // use cp->run_new_file_command instead 1091 void change_run_new_file_command(change::pointer cp, string_list_ty *slp, 1092 user_ty::pointer up) DEPRECATED; 1093 1094 // use cp->run_new_file_undo_command instead 1095 void change_run_new_file_undo_command(change::pointer cp, string_list_ty *slp, 1096 user_ty::pointer up) DEPRECATED; 1097 1098 // use cp->run_new_test_command instead 1099 void change_run_new_test_command(change::pointer cp, string_list_ty *slp, 1100 user_ty::pointer up) DEPRECATED; 1101 1102 // use cp->run_new_test_undo_command instead 1103 void change_run_new_test_undo_command(change::pointer cp, string_list_ty *slp, 1104 user_ty::pointer up) DEPRECATED; 1105 1106 // use cp->run_copy_file_command instead 1107 void change_run_copy_file_command(change::pointer cp, string_list_ty *slp, 1108 user_ty::pointer up) DEPRECATED; 1109 1110 // use cp->run_copy_file_undo_command instead 1111 void change_run_copy_file_undo_command(change::pointer cp, string_list_ty *slp, 1112 user_ty::pointer up) DEPRECATED; 1113 1114 // use cp->run_remove_file_command instead 1115 void change_run_remove_file_command(change::pointer cp, string_list_ty *slp, 1116 user_ty::pointer up) DEPRECATED; 1117 1118 // use cp->run_remove_file_undo_command instead 1119 void change_run_remove_file_undo_command(change::pointer cp, 1120 string_list_ty *slp, user_ty::pointer up) DEPRECATED; 1121 1122 // use cp->run_make_transparent_command instead 1123 void change_run_make_transparent_command(change::pointer cp, 1124 string_list_ty *slp, user_ty::pointer up) DEPRECATED; 1125 1126 // use cp->run_make_transparent_undo_command instead 1127 void change_run_make_transparent_undo_command(change::pointer cp, 1128 string_list_ty *slp, user_ty::pointer up) DEPRECATED; 1129 1130 // use vp->run_project_file_command_needed() instead 1131 int change_run_project_file_command_needed(change::pointer cp) DEPRECATED; 1132 1133 // use cp->run_project_file_command(up) instead 1134 void change_run_project_file_command(change::pointer cp, user_ty::pointer up) 1135 DEPRECATED; 1136 1137 // use cp->run_forced_develop_begin_notify_command instead 1138 void change_run_forced_develop_begin_notify_command(change::pointer cp, 1139 user_ty::pointer up) DEPRECATED; 1140 1141 // use cp->run_develop_end_notify_command instead 1142 void change_run_develop_end_notify_command(change::pointer cp) DEPRECATED; 1143 1144 // use cp->run_develop_end_undo_notify_command instead 1145 void change_run_develop_end_undo_notify_command(change::pointer cp) DEPRECATED; 1146 1147 // use cp->run_review_begin_notify_command instead 1148 void change_run_review_begin_notify_command(change::pointer cp) DEPRECATED; 1149 1150 // use cp->run_review_begin_undo_notify_command 1151 void change_run_review_begin_undo_notify_command(change::pointer cp) DEPRECATED; 1152 1153 // use cp->run_review_pass_notify_command instead 1154 void change_run_review_pass_notify_command(change::pointer cp) DEPRECATED; 1155 1156 // use cp->run_review_pass_undo_notify_command instead 1157 void change_run_review_pass_undo_notify_command(change::pointer cp) DEPRECATED; 1158 1159 // use cp->run_review_fail_notify_command instead 1160 void change_run_review_fail_notify_command(change::pointer cp) DEPRECATED; 1161 1162 // use cp->run_integrate_pass_notify_command instead 1163 void change_run_integrate_pass_notify_command(change::pointer cp) DEPRECATED; 1164 1165 // use cp->run_integrate_fail_notify_command instead 1166 void change_run_integrate_fail_notify_command(change::pointer cp) DEPRECATED; 1167 1168 void change_run_history_get_command(change::pointer cp, fstate_src_ty *src, 1169 string_ty *output_file, user_ty::pointer up); 1170 void change_run_history_create_command(change::pointer cp, fstate_src_ty *); 1171 void change_run_history_put_command(change::pointer cp, fstate_src_ty *); 1172 1173 /** 1174 * The change_run_history_query_command function is used to obtain the 1175 * head revision number of the history of the given source file. 1176 * 1177 * @param cp 1178 * The change to operate within. 1179 * @param src 1180 * The source file meta-data of the file of interest. 1181 * @returns 1182 * Pointer to string containing the version. Use str_free() when 1183 * you are done with it. 1184 */ 1185 string_ty *change_run_history_query_command(change::pointer cp, 1186 fstate_src_ty *src); 1187 1188 void change_run_history_label_command(change::pointer cp, fstate_src_ty *, 1189 string_ty *label); 1190 1191 /** 1192 * The change_run_history_transaction_begin_command function is 1193 * used to run the history_transaction_begin_command in the project 1194 * configuration file. This is used by the aeipass(1) command before 1195 * any history put or create commands. 1196 * 1197 * @param cp 1198 * The change to operate within. 1199 */ 1200 void change_run_history_transaction_begin_command(change::pointer cp); 1201 1202 /** 1203 * The change_run_history_transaction_end_command function is 1204 * used to run the history_transaction_end_command in the project 1205 * configuration file. This is used by the aeipass(1) command after 1206 * any history put or create commands. 1207 * 1208 * @param cp 1209 * The change to operate within. 1210 */ 1211 void change_run_history_transaction_end_command(change::pointer cp); 1212 1213 /** 1214 * The change_run_history_transaction_abort_command function is 1215 * used to run the history_transaction_abort_command in the project 1216 * configuration file. This is used by the aeipass(1) command if 1217 * a history transaction needs to be aborted. 1218 * 1219 * @param cp 1220 * The change to operate within. 1221 */ 1222 void change_run_history_transaction_abort_command(change::pointer cp); 1223 1224 void change_history_trashed_fingerprints(change::pointer , string_list_ty *); 1225 void change_run_diff_command(change::pointer cp, user_ty::pointer up, 1226 string_ty *original, string_ty *input, string_ty *output); 1227 void change_run_diff3_command(change::pointer cp, user_ty::pointer up, 1228 string_ty *original, string_ty *most_recent, string_ty *input, 1229 string_ty *output); 1230 void change_run_merge_command(change::pointer cp, user_ty::pointer up, 1231 string_ty *original, string_ty *most_recent, string_ty *input, 1232 string_ty *output); 1233 void change_run_patch_diff_command(change::pointer cp, user_ty::pointer up, 1234 string_ty *original, string_ty *input, string_ty *output, 1235 string_ty *index_name); 1236 void change_run_annotate_diff_command(change::pointer cp, user_ty::pointer up, 1237 string_ty *original, string_ty *input, string_ty *output, 1238 string_ty *index_name, const char *diff_option); 1239 int change_has_merge_command(change::pointer ); 1240 void change_run_integrate_begin_command(change::pointer ); 1241 void change_run_integrate_begin_undo_command(change::pointer ); 1242 1243 void change_run_develop_begin_command(change::pointer cp, user_ty::pointer up) 1244 DEPRECATED; 1245 1246 void change_run_develop_begin_undo_command(change::pointer cp, 1247 user_ty::pointer up); 1248 int change_run_test_command(change::pointer cp, user_ty::pointer up, 1249 string_ty *, string_ty *, int, int, 1250 const nstring_list &variable_assignments); 1251 int change_run_development_test_command(change::pointer cp, user_ty::pointer up, 1252 string_ty *, string_ty *, int, int, 1253 const nstring_list &variable_assignments); 1254 void change_run_build_command(change::pointer ); 1255 void change_run_build_time_adjust_notify_command(change::pointer ); 1256 void change_run_development_build_command(change::pointer , user_ty::pointer , 1257 string_list_ty *); 1258 1259 /** 1260 * The change_run_develop_end_policy_command function is used to 1261 * run the develop_end_policy_command specified in the project 1262 * configuration file. 1263 * 1264 * @param cp 1265 * The change in question. 1266 * @param up 1267 * The developer of the change. 1268 * @note 1269 * This function does not return if the command exits with a 1270 * non-zero exit status. 1271 */ 1272 void change_run_develop_end_policy_command(change::pointer cp, 1273 user_ty::pointer up); 1274 1275 string_ty *change_file_whiteout(change::pointer , string_ty *); 1276 void change_file_whiteout_write(change::pointer cp, string_ty *path, 1277 user_ty::pointer up); 1278 void change_become(change::pointer ); 1279 void change_become_undo(change::pointer cp); 1280 void change_developer_become(change::pointer ); 1281 void change_developer_become_undo(change::pointer cp); 1282 1283 void change_development_directory_clear(change::pointer ); 1284 void change_integration_directory_clear(change::pointer ); 1285 void change_architecture_clear(change::pointer ); 1286 void change_architecture_add(change::pointer , string_ty *); 1287 void change_architecture_query(change::pointer ); 1288 string_ty *change_architecture_name(change::pointer , int); 1289 string_ty *change_run_architecture_discriminator_command(change::pointer cp); 1290 cstate_architecture_times_ty *change_architecture_times_find(change::pointer , 1291 string_ty *); 1292 void change_build_time_set(change::pointer ); 1293 1294 /** 1295 * The change_test_time_set function is used to set the test time for a 1296 * change. The architecture of the currently executing session is used. 1297 * 1298 * @param cp 1299 * The change in question. 1300 * @param when 1301 * The time the test was performed. 1302 */ 1303 void change_test_time_set(change::pointer cp, time_t when); 1304 1305 /** 1306 * The change_test_time_set function is used to set the test time for a 1307 * change, for the given architecture variant. 1308 * 1309 * @param cp 1310 * The change in question. 1311 * @param variant 1312 * The name of the architecture of interest. 1313 * @param when 1314 * The time the test was performed. 1315 */ 1316 void change_test_time_set(change::pointer cp, string_ty *variant, time_t when); 1317 1318 /** 1319 * The change_test_baseline_time_set function is used to set the 1320 * baseline test time for a change. The architecture of the currently 1321 * executing session is used. 1322 * 1323 * @param cp 1324 * The change in question. 1325 * @param when 1326 * The time the test was performed. 1327 */ 1328 void change_test_baseline_time_set(change::pointer cp, time_t when); 1329 1330 /** 1331 * The change_test_baseline_time_set function is used to set the test 1332 * time for a change, for the given architecture variant. 1333 * 1334 * @param cp 1335 * The change in question. 1336 * @param variant 1337 * The name of the architecture of interest. 1338 * @param when 1339 * The time the test was performed. 1340 */ 1341 void change_test_baseline_time_set(change::pointer cp, string_ty *variant, 1342 time_t when); 1343 1344 /** 1345 * The change_regression_test_time_set function is used to set (or 1346 * clear) the regression test time stamp of the chanegh set. 1347 * 1348 * @param cp 1349 * The change set in question. 1350 * @param when 1351 * The time the test was performed, or zero to clear the time. 1352 * @param arch_name 1353 * The name of the architecture, or the NULL pointer to mean "the 1354 * current one". 1355 */ 1356 void change_regression_test_time_set(change::pointer cp, time_t when, 1357 string_ty *arch_name = 0); 1358 1359 void change_test_times_clear(change::pointer ); 1360 void change_build_times_clear(change::pointer ); 1361 void change_architecture_from_pconf(change::pointer ); 1362 1363 const char *change_outstanding_builds(change::pointer , time_t); 1364 const char *change_outstanding_tests(change::pointer , time_t); 1365 const char *change_outstanding_tests_baseline(change::pointer , time_t); 1366 const char *change_outstanding_tests_regression(change::pointer , time_t); 1367 1368 int change_pathconf_name_max(change::pointer ); 1369 string_ty *change_filename_check(change::pointer , string_ty *); 1370 1371 void change_create_symlinks_to_baseline(change::pointer , user_ty::pointer , 1372 const work_area_style_ty &); 1373 1374 /** 1375 * The change_maintain_symlinks_to_baseline is used to repair the 1376 * symbolic links (etc) as dictated by the development_directory_style 1377 * field of the project configuration file. 1378 * 1379 * The "symlink" in the name is an historical accident, it also 1380 * maintains the hard links and copies as well. 1381 * 1382 * @param cp 1383 * The change to operatte on 1384 * @param up 1385 * The user to operate as 1386 * @param undoing 1387 * True if this call is in response to and undo operation (aecpu, 1388 * aemtu) because they need special attention for file time stamps. 1389 * Defaults to false if not specified. 1390 * 1391 * @note 1392 * This function is NOT to be called by aeb, because it needs 1393 * different logic. 1394 * @note 1395 * This function may only be called when the change is in the 1396 * "being developed" state. 1397 */ 1398 void change_maintain_symlinks_to_baseline(change::pointer cp, 1399 user_ty::pointer up, bool undoing = false); 1400 1401 void change_remove_symlinks_to_baseline(change::pointer , user_ty::pointer , 1402 const work_area_style_ty &); 1403 1404 void change_rescind_test_exemption(change::pointer ); 1405 1406 /** 1407 * The change_fstate_filename_get function is used to obtain the 1408 * absolute path of the file which holds the change's file state. 1409 * 1410 * @param cp 1411 * The change being operated on. 1412 * @returns 1413 * a string. DO NOT str_free it when you are done with it, 1414 * it is cached. 1415 */ 1416 string_ty *change_fstate_filename_get(change::pointer cp); 1417 1418 /** 1419 * The change_pfstate_filename_get function is used to obtain the 1420 * absolute path of the file which holds the delta's cache of the 1421 * project file state. 1422 * 1423 * @param cp 1424 * The change being operated on. 1425 * @returns 1426 * a string. DO NOT str_free it when you are done with it, 1427 * it is cached. 1428 */ 1429 string_ty *change_pfstate_filename_get(change::pointer cp); 1430 1431 void change_rescind_test_exemption_undo(change::pointer ); 1432 void change_force_regression_test_exemption(change::pointer ); 1433 void change_force_regression_test_exemption_undo(change::pointer ); 1434 1435 void change_check_architectures(change::pointer ); 1436 string_ty *change_new_test_filename_get(change::pointer , long, int); 1437 string_ty *change_development_directory_template(change::pointer , 1438 user_ty::pointer ); 1439 string_ty *change_metrics_filename_pattern_get(change::pointer ); 1440 1441 /** 1442 * The change_uuid_set function is used to set a change's UUID, 1443 * if it has not been set already. 1444 */ 1445 void change_uuid_set(change::pointer cp); 1446 1447 /** 1448 * The change_uuid_clear function is used to clear a change's UUID, 1449 * if it has been set in the past. 1450 */ 1451 void change_uuid_clear(change::pointer cp); 1452 1453 /** 1454 * The change_reviewer_list function is used to get the list of 1455 * reviewers since the last develop_end. There can be more than one 1456 * if the review_policy_command filed of the project configuration is 1457 * being used. 1458 * 1459 * @param cp 1460 * The change to be consulted. 1461 * @param result 1462 * where to put the answers. 1463 */ 1464 void change_reviewer_list(change::pointer cp, string_list_ty &result); 1465 1466 /** 1467 * The change_reviewer_already function is used to determine if a user 1468 * has already reviewed a change, since the last develop end. 1469 * 1470 * @param cp 1471 * The change to be consulted. 1472 * @param login 1473 * The login name of the user in question. 1474 * @returns 1475 * bool; true if the user has reviewed already, false if not. 1476 */ 1477 bool change_reviewer_already(change::pointer cp, string_ty *login); 1478 1479 /** 1480 * The change_reviewer_already function is used to determine if a user 1481 * has already reviewed a change, since the last develop end. 1482 * 1483 * @param cp 1484 * The change to be consulted. 1485 * @param login 1486 * The login name of the user in question. 1487 * @returns 1488 * bool; true if the user has reviewed already, false if not. 1489 */ 1490 bool change_reviewer_already(change::pointer cp, const nstring &login); 1491 1492 /** 1493 * The change_when_get function is used to obtain the last (most 1494 * recent) time for the given state transition. 1495 * 1496 * @param cp 1497 * The change in qiestion. 1498 * @param what 1499 * The state transition to look for. 1500 * @returns 1501 * time_t; the time of the event, or 0 if not found. 1502 */ 1503 time_t change_when_get(change::pointer cp, cstate_history_what_ty what); 1504 1505 /** 1506 * The change_diff_required function is used to see of the project (and 1507 * this specific change set) need the diff command to be run. 1508 * 1509 * @param cp 1510 * The change in question. 1511 * @returns 1512 * bool; true if diff command needs to be run, false if not. 1513 */ 1514 bool change_diff_required(change::pointer cp); 1515 1516 /** 1517 * The change_build_required function is used to see of the project (and 1518 * this specific change set) need the build command to be run. 1519 * 1520 * @param cp 1521 * The change in question. 1522 * @param conf_exists 1523 * true if the project configuration file must exist (causing fatal 1524 * error if it does not), or false if it doesn't matter. 1525 * @returns 1526 * bool; true if build command needs to be run, false if not. 1527 */ 1528 bool change_build_required(change::pointer cp, bool conf_exists = true); 1529 1530 // vim: set ts=8 sw=4 et : 1531 #endif // LIBAEGIS_CHANGE_H 1532