1 //
2 // aegis - project change supervisor
3 // Copyright (C) 1992-1999, 2001-2008, 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 PROJECT_H
21 #define PROJECT_H
22
23 #include <common/ac/time.h>
24
25 #include <libaegis/pattr.fmtgen.h>
26 #include <libaegis/pstate.fmtgen.h>
27 #include <libaegis/view_path.h>
28 #include <libaegis/change.h>
29
30 class string_list_ty; // forward
31 class sub_context_ty; // forward
32 class fstate_src_ty; // forward
33 class itab_ty; // forward
34
35 /**
36 * The project class is used to remember the state of a project.
37 *
38 * Eventually, it will be discouraged to use this class directly. The
39 * preferred method will be to access it via a project class (see
40 * below) smart pointer. This will be able to guarantee the reference
41 * counting semantics.
42 *
43 * This class is presently in transition from being a C struct. One by
44 * one the access functions will be turned into access methids, and the
45 * instance variables will become private.
46 */
47 class project
48 {
49 public:
50 /**
51 * The pointer typedef is provided so that clients of this
52 * interface may use change::pointer everywhere they need to point
53 * at a change instance, and only this typedef needs to be edited
54 * to use a variety of smart pointer instead.
55 */
56 typedef project *pointer;
57
58 /**
59 * The destructor.
60 *
61 * It is not virtual; thou shalt not derive fron this class.
62 *
63 * @note
64 * Eventually this method will be private, to ensure the
65 * reference counting always works. The correct method is to
66 * call the project_free function.
67 */
68 ~project();
69
70 /**
71 * The constructor.
72 *
73 * @param name
74 * The name of the project.
75 */
76 project(string_ty *name);
77
78 // NOTE: methods are sorted alphabetically. To have methods
79 // grouped, make sure they change their suffix rather than their
80 // prefix. E.g. thingumy_get and thingumy_set rather than
81 // get_thingumy and set_thingumy.
82 //
83 // Note: public or protected or private, it doesn't matter, keep
84 // them sorted.
85
86 // ---------- A ------------------------------------------------------
87
88 /**
89 * The attribute_get method is used to obtain the value of an
90 * attribute of this project.
91 *
92 * The project attributes are kept in the <tt>project_specific</tt>
93 * field of the project config file (<tt>aegis.conf</tt>) which is
94 * a project source file. Only use this method when you want the
95 * <b>baseline</b> attributes, use change::pconf_attributes_find
96 * within a change set.
97 *
98 * @param name
99 * The name of the attribute.
100 * Attribute names are not case sensitive.
101 * @returns
102 * the string value of the attribute, or the empty string
103 * if not found.
104 */
105 nstring attribute_get(const nstring &name);
106
107 /**
108 * The attribute_get_boolean method is used to obtain the value of
109 * an attribute of this project, as a true/false value.
110 *
111 * The project attributes are kept in the <tt>project_specific</tt>
112 * field of the project config file (<tt>aegis.conf</tt>)
113 * which is a project source file. Only use this method
114 * when you want the <b>baseline</b> attributes, use
115 * change::pconf_attributes_find_boolean within a change set.
116 *
117 * @param name
118 * The name of the attribute.
119 * Attribute names are not case sensitive.
120 * @returns
121 * the boolean value of the attribute, or false if the
122 * attribute is not found or is not interpretable as a
123 * boolean.
124 */
125 bool attribute_get_boolean(const nstring &name);
126
127 // ---------- B ------------------------------------------------------
128
129 /**
130 * The baseline_path_get method is used to obtain the absolure path
131 * of the project's (branch's) baseline.
132 *
133 * @param resolve
134 * Whether or not to resolve all of the symlinks in the path.
135 */
136 string_ty *baseline_path_get(bool resolve = false);
137
138 /**
139 * The bind_branch method is used to bind a branch of this project
140 * into a new project object.
141 *
142 * @param bp
143 * The change corresponding to the project of interest.
144 */
145 project *bind_branch(change::pointer bp);
146
147 /**
148 * The bind_existing method is used to bind a newly created project
149 * object to an existing project.
150 *
151 * @note
152 * This method does not return if there is an error. A fatal
153 * error message will be produced in this case.
154 */
155 void bind_existing();
156
157 /**
158 * The bind_existing_errok method is used to bind a newly created
159 * project object to an existing project.
160 *
161 * @returns
162 * bool; true if bound successfully, false if not
163 */
164 bool bind_existing_errok();
165
166 /**
167 * The bind_keep method is used to bind a new project to an
168 * existing directory, as needed by the "aenpr -keep" option.
169 *
170 * @param path
171 * The directory containing the project.
172 */
173 void bind_keep(const nstring &path);
174
175 /**
176 * The bind_new method is used to bind a new project object to a
177 * new name. This will create all of the necessary data structures
178 * and (eventually) files, once the project directory has been set.
179 */
180 void bind_new();
181
182 // ---------- C ------------------------------------------------------
183
184 /**
185 * The change_completion_timestamp is used to
186 * determine the completion timestamp of a change.
187 *
188 * @param change_number
189 * the number of the change.
190 *
191 * @returns
192 * the completion timestamp of the change.
193 *
194 * @note
195 * this method caches its results for speed.
196 */
197 time_t change_completion_timestamp(long change_number);
198
199 /**
200 * The change_get method is used to obtain a pointer to the change
201 * object representing this project branch.
202 *
203 * @returns
204 * pointer to change object;
205 * DO NOT change_free() or delete it.
206 */
207 change::pointer change_get(void);
208
209 /**
210 * The change_get_raw method is used to obtain a pointer to the change
211 * object representing this project branch or NULL if no such object
212 * is in the project.
213 *
214 * @returns
215 * pointer to change object;
216 * DO NOT change_free() or delete it.
217 */
change_get_raw()218 change::pointer change_get_raw() { return pcp; }
219
220 /**
221 * The change_path_get method is used to obtain the absolute path
222 * of the meta-data of a specific change set.
223 *
224 * @param change_number
225 * The number of the change for which the path is desired.
226 * @returns
227 * a string; use str_free when you are done with.
228 */
229 string_ty *change_path_get(long change_number);
230
231 void
change_reset()232 change_reset()
233 {
234 change::pointer tmp = pcp;
235 pcp = 0;
236 change_free(tmp);
237 }
238
239 /**
240 * The changes_path_get method is used to obtain the absolute path
241 * of the directory containing change set meta-data.
242 *
243 * @returns
244 * a string; do not str_free or delete it, because it is cached.
245 */
246 string_ty *changes_path_get();
247
248 public: // during transition, then private
249 /**
250 * The convert_to_new_format method is used to convert Aegis 2.3
251 * project meta-data into Aegis 3.0 (and later) project meta-data.
252 */
253 void convert_to_new_format();
254
255 public:
256 /**
257 * The copy_the_owner method is used to copy the owner from another
258 * project. It is only ever used by aenrls, which sort-of clones
259 * another project. Don't use this method.
260 *
261 * Note: this is only a transient requirement for new projects.
262 * Existing projects take their uid and gid from the Unix uid and
263 * gid of the project directory.
264 */
265 void copy_the_owner(project *pp);
266
267 /**
268 * the copyright_years_slurp method is used to determine the range
269 * of copyright years covered by this project and all its ancrestor
270 * projects back to the trunk.
271 *
272 * @param a
273 * The array to store the results in
274 * @param amax
275 * The maximum number of distinct years which can be stored in
276 * the array (see SIZEOF macro).
277 * @param alen_p
278 * This is a pointer to the array length used to date.
279 */
280 void copyright_years_slurp(int *a, int amax, int *alen_p);
281
282 // ---------- D ------------------------------------------------------
283 // ---------- E ------------------------------------------------------
284 // ---------- F ------------------------------------------------------
285
286 /**
287 * The file_directory_query method is used to determine whether or
288 * not a given file name is actually a directory name, and if it
289 * is, expand it into a list of files below that directory.
290 *
291 * @param filename
292 * The name of the file to be checked.
293 * @param result_in
294 * If the filename is a directory, will be filled with a list
295 * of files existing in that directory.
296 * @param result_out
297 * If the filename is a directory, will be filled with a list
298 * of removed files from that directory.
299 * @param as_view_path
300 * The view path style to be used.
301 */
302 bool file_directory_query(const nstring &filename, nstring_list &result_in,
303 nstring_list &result_out, view_path_ty as_view_path);
304
305 /**
306 * The file_directory_query method is used to determine whether or
307 * not a given file name is actually a directory name, and if it
308 * is, expand it into a list of files below that directory.
309 *
310 * @param filename
311 * The name of the file to be checked.
312 * @param result_in
313 * If not NULL, and if the filename is a directory, will be
314 * filled with a list of files existing in that directory.
315 * @param result_out
316 * If not NULL, and if the filename is a directory, will be
317 * filled with a list of removed files from that directory.
318 * @param as_view_path
319 * The view path style to be used.
320 */
321 void file_directory_query(string_ty *filename,
322 struct string_list_ty *result_in, struct string_list_ty *result_out,
323 view_path_ty as_view_path);
324
325 /**
326 * The file_exists method is used to determine whether or not a
327 * file exists in the project baseline, or any of the ancestor
328 * basleines.
329 *
330 * @param filename
331 * The base-relative name of the file to search for.
332 */
333 bool file_exists(const nstring &filename);
334
335 /**
336 * The file_find method is used to find the state information of
337 * the named file within the project. It will search the immediate
338 * branch, and then any ancestor branches until the file is found.
339 *
340 * @param filename
341 * The base-relative name of the file to search for.
342 * @param as_view_path
343 * If this is true, apply viewpath rules to the file (i.e. if
344 * it is removed, return a null pointer) if false return first
345 * instance found.
346 */
347 fstate_src_ty *file_find(const nstring &filename,
348 view_path_ty as_view_path);
349
350 /**
351 * The file_find method is used to find the state information of
352 * the named file within the project. It will search the immediate
353 * branch, and then any ancestor branches until the file is found.
354 *
355 * @param filename
356 * The base-relative name of the file to search for.
357 * @param as_view_path
358 * If this is true, apply viewpath rules to the file (i.e. if
359 * it is removed, return a null pointer) if false return first
360 * instance found.
361 */
362 fstate_src_ty *file_find(string_ty *filename, view_path_ty as_view_path);
363
364 /**
365 * The file_find method is used to find the state information of a
366 * file within the project, given the corresponding change file's
367 * meta-data. It will search the immediate branch, and then any
368 * ancestor branches until the file is found.
369 *
370 * @param c_src
371 * The change file meta-data for which the corresponding project
372 * file is sought.
373 * @param as_view_path
374 * If this is true, apply viewpath rules to the file (i.e. if
375 * it is removed, return a null pointer) if false return first
376 * instance found.
377 */
378 fstate_src_ty *file_find(fstate_src_ty *c_src, view_path_ty as_view_path);
379
380 /**
381 * The file_find method is used to find the state information of a
382 * file within the project, given the corresponding change file's
383 * meta-data. It will search the immediate branch, and then any
384 * ancestor branches until the file is found.
385 *
386 * @param c_src
387 * The change file meta-data for which the corresponding project
388 * file is sought.
389 * @param as_view_path
390 * If this is true, apply viewpath rules to the file (i.e. if
391 * it is removed, return a null pointer) if false return first
392 * instance found.
393 */
394 fstate_src_ty *file_find(cstate_src_ty *c_src, view_path_ty as_view_path);
395
396 /**
397 * The file_find_by_uuid method is used to find the state
398 * information of a file within the project, given the file's UUID.
399 * It will search the immediate branch, and then any ancestor
400 * branches until the file is found.
401 *
402 * \param uuid
403 * The UUID of the file to search for.
404 * \param vp
405 * If this is true, apply viewpath rules to the file (i.e. if
406 * it is removed, return a null pointer) if false return first
407 * instance found.
408 */
409 fstate_src_ty *file_find_by_uuid(string_ty *uuid, view_path_ty vp);
410
411 /**
412 * The file_find_fuzzy method is used to find the state information
413 * for a project file when the project::file_find function fails.
414 * It uses fuzzy string matching, which is significantly slower
415 * than exact searching, but can provide very useful error messages
416 * for users.
417 *
418 * \param filename
419 * The base-relative name of the file to search for.
420 * \param as_view_path
421 * If this is true, apply viewpath rules to the file (i.e. if
422 * it is removed, return a null pointer) if false return first
423 * instance found.
424 */
425 fstate_src_ty *file_find_fuzzy(string_ty *filename,
426 view_path_ty as_view_path);
427
428 private:
429 /**
430 * The file_list_get method is used to obtain a list of file names.
431 * The lists are calculated on demand and cached.
432 *
433 * \param as_view_path
434 * The view path style to use when calculating the list of
435 * project files.
436 * \returns
437 * Pointer to a string list, do not delete it, it is cached.
438 */
439 struct string_list_ty *file_list_get(view_path_ty as_view_path);
440
441 public:
442 /**
443 * The file_list_invalidate method is used to clear the cahced
444 * project file information when it becomes stale.
445 */
446 void file_list_invalidate();
447
448 /**
449 * The file_new method is used to create a new project file by
450 * name, and add it to the project file manifest. No validation is
451 * done, the called must guarantee that the file name is unique.
452 *
453 * \param file_name
454 * The base-relative name of the file to search for.
455 */
456 fstate_src_ty *file_new(string_ty *file_name);
457
458 /**
459 * The file_new method is used to create a new project file from
460 * the meta data of an existing (usually change set) file, and add
461 * it to the project file manifest. No validation is done, the
462 * caller must guarantee that the file name and UUID are unique.
463 *
464 * \param meta
465 * The meta data, including the name and UUID, of the file to
466 * be created.
467 */
468 fstate_src_ty *file_new(fstate_src_ty *meta);
469
470 /**
471 * The file_nth method is used to get the 'n'th file from the list
472 * of project files.
473 *
474 * \param n
475 * The file number to obtain (zero based).
476 * \param as_view_path
477 * The style of view path to use when calculating the list.
478 * \returns
479 * pointer to file mete-data, or NULL if beyond end of list
480 */
481 fstate_src_ty *file_nth(size_t n, view_path_ty as_view_path);
482
483 /**
484 * The find_branch method is used to locate the branch with the
485 * given number in this project.
486 *
487 * @param number
488 * The branch number to locate.
489 * @returns
490 * Pointer to valid project object.
491 */
492 project *find_branch(const char *number);
493
494 // ---------- G ------------------------------------------------------
495
496 private:
497 /**
498 * The get_the_owner method is used to determine the Unix pid and
499 * gid for the project.
500 */
501 void get_the_owner();
502
503 public:
504 /**
505 * The get_user method may be used to obtain a pointer to the user
506 * (and group) ownership date for this project.
507 */
508 user_ty::pointer get_user() const;
509
510 /**
511 * The gid_get method is used to obtain the Unix group id of the
512 * project owner.
513 */
514 int gid_get();
515
516 // ---------- H ------------------------------------------------------
517
518 /**
519 * The history_path_get method is used to determine the top-level
520 * directory of the tree which is used to hold the project's
521 * history files.
522 *
523 * @returns
524 * a pointer to a string. Do NOT free this string when you are
525 * done with it, because it is cached.
526 */
527 string_ty *history_path_get();
528
529 /**
530 * The home_path_get method is used to get the "home" directory
531 * of a project; the directory which contains trunk's delta
532 * directories and the baseline, and the "info" meta-data
533 * directory.
534 *
535 * @returns
536 * a string containing the absolute path.
537 * DO NOT str_free or delete it.
538 *
539 * @note
540 * It is a bug to call this method for anything other than a
541 * trunk project. Calling if for a branch will result in an
542 * assert failure.
543 */
544 string_ty *home_path_get();
545
546 /**
547 * The home_path_set method is used when creating a new project to
548 * remeber the directory the project beaselines and meta-data are
549 * stored within.
550 *
551 * @param dir
552 * The absolute path of the directory in which to keep the
553 * project. To cope with automounters, directories are stored
554 * as given, or are derived from the home directory in the
555 * passwd file. Within Aegis, pathnames have their symbolic
556 * links resolved, and any comparison of paths is done on this
557 * "system idea" of the pathname.
558 */
559 void home_path_set(string_ty *dir);
560 void home_path_set(const nstring &dir);
561
562 // ---------- I ------------------------------------------------------
563
564 /**
565 * The info_path_get method is used to obtain the absolute path of
566 * the meta-data file for this project (branch).
567 *
568 * @returns
569 * a string; do not str_free or delete it, because it is cached.
570 * @note
571 * it is a bug to call this for anything but a top-level
572 * (trunk) project.
573 */
574 string_ty *info_path_get();
575
576 /**
577 * The is_a_trunk method is used to determine whether a project
578 * is a trunk branch (is the deepest ancestor) or a normal nested
579 * branch (has at least one ancestor branch).
580 *
581 * @returns
582 * bool; true if is a trunk, false if is a branch
583 */
is_a_trunk()584 bool is_a_trunk() const { return (parent == 0); }
585
586 // ---------- J ------------------------------------------------------
587 // ---------- K ------------------------------------------------------
588 // ---------- L ------------------------------------------------------
589
590 /**
591 * The list_inner method is used to append the branch names to the
592 * result list. This is one step of building a complete list of
593 * projects.
594 *
595 * @param result
596 * Append all project branch names to this list.
597 */
598 void list_inner(string_list_ty &result);
599
600 /**
601 * The lock_prepare_everything method is used to take a resd-only
602 * lock of everything in the project: pstate, baseline, changes,
603 * and recurse into all active branches.
604 */
605 void lock_prepare_everything();
606
607 private:
608 /**
609 * The lock_sync method is used to invalidate the project state
610 * data if the lock has been released and taken again.
611 *
612 * @note
613 * it is a bug to call this for anything but a top-level
614 * (trunk) project.
615 */
616 void lock_sync();
617
618 // ---------- M ------------------------------------------------------
619 // ---------- N ------------------------------------------------------
620
621 public:
622 /**
623 * The name_get method is used to get the name of the project.
624 *
625 * @returns
626 * a string; the name of the project.
627 * DO NOT str_free it.
628 */
629 string_ty *name_get() const;
630
631 // ---------- O ------------------------------------------------------
632 // ---------- P ------------------------------------------------------
633
634 /**
635 * The parent_branch_number_get method is used to get the branch
636 * (change) number of this branch in the parent branch.
637 *
638 * @note
639 * This method is not meaningful for trunk projects (branches).
640 */
parent_branch_number_get()641 long parent_branch_number_get() const { return parent_bn; }
642
643 /**
644 * The parent_get method is used to obtain the parent brach of this
645 * project.
646 *
647 * @returns
648 * pointer to project; do not delete or project_free
649 */
parent_get()650 project *parent_get() { return (parent ? parent : this); }
651
652 /**
653 * The pstate_get method is used to obtain the project state data.
654 *
655 * @returns
656 * pointer to pstate_ty data; do not delete, it is cached.
657 * @note
658 * it is a bug to call this for anything but a top-level
659 * (trunk) project.
660 */
661 pstate_ty *pstate_get();
662
663 /**
664 * The pstate_lock_prepare method is used to prepare to take a
665 * project pstate lock for this project, prior to lock_take() being
666 * called.
667 */
668 void pstate_lock_prepare();
669
670 /**
671 * The pstate_path_get method is used to obtain the absolute path
672 * of the pstate (project state) file.
673 *
674 * @returns
675 * a string; do not str_free or delete it, because it is cached.
676 * @note
677 * it is a bug to call this for anything but a top-level
678 * (trunk) project.
679 */
680 string_ty *pstate_path_get();
681
682 /**
683 * The search_path_get method may be used to obtain the search path
684 * (list of progressively more out-of-date ancestor btranches)
685 * within which to search for files.
686 *
687 * @param result
688 * Where to append the additional directories.
689 * @param resolve
690 * Whether or not to expand synbolic links within paths.
691 */
692 void search_path_get(string_list_ty *result, bool resolve);
693
694 /**
695 * The search_path_get method may be used to obtain the search path
696 * (list of progressively more out-of-date ancestor btranches)
697 * within which to search for files.
698 *
699 * @param result
700 * Where to append the additional directories.
701 * @param resolve
702 * Whether or not to expand synbolic links within paths.
703 */
704 void search_path_get(nstring_list &result, bool resolve);
705
706 /**
707 * The pstate_write method is used to write out the project state
708 * data into the meta-data directory tree.
709 */
710 void pstate_write();
711
712 // ---------- Q ------------------------------------------------------
713 // ---------- R ------------------------------------------------------
714 // ---------- S ------------------------------------------------------
715 // ---------- T ------------------------------------------------------
716
717 /**
718 * The trunk_get method is used to find the trunk project of this
719 * project, then top-level branch of this project.
720 */
721 project *trunk_get();
722
723 // ---------- U ------------------------------------------------------
724 // ---------- V ------------------------------------------------------
725 // ---------- W ------------------------------------------------------
726 // ---------- X ------------------------------------------------------
727 // ---------- Y ------------------------------------------------------
728 // ---------- Z ------------------------------------------------------
729 // ---------------------------------------------------------------------
730
731 /**
732 * The uid_get method is used to obtain the Unix user id of the
733 * project owner.
734 */
735 int uid_get();
736
737 /**
738 * The umask_get method is used to obtain the file creation mode
739 * mask for this project.
740 */
741 int umask_get();
742
743 public: // during transition
744 long reference_count;
745
746 private:
747 /**
748 * The name instance variable is used to remember the name of this
749 * project.
750 */
751 string_ty *name;
752
753 /**
754 * The home_path instance variable is used to remember the "home"
755 * directory of a project; the directory which contains trunk's
756 * delta directories and the baseline, and the "info" meta-data
757 * directory.
758 *
759 * @note
760 * Never access this instance variable directly, always go via
761 * home_path_get() in case it hasn't been calculated yet.
762 */
763 string_ty *home_path;
764
765 /**
766 * The baseline_path_unresolved instance variable is used to
767 * remember the absolute path of this project's (branch's) baseline
768 * directory. It has not had is symbolic links resolved. All
769 * access is via the baseline_path_get method, which takes care of
770 * calculating it on demand.
771 */
772 string_ty *baseline_path_unresolved;
773
774 /**
775 * The baseline_path_unresolved instance variable is used to
776 * remember the absolute path of this project's (branch's) baseline
777 * directory. It has not had is symbolic links resolved. All
778 * access is via the baseline_path_get method, which takes care of
779 * calculating it on demand.
780 */
781 string_ty *baseline_path;
782
783 /**
784 * The change2time_stp instance variable is used to remember for
785 * each change the completion timestamp. All access are via the
786 * change_completion_timestamp_maybe_cached method, which take
787 * care of calculating it on demand.
788 */
789 itab_ty *change2time_stp;
790
791 /**
792 * The history_path is used to remember the absolute path of the
793 * distory directory. The calculation is deferred until needed.
794 * Always use the history_path_get method, never access this
795 * instance variable directly.
796 */
797 string_ty *history_path;
798
799 /**
800 * The info_path instance variable is used to remember the location
801 * of the meta-data file for this project (branch). Never access
802 * the info_path variable directly, always go via the info_path_get
803 * method.
804 */
805 string_ty *info_path;
806
807 /**
808 * The pstate_path instance variable is used to remember the
809 * absolute path of the pstate (project state) file. It is
810 * calculated as needed. Never access this instance variable
811 * directly, always go via the pstate_path_get method.
812 */
813 string_ty *pstate_path;
814
815 /**
816 * The changes_path instance variable is used to remember the
817 * absolute path of the directory containing change set meta-data.
818 * It is calculated as needed. Never access this instance variable
819 * directly, always go via the changes_path_get method.
820 */
821 string_ty *changes_path;
822
823 /**
824 * The pstate_data instance variable is used to remember the
825 * project state data. It is calculated as needed. Never
826 * access this instance variable directly, always go via the
827 * pstate_get method.
828 */
829 pstate_ty *pstate_data;
830
831 /**
832 * The is_a_new_file instance variable is used to remember whether
833 * the pstate file is a new file which has to be created.
834 */
835 bool is_a_new_file;
836
837 /**
838 * The lock_magic instance variable is used to remember the last
839 * time the lock was taken. If the lock_sync function returns
840 * different, it means we have to invalidate all our project data
841 * and read it in again, because something could have changed.
842 * Only every accessed by the lock_sync ethod.
843 */
844 long lock_magic;
845
846 /**
847 * The pcp instance variable is used to remember the change object
848 * representing this branch's state.
849 *
850 * @note
851 * Never access this instance variable directly, event from a
852 * project method, always go via the change_get() method in
853 * case it has not been calculated yet.
854 */
855 change::pointer pcp;
856
857 /**
858 * The uid instance variable is used to remember the Unix user id
859 * for the project owner. This is set by the get_the_owner method.
860 */
861 int uid;
862
863 /**
864 * The gid instance variable is used to remember the Unix group id
865 * for the project owner. This is set by the get_the_owner method.
866 */
867 int gid;
868
869 /**
870 * The parent instance variable is used to remember the project
871 * which this project is a branch of. If it is NULL, then this is
872 * a trunk project.
873 */
874 project *parent;
875
876 /**
877 * The parent_bn instance variable is used to remember the change
878 * (branch) number of this project relative to the parent branch.
879 * If it is TRUNK_BRANCH_NUMER, then this is a trunk project.
880 */
881 long parent_bn;
882
883 /**
884 * The file_list instance variable is used to remember the list
885 * of files in the project, one list for each style of view path.
886 * Never access this instance variable directly, always go via the
887 * file_list_get method, they are calculated on demand.
888 */
889 struct string_list_ty *file_list[view_path_MAX];
890
891 /**
892 * The file_by_uuid instance variable is used to remember a symbol
893 * table of files indexed by UUID (or by file name if your project
894 * has any files without a UUID for backwards compatibility).
895 *
896 * This instance variable shall always be accessed via the
897 * find_file_by_uuid method. The tables are calculated on demand
898 * and cached.
899 */
900 struct symtab_ty *file_by_uuid[view_path_MAX];
901
902 //
903 // If you add an instance variable to this class, make sure you
904 // dispose of it in the destructor and initialize in in the
905 // constructor. Both may be found in libaegis/project.cc
906 //
907
908 private:
909 /**
910 * The up instance variable is used to remember the user (and
911 * group) which owns this project.
912 */
913 user_ty::pointer up;
914
915 /**
916 * The off_limits instance variable is used to remember when
917 * a project is inaccessable to the executing user. This
918 * flag is normally false, but it will be set to true by
919 * project::bind_existing for projects which are inaccessable.
920 */
921 bool off_limits;
922
923 /**
924 * The default constructor.
925 *
926 * Do not use this method. It is not defined. Projects will
927 * always have a name, it it shall always be supplied to the
928 * constructor.
929 */
930 project();
931
932 /**
933 * The copy constructor. Do not use.
934 *
935 * The prefereed mechanism is to use the reference counting
936 * provided the the project class (see below) smart pointer.
937 */
938 project(const project &);
939
940 /**
941 * The assignment operator. Do not use.
942 *
943 * The prefereed mechanism is to use the reference counting
944 * provided the the project class (see below) smart pointer.
945 */
946 project &operator=(const project &);
947 };
948
949 project *project_alloc(string_ty *name);
950
951 inline DEPRECATED void
project_bind_existing(project * pp)952 project_bind_existing(project *pp)
953 {
954 pp->bind_existing();
955 }
956
957 inline DEPRECATED bool
project_bind_existing_errok(project * pp)958 project_bind_existing_errok(project *pp)
959 {
960 return pp->bind_existing_errok();
961 }
962
963 inline DEPRECATED project *
project_bind_branch(project * ppp,change::pointer bp)964 project_bind_branch(project *ppp, change::pointer bp)
965 {
966 return ppp->bind_branch(bp);
967 }
968
969 inline DEPRECATED void
project_bind_new(project * pp)970 project_bind_new(project *pp)
971 {
972 pp->bind_new();
973 }
974
975 void project_list_get(struct string_list_ty *);
976
977 inline DEPRECATED void
project_list_inner(struct string_list_ty * result,project * pp)978 project_list_inner(struct string_list_ty *result, project *pp)
979 {
980 pp->list_inner(*result);
981 }
982
983 inline DEPRECATED project *
project_find_branch(project * pp,const char * number)984 project_find_branch(project *pp, const char *number)
985 {
986 return pp->find_branch(number);
987 }
988
989 void project_free(project *);
990
991 inline nstring
project_name_get(project * pp)992 project_name_get(project *pp)
993 {
994 return nstring(pp->name_get());
995 }
996
997 project *project_copy(project *);
998
999 inline DEPRECATED change::pointer
project_change_get(project * pp)1000 project_change_get(project *pp)
1001 {
1002 return pp->change_get();
1003 }
1004
1005 inline DEPRECATED string_ty *
project_home_path_get(project * pp)1006 project_home_path_get(project *pp)
1007 {
1008 return pp->home_path_get();
1009 }
1010
1011 string_ty *project_Home_path_get(project *);
1012 string_ty *project_top_path_get(project *, int);
1013
1014 /**
1015 * The project_rss_path_get function is used to get the path of the RSS
1016 * directory for the given project.
1017 *
1018 * @param pp
1019 * The project in question
1020 * @param resolve
1021 * Whether or not to resolve symlinks in the path.
1022 * @returns
1023 * a string containing the absolute path
1024 */
1025 nstring project_rss_path_get(project *pp, bool resolve = false);
1026
1027 inline DEPRECATED void
project_home_path_set(project * pp,string_ty * dir)1028 project_home_path_set(project *pp, string_ty *dir)
1029 {
1030 pp->home_path_set(dir);
1031 }
1032
1033 inline DEPRECATED string_ty *
1034 project_baseline_path_get(project *pp, bool resolve = false)
1035 {
1036 return pp->baseline_path_get(resolve);
1037 }
1038
1039 inline DEPRECATED string_ty *
project_history_path_get(project * pp)1040 project_history_path_get(project *pp)
1041 {
1042 return pp->history_path_get();
1043 }
1044
1045 /**
1046 * The project_history_filename_get function is used to determine the
1047 * absolute path pf the file used to contain the history of the given file.
1048 *
1049 * @returns
1050 * a pointer to a string. You are required to str_free this string
1051 * when you are done with it.
1052 */
1053 string_ty *project_history_filename_get(project *, struct fstate_src_ty *);
1054
1055 inline DEPRECATED string_ty *
project_info_path_get(project * pp)1056 project_info_path_get(project *pp)
1057 {
1058 return pp->info_path_get();
1059 }
1060
1061 inline DEPRECATED string_ty *
project_changes_path_get(project * pp)1062 project_changes_path_get(project *pp)
1063 {
1064 return pp->changes_path_get();
1065 }
1066
1067 DEPRECATED
1068 string_ty *project_change_path_get(project *, long);
1069
1070 inline DEPRECATED string_ty *
project_pstate_path_get(project * pp)1071 project_pstate_path_get(project *pp)
1072 {
1073 return pp->pstate_path_get();
1074 }
1075
1076 inline DEPRECATED pstate_ty *
project_pstate_get(project * pp)1077 project_pstate_get(project *pp)
1078 {
1079 return pp->pstate_get();
1080 }
1081
1082 inline DEPRECATED void
project_pstate_write(project * pp)1083 project_pstate_write(project *pp)
1084 {
1085 pp->pstate_write();
1086 }
1087
1088 void project_pstate_write_top(project *);
1089
1090 inline DEPRECATED void
project_pstate_lock_prepare(project * pp)1091 project_pstate_lock_prepare(project *pp)
1092 {
1093 pp->pstate_lock_prepare();
1094 }
1095
1096 void project_pstate_lock_prepare_top(project *);
1097 void project_baseline_read_lock_prepare(project *);
1098 void project_baseline_write_lock_prepare(project *);
1099 void project_history_lock_prepare(project *);
1100 void project_error(project *, struct sub_context_ty *, const char *);
1101 void project_fatal(project *, struct sub_context_ty *, const char *)
1102 NORETURN;
1103 void project_verbose(project *, struct sub_context_ty *, const char *);
1104 void project_change_append(project *, long, int);
1105 void project_change_delete(project *, long);
1106 int project_change_number_in_use(project *, long);
1107 nstring project_version_short_get(project *);
1108 nstring project_version_get(project *);
1109
1110 inline DEPRECATED int
project_uid_get(project * pp)1111 project_uid_get(project *pp)
1112 {
1113 return pp->uid_get();
1114 }
1115
1116 inline DEPRECATED int
project_gid_get(project * pp)1117 project_gid_get(project *pp)
1118 {
1119 return pp->gid_get();
1120 }
1121
1122 user_ty::pointer project_user(project *);
1123 void project_become(project *);
1124 void project_become_undo(project *pp);
1125 long project_next_test_number_get(project *);
1126 int project_is_readable(project *);
1127 long project_minimum_change_number_get(project *);
1128 void project_minimum_change_number_set(project *, long);
1129 bool project_reuse_change_numbers_get(project *);
1130 void project_reuse_change_numbers_set(project *, bool);
1131 long project_minimum_branch_number_get(project *);
1132 void project_minimum_branch_number_set(project *, long);
1133 bool project_skip_unlucky_get(project *);
1134 void project_skip_unlucky_set(project *, bool);
1135 bool project_compress_database_get(project *);
1136 void project_compress_database_set(project *, bool);
1137 int project_develop_end_action_get(project *);
1138 void project_develop_end_action_set(project *, int);
1139 bool project_protect_development_directory_get(project *);
1140 void project_protect_development_directory_set(project *, bool);
1141
1142 int break_up_version_string(const char *, long *, int, int *, int);
1143 void extract_version_from_project_name(string_ty **, long *, int, int *);
1144 int project_name_ok(string_ty *);
1145
1146 pconf_ty *project_pconf_get(project *);
1147
1148 /**
1149 * The project_new_branch function is used to create new branches.
1150 *
1151 * @param pp
1152 * The project to create the branch below.
1153 * @param up
1154 * The authorised user requesting the new branch.
1155 * @param change_number
1156 * The change number to use for the new branch.
1157 * @param topdir
1158 * The change (branch) directory, It is in the same place as the
1159 * rest of the project, unless otherwise specified (i.e. not NULL).
1160 * This makes it easy to collect the whole project tree, branches,
1161 * info and all, in a simple tar or cpio command for archiving or
1162 * moving.
1163 * @param reason
1164 * The reason the user gave on the command line, or NULL for no
1165 * reason to be attached to the change's history.
1166 * @returns
1167 * A pointer to the new project represented by the new branch.
1168 */
1169 project *project_new_branch(project *pp, user_ty::pointer up,
1170 long change_number, string_ty *topdir = 0, string_ty *reason = 0);
1171
1172 inline DEPRECATED void
project_file_list_invalidate(project * pp)1173 project_file_list_invalidate(project *pp)
1174 {
1175 pp->file_list_invalidate();
1176 }
1177
1178 string_ty *project_brief_description_get(project *);
1179
1180 /**
1181 * The project_uuid_find function is used to locate a change given its UUID.
1182 *
1183 * @param pp
1184 * The project to search. Will rewind to the trunk project
1185 * before the search commences.
1186 * @param uuid
1187 * The change UUID to search for.
1188 * @returns
1189 * a pointer to the change with th given UUID, or NULL if no change
1190 * has the given UUID.
1191 */
1192 change::pointer project_uuid_find(project *pp, string_ty *uuid);
1193
1194 // vim: set ts=8 sw=4 et :
1195 #endif // PROJECT_H
1196