#!/usr/bin/env perl # # Copyright (C) 2006 Felix Fietkau # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. # use warnings; use strict; my @arg; my $PREFIX = "CONFIG_"; sub set_config($$$$) { my $config = shift; my $idx = shift; my $newval = shift; my $mod_plus = shift; if (!defined($config->{$idx}) or !$mod_plus or $config->{$idx} eq '#undef' or $newval eq 'y') { $config->{$idx} = $newval; } } sub load_config($$) { my $file = shift; my $mod_plus = shift; my %config; open FILE, "$file" or die "can't open file '$file'"; while () { chomp; /^$PREFIX(.+?)=(.+)/ and do { set_config(\%config, $1, $2, $mod_plus); next; }; /^# $PREFIX(.+?) is not set/ and do { set_config(\%config, $1, "#undef", $mod_plus); next; }; /^#/ and next; /^(.+)$/ and warn "WARNING: can't parse line: $1\n"; } return \%config; } sub config_and($$) { my $cfg1 = shift; my $cfg2 = shift; my %config; foreach my $config (keys %$cfg1) { my $val1 = $cfg1->{$config}; my $val2 = $cfg2->{$config}; $val2 and ($val1 eq $val2) and do { $config{$config} = $val1; }; } return \%config; } sub config_add($$$) { my $cfg1 = shift; my $cfg2 = shift; my $mod_plus = shift; my %config; for ($cfg1, $cfg2) { my %cfg = %$_; foreach my $config (keys %cfg) { if ($mod_plus and $config{$config}) { next if $config{$config} eq "y"; next if $cfg{$config} eq '#undef'; } $config{$config} = $cfg{$config}; } } return \%config; } sub config_diff($$$) { my $cfg1 = shift; my $cfg2 = shift; my $new_only = shift; my %config; foreach my $config (keys %$cfg2) { if (!defined($cfg1->{$config}) or $cfg1->{$config} ne $cfg2->{$config}) { next if $new_only and !defined($cfg1->{$config}) and $cfg2->{$config} eq '#undef'; $config{$config} = $cfg2->{$config}; } } return \%config } sub config_sub($$) { my $cfg1 = shift; my $cfg2 = shift; my %config = %{$cfg1}; foreach my $config (keys %$cfg2) { delete $config{$config}; } return \%config; } sub print_cfgline($$) { my $name = shift; my $val = shift; if ($val eq '#undef' or $val eq 'n') { print "# $PREFIX$name is not set\n"; } else { print "$PREFIX$name=$val\n"; } } sub dump_config($) { my $cfg = shift; die "argument error in dump_config" unless ($cfg); my %config = %$cfg; foreach my $config (sort keys %config) { print_cfgline($config, $config{$config}); } } sub parse_expr { my $pos = shift; my $mod_plus = shift; my $arg = $arg[$$pos++]; die "Parse error" if (!$arg); if ($arg eq '&') { my $arg1 = parse_expr($pos); my $arg2 = parse_expr($pos); return config_and($arg1, $arg2); } elsif ($arg =~ /^\+/) { my $arg1 = parse_expr($pos); my $arg2 = parse_expr($pos); return config_add($arg1, $arg2, 0); } elsif ($arg =~ /^m\+/) { my $arg1 = parse_expr($pos); my $arg2 = parse_expr($pos, 1); return config_add($arg1, $arg2, 1); } elsif ($arg eq '>') { my $arg1 = parse_expr($pos); my $arg2 = parse_expr($pos); return config_diff($arg1, $arg2, 0); } elsif ($arg eq '>+') { my $arg1 = parse_expr($pos); my $arg2 = parse_expr($pos); return config_diff($arg1, $arg2, 1); } elsif ($arg eq '-') { my $arg1 = parse_expr($pos); my $arg2 = parse_expr($pos); return config_sub($arg1, $arg2); } else { return load_config($arg, $mod_plus); } } while (@ARGV > 0 and $ARGV[0] =~ /^-\w+$/) { my $cmd = shift @ARGV; if ($cmd =~ /^-n$/) { $PREFIX = ""; } elsif ($cmd =~ /^-p$/) { $PREFIX = shift @ARGV; } else { die "Invalid option: $cmd\n"; } } @arg = @ARGV; my $pos = 0; dump_config(parse_expr(\$pos)); die "Parse error" if ($arg[$pos]); d='n2' href='#n2'>2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
#
# Copyright (C) 2006-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

DOWNLOAD_RDEP=$(STAMP_PREPARED) $(HOST_STAMP_PREPARED)

# Try to guess the download method from the URL
define dl_method
$(strip \
  $(if $(2),$(2), \
    $(if $(filter @GNOME/% @GNU/% @KERNEL/% @SF/% ftp://% http://% https://% file://%,$(1)),default, \
      $(if $(filter git://%,$(1)),git, \
        $(if $(filter svn://%,$(1)),svn, \
          $(if $(filter cvs://%,$(1)),cvs, \
            $(if $(filter hg://%,$(1)),hg, \
              $(if $(filter sftp://%,$(1)),bzr, \
                unknown \
              ) \
            ) \
          ) \
        ) \
      ) \
    ) \
  ) \
)
endef

# code for creating tarballs from cvs/svn/git/bzr/hg/darcs checkouts - useful for mirror support
dl_pack/bz2=$(TAR) cjf $(1) $(2)
dl_pack/gz=$(TAR) czf $(1) $(2)
dl_pack/unknown=echo "ERROR: Unknown pack format for file $(1)"; false
define dl_pack
	$(if $(dl_pack/$(call ext,$(1))),$(dl_pack/$(call ext,$(1))),$(dl_pack/unknown))
endef

define DownloadMethod/unknown
	@echo "ERROR: No download method available"; false
endef

define DownloadMethod/default
	$(SCRIPT_DIR)/download.pl "$(DL_DIR)" "$(FILE)" "$(MD5SUM)" $(foreach url,$(URL),"$(url)")
endef

define wrap_mirror
	$(if $(if $(MIRROR),$(filter-out x,$(MIRROR_MD5SUM))),@$(SCRIPT_DIR)/download.pl "$(DL_DIR)" "$(FILE)" "$(MIRROR_MD5SUM)" || ( $(1) ),$(1))
endef

define DownloadMethod/cvs
	$(call wrap_mirror, \
		echo "Checking out files from the cvs repository..."; \
		mkdir -p $(TMP_DIR)/dl && \
		cd $(TMP_DIR)/dl && \
		rm -rf $(SUBDIR) && \
		[ \! -d $(SUBDIR) ] && \
		cvs -d $(URL) export $(VERSION) $(SUBDIR) && \
		echo "Packing checkout..." && \
		$(call dl_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
		rm -rf $(SUBDIR); \
	)
endef

define DownloadMethod/svn
	$(call wrap_mirror, \
		echo "Checking out files from the svn repository..."; \
		mkdir -p $(TMP_DIR)/dl && \
		cd $(TMP_DIR)/dl && \
		rm -rf $(SUBDIR) && \
		[ \! -d $(SUBDIR) ] && \
		( svn help export | grep -q trust-server-cert && \
		svn export --non-interactive --trust-server-cert -r$(VERSION) $(URL) $(SUBDIR) || \
		svn export --non-interactive -r$(VERSION) $(URL) $(SUBDIR) ) && \
		echo "Packing checkout..." && \
		$(call dl_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
		rm -rf $(SUBDIR); \
	)
endef

define DownloadMethod/git
	$(call wrap_mirror, \
		echo "Checking out files from the git repository..."; \
		mkdir -p $(TMP_DIR)/dl && \
		cd $(TMP_DIR)/dl && \
		rm -rf $(SUBDIR) && \
		[ \! -d $(SUBDIR) ] && \
		git clone $(URL) $(SUBDIR) --recursive && \
		(cd $(SUBDIR) && git checkout $(VERSION) && git submodule update) && \
		echo "Packing checkout..." && \
		rm -rf $(SUBDIR)/.git && \
		$(call dl_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
		rm -rf $(SUBDIR); \
	)
endef

define DownloadMethod/bzr
	$(call wrap_mirror, \
		echo "Checking out files from the bzr repository..."; \
		mkdir -p $(TMP_DIR)/dl && \
		cd $(TMP_DIR)/dl && \
		rm -rf $(SUBDIR) && \
		[ \! -d $(SUBDIR) ] && \
		bzr export -r$(VERSION) $(SUBDIR) $(URL) && \
		echo "Packing checkout..." && \
		$(call dl_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
		rm -rf $(SUBDIR); \
	)
endef

define DownloadMethod/hg
	$(call wrap_mirror, \
		echo "Checking out files from the hg repository..."; \
		mkdir -p $(TMP_DIR)/dl && \
		cd $(TMP_DIR)/dl && \
		rm -rf $(SUBDIR) && \
		[ \! -d $(SUBDIR) ] && \
		hg clone -r $(VERSION) $(URL) $(SUBDIR) && \
		find $(SUBDIR) -name .hg | xargs rm -rf && \
		echo "Packing checkout..." && \
		$(call dl_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
		rm -rf $(SUBDIR); \
	)
endef

define DownloadMethod/darcs
	$(call wrap_mirror, \
		echo "Checking out files from the darcs repository..."; \
		mkdir -p $(TMP_DIR)/dl && \
		cd $(TMP_DIR)/dl && \
		rm -rf $(SUBDIR) && \
		[ \! -d $(SUBDIR) ] && \
		darcs get -t $(VERSION) $(URL) $(SUBDIR) && \
		find $(SUBDIR) -name _darcs | xargs rm -rf && \
		echo "Packing checkout..." && \
		$(call dl_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
		rm -rf $(SUBDIR); \
	)
endef

Validate/cvs=VERSION SUBDIR
Validate/svn=VERSION SUBDIR
Validate/git=VERSION SUBDIR
Validate/bzr=VERSION SUBDIR
Validate/hg=VERSION SUBDIR
Validate/darcs=VERSION SUBDIR

define Download/Defaults
  URL:=
  FILE:=
  PROTO:=
  MD5SUM:=
  SUBDIR:=
  MIRROR:=1
  MIRROR_MD5SUM:=x
  VERSION:=
endef

define Download
  $(eval $(Download/Defaults))
  $(eval $(Download/$(1)))
  $(foreach FIELD,URL FILE $(Validate/$(call dl_method,$(URL),$(PROTO))),
    ifeq ($($(FIELD)),)
      $$(error Download/$(1) is missing the $(FIELD) field.)
    endif
  )

  $(foreach dep,$(DOWNLOAD_RDEP),
    $(dep): $(DL_DIR)/$(FILE)
  )
  download: $(DL_DIR)/$(FILE)

  $(DL_DIR)/$(FILE):
	mkdir -p $(DL_DIR)
	$(if $(DownloadMethod/$(call dl_method,$(URL),$(PROTO))),$(DownloadMethod/$(call dl_method,$(URL),$(PROTO))),$(DownloadMethod/unknown))

endef