This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ecosadmin.tcl - update for Cygwin


This patch allows ecosadmin.tcl to work well with recent Cygwin and adds
a repository validation command. Checked in.

John Dallaway
eCosCentric Limited
Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/ChangeLog,v
retrieving revision 1.192
diff -U5 -r1.192 ChangeLog
--- ChangeLog	4 Nov 2008 16:22:46 -0000	1.192
+++ ChangeLog	10 Nov 2008 12:29:12 -0000
@@ -151,18 +151,39 @@
 	* ecos.db: Added support for the AT91SAM7S. This includes a new
 	flash driver, watchdog driver, minor changes to the AT91 USART
 	driver, and extensions to the AT91 variant HAL in addition to the
 	AT91SAM7S HAL.
 
+2005-08-17  John Dallaway  <jld@ecoscentric.com>
+
+	* ecosadmin.tcl: Add new packages to an existing target
+	record where necessary when installing an eCos package
+	distribution file (.epk).
+
+2005-07-18  John Dallaway  <jld@ecoscentric.com>
+
+	* ecosadmin.tcl: Update hardware package lists within
+	target records when a package is missing.
+
+2005-07-12  John Dallaway  <jld@ecoscentric.com>
+
+	* ecosadmin.tcl: Optionally update hardware package lists
+	within target records when removing packages.
+
 2005-06-28  Nick Garnett  <nickg@ecoscentric.com>
 
 	* ecos.db: Added Object Loader package.
 
 2005-06-12   Brandl Harald <Harald.Brandl@fh-joanneum.at>
 
 	* ecos.db: Added a ethernet device driver for the NETARM.
 	
+2005-06-10  John Dallaway  <jld@ecoscentric.com>
+
+	* ecosadmin.tcl(ecosadmin::locate_subdirs): Accommodate
+	the behaviour of recent versions of Cygwin.
+
 2005-04-17   Andrew Lunn <andrew.lunn@ascom.ch>
 
 	* ecos.db: Added support for the AT91 based PhyCore
 
 2005-03-03   Jay Foster <jay@systech.cam>
@@ -187,10 +208,14 @@
 	
 2004-11-19  Jani Monoses <jani@iv.ro>
 
 	* ecos.db: New lpc2xxx platform, Olimex LPC-MT.
 
+2004-11-16  John Dallaway  <jld@ecoscentric.com>
+
+	* ecosadmin.tcl: Add "clean" and "check" commands.
+
 2004-11-14  Jani Monoses <jani@iv.ro>
 
 	* ecos.db: New packages which include a hal variant port for the
 	lpc2xxx, generic serial and watchdog drivers for the lpc2xxx and
 	ports for the Keil MCB2100 and Olimex P2106.
Index: ecosadmin.tcl
===================================================================
RCS file: /cvs/ecos/ecos/packages/ecosadmin.tcl,v
retrieving revision 1.15
diff -U5 -r1.15 ecosadmin.tcl
--- ecosadmin.tcl	30 Jan 2004 10:26:18 -0000	1.15
+++ ecosadmin.tcl	10 Nov 2008 12:29:12 -0000
@@ -17,11 +17,11 @@
 #####ECOSGPLCOPYRIGHTBEGIN####
 ## -------------------------------------------
 ## This file is part of eCos, the Embedded Configurable Operating System.
 ## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
 ## Copyright (C) 2003 John Dallaway
-## Copyright (C) 2004 eCosCentric Limited
+## Copyright (C) 2004, 2005 eCosCentric Limited
 ##
 ## eCos is free software; you can redistribute it and/or modify it under
 ## the terms of the GNU General Public License as published by the Free
 ## Software Foundation; either version 2 or (at your option) any later version.
 ##
@@ -118,14 +118,17 @@
 		}
 	}
 
 	# Details of the command line arguments, if any.
 	variable list_packages_arg   0;     # list
+	variable clean_database_arg  0;     # clean
+	variable check_database_arg  0;     # check
 	variable accept_license_arg  0;     # --accept_license
 	variable extract_license_arg 0;     # --extract_license
 	variable add_package        "";     # add FILE
 	variable remove_package     "";     # remove PACKAGE
+	variable keep_targets_arg   "";     # --keep_targets
 	variable merge_repository   "";     # merge REPOSITORY
 	variable version_arg        "";     # --version VER
 	
 	# Details of all known packages, targets and templates
 	# read from the ecos.db file
@@ -392,10 +395,22 @@
 			if { [regexp -- {^-?-?list$} $args($i)] == 1 } {
 				set ecosadmin::list_packages_arg 1
 				continue
 			}
 
+			# check for the clean command
+			if { [regexp -- {^-?-?clean$} $args($i)] == 1 } {
+				set ecosadmin::clean_database_arg 1
+				continue
+			}
+				
+			# check for the check command
+			if { [regexp -- {^-?-?check$} $args($i)] == 1 } {
+				set ecosadmin::check_database_arg 1
+				continue
+			}
+				
 			# check for --version
 			if { [regexp -- {^-?-version=?(.*)$} $args($i) dummy match1] == 1 } {
 				if { $match1 != "" } {
 					set ecosadmin::version_arg $match1
 				} else {
@@ -418,10 +433,16 @@
 			if { [regexp -- {^-?-extract_license$} $args($i)] == 1 } {
 				set ecosadmin::extract_license_arg 1
 				continue
 			}
 		
+			# check for --keep_targets
+			if { [regexp -- {^-?-keep_targets$} $args($i)] == 1 } {
+				set ecosadmin::keep_targets_arg 1
+				continue
+			}
+
 			# check for the add command
 			if { [regexp -- {^-?-?add=?(.*)$} $args($i) dummy match1] == 1 } {
 				if { $match1 != "" } {
 					set ecosadmin::add_package $match1
 				} else {
@@ -495,10 +516,11 @@
 proc ecosadmin::argument_help { } {
 
 	puts "Usage: ecosadmin \[ command \]"
 	puts "  commands are:"
 	puts "    list                                   : list packages"
+	puts "    check                                  : check database"
 	puts "    add FILE                               : add packages"
 	puts "    remove PACKAGE \[ --version VER \]       : remove a package"
 }
 
 # }}}
@@ -732,16 +754,18 @@
 # A variant glob pattern is used here. This version is not recursive.
 proc ecosadmin::locate_subdirs { dir { pattern "*" }} {
 
 	ASSERT { $dir != "" }
 
-	set dirlist [glob -nocomplain -- [file join $dir $pattern "."]]
+	set dirlist [glob -nocomplain -- [file join $dir $pattern]]
 
-	# Eliminate the pathnames and the spurious /. at the end of each entry
+	# Eliminate the pathnames and the regular (non-directory) files
 	set dirnames ""
 	foreach dir $dirlist {
-		lappend dirnames [file tail [file dirname $dir]]
+		if { [file isdirectory $dir] } {
+			lappend dirnames [file tail $dir]
+		}
 	}
 
 	# Get rid of the CVS directory, if any
         if { $ecosadmin::keep_cvs == 0 } {
                 set index [lsearch -exact $dirnames "CVS"]
@@ -921,10 +945,14 @@
 #-----------------------------------------------------------------------
 # Procedure merge_new_packages adds any entries in the specified data
 # file to the eCos repository database iff they are not already present
 
 proc ecosadmin::merge_new_packages { datafile } {
+	# array of targets which require merging of package list
+	array set ::ecosadmin::merge_target_packages {}
+	variable ::ecosadmin::merge_targets ""
+	variable ::ecosadmin::target_packages ""
 
 	# open the eCos database file for appending
 	set ecosfile [ file join $ecosadmin::component_repository "ecos.db" ]
 	variable outfile [ open $ecosfile a+ ]
 
@@ -938,34 +966,65 @@
 		# append the new package/target/template only if it is not already known
 		if { ( ( $command == "package" ) && ( [ lsearch -exact $ecosadmin::known_packages $name ] == -1 ) ) ||
 			( ( $command == "target" ) && ( [ lsearch -exact $ecosadmin::known_targets $name ] == -1 ) ) ||
 			( ( $command == "template" ) && ( [ lsearch -exact $ecosadmin::known_templates $name ] == -1 ) ) } {
 			puts $ecosadmin::outfile "$command $name {$body}\n"
+		} elseif { ($command == "target") } {
+			# target is already defined so store any new package names for a possible merge
+			set merge_required 0
+			foreach pkg $ecosadmin::target_packages {
+				# for each package name in the target record
+				if { [ lsearch $ecosadmin::target_data($name,packages) $pkg ] == -1 } {
+					# package name is not in the existing target record
+					lappend ecosadmin::merge_target_packages($name) $pkg
+					set merge_required 1
+				}
+			}
+			if { $merge_required == 1 } {
+				# at least one package name is not in the existing target record
+				lappend ecosadmin::merge_targets $name
+			}
 		}
 		
 		# add new packages to the list of merged packages
 		if { ( "package" == $command ) } {
 			lappend ecosadmin::merge_packages $name
 		}
 	}
 
+	proc set_target_packages { packages } {
+		set ecosadmin::target_packages $packages
+	}
+
 	# Create the parser, add the aliased commands, and then define
 	# the routines that do the real work.
 	set parser [ interp create -safe ]
 	$parser alias merge ecosadmin::merge
+	$parser alias set_target_packages ecosadmin::set_target_packages
 	$parser eval {
 		proc package { name body } {
 			merge "package" $name $body
 		}
 
 		proc template { name body } {
 			merge "template" $name $body
 		}
 
 		proc target { name body } {
+			eval $body
 			merge "target" $name $body
 		}
+
+		proc packages { str } {
+			set_target_packages $str
+		}
+
+		proc alias { str } { }
+		proc description { str } { }
+		proc disable { str } { }
+		proc enable { str } { }
+		proc set_value { str1 str2 } { }
 	}
 
 	# The parser is ready to evaluate the script. To avoid having to give the
 	# safe interpreter file I/O capabilities, the file is actually read in
 	# here and then evaluated.
@@ -976,19 +1035,135 @@
 		$parser eval $script
 	} message ]
 
 	# The interpreter and the aliased commands are no longer required.
 	rename merge {}
+	rename set_target_packages {}
 	interp delete $parser
 
 	# close the eCos database file
 	close $outfile
 
 	# report errors
 	if { $status != 0 } {
 		ecosadmin::fatal_error "parsing $datafile:\n$message"
 	}
+
+	# having appended any new records to ecos.db we can now merge extra
+	# packages into target records as necessary
+
+	# open the new eCos database file for writing
+	set ecosfile [ file join $ecosadmin::component_repository "ecos.db.new" ]
+	variable outfile [ open $ecosfile w ]
+	variable target_packages ""
+	variable target_attributes ""
+
+	# this procedure is called when the interpreter encounters a command in ecos.db when
+	# merging extra packages into target records
+	proc merge_target { command name body } {
+		if { ( $command == "target" ) && ( [ lsearch $ecosadmin::merge_targets $name ] != -1 ) } {
+			# add new package(s) to the target definition
+			puts $ecosadmin::outfile "$command $name \{\n$ecosadmin::target_attributes \tpackages \{"
+			foreach pkg $ecosadmin::target_packages {
+				puts $ecosadmin::outfile "\t\t$pkg"
+			}
+			foreach pkg $ecosadmin::merge_target_packages($name) {
+				ecosadmin::report "adding $pkg to target $name"			
+				puts $ecosadmin::outfile "\t\t$pkg"
+			}
+			puts $ecosadmin::outfile "\t\}\n\}\n"
+		} else {
+			# copy the data record to the new database
+			puts $ecosadmin::outfile "$command $name {$body}\n"
+		}
+	}
+
+	proc add_target_attribute { attribute value } {
+		set ecosadmin::target_attributes "$ecosadmin::target_attributes \t$attribute $value\n"
+	}
+
+	proc clear_target_attributes { } {
+		set ecosadmin::target_attributes ""
+	}
+
+	proc set_target_packages { packages } {
+		set ecosadmin::target_packages $packages
+	}
+
+	# Create the parser, add the aliased commands, and then define
+	# the routines that do the real work.
+	set parser [ interp create -safe ]
+	$parser alias add_target_attribute ecosadmin::add_target_attribute
+	$parser alias set_target_packages ecosadmin::set_target_packages
+	$parser alias clear_target_attributes ecosadmin::clear_target_attributes
+	$parser eval {
+		proc package { name body } {
+			filter "package" $name $body
+		}
+
+		proc template { name body } {
+			filter "template" $name $body
+		}
+
+		proc target { name body } {
+			clear_target_attributes
+			eval $body
+			filter "target" $name $body
+		}
+
+		proc packages { str } {
+			set_target_packages $str
+		}
+
+		proc alias { str } {
+			add_target_attribute "alias" \{$str\}
+		}
+
+		proc description { str } {
+			add_target_attribute "description" \"$str\"
+		}
+
+		proc disable { str } {
+			add_target_attribute "disable" \{$str\}
+		}
+
+		proc enable { str } {
+			add_target_attribute "enable" \{$str\}
+		}
+
+		proc set_value { str1 str2 } {
+			add_target_attribute "set_value" "$str1 \"$str2\""
+		}
+	}
+
+	# The parser is ready to evaluate the script. To avoid having to give the
+	# safe interpreter file I/O capabilities, the file is actually read in
+	# here and then evaluated.
+	set filename [ file join $ecosadmin::component_repository "ecos.db" ]
+	set status [ catch {
+		set fd [ open $filename r ]
+		set script [ read $fd ]
+		close $fd
+
+		$parser alias filter ecosadmin::merge_target
+		$parser eval $script
+	} message ]
+
+	# The interpreter and the aliased commands are no longer required.
+	rename merge_target {}
+	interp delete $parser
+
+	# close the new eCos database file
+	close $outfile
+
+	# report errors
+	if { $status != 0 } {
+		ecosadmin::fatal_error "parsing $filename:\n$message"
+	}
+
+	# replace the old eCos database file with the new one
+	file rename -force $ecosfile $filename
 }
 
 #-----------------------------------------------------------------------
 # Procedure filter_old_packages removes the specified packages/versions
 # from the eCos repository database. Any targets and templates dependent
@@ -999,10 +1174,12 @@
 	# open the new eCos database file for writing
 	set ecosfile [ file join $ecosadmin::component_repository "ecos.db.new" ]
 	variable outfile [ open $ecosfile w ]
 	variable filter_list $old_packages
 	variable removed_packages ""
+	variable target_packages ""
+	variable target_attributes ""
 
 	# this procedure is called when the interpreter encounters a command in the datafile on the first pass
 	# it generates a list of packages which will be removed on the second pass
 	proc removelist { command name body } {
 		if { [ lsearch $ecosadmin::filter_list $name ] != -1 } {
@@ -1015,12 +1192,28 @@
 	}
 
 	# this procedure is called when the interpreter encounters a command in the datafile on the second pass
 	proc filter { command name body } {
 		if { ( $command == "target" ) && ( ( [ target_requires_any_package $name $ecosadmin::removed_packages ] != 0 ) || ( [ target_requires_missing_package $name ] != 0 ) ) } {
-			# the target requires a package which has been removed so remove the target
-			ecosadmin::report "removing target $name"
+			# the target requires a package which has been removed
+			if { $ecosadmin::keep_targets_arg != 1 } {
+				# "--keep_targets" not specified so remove targets with missing packages
+				ecosadmin::report "removing target $name"
+			} else {
+				# "--keep_targets" specified so remove missing packages from the target definition
+				puts $ecosadmin::outfile "$command $name \{\n$ecosadmin::target_attributes \tpackages \{"
+				foreach pkg $ecosadmin::target_packages {
+					if { ([ lsearch $ecosadmin::removed_packages $pkg ] == -1) && ([ lsearch $ecosadmin::known_packages $pkg ] != -1) } {
+						# package exists and has not been listed for removal so keep it in the target definition
+						puts $ecosadmin::outfile "\t\t$pkg"
+					} else {
+						# package is missing or has been listed for removal so remove it from the target definition
+						puts "removing $pkg from $name target record"
+					}
+				}
+				puts $ecosadmin::outfile "\t\}\n\}\n"
+			}
 		} elseif { ( $command == "template" ) && ( ( [ template_requires_any_package $name $ecosadmin::removed_packages ] != 0 ) || ( [ template_requires_missing_package $name ] != 0 ) ) } {
 			# the template requires a package which has been removed so remove the template
 			ecosadmin::report "removing template $name"
 		} elseif { [ lsearch $ecosadmin::filter_list $name ] == -1 } {
 			# the package is not in the filter list so copy the data to the new database
@@ -1052,25 +1245,66 @@
 				set dir [ file dirname $dir ]
 			}
 		}
 	}
 
+	proc add_target_attribute { attribute value } {
+		set ecosadmin::target_attributes "$ecosadmin::target_attributes \t$attribute $value\n"
+	}
+
+	proc clear_target_attributes { } {
+		set ecosadmin::target_attributes ""
+	}
+
+	proc set_target_packages { packages } {
+		set ecosadmin::target_packages $packages
+	}
+
 	# Create the parser, add the aliased commands, and then define
 	# the routines that do the real work.
 	set parser [ interp create -safe ]
+	$parser alias add_target_attribute ecosadmin::add_target_attribute
+	$parser alias set_target_packages ecosadmin::set_target_packages
+	$parser alias clear_target_attributes ecosadmin::clear_target_attributes
 	$parser eval {
 		proc package { name body } {
 			filter "package" $name $body
 		}
 
 		proc template { name body } {
 			filter "template" $name $body
 		}
 
 		proc target { name body } {
+			clear_target_attributes
+			eval $body
 			filter "target" $name $body
 		}
+
+		proc packages { str } {
+			set_target_packages $str
+		}
+
+		proc alias { str } {
+			add_target_attribute "alias" \{$str\}
+		}
+
+		proc description { str } {
+			add_target_attribute "description" \"$str\"
+		}
+
+		proc disable { str } {
+			add_target_attribute "disable" \{$str\}
+		}
+
+		proc enable { str } {
+			add_target_attribute "enable" \{$str\}
+		}
+
+		proc set_value { str1 str2 } {
+			add_target_attribute "set_value" "$str1 \"$str2\""
+		}
 	}
 
 	# The parser is ready to evaluate the script. To avoid having to give the
 	# safe interpreter file I/O capabilities, the file is actually read in
 	# here and then evaluated.
@@ -1203,26 +1437,70 @@
 
 	# get the formal package name
 	set package_name [ ecosadmin::find_package $ecosadmin::remove_package ]
 	if { $package_name == "" } {
 		# package not found
-		fatal_error "package not found"
+		fatal_error "package $ecosadmin::remove_package not found"
 	} elseif { $ecosadmin::version_arg == "" } {
 		# version not specified
 #		if { [ llength $ecosadmin::package_data($package_name,versions) ] > 1 } {
 #			fatal_error "multiple versions, use --version"
 #		}
 	} elseif { [ lsearch $ecosadmin::package_data($package_name,versions) $ecosadmin::version_arg ] == -1 } {
 		# specified version not found
-		fatal_error "version not found"
+		fatal_error "version $ecosadmin::version_arg not found"
 	}
 	
 	# filter out the old package from the eCos database file
 	filter_old_packages $package_name
 }
 
 # ----------------------------------------------------------------------------
+# Process_clean_database. This routine is responsible for tidying up an
+# eCos repository package database
+#
+
+proc ecosadmin::process_clean_database { } {
+
+	# filter out missing packages from the eCos database file
+	filter_old_packages ""
+}
+
+# ----------------------------------------------------------------------------
+# Process_check_database. This routine is responsible for checking an
+# eCos repository package database
+#
+
+proc ecosadmin::process_check_database { } {
+
+	foreach target $ecosadmin::known_targets {
+		foreach package $ecosadmin::target_data($target,packages) {
+			if { [ lsearch -exact $ecosadmin::known_packages $package ] != -1 } {
+				if { $ecosadmin::package_data($package,hardware) != 1 } {
+					ecosadmin::warning "non-hardware package $package used in target $target"
+				}
+			} else {
+				ecosadmin::warning "target $target refers to non-existent package $package"
+			}
+		}
+	}
+	foreach package $ecosadmin::known_packages {
+		if { $ecosadmin::package_data($package,hardware) == 1 } {
+			variable hardware_package_required 0
+			foreach target $ecosadmin::known_targets {
+				if { [ target_requires_any_package $target $package ] } {
+					set hardware_package_required 1
+				}
+			}
+			if { $hardware_package_required == 0 } {
+				ecosadmin::warning "hardware package $package not used by any target"
+			}
+		}
+	}
+}
+
+# ----------------------------------------------------------------------------
 # Process_merge_repository. This routine is responsible for merging packages
 # from another repository into the eCos repository
 #
 
 proc ecosadmin::process_merge_repository { } {
@@ -1255,11 +1533,11 @@
 	# copy new files from the pkgconf and templates directory hierarchies into the repository as necessary
 	foreach topdir { pkgconf templates } {
 		set repository_files [ ecosadmin::locate_all_files [ file join $ecosadmin::component_repository $topdir ] ]
 		set merge_files [ ecosadmin::locate_all_files [ file join $ecosadmin::merge_repository $topdir ] ]
 		foreach filename $merge_files {
-			if { [lsearch $repository_files $filename] == -1 } {
+			if { [string length $filename] > 0 && [lsearch $repository_files $filename] == -1 } {
 				ecosadmin::report "copying $topdir file $filename"
 				file mkdir [ file join $ecosadmin::component_repository $topdir [ file dirname $filename ] ]
 				file copy [ file join $ecosadmin::merge_repository $topdir $filename ] [ file join $ecosadmin::component_repository $topdir $filename ]
 			}
 		}
@@ -1351,10 +1629,14 @@
 			ecosadmin::process_add_package
 		} elseif { $ecosadmin::remove_package != "" } {
 			ecosadmin::process_remove_package
 		} elseif { $ecosadmin::merge_repository != "" } {
 			ecosadmin::process_merge_repository
+		} elseif { $ecosadmin::clean_database_arg != 0 } {
+			ecosadmin::process_clean_database
+		} elseif { $ecosadmin::check_database_arg != 0 } {
+			ecosadmin::process_check_database
 		}
 
 	} error_message ] != 0 } { 
 
 		# handle error message

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]