#!/usr/bin/perl ############################################################################ # $Id$ # # Generates a tmake project file. # # Copyright (C) 1996-1998 by Troll Tech AS. All rights reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, provided # that this copyright notice appears in all copies. # No representations are made about the suitability of this software for any # purpose. It is provided "as is" without express or implied warranty. # ############################################################################ # Default project settings $project{"TEMPLATE"} = "app"; $project{"CONFIG"} = "qt warn_on release"; @project_extra = (); while ( @ARGV ) { # parse command line args $_ = shift @ARGV; if ( s/^-// ) { if ( /^o(.*)/ ) { $outfile = ($1 eq "") ? shift @ARGV : $1; ($outfile eq "-") && ($outfile = ""); } elsif ( /^n(.*)/ ) { $project{"TARGET"} = ($1 eq "") ? shift @ARGV : $1; } elsif ( /^t(.*)/ ) { $project{"TEMPLATE"} = ($1 eq "") ? shift @ARGV : $1; $project{"TEMPLATE"} =~ s/\.t$//i; } elsif ( /lower/ ) { $tolower = 1; } else { &progen_usage; } } elsif ( /^\s*(?:[\w\-]+:)?\w+\s*[\+\-\*\/]?=/ ) { # project override push( @project_extra, $_ ); } else { push (@files, $_ ); } } $outfile eq "" || open(STDOUT,">" . $outfile) || &progen_error("Can't create \"$outfile\""); if ( ! @files ) { @files = &find_files(".",".*",1); } if ( $tolower ) { foreach $f ( @files ) { $f =~ tr/A-Z/a-z/; } } @hdr = sort grep(/\.(h|hh|hpp|hxx)$/i,@files); @src = sort grep(/\.(c|cpp|cc|cxx)$/i && ! /moc_/i,@files); # Remove source files that are included by other source files foreach $f ( @src ) { $srcdict{$f} = 1; } foreach $f ( @src ) { if ( open(F,"< $f") ) { while ( ) { if ( /^\s*#\s*include\s+\"([^\"]*)\"/ ) { $srcdict{$1} = 0; } } } } foreach $f( @src ) { $srcdict{$f} && (push(@src2,$f)); } @src = @src2; $project{"HEADERS"} = join(" ",sort @hdr); $project{"SOURCES"} = join(" ",sort @src); foreach $p ( @project_extra ) { if ( $p =~ /^\s*((?:[\w\-]+:)?\w+)\s*([\+\-\*\/])?=\s*(.*)/ ) { if ( $project{$1} ne "" ) { Project($p); } } } $project{"HEADERS"} =~ s/\s+/ \\\n\t\t /g; $project{"SOURCES"} =~ s/\s+/ \\\n\t\t /g; print "TEMPLATE\t= " . $project{"TEMPLATE"} . "\n"; print "CONFIG\t\t= " . $project{"CONFIG"} . "\n"; print "HEADERS\t\t= " . $project{"HEADERS"} . "\n"; print "SOURCES\t\t= " . $project{"SOURCES"} . "\n"; if ( $project{"TARGET"} ne "" ) { print "TARGET\t\t= " . $project{"TARGET"} . "\n"; } foreach ( @project_extra ) { if ( /^\s*((?:[\w\-]+:)?\w+)\s*([\+\-\*\/])?=\s*(.*)/ ) { if ( $project{$1} eq "" ) { $t = $1; if ( length($t) < 8 ) { $t .= "\t\t"; } elsif ( length($t) < 16 ) { $t .= "\t"; } else { $t .= " "; } print "$t$2= $3\n"; } } } exit 0; # # progen_usage() # # Prints a message about program usage and exits # sub progen_usage { print STDERR "Usage:\n progen [options] [files]\n"; print STDERR "Options:\n"; print STDERR " -lower Lower-case letters filenames (useful for non-Unix)\n"; print STDERR " -n name Specify a project name (= TARGET)\n"; print STDERR " -o file Write output to \"file\"\n"; print STDERR " -t file Specify a template file other than qtapp\n"; exit 1; } # # progen_error(msg) # # Prints the message and exits # sub progen_error { my($msg) = @_; print STDERR "progen error: " . $msg . "\n"; exit 1; } # # Finds files. # # Examples: # find_files("/usr","\.cpp$",1) - finds .cpp files in /usr and below # find_files("/tmp","^#",0) - finds #* files in /tmp # sub find_files { my($dir,$match,$descend) = @_; my($file,$p,@files); local(*D); $dir =~ s=\\=/=g; ($dir eq "") && ($dir = "."); if ( opendir(D,$dir) ) { if ( $dir eq "." ) { $dir = ""; } else { ($dir =~ /\/$/) || ($dir .= "/"); } foreach $file ( readdir(D) ) { next if ( $file =~ /^\.\.?$/ ); $p = $dir . $file; ($file =~ /$match/i) && (push @files, $p); if ( $descend && -d $p && ! -l $p ) { push @files, &find_files($p,$match,$descend); } } closedir(D); } return @files; } # # strip_project_val(tag) # # Strips white space from project value strings. # sub strip_project_val { my($v) = @_; $v =~ s/^\s+//; # trim white space $v =~ s/\s+$//; return $v; } # # Project(strings) # # This is a powerful function for setting or reading project variables. # Returns the resulting project variables (joined with space between). # # This is a slightly modified version of the Project function in tmake. sub Project { my @settings = @_; my($r,$t,$s,$v,$p,$c); $r = ""; foreach ( @settings ) { $v = $_; if ( $v =~ s/^\s*((?:[\w\-]+:)?\w+)\s*(\+=|\*=|\-=|\/=|=)\s*// ) { $t = $1; $s = $2; $v = strip_project_val($v); $p = $project{$t}; if ( $s eq "=" ) { # set variable $p = $v; } elsif ( $s eq "+=" ) { # append if ( $p eq "" ) { $p = $v; } else { $p .= " " . $v; } } elsif ( $s eq "*=" ) { # append if not contained if ( !($p =~ /(?:^|\s)\Q$v\E(?:\s|$)/) ) { if ( $p eq "" ) { $p = $v; } else { $p .= " " . $v; } } } elsif ( $s eq "-=" ) { # subtract $p =~ s/$v//g; } elsif ( $s eq "/=" ) { # sed $cmd = '$p =~ ' . $v; eval $cmd; } $project{$t} = strip_project_val($p); } else { $p = strip_project_val($project{$v}); } if ( $p ne "" ) { $r = ($r eq "") ? $p : ($r . " " . $p); } } return $r; }