Annotation of loncom/build/lpml_parse.pl, revision 1.20
1.1 harris41 1: #!/usr/bin/perl
1.2 albertel 2:
3: # Scott Harrison
1.4 harris41 4: # YEAR=2001
1.2 albertel 5: # May 2001
1.3 harris41 6: # 06/19/2001,06/20,06/24 - Scott Harrison
1.5 harris41 7: # 9/5/2001,9/6,9/7,9/8 - Scott Harrison
1.14 harris41 8: # 9/17,9/18 - Scott Harrison
1.18 harris41 9: # 11/4,11/5,11/6,11/7,11/16 - Scott Harrison
10: #
1.20 ! harris41 11: # $Id: lpml_parse.pl,v 1.19 2001/11/17 18:35:21 harris41 Exp $
1.18 harris41 12: ###
1.3 harris41 13:
1.4 harris41 14: ###############################################################################
15: ## ##
16: ## ORGANIZATION OF THIS PERL SCRIPT ##
17: ## 1. Notes ##
18: ## 2. Get command line arguments ##
19: ## 3. First pass through (grab distribution-specific information) ##
20: ## 4. Second pass through (parse out what is not necessary) ##
21: ## 5. Third pass through (translate markup according to specified mode) ##
1.14 harris41 22: ## 6. Functions (most all just format contents of different markup tags) ##
23: ## 7. POD (plain old documentation, CPAN style) ##
1.4 harris41 24: ## ##
25: ###############################################################################
26:
27: # ----------------------------------------------------------------------- Notes
28: #
1.3 harris41 29: # I am using a multiple pass-through approach to parsing
30: # the lpml file. This saves memory and makes sure the server
31: # will never be overloaded.
1.4 harris41 32: #
33: # This is meant to parse files meeting the lpml document type.
34: # See lpml.dtd. LPML=Linux Packaging Markup Language.
1.2 albertel 35:
1.1 harris41 36: use HTML::TokeParser;
1.2 albertel 37:
1.3 harris41 38: my $usage=<<END;
39: **** ERROR ERROR ERROR ERROR ****
40: Usage is for lpml file to come in through standard input.
41: 1st argument is the mode of parsing.
1.4 harris41 42: 2nd argument is the category permissions to use (runtime or development)
43: 3rd argument is the distribution (default,redhat6.2,debian2.2,redhat7.1,etc).
44: 4th argument is to manually specify a sourceroot.
45: 5th argument is to manually specify a targetroot.
1.3 harris41 46:
47: Only the 1st argument is mandatory for the program to run.
48:
49: Example:
50:
51: cat ../../doc/loncapafiles.lpml |\\
52: perl lpml_parse.pl html default /home/sherbert/loncapa /tmp/install
53: END
54:
55: # ------------------------------------------------- Grab command line arguments
56:
57: my $mode;
1.4 harris41 58: if (@ARGV==5) {
1.3 harris41 59: $mode = shift @ARGV;
60: }
61: else {
1.4 harris41 62: @ARGV=();shift @ARGV;
1.3 harris41 63: while(<>){} # throw away the input to avoid broken pipes
64: print $usage;
65: exit -1; # exit with error status
66: }
67:
1.4 harris41 68: my $categorytype;
69: if (@ARGV) {
70: $categorytype = shift @ARGV;
71: }
72:
1.3 harris41 73: my $dist;
74: if (@ARGV) {
75: $dist = shift @ARGV;
76: }
1.2 albertel 77:
1.3 harris41 78: my $targetroot;
79: my $sourceroot;
80: if (@ARGV) {
1.4 harris41 81: $sourceroot = shift @ARGV;
1.3 harris41 82: }
83: if (@ARGV) {
1.4 harris41 84: $targetroot = shift @ARGV;
1.3 harris41 85: }
1.4 harris41 86: $sourceroot=~s/\/$//;
87: $targetroot=~s/\/$//;
1.3 harris41 88:
1.19 harris41 89: my $logcmd='| tee -a WARNINGS';
90:
1.5 harris41 91: my $invocation;
92: # --------------------------------------------------- Record program invocation
1.17 harris41 93: if ($mode eq 'install' or $mode eq 'configinstall' or $mode eq 'build') {
1.5 harris41 94: $invocation=(<<END);
95: # Invocation: STDINPUT | lpml_parse.pl
96: # 1st argument (mode) is: $mode
97: # 2nd argument (category type) is: $categorytype
98: # 3rd argument (distribution) is: $dist
99: # 4th argument (targetroot) is: described below
100: # 5th argument (sourceroot) is: described below
101: END
102: }
103:
1.3 harris41 104: # ---------------------------------------------------- Start first pass through
1.2 albertel 105: my @parsecontents = <>;
106: my $parsestring = join('',@parsecontents);
107: my $outstring;
108:
1.3 harris41 109: # Need to make a pass through and figure out what defaults are
110: # overrided. Top-down overriding strategy (leaves don't know
111: # about distant leaves).
112:
113: my @hierarchy;
114: $hierarchy[0]=0;
115: my $hloc=0;
116: my $token;
117: $parser = HTML::TokeParser->new(\$parsestring) or
118: die('can\'t create TokeParser object');
119: $parser->xml_mode('1');
120: my %hash;
121: my $key;
122: while ($token = $parser->get_token()) {
123: if ($token->[0] eq 'S') {
124: $hloc++;
125: $hierarchy[$hloc]++;
126: $key=$token->[1].join(',',@hierarchy[0..($hloc-1)]);
127: my $thisdist=' '.$token->[2]{'dist'}.' ';
128: if ($thisdist eq ' default ') {
129: $hash{$key}=1; # there is a default setting for this key
130: }
131: elsif ($dist && $hash{$key}==1 && $thisdist=~/\s$dist\s/) {
132: $hash{$key}=2; # disregard default setting for this key if
133: # there is a directly requested distribution match
134: }
135: }
136: if ($token->[0] eq 'E') {
137: $hloc--;
138: }
139: }
140:
141: # --------------------------------------------------- Start second pass through
142: undef $hloc;
143: undef @hierarchy;
144: undef $parser;
145: $hierarchy[0]=0;
146: $parser = HTML::TokeParser->new(\$parsestring) or
147: die('can\'t create TokeParser object');
148: $parser->xml_mode('1');
149: my $cleanstring;
150: while ($token = $parser->get_token()) {
151: if ($token->[0] eq 'S') {
152: $hloc++;
153: $hierarchy[$hloc]++;
154: $key=$token->[1].join(',',@hierarchy[0..($hloc-1)]);
155: my $thisdist=' '.$token->[2]{'dist'}.' ';
1.4 harris41 156: # This conditional clause is set up to ignore two sets
157: # of invalid conditions before accepting entry into
158: # the cleanstring.
1.3 harris41 159: if ($hash{$key}==2 and
160: !($thisdist eq ' ' or $thisdist =~/\s$dist\s/)) {
161: if ($token->[4]!~/\/>$/) {
162: $parser->get_tag('/'.$token->[1]);
163: $hloc--;
164: }
165: }
166: elsif ($thisdist ne ' ' and $thisdist!~/\s$dist\s/ and
167: !($thisdist eq ' default ' and $hash{$key}!=2)) {
168: if ($token->[4]!~/\/>$/) {
169: $parser->get_tag('/'.$token->[1]);
170: $hloc--;
171: }
172: }
173: else {
174: $cleanstring.=$token->[4];
175: }
176: if ($token->[4]=~/\/>$/) {
177: $hloc--;
178: }
179: }
180: if ($token->[0] eq 'E') {
181: $cleanstring.=$token->[2];
182: $hloc--;
183: }
184: if ($token->[0] eq 'T') {
185: $cleanstring.=$token->[1];
186: }
187: }
188: $cleanstring=&trim($cleanstring);
1.10 harris41 189: $cleanstring=~s/\>\s*\n\s*\</\>\</g;
190:
1.3 harris41 191: # ---------------------------------------------------- Start final pass through
192:
193: # storage variables
194: my $lpml;
195: my $categories;
196: my $category;
197: my $category_att_name;
198: my $category_att_type;
199: my $chown;
200: my $chmod;
201: my $rpm;
202: my $rpmSummary;
203: my $rpmName;
204: my $rpmVersion;
205: my $rpmRelease;
206: my $rpmVendor;
207: my $rpmBuildRoot;
208: my $rpmCopyright;
209: my $rpmGroup;
210: my $rpmSource;
211: my $rpmAutoReqProv;
212: my $rpmdescription;
213: my $rpmpre;
214: my $directories;
215: my $directory;
216: my $targetdirs;
217: my $targetdir;
218: my $categoryname;
219: my $description;
220: my $files;
221: my $fileglobs;
222: my $links;
223: my $file;
224: my $link;
225: my $fileglob;
226: my $sourcedir;
227: my $targets;
228: my $target;
229: my $source;
230: my $note;
231: my $build;
1.14 harris41 232: my $buildlink;
1.3 harris41 233: my $commands;
234: my $command;
235: my $status;
236: my $dependencies;
237: my $dependency;
1.4 harris41 238: my @links;
239: my %categoryhash;
1.3 harris41 240:
1.11 harris41 241: my @buildall;
1.12 harris41 242: my @buildinfo;
243:
244: my @configall;
1.11 harris41 245:
1.3 harris41 246: # Make new parser with distribution specific input
247: undef $parser;
248: $parser = HTML::TokeParser->new(\$cleanstring) or
249: die('can\'t create TokeParser object');
250: $parser->xml_mode('1');
251:
252: # Define handling methods for mode-dependent text rendering
253: $parser->{textify}={
254: targetroot => \&format_targetroot,
255: sourceroot => \&format_sourceroot,
256: categories => \&format_categories,
257: category => \&format_category,
258: targetdir => \&format_targetdir,
259: chown => \&format_chown,
260: chmod => \&format_chmod,
261: rpm => \&format_rpm,
262: rpmSummary => \&format_rpmSummary,
263: rpmName => \&format_rpmName,
264: rpmVersion => \&format_rpmVersion,
265: rpmRelease => \&format_rpmRelease,
266: rpmVendor => \&format_rpmVendor,
267: rpmBuildRoot => \&format_rpmBuildRoot,
268: rpmCopyright => \&format_rpmCopyright,
269: rpmGroup => \&format_rpmGroup,
270: rpmSource => \&format_rpmSource,
271: rpmAutoReqProv => \&format_rpmAutoReqProv,
272: rpmdescription => \&format_rpmdescription,
273: rpmpre => \&format_rpmpre,
274: directories => \&format_directories,
275: directory => \&format_directory,
276: categoryname => \&format_categoryname,
277: description => \&format_description,
278: files => \&format_files,
279: file => \&format_file,
280: fileglob => \&format_fileglob,
1.4 harris41 281: links => \&format_links,
1.3 harris41 282: link => \&format_link,
283: linkto => \&format_linkto,
284: source => \&format_source,
285: target => \&format_target,
286: note => \&format_note,
287: build => \&format_build,
288: status => \&format_status,
289: dependencies => \&format_dependencies,
1.14 harris41 290: buildlink => \&format_buildlink,
1.3 harris41 291: glob => \&format_glob,
292: sourcedir => \&format_sourcedir,
293: filenames => \&format_filenames,
294: };
295:
296: my $text;
297: my $token;
298: undef $hloc;
299: undef @hierarchy;
300: my $hloc;
301: my @hierarchy2;
302: while ($token = $parser->get_tag('lpml')) {
303: &format_lpml(@{$token});
304: $text = &trim($parser->get_text('/lpml'));
305: $token = $parser->get_tag('/lpml');
306: print $lpml;
307: print "\n";
1.4 harris41 308: # $text=~s/\s*\n\s*\n\s*/\n/g;
1.3 harris41 309: print $text;
310: print "\n";
311: print &end();
312: }
313: exit;
314:
1.14 harris41 315: # ---------- Functions (most all just format contents of different markup tags)
316:
317: # ------------------------ Final output at end of markup parsing and formatting
1.3 harris41 318: sub end {
319: if ($mode eq 'html') {
1.10 harris41 320: return "<br />THE END\n";
1.3 harris41 321: }
1.4 harris41 322: if ($mode eq 'install') {
323: return '';
324: }
1.3 harris41 325: }
326:
327: # ----------------------- Take in string to parse and the separation expression
328: sub extract_array {
329: my ($stringtoparse,$sepexp) = @_;
330: my @a=split(/$sepexp/,$stringtoparse);
331: return \@a;
332: }
333:
334: # --------------------------------------------------------- Format lpml section
335: sub format_lpml {
336: my (@tokeninfo)=@_;
337: my $date=`date`; chop $date;
338: if ($mode eq 'html') {
1.10 harris41 339: $lpml = "<br />LPML BEGINNING: $date";
1.3 harris41 340: }
1.4 harris41 341: elsif ($mode eq 'install') {
342: print '# LPML install targets. Linux Packaging Markup Language,';
343: print ' by Scott Harrison 2001'."\n";
344: print '# This file was automatically generated on '.`date`;
1.5 harris41 345: print "\n".$invocation;
1.14 harris41 346: $lpml .= "SHELL=\"/bin/bash\"\n\n";
1.4 harris41 347: }
1.16 harris41 348: elsif ($mode eq 'configinstall') {
1.17 harris41 349: print '# LPML configuration file targets (configinstall).'."\n";
350: print '# Linux Packaging Markup Language,';
1.16 harris41 351: print ' by Scott Harrison 2001'."\n";
352: print '# This file was automatically generated on '.`date`;
353: print "\n".$invocation;
354: $lpml .= "SHELL=\"/bin/bash\"\n\n";
355: }
1.11 harris41 356: elsif ($mode eq 'build') {
1.14 harris41 357: $lpml = "# LPML build targets. Linux Packaging Markup Language,";
358: $lpml .= ' by Scott Harrison 2001'."\n";
1.11 harris41 359: $lpml .= '# This file was automatically generated on '.`date`;
1.17 harris41 360: $lpml .= "\n".$invocation;
1.11 harris41 361: $lpml .= "SHELL=\"/bin/sh\"\n\n";
362: }
1.4 harris41 363: else {
364: return '';
365: }
1.3 harris41 366: }
367: # --------------------------------------------------- Format targetroot section
368: sub format_targetroot {
369: my $text=&trim($parser->get_text('/targetroot'));
370: $text=$targetroot if $targetroot;
371: $parser->get_tag('/targetroot');
372: if ($mode eq 'html') {
1.10 harris41 373: return $targetroot="\n<br />TARGETROOT: $text";
1.3 harris41 374: }
1.17 harris41 375: elsif ($mode eq 'install' or $mode eq 'build' or
376: $mode eq 'configinstall') {
1.11 harris41 377: return '# TARGET INSTALL LOCATION is "'.$targetroot."\"\n";
378: }
1.3 harris41 379: else {
380: return '';
381: }
382: }
383: # --------------------------------------------------- Format sourceroot section
384: sub format_sourceroot {
385: my $text=&trim($parser->get_text('/sourceroot'));
386: $text=$sourceroot if $sourceroot;
387: $parser->get_tag('/sourceroot');
388: if ($mode eq 'html') {
1.10 harris41 389: return $sourceroot="\n<br />SOURCEROOT: $text";
1.3 harris41 390: }
1.17 harris41 391: elsif ($mode eq 'install' or $mode eq 'build' or
392: $mode eq 'configinstall') {
1.11 harris41 393: return '# SOURCE CODE LOCATION IS "'.$sourceroot."\"\n";;
394: }
1.3 harris41 395: else {
396: return '';
397: }
398: }
399: # --------------------------------------------------- Format categories section
400: sub format_categories {
401: my $text=&trim($parser->get_text('/categories'));
402: $parser->get_tag('/categories');
403: if ($mode eq 'html') {
1.10 harris41 404: return $categories="\n<br />BEGIN CATEGORIES\n$text\n".
405: "<br />END CATEGORIES\n";
1.3 harris41 406: }
407: else {
408: return '';
409: }
410: }
411: # --------------------------------------------------- Format categories section
412: sub format_category {
413: my (@tokeninfo)=@_;
414: $category_att_name=$tokeninfo[2]->{'name'};
415: $category_att_type=$tokeninfo[2]->{'type'};
416: $chmod='';$chown='';
417: $parser->get_text('/category');
418: $parser->get_tag('/category');
419: if ($mode eq 'html') {
1.10 harris41 420: return $category="\n<br />CATEGORY $category_att_name ".
421: "$category_att_type $chmod $chown";
1.3 harris41 422: }
423: else {
1.4 harris41 424: if ($category_att_type eq $categorytype) {
425: my ($user,$group)=split(/\:/,$chown);
426: $categoryhash{$category_att_name}='-o '.$user.' -g '.$group.
427: ' -m '.$chmod;
428: }
1.3 harris41 429: return '';
430: }
431: }
432: # -------------------------------------------------------- Format chown section
433: sub format_chown {
434: my @tokeninfo=@_;
435: $chown='';
436: my $text=&trim($parser->get_text('/chown'));
437: if ($text) {
438: $parser->get_tag('/chown');
439: $chown=$text;
440: }
441: return '';
442: }
443: # -------------------------------------------------------- Format chmod section
444: sub format_chmod {
445: my @tokeninfo=@_;
446: $chmod='';
447: my $text=&trim($parser->get_text('/chmod'));
448: if ($text) {
449: $parser->get_tag('/chmod');
450: $chmod=$text;
451: }
452: return '';
453: }
454: # ---------------------------------------------------------- Format rpm section
455: sub format_rpm {
456: my $text=&trim($parser->get_text('/rpm'));
457: $parser->get_tag('/rpm');
458: if ($mode eq 'html') {
1.10 harris41 459: return $rpm="\n<br />BEGIN RPM\n$text\n<br />END RPM";
1.3 harris41 460: }
461: else {
462: return '';
463: }
464: }
465: # --------------------------------------------------- Format rpmSummary section
466: sub format_rpmSummary {
467: my $text=&trim($parser->get_text('/rpmSummary'));
468: $parser->get_tag('/rpmSummary');
469: if ($mode eq 'html') {
1.10 harris41 470: return $rpmSummary="\n<br />RPMSUMMARY $text";
1.3 harris41 471: }
472: else {
473: return '';
474: }
475: }
476: # ------------------------------------------------------ Format rpmName section
477: sub format_rpmName {
478: my $text=&trim($parser->get_text('/rpmName'));
479: $parser->get_tag('/rpmName');
480: if ($mode eq 'html') {
1.10 harris41 481: return $rpmName="\n<br />RPMNAME $text";
1.3 harris41 482: }
483: else {
484: return '';
485: }
486: }
487: # --------------------------------------------------- Format rpmVersion section
488: sub format_rpmVersion {
489: my $text=$parser->get_text('/rpmVersion');
490: $parser->get_tag('/rpmVersion');
491: if ($mode eq 'html') {
1.10 harris41 492: return $rpmVersion="\n<br />RPMVERSION $text";
1.3 harris41 493: }
494: else {
495: return '';
496: }
497: }
498: # --------------------------------------------------- Format rpmRelease section
499: sub format_rpmRelease {
500: my $text=$parser->get_text('/rpmRelease');
501: $parser->get_tag('/rpmRelease');
502: if ($mode eq 'html') {
1.10 harris41 503: return $rpmRelease="\n<br />RPMRELEASE $text";
1.3 harris41 504: }
505: else {
506: return '';
507: }
508: }
509: # ---------------------------------------------------- Format rpmVendor section
510: sub format_rpmVendor {
511: my $text=$parser->get_text('/rpmVendor');
512: $parser->get_tag('/rpmVendor');
513: if ($mode eq 'html') {
1.10 harris41 514: return $rpmVendor="\n<br />RPMVENDOR $text";
1.3 harris41 515: }
516: else {
517: return '';
518: }
519: }
520: # ------------------------------------------------- Format rpmBuildRoot section
521: sub format_rpmBuildRoot {
522: my $text=$parser->get_text('/rpmBuildRoot');
523: $parser->get_tag('/rpmBuildRoot');
524: if ($mode eq 'html') {
1.10 harris41 525: return $rpmBuildRoot="\n<br />RPMBUILDROOT $text";
1.3 harris41 526: }
527: else {
528: return '';
529: }
530: }
531: # ------------------------------------------------- Format rpmCopyright section
532: sub format_rpmCopyright {
533: my $text=$parser->get_text('/rpmCopyright');
534: $parser->get_tag('/rpmCopyright');
535: if ($mode eq 'html') {
1.10 harris41 536: return $rpmCopyright="\n<br />RPMCOPYRIGHT $text";
1.3 harris41 537: }
538: else {
539: return '';
540: }
541: }
542: # ----------------------------------------------------- Format rpmGroup section
543: sub format_rpmGroup {
544: my $text=$parser->get_text('/rpmGroup');
545: $parser->get_tag('/rpmGroup');
546: if ($mode eq 'html') {
1.10 harris41 547: return $rpmGroup="\n<br />RPMGROUP $text";
1.3 harris41 548: }
549: else {
550: return '';
551: }
552: }
553: # ---------------------------------------------------- Format rpmSource section
554: sub format_rpmSource {
555: my $text=$parser->get_text('/rpmSource');
556: $parser->get_tag('/rpmSource');
557: if ($mode eq 'html') {
1.10 harris41 558: return $rpmSource="\n<br />RPMSOURCE $text";
1.3 harris41 559: }
560: else {
561: return '';
562: }
563: }
564: # ----------------------------------------------- Format rpmAutoReqProv section
565: sub format_rpmAutoReqProv {
566: my $text=$parser->get_text('/rpmAutoReqProv');
567: $parser->get_tag('/rpmAutoReqProv');
568: if ($mode eq 'html') {
1.10 harris41 569: return $rpmAutoReqProv="\n<br />RPMAUTOREQPROV $text";
1.3 harris41 570: }
571: else {
572: return '';
573: }
574: }
575: # ----------------------------------------------- Format rpmdescription section
576: sub format_rpmdescription {
577: my $text=$parser->get_text('/rpmdescription');
578: $parser->get_tag('/rpmdescription');
579: if ($mode eq 'html') {
1.10 harris41 580: return $rpmdescription="\n<br />RPMDESCRIPTION $text";
1.3 harris41 581: }
582: else {
583: return '';
584: }
585: }
586: # ------------------------------------------------------- Format rpmpre section
587: sub format_rpmpre {
588: my $text=$parser->get_text('/rpmpre');
589: $parser->get_tag('/rpmpre');
590: if ($mode eq 'html') {
1.10 harris41 591: return $rpmpre="\n<br />RPMPRE $text";
1.3 harris41 592: }
593: else {
594: return '';
595: }
596: }
597: # -------------------------------------------------- Format directories section
598: sub format_directories {
1.4 harris41 599: my $text=$parser->get_text('/directories');
1.3 harris41 600: $parser->get_tag('/directories');
601: if ($mode eq 'html') {
1.10 harris41 602: return $directories="\n<br />BEGIN DIRECTORIES\n$text\n<br />".
603: "END DIRECTORIES\n";
1.3 harris41 604: }
1.4 harris41 605: elsif ($mode eq 'install') {
606: return "\n".'directories:'."\n".$text;
607: }
1.3 harris41 608: else {
609: return '';
610: }
611: }
612: # ---------------------------------------------------- Format directory section
613: sub format_directory {
614: my (@tokeninfo)=@_;
615: $targetdir='';$categoryname='';$description='';
616: $parser->get_text('/directory');
617: $parser->get_tag('/directory');
618: if ($mode eq 'html') {
1.10 harris41 619: return $directory="\n<br />DIRECTORY $targetdir $categoryname ".
620: "$description";
1.3 harris41 621: }
1.4 harris41 622: elsif ($mode eq 'install') {
1.8 harris41 623: return "\t".'install '.$categoryhash{$categoryname}.' -d '.
624: $targetroot.'/'.$targetdir."\n";
1.4 harris41 625: }
1.3 harris41 626: else {
627: return '';
628: }
629: }
630: # ---------------------------------------------------- Format targetdir section
631: sub format_targetdir {
632: my @tokeninfo=@_;
633: $targetdir='';
634: my $text=&trim($parser->get_text('/targetdir'));
635: if ($text) {
636: $parser->get_tag('/targetdir');
637: $targetdir=$text;
638: }
639: return '';
640: }
641: # ------------------------------------------------- Format categoryname section
642: sub format_categoryname {
643: my @tokeninfo=@_;
644: $categoryname='';
645: my $text=&trim($parser->get_text('/categoryname'));
646: if ($text) {
647: $parser->get_tag('/categoryname');
648: $categoryname=$text;
649: }
650: return '';
651: }
652: # -------------------------------------------------- Format description section
653: sub format_description {
654: my @tokeninfo=@_;
655: $description='';
1.10 harris41 656: my $text=&htmlsafe(&trim($parser->get_text('/description')));
1.3 harris41 657: if ($text) {
658: $parser->get_tag('/description');
659: $description=$text;
660: }
661: return '';
662: }
663: # -------------------------------------------------------- Format files section
664: sub format_files {
1.4 harris41 665: my $text=$parser->get_text('/files');
1.3 harris41 666: $parser->get_tag('/files');
667: if ($mode eq 'html') {
1.10 harris41 668: return $directories="\n<br />BEGIN FILES\n$text\n<br />END FILES\n";
1.3 harris41 669: }
1.4 harris41 670: elsif ($mode eq 'install') {
671: return "\n".'files:'."\n".$text.
672: "\n".'links:'."\n".join('',@links);
673: }
1.12 harris41 674: elsif ($mode eq 'configinstall') {
675: return "\n".'configfiles: '.
676: join(' ',@configall).
1.14 harris41 677: "\n\n".$text.
678: "\n\nalwaysrun:\n\n";
1.12 harris41 679: }
1.11 harris41 680: elsif ($mode eq 'build') {
681: my $binfo;
682: my $tword;
683: my $command2;
684: my @deps;
685: foreach my $bi (@buildinfo) {
1.14 harris41 686: my ($target,$source,$command,$trigger,@deps)=split(/\;/,$bi);
1.11 harris41 687: $tword=''; $tword=' alwaysrun' if $trigger eq 'always run';
688: $command=~s/\/([^\/]*)$//;
689: $command2="cd $command; sh ./$1;\\";
690: my $depstring;
1.14 harris41 691: my $depstring2="\t\t\@echo '';\\\n";
692: my $olddep;
1.11 harris41 693: foreach my $dep (@deps) {
1.14 harris41 694: unless ($olddep) {
695: $olddep=$deps[$#deps];
696: }
1.11 harris41 697: $depstring.="\telif !(test -r $command/$dep);\\\n";
698: $depstring.="\t\tthen echo ".
1.14 harris41 699: "\"**** WARNING **** missing the file: ".
1.19 harris41 700: "$command/$dep\"$logcmd;\\\n";
1.14 harris41 701: $depstring.="\t\ttest -e $source || test -e $target || echo ".
702: "'**** ERROR **** neither source=$source nor target=".
1.19 harris41 703: "$target exist and they cannot be built'$logcmd;\\\n";
1.14 harris41 704: $depstring.="\t\tmake -f Makefile.build ${source}___DEPS;\\\n";
705: if ($olddep) {
706: $depstring2.="\t\tECODE=0;\\\n";
707: $depstring2.="\t\t! test -e $source && test -r $command/$olddep &&".
1.19 harris41 708: " { perl filecompare.pl -b2 $command/$olddep $target || ECODE=\$\$?; } && { [ \$\$ECODE != \"2\" ] || echo \"**** WARNING **** dependency $command/$olddep is newer than target file $target; SOMETHING MAY BE WRONG\"$logcmd; };\\\n";
1.14 harris41 709: }
710: $olddep=$dep;
1.11 harris41 711: }
712: $binfo.="$source: $tword\n".
713: "\t\@if !(echo \"\");\\\n\t\tthen echo ".
1.14 harris41 714: "\"**** WARNING **** Strange shell. ".
1.19 harris41 715: "Check your path settings.\"$logcmd;\\\n".
1.11 harris41 716: $depstring.
717: "\telse \\\n\t\t$command2\n\tfi\n\n";
1.14 harris41 718: $binfo.="${source}___DEPS:\n".$depstring2."\t\tECODE=0;\n\n";
1.11 harris41 719: }
720: return 'all: '.join(' ',@buildall)."\n\n".
721: $text.
722: $binfo."\n".
723: "alwaysrun:\n\n";
724: }
1.3 harris41 725: else {
726: return '';
727: }
728: }
729: # ---------------------------------------------------- Format fileglobs section
730: sub format_fileglobs {
731:
732: }
733: # -------------------------------------------------------- Format links section
1.4 harris41 734: # deprecated.. currently <link></link>'s are included in <files></files>
1.3 harris41 735: sub format_links {
1.4 harris41 736: my $text=$parser->get_text('/links');
737: $parser->get_tag('/links');
738: if ($mode eq 'html') {
1.10 harris41 739: return $links="\n<br />BEGIN LINKS\n$text\n<br />END LINKS\n";
1.4 harris41 740: }
741: elsif ($mode eq 'install') {
742: return "\n".'links:'."\n\t".$text;
743: }
744: else {
745: return '';
746: }
1.1 harris41 747: }
1.3 harris41 748: # --------------------------------------------------------- Format file section
749: sub format_file {
750: my @tokeninfo=@_;
751: $file=''; $source=''; $target=''; $categoryname=''; $description='';
752: $note=''; $build=''; $status=''; $dependencies='';
753: my $text=&trim($parser->get_text('/file'));
1.14 harris41 754: my $buildtest;
1.3 harris41 755: if ($source) {
756: $parser->get_tag('/file');
757: if ($mode eq 'html') {
1.10 harris41 758: return ($file="\n<br />BEGIN FILE\n".
1.3 harris41 759: "$source $target $categoryname $description $note " .
760: "$build $status $dependencies" .
761: "\nEND FILE");
762: }
1.5 harris41 763: elsif ($mode eq 'install' && $categoryname ne 'conf') {
1.14 harris41 764: if ($build) {
765: my $bi=$sourceroot.'/'.$source.';'.$build.';'.
766: $dependencies;
767: my ($source2,$command,$trigger,@deps)=split(/\;/,$bi);
768: $tword=''; $tword=' alwaysrun' if $trigger eq 'always run';
769: $command=~s/\/([^\/]*)$//;
770: $command2="cd $command; sh ./$1;\\";
771: my $depstring;
772: foreach my $dep (@deps) {
773: $depstring.=<<END;
774: ECODE=0; DEP=''; \\
1.19 harris41 775: test -e $command/$dep || (echo '**** WARNING **** cannot evaluate status of dependency $command/$dep (for building ${sourceroot}/${source} with)'$logcmd); DEP="1"; \\
1.18 harris41 776: [ -n DEP ] && { perl filecompare.pl -b2 $command/$dep ${targetroot}/${target} || ECODE=\$\$?; } || DEP="1"; \\
1.14 harris41 777: case "\$\$ECODE" in \\
1.19 harris41 778: 2) echo "**** WARNING **** dependency $command/$dep is newer than target file ${targetroot}/${target}; you may want to run make build"$logcmd;; \\
1.14 harris41 779: esac; \\
780: END
781: }
782: chomp $depstring;
783: $buildtest=<<END;
784: \@if !(test -e "${sourceroot}/${source}") && !(test -e "${targetroot}/${target}"); then \\
1.19 harris41 785: echo "**** ERROR **** ${sourceroot}/${source} is missing and is also not present at target location ${targetroot}/${target}; you must run make build"$logcmd; exit; \\
1.14 harris41 786: END
787: $buildtest.=<<END if $depstring;
788: elif !(test -e "${sourceroot}/${source}"); then \\
789: $depstring
790: END
791: $buildtest.=<<END;
792: fi
793: END
794: }
1.18 harris41 795: my $bflag='-b1';
796: $bflag='-b3' if $dependencies or $buildlink;
1.14 harris41 797: return <<END;
1.19 harris41 798: $buildtest \@if !(test -e "${sourceroot}/${source}") && !(test -e "${targetroot}/${target}"); then \\
799: echo "**** ERROR **** CVS source file does not exist: ${sourceroot}/${source} and neither does target: ${targetroot}/${target}"$logcmd; \\
800: elif !(test -e "${sourceroot}/${source}"); then \\
801: echo "**** WARNING **** CVS source file does not exist: ${sourceroot}/${source}"$logcmd; \\
1.14 harris41 802: else \\
803: ECODE=0; \\
804: perl filecompare.pl $bflag ${sourceroot}/${source} ${targetroot}/${target} || ECODE=\$\$?; \\
805: case "\$\$ECODE" in \\
806: 1) echo "${targetroot}/${target} is unchanged";; \\
1.19 harris41 807: 2) echo "**** WARNING **** target file ${targetroot}/${target} is newer than CVS source; creating ${targetroot}/${target}.lpmlnewfile instead"$logcmd && install -o www -g www -m 0500 ${sourceroot}/${source} ${targetroot}/${target}.lpmlnewfile;; \\
1.14 harris41 808: 0) echo "install -o www -g www -m 0500 ${sourceroot}/${source} ${targetroot}/${target}" && install -o www -g www -m 0500 ${sourceroot}/${source} ${targetroot}/${target};; \\
809: esac; \\
810: fi
811: END
812: # return "\t".'@test -e '.$sourceroot.'/'.$source.
813: # ' && perl filecompare.pl -b '.$sourceroot.'/'.$source.' '.
814: # $targetroot.'/'.$target.
815: # ' && install '.
816: # $categoryhash{$categoryname}.' '.
817: # $sourceroot.'/'.$source.' '.
818: # $targetroot.'/'.$target.
1.19 harris41 819: # ' || echo "**** WARNING '.
1.14 harris41 820: # '**** CVS source file does not exist: '.$sourceroot.'/'.
821: # $source.'"'."\n";
1.12 harris41 822: }
823: elsif ($mode eq 'configinstall' && $categoryname eq 'conf') {
824: push @configall,$targetroot.'/'.$target;
1.14 harris41 825: return $targetroot.'/'.$target.': alwaysrun'."\n".
1.20 ! harris41 826: "\t".'@echo -n ""; ECODE=0 && { perl filecompare.pl -b4 '.
! 827: $sourceroot.'/'.$source.' '.$targetroot.'/'.$target.
! 828: ' || ECODE=$$?; } && '.
! 829: '{ [ $$ECODE != "2" ] || (install '.
! 830: $categoryhash{$categoryname}.' '.
1.12 harris41 831: $sourceroot.'/'.$source.' '.
832: $targetroot.'/'.$target.'.lpmlnewconf'.
1.19 harris41 833: ' && echo "**** NOTE: CONFIGURATION FILE CHANGE ****"'.
834: $logcmd.' && echo "'.
1.14 harris41 835: 'You likely need to compare contents of '.
836: ''.$targetroot.'/'.$target.' with the new '.
837: ''.$targetroot.'/'.$target.'.lpmlnewconf"'.
1.20 ! harris41 838: "$logcmd); } && ".
! 839: '{ [ $$ECODE != "3" ] || (install '.
! 840: $categoryhash{$categoryname}.' '.
! 841: $sourceroot.'/'.$source.' '.
! 842: $targetroot.'/'.$target.''.
! 843: ' && echo "**** WARNING: NEW CONFIGURATION FILE ADDED ****"'.
! 844: $logcmd.' && echo "'.
! 845: 'You likely need to review the contents of '.
! 846: ''.$targetroot.'/'.$target.' to make sure its '.
! 847: 'settings are compatible with your overall system"'.
! 848: "$logcmd); } && ".
! 849: '{ [ $$ECODE != "1" ] || ('.
! 850: 'echo "**** ERROR ****"'.
! 851: $logcmd.' && echo "'.
! 852: 'Configuration source file does not exist '.
! 853: ''.$sourceroot.'/'.$source.'"'.
1.19 harris41 854: "$logcmd); };\n\n";
1.4 harris41 855: }
1.11 harris41 856: elsif ($mode eq 'build' && $build) {
857: push @buildall,$sourceroot.'/'.$source;
1.14 harris41 858: push @buildinfo,$targetroot.'/'.$target.';'.$sourceroot.'/'.
859: $source.';'.$build.';'.
1.11 harris41 860: $dependencies;
861: # return '# need to build '.$source.";
862: }
1.3 harris41 863: else {
864: return '';
865: }
866: }
867: return '';
868: }
869: # --------------------------------------------------------- Format link section
870: sub format_link {
871: my @tokeninfo=@_;
872: $link=''; $linkto=''; $target=''; $categoryname=''; $description='';
873: $note=''; $build=''; $status=''; $dependencies='';
874: my $text=&trim($parser->get_text('/link'));
875: if ($linkto) {
876: $parser->get_tag('/link');
877: if ($mode eq 'html') {
1.10 harris41 878: return $link="\n<br />BEGIN LINK\n".
1.3 harris41 879: "$linkto $target $categoryname $description $note " .
880: "$build $status $dependencies" .
881: "\nEND LINK";
1.4 harris41 882: }
883: elsif ($mode eq 'install') {
1.10 harris41 884: my @targets=map {s/^\s*//;s/\s$//;$_} split(/\;/,$target);
1.5 harris41 885: foreach my $tgt (@targets) {
886: push @links,"\t".'ln -fs /'.$linkto.' /'.$targetroot.$tgt.
887: "\n";
888: }
1.4 harris41 889: return '';
1.3 harris41 890: }
891: else {
892: return '';
893: }
894: }
895: return '';
896: }
897: # ----------------------------------------------------- Format fileglob section
898: sub format_fileglob {
899: my @tokeninfo=@_;
900: $fileglob=''; $glob=''; $sourcedir='';
901: $targetdir=''; $categoryname=''; $description='';
902: $note=''; $build=''; $status=''; $dependencies='';
903: $filenames='';
904: my $text=&trim($parser->get_text('/fileglob'));
905: if ($sourcedir) {
906: $parser->get_tag('/fileglob');
907: if ($mode eq 'html') {
1.10 harris41 908: return $fileglob="\n<br />BEGIN FILEGLOB\n".
1.3 harris41 909: "$glob sourcedir $targetdir $categoryname $description $note ".
910: "$build $status $dependencies $filenames" .
911: "\nEND FILEGLOB";
912: }
1.5 harris41 913: elsif ($mode eq 'install') {
914: return "\t".'install '.
915: $categoryhash{$categoryname}.' '.
1.13 albertel 916: $sourceroot.'/'.$sourcedir.'[^C][^V][^S]'.$glob.' '.
1.5 harris41 917: $targetroot.'/'.$targetdir.'.'."\n";
918: }
1.3 harris41 919: else {
920: return '';
921: }
922: }
923: return '';
924: }
925: # ---------------------------------------------------- Format sourcedir section
926: sub format_sourcedir {
927: my @tokeninfo=@_;
928: $sourcedir='';
929: my $text=&trim($parser->get_text('/sourcedir'));
930: if ($text) {
931: $parser->get_tag('/sourcedir');
932: $sourcedir=$text;
933: }
934: return '';
935: }
936: # ------------------------------------------------------- Format target section
937: sub format_target {
938: my @tokeninfo=@_;
939: $target='';
940: my $text=&trim($parser->get_text('/target'));
941: if ($text) {
942: $parser->get_tag('/target');
943: $target=$text;
944: }
945: return '';
946: }
947: # ------------------------------------------------------- Format source section
948: sub format_source {
949: my @tokeninfo=@_;
950: $source='';
951: my $text=&trim($parser->get_text('/source'));
952: if ($text) {
953: $parser->get_tag('/source');
954: $source=$text;
955: }
956: return '';
957: }
958: # --------------------------------------------------------- Format note section
959: sub format_note {
960: my @tokeninfo=@_;
961: $note='';
962: my $text=&trim($parser->get_text('/note'));
963: if ($text) {
964: $parser->get_tag('/note');
965: $note=$text;
966: }
967: return '';
968:
969: }
970: # -------------------------------------------------------- Format build section
971: sub format_build {
972: my @tokeninfo=@_;
973: $build='';
974: my $text=&trim($parser->get_text('/build'));
975: if ($text) {
976: $parser->get_tag('/build');
1.11 harris41 977: $build=$sourceroot.'/'.$text.';'.$tokeninfo[2]{'trigger'};
1.3 harris41 978: }
979: return '';
980: }
1.14 harris41 981: # -------------------------------------------------------- Format build section
982: sub format_buildlink {
983: my @tokeninfo=@_;
984: $buildlink='';
985: my $text=&trim($parser->get_text('/buildlink'));
986: if ($text) {
987: $parser->get_tag('/buildlink');
988: $buildlink=$sourceroot.'/'.$text;
989: }
990: return '';
991: }
1.3 harris41 992: # ------------------------------------------------------- Format status section
993: sub format_status {
994: my @tokeninfo=@_;
995: $status='';
996: my $text=&trim($parser->get_text('/status'));
997: if ($text) {
998: $parser->get_tag('/status');
999: $status=$text;
1000: }
1001: return '';
1002: }
1003: # ------------------------------------------------- Format dependencies section
1004: sub format_dependencies {
1005: my @tokeninfo=@_;
1006: $dependencies='';
1007: my $text=&trim($parser->get_text('/dependencies'));
1008: if ($text) {
1009: $parser->get_tag('/dependencies');
1.11 harris41 1010: $dependencies=join(';',
1011: (map {s/^\s*//;s/\s$//;$_} split(/\;/,$text)));
1.3 harris41 1012: }
1013: return '';
1014: }
1015: # --------------------------------------------------------- Format glob section
1016: sub format_glob {
1017: my @tokeninfo=@_;
1018: $glob='';
1019: my $text=&trim($parser->get_text('/glob'));
1020: if ($text) {
1021: $parser->get_tag('/glob');
1022: $glob=$text;
1023: }
1024: return '';
1025: }
1026: # ---------------------------------------------------- Format filenames section
1027: sub format_filenames {
1028: my @tokeninfo=@_;
1029: my $text=&trim($parser->get_text('/filenames'));
1030: if ($text) {
1031: $parser->get_tag('/filenames');
1032: $filenames=$text;
1033: }
1034: return '';
1035: }
1036: # ------------------------------------------------------- Format linkto section
1037: sub format_linkto {
1038: my @tokeninfo=@_;
1039: my $text=&trim($parser->get_text('/linkto'));
1040: if ($text) {
1041: $parser->get_tag('/linkto');
1042: $linkto=$text;
1043: }
1044: return '';
1.10 harris41 1045: }
1046: # ------------------------------------- Render less-than and greater-than signs
1047: sub htmlsafe {
1048: my $text=@_[0];
1049: $text =~ s/</</g;
1050: $text =~ s/>/>/g;
1051: return $text;
1.3 harris41 1052: }
1053: # --------------------------------------- remove starting and ending whitespace
1054: sub trim {
1055: my ($s)=@_; $s=~s/^\s*//; $s=~s/\s*$//; return $s;
1056: }
1.14 harris41 1057:
1058: # ----------------------------------- POD (plain old documentation, CPAN style)
1.18 harris41 1059:
1060: =head1 NAME
1061:
1062: lpml_parse.pl - This is meant to parse files meeting the lpml document type.
1063: See lpml.dtd. LPML=Linux Packaging Markup Language.
1064:
1065: =head1 SYNOPSIS
1066:
1067: Usage is for lpml file to come in through standard input.
1068:
1069: =over 4
1070:
1071: =item *
1072:
1073: 1st argument is the mode of parsing.
1074:
1075: =item *
1076:
1077: 2nd argument is the category permissions to use (runtime or development)
1078:
1079: =item *
1080:
1081: 3rd argument is the distribution
1082: (default,redhat6.2,debian2.2,redhat7.1,etc).
1083:
1084: =item *
1085:
1086: 4th argument is to manually specify a sourceroot.
1087:
1088: =item *
1089:
1090: 5th argument is to manually specify a targetroot.
1091:
1092: =back
1093:
1094: Only the 1st argument is mandatory for the program to run.
1095:
1096: Example:
1097:
1098: cat ../../doc/loncapafiles.lpml |\\
1099: perl lpml_parse.pl html default /home/sherbert/loncapa /tmp/install
1100:
1101: =head1 DESCRIPTION
1102:
1103: I am using a multiple pass-through approach to parsing
1104: the lpml file. This saves memory and makes sure the server
1105: will never be overloaded.
1106:
1107: =head1 README
1108:
1109: I am using a multiple pass-through approach to parsing
1110: the lpml file. This saves memory and makes sure the server
1111: will never be overloaded.
1112:
1113: =head1 PREREQUISITES
1114:
1115: HTML::TokeParser
1116:
1117: =head1 COREQUISITES
1118:
1119: =head1 OSNAMES
1120:
1121: linux
1122:
1123: =head1 SCRIPT CATEGORIES
1124:
1125: Packaging/Administrative
1126:
1127: =cut
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>