1 //
2 // aegis - project change supervisor
3 // Copyright (C) 2004-2006, 2008, 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 #include <common/ac/string.h>
21 
22 #include <aemakefile/process/tail.h>
23 
24 
~process_tail()25 process_tail::~process_tail()
26 {
27 }
28 
29 
process_tail(printer & arg)30 process_tail::process_tail(printer &arg) :
31     process(arg)
32 {
33     dir_st.set_reaper();
34 
35     clean_files.push_back("core");
36     clean_files.push_back("bin/fmtgen$(EXEEXT)");
37     clean_files.push_back("libaegis/libaegis.$(LIBEXT)");
38     clean_files.push_back("common/common.$(LIBEXT)");
39     clean_files.push_back(".bin");
40     clean_files.push_back(".bindir");
41     clean_files.push_back(".po_files");
42     clean_files.push_back(".man1dir");
43     clean_files.push_back(".man3dir");
44     clean_files.push_back(".man5dir");
45     clean_files.push_back(".comdir");
46 
47     common_files = new nstring_list;
48     dir_st.assign("common", common_files);
49 
50     libaegis_files = new nstring_list;
51     dir_st.assign("libaegis", libaegis_files);
52 
53     datadir_files.push_back(
54         "$(DESTDIR)$(sysconfdir)/profile.d/aegis.sh");
55     datadir_files.push_back(
56         "$(DESTDIR)$(sysconfdir)/profile.d/aegis.csh");
57 }
58 
59 
60 static nstring
dirname(const nstring & s)61 dirname(const nstring &s)
62 {
63     const char *cp = s.c_str();
64     const char *ep = strrchr(cp, '/');
65     if (!ep)
66         return ".";
67     return nstring(cp, ep - cp);
68 }
69 
70 
71 
72 //
73 // Create directories and any necessary parent directories.
74 //
75 void
recursive_mkdir(const nstring & src_dir_arg,const nstring & dst_dir_arg,const nstring & dir_suffix)76 process_tail::recursive_mkdir(const nstring &src_dir_arg,
77     const nstring &dst_dir_arg, const nstring &dir_suffix)
78 {
79     nstring src_dir(src_dir_arg);
80     nstring dst_dir(dst_dir_arg);
81     static int defined;
82     static symtab<int> dir_exists;
83     for (;;)
84     {
85         nstring dirvar = "mkdir." + src_dir + "." + dir_suffix;
86         nstring dotdot = dirname(src_dir);
87 
88         if (!dir_exists.query(dirvar))
89         {
90             dir_exists.assign(dirvar, &defined);
91             print << "\n";
92             if (dotdot != ".")
93             {
94                 print << src_dir << "/.mkdir." << dir_suffix << ": "
95                     << dotdot << "/.mkdir." << dir_suffix << "\n";
96             }
97             else
98             {
99                 print << src_dir << "/.mkdir." << dir_suffix << ":\n";
100             }
101             print << "\t-$(INSTALL) -m 0755 -d " << dst_dir << "\n";
102             print << "\t-@touch $@\n";
103             print << "\t@sleep 1\n";
104             clean_files.push_back(src_dir + "/.mkdir." + dir_suffix);
105         }
106         src_dir = dotdot;
107         if (src_dir == ".")
108             break;
109         dst_dir = dirname(dst_dir);
110     }
111 }
112 
113 
114 void
per_file(const nstring & filename)115 process_tail::per_file(const nstring &filename)
116 {
117     nstring file(filename);
118     if (!file.starts_with("script/") && file.ends_with(".in"))
119     {
120         file = nstring(file.c_str(), file.size() - 3);
121         clean_files.push_back_unique(file);
122     }
123 
124     else if (file.starts_with("script/"))
125     {
126         if (file.ends_with(".in"))
127         {
128             nstring name = nstring(file.c_str(), file.size() - 3);
129             clean_files.push_back_unique(name);
130         }
131         nstring name = file.trim_extension().basename();
132         if (name != "aegis.synpic" && name != "ae-symlinks")
133         {
134             commands_bin.push_back("bin/" + name + "$(EXEEXT)");
135             clean_files.push_back("bin/" + name + "$(EXEEXT)");
136             if (!name.starts_with("test_"))
137             {
138                 nstring install_name = "$(DESTDIR)$(bindir)/"
139                     "$(PROGRAM_PREFIX)" + name + "$(PROGRAM_SUFFIX)$(EXEEXT)";
140                 commands_install.push_back(install_name);
141             }
142         }
143     }
144     else if (file.ends_with("/main.cc"))
145     {
146         nstring name(file.field('/', 0));
147         commands.push_back(name);
148         commands_bin.push_back("bin/" + name + "$(EXEEXT)");
149 
150         if
151         (
152             name != "aefp"
153         &&
154             name != "fmtgen"
155         &&
156             name != "aemakefile"
157         &&
158             !name.starts_with("test_")
159         )
160         {
161             commands_install.push_back(
162                 "$(DESTDIR)$(bindir)/$(PROGRAM_PREFIX)" + name +
163                 "$(PROGRAM_SUFFIX)$(EXEEXT)");
164         }
165     }
166 
167     if (file.ends_with(".cc"))
168     {
169         nstring dir(file.field('/', 0));
170         nstring_list *dir_p = dir_st.query(dir);
171         if (!dir_p)
172         {
173             dir_p = new nstring_list;
174             dir_st.assign(dir, dir_p);
175         }
176         nstring stem(file.c_str(), file.size() - 3);
177         nstring obj(stem + ".$(OBJEXT)");
178         dir_p->push_back(obj);
179         clean_files.push_back(obj);
180     }
181     else if (file.ends_with(".def"))
182     {
183         nstring dir(file.field('/', 0));
184         nstring_list *dir_p = dir_st.query(dir);
185         if (!dir_p)
186         {
187             dir_p = new nstring_list;
188             dir_st.assign(dir, dir_p);
189         }
190         nstring stem(file.c_str(), file.size() - 4);
191         nstring obj(stem + ".$(OBJEXT)");
192         dir_p->push_back(obj);
193         clean_files.push_back(obj);
194         clean_files.push_back(stem + ".cc");
195         clean_files.push_back(stem + ".h");
196     }
197     else if (file.ends_with(".y"))
198     {
199         nstring dir(file.field('/', 0));
200         nstring_list *dir_p = dir_st.query(dir);
201         if (!dir_p)
202         {
203             dir_p = new nstring_list;
204             dir_st.assign(dir, dir_p);
205         }
206         nstring stem(file.c_str(), file.size() - 2);
207         nstring obj(stem + ".yacc.$(OBJEXT)");
208         dir_p->push_back(obj);
209         clean_files.push_back(stem + ".yacc.cc");
210         clean_files.push_back(stem + ".yacc.h");
211         clean_files.push_back(obj);
212     }
213     else if (file.starts_with("lib/") && file.ends_with("/libaegis.po"))
214     {
215         // obsolete
216     }
217     else if (file.starts_with("lib/") && file.ends_with(".po"))
218     {
219         nstring stem = nstring(file.c_str() + 4, file.size() - 7);
220         nstring src("lib/" + stem + ".mo");
221         po_files.push_back(src);
222         clean_files.push_back(src);
223         nstring dst("$(DESTDIR)$(NLSDIR)/" + stem + ".mo");
224         install_po_files.push_back(dst);
225         recursive_mkdir(dirname(src), dirname(dst), "libdir");
226     }
227     else if (file.gmatch("lib/*.so"))
228     {
229         // documentation include file
230     }
231     else if (file.gmatch("lib/*.bib"))
232     {
233         // documentation include file
234     }
235     else if (file.gmatch("lib/icon2/*.uue"))
236     {
237         nstring stem(file.c_str() + 10, file.size() - 14);
238         nstring tmp = "lib/icon/" + stem;
239         nstring dst = "$(DESTDIR)$(datadir)/icon/" + stem;
240         datadir_files.push_back(dst);
241         recursive_mkdir(dirname(tmp), dirname(dst), "datadir");
242         clean_files.push_back(tmp);
243     }
244     else if (file.gmatch("lib/icon/*.uue"))
245     {
246         nstring stem(file.c_str() + 9, file.size() - 13);
247         nstring dst = "$(DESTDIR)$(datadir)/icon/" + stem;
248         datadir_files.push_back(dst);
249         recursive_mkdir(dirname(file), dirname(dst), "datadir");
250         clean_files.push_back("lib/icon/" + stem);
251     }
252     else if (file.gmatch("lib/*.uue"))
253     {
254         // do nothing
255     }
256     else if (file.gmatch("lib/*/man[1-9]/*.[1-9]"))
257     {
258         nstring stem = nstring(file.c_str() + 4, file.size() - 4);
259         install_doc_files.push_back("$(DESTDIR)$(datadir)/" + stem);
260         nstring src(file);
261         nstring dst("$(DESTDIR)$(datadir)/" + stem);
262         recursive_mkdir(dirname(src), dirname(dst), "datadir");
263         if (file.gmatch("lib/en/*"))
264         {
265             nstring part = nstring(file.c_str() + 7, file.size() - 7);
266             man_files.push_back("$(DESTDIR)$(mandir)/" + part);
267         }
268     }
269     else if (file.gmatch("lib/*/*/main.*"))
270     {
271         nstring stem = file.field('/', 1) + "/" + file.field('/', 2);
272         ps_doc_files.push_back("lib/" + stem + ".ps");
273         dvi_doc_files.push_back("lib/" + stem + ".dvi");
274         txt_doc_files.push_back("lib/" + stem + ".txt");
275         clean_files.push_back("lib/" + stem + ".ps");
276         clean_files.push_back("lib/" + stem + ".dvi");
277         clean_files.push_back("lib/" + stem + ".txt");
278         install_doc_files.push_back("$(DESTDIR)$(datadir)/" + stem
279             + ".ps");
280         install_doc_files.push_back("$(DESTDIR)$(datadir)/" + stem
281             + ".txt");
282         nstring src("lib/" + stem + ".ps");
283         nstring dst("$(DESTDIR)$(datadir)/" + stem + ".ps");
284         recursive_mkdir(dirname(src), dirname(dst), "datadir");
285     }
286     else if (file.starts_with("lib/"))
287     {
288         nstring rest(file.c_str() + 4, file.size() - 4);
289         nstring dst("$(DESTDIR)$(datadir)/" + rest);
290         datadir_files.push_back(dst);
291         recursive_mkdir(dirname(file), dirname(dst), "datadir");
292     }
293     else if (file.gmatch("test/*/*.sh"))
294     {
295         nstring stem(file.c_str(), file.size() - 3);
296         test_files.push_back(stem + ".ES");
297         clean_files.push_back(stem + ".ES");
298     }
299 }
300 
301 
302 void
postlude()303 process_tail::postlude()
304 {
305     commands_bin.sort();
306     print << "\n";
307     print << "all-bin: " << commands_bin << "\n";
308 
309     for (size_t j = 0; j < commands.size(); ++j)
310     {
311         nstring name(commands[j]);
312         nstring_list *dir_p = dir_st.query(name);
313         if (!dir_p)
314             continue;
315         print << "\n";
316         print << name << "_files = " << *dir_p << "\n";
317         print << "\n";
318 
319         if
320         (
321             name == "aemakefile"
322         ||
323             name == "aemeasure"
324         ||
325             name == "fmtgen"
326         )
327         {
328             print << "bin/" << name << "$(EXEEXT): $(" << name
329                 << "_files) common/common.$(LIBEXT) .bin\n"
330                 << "\t@sleep 1\n"
331                 << "\t$(CXX) $(LDFLAGS) -o $@ $(" << name
332                     << "_files) common/common.$(LIBEXT) $(LIBS)\n"
333                 << "\t@sleep 1\n";
334         }
335         else
336         {
337             print << "bin/" << name << "$(EXEEXT): $(" << name
338                 << "_files) libaegis/libaegis.$(LIBEXT) .bin\n";
339             print << "\t@sleep 1\n";
340             print << "\t$(CXX) $(LDFLAGS) -o $@ $(" << name
341                 << "_files) libaegis/libaegis.$(LIBEXT) $(LIBS)\n";
342             if (name == "aegis" || name == "aeimport" || name == "aelock")
343                 print << "\t-chown root $@ && chmod 4755 $@\n";
344             print << "\t@sleep 1\n";
345         }
346 
347         print << "\n";
348         print << "$(DESTDIR)$(bindir)/$(PROGRAM_PREFIX)" << name
349             << "$(PROGRAM_SUFFIX)$(EXEEXT): bin/" << name
350             << "$(EXEEXT) .bindir\n";
351         print << "\t$(INSTALL_PROGRAM) bin/" << name << "$(EXEEXT) $@\n";
352         if (name == "aegis" || name == "aeimport" || name == "aelock")
353             print << "\t-chown root $@ && chmod 4755 $@\n";
354     }
355 
356     print << "\nCommonFiles = " << *common_files << "\n";
357     print << "\nlibaegis_obj = " << *libaegis_files << " " << *common_files
358         << "\n";
359     print << "\nLibFiles = " << libdir_files << "\n";
360     print << "\nDataFiles = " << datadir_files << "\n";
361     print << "\ninstall-man-yes: " << man_files << "\n";
362 
363     print << "\n"
364         "uninstall-man:\n"
365         "\trm -f " << man_files << "\n";
366 
367     print << "\ninstall-man-no:\n";
368     print << "\npo_files_yes: " << po_files << "\n";
369     print << "\npo_files_no:\n";
370     print << "\ninstall-po-yes: " << install_po_files << "\n";
371 
372     print << "\n"
373         "uninstall-po:\n"
374         "\trm -f " << install_po_files << "\n";
375 
376     print << "\ninstall-po-no:\n";
377     print << "\ndvi-doc-files: " << dvi_doc_files << "\n";
378     print << "\ndoc_files_yes: " << ps_doc_files << " " << txt_doc_files
379         << "\n";
380     print << "\ndoc_files_no:\n";
381     print << "\ninstall-doc-yes: " << install_doc_files << "\n";
382 
383     print << "\n"
384         "uninstall-doc:\n"
385         "\trm -f " << install_doc_files << "\n";
386 
387     print << "\ninstall-doc-no:\n";
388     print << "\nTestFiles = " << test_files << "\n";
389 
390     //
391     // clean up the area
392     //  (make sure command lines do not get too long)
393     //
394     print << "\nclean-obj:\n";
395     clean_files.sort();
396     for (size_t m = 0; m < clean_files.size(); ++m)
397         print << "\trm -f " << clean_files[m] << "\n";
398 
399     print << "\nclean: clean-obj\n";
400     print << "\trm -f " << commands_bin << "\n";
401 
402     commands_install.sort();
403     print << "\ninstall-bin: " << commands_install << "\n";
404     print << "\n"
405         "uninstall-bin:\n"
406         "\trm -f " << commands_install << "\n";
407 
408     print << "\n"
409         ".bindir:\n"
410         "\t-$(INSTALL) -m 0755 -d $(DESTDIR)$(bindir)\n"
411         "\t-@touch $@\n"
412         "\t@sleep 1\n"
413         "\n"
414         ".man1dir:\n"
415         "\t-$(INSTALL) -m 0755 -d $(DESTDIR)$(mandir)/man1\n"
416         "\t-@touch $@\n"
417         "\t@sleep 1\n"
418         "\n"
419         ".man3dir:\n"
420         "\t-$(INSTALL) -m 0755 -d $(DESTDIR)$(mandir)/man3\n"
421         "\t-@touch $@\n"
422         "\t@sleep 1\n"
423         "\n"
424         ".man5dir:\n"
425         "\t-$(INSTALL) -m 0755 -d $(DESTDIR)$(mandir)/man5\n"
426         "\t-@touch $@\n"
427         "\t@sleep 1\n"
428         "\n"
429         ".comdir:\n"
430         "\t-$(INSTALL) -m 0755 -d $(DESTDIR)$(comdir)\n"
431         "\t-chown $(AEGIS_UID) $(DESTDIR)$(comdir) && "
432             "chgrp $(AEGIS_GID) $(DESTDIR)$(comdir)\n"
433         "\t$(SH) etc/compat.2.3\n"
434         "\t-@touch $@\n"
435         "\t@sleep 1\n"
436         "\n"
437         ".po_files: po_files_$(HAVE_MSGFMT)\n"
438         "\t@touch $@\n"
439         "\n"
440         ".doc_files: doc_files_$(HAVE_GROFF)\n"
441         "\t@touch $@\n"
442         "\n"
443         "distclean: clean\n"
444         "\trm -f config.status config.log config.cache\n"
445         "\trm -f Makefile common/config.h etc/howto.conf\n"
446         "\trm -f lib/cshrc lib/profile etc/libdir.so\n"
447         "\n"
448         ".bin:\n"
449         "\t-mkdir bin\n"
450         "\t-@touch $@\n"
451         "\n"
452         "common/common.$(LIBEXT): $(CommonFiles)\n"
453         "\trm -f $@\n"
454         "\t$(AR) qc $@ $(CommonFiles)\n"
455         "\t$(RANLIB) $@\n"
456         "\n"
457         "libaegis/libaegis.$(LIBEXT): $(libaegis_obj)\n"
458         "\trm -f $@\n"
459         "\t$(AR) qc $@ $(libaegis_obj)\n"
460         "\t$(RANLIB) $@\n"
461         "\n"
462         "sure: $(TestFiles) etc/test.sh\n"
463         "\t@$(SH) etc/test.sh -summary $(TestFiles)\n"
464         "\n"
465         "#\n"
466         "# This target is used when preparing for the second\n"
467         "# pass of testing, when aegis is set-uid-root.\n"
468         "#\n"
469         "install-libdir: lib/.mkdir.datadir lib/.mkdir.libdir .comdir "
470             "install-po\n"
471         "\t-chown root bin/aegis$(EXEEXT) "
472             "&& chmod 4755 bin/aegis$(EXEEXT)\n"
473         "\t-chown root bin/aeimport$(EXEEXT) "
474             "&& chmod 4755 bin/aeimport$(EXEEXT)\n"
475         "\n"
476         "install-lib: $(LibFiles) $(DataFiles) .comdir\n"
477         "\n"
478         "uninstall-lib:\n"
479         "\trm -f $(LibFiles) $(DataFiles)\n"
480         "\n"
481         "install-po: install-po-$(HAVE_MSGFMT)\n"
482         "\n"
483         "install-man: install-man-$(HAVE_GROFF)\n"
484         "\n"
485         "install-doc: install-doc-$(HAVE_GROFF)\n"
486         "\n"
487         "install: install-bin install-lib install-po install-man install-doc\n"
488         "\n"
489         "uninstall: uninstall-bin uninstall-lib uninstall-po uninstall-man "
490             "uninstall-doc\n";
491 }
492 
493 
494 // vim: set ts=8 sw=4 et :
495