- Added more DeviceVendorEnum values based on non-conforming real world description files

- Added current (1.4.6) Pack.XSD to repository for reference
- Updated FileDownloadProgress to take advantage of C# 6 language features
- renamed several methods to use xxxAsync standard naming
- Added IDisposable to IRepository
- Added IRepositoryProvider to abstract information about respository locations from applications.
- Added MDK specific repository provider
- removed PackIndex.DefaultIndexUriPath it is now part of the provider
- removed APIs that assumed the default index URI
- Added support for downloading missing PDSC files from the index URI
- updated PackRepository.LastUpdatedTimeUTC so that if the index file doesn't exist it will provide a default constructed DateTime so it will be earlier than DateTime.Now
- Added new test/debug app to parse all the PDSC files and validate them against the "official" schemas to log errors in the official released and apparently "sanctioned" PDSC files that are not in conformance with the schema. This includes some workarounds and is helping to point to additional new workarounds.
This commit is contained in:
Steve Maillet 2016-09-02 21:37:40 -07:00
Родитель fb88df26e0
Коммит b7970d2b06
25 изменённых файлов: 9120 добавлений и 73 удалений

Просмотреть файл

@ -56,6 +56,7 @@
<ItemGroup>
<Compile Include="FileDownloadProgress.cs" />
<Compile Include="Interfaces.cs" />
<Compile Include="MDKRepositoryProvider.cs" />
<Compile Include="PackDescription\AlgorithmType.cs" />
<Compile Include="PackDescription\ApiType.cs" />
<Compile Include="PackDescription\BoardFeature.cs" />
@ -127,6 +128,9 @@
<Compile Include="VersionParser.cs" />
</ItemGroup>
<ItemGroup>
<None Include="PackDescription\PACK.xsd">
<SubType>Designer</SubType>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -7,28 +7,22 @@ namespace CMSIS.Pack
{
public FileDownloadProgress( Uri source, TimeSpan elapsedTime, long sizeSoFar, long totalSize)
{
SourceUrl_ = source;
ElapsedTime_ = elapsedTime;
SizeSoFar_ = sizeSoFar;
TotalSize_ = totalSize;
SourceUrl = source;
ElapsedTime = elapsedTime;
SizeSoFar = sizeSoFar;
TotalSize = totalSize;
}
public double PercentComplete
{
get { return 100.0 * (double)SizeSoFar/(double)TotalSize; }
}
public double PercentComplete => 100.0 * SizeSoFar / TotalSize;
public bool IsCompleted { get { return SizeSoFar_ == -1 || TotalSize_ == -1; } }
public Uri SourceUrl { get { return SourceUrl_; } }
private readonly Uri SourceUrl_;
public bool IsCompleted => SizeSoFar == -1 || TotalSize == -1;
public TimeSpan ElapsedTime { get { return ElapsedTime_; } }
private readonly TimeSpan ElapsedTime_;
public Uri SourceUrl { get; }
public long SizeSoFar { get { return SizeSoFar_; } }
private readonly long SizeSoFar_;
public TimeSpan ElapsedTime { get; }
public long TotalSize { get { return TotalSize_; } }
private readonly long TotalSize_;
public long SizeSoFar { get; }
public long TotalSize { get; }
}
}

Просмотреть файл

@ -10,6 +10,7 @@ namespace CMSIS.Pack
{
AvailableForDownload,
Downloading,
NotFoundOnServer,
Downloaded,
Installing,
Installed,
@ -68,9 +69,9 @@ namespace CMSIS.Pack
PackInstallState InstallState { get; }
IRepository Repository { get; }
Task Download( IProgress<FileDownloadProgress> progressSink );
Task InstallPack( IProgress<PackInstallProgress> progressSink );
Task DownloadAsync( IProgress<FileDownloadProgress> progressSink );
Task InstallPackAsync( IProgress<PackInstallProgress> progressSink );
}
public enum RepositoryState
@ -87,6 +88,7 @@ namespace CMSIS.Pack
/// <summary>Represents a remote repository and local store of the installed pack files</summary>
public interface IRepository
: IDisposable
{
/// <summary>Location of the source of packs to download from</summary>
Uri SourceUri { get; }

Просмотреть файл

@ -0,0 +1,52 @@
using CMSIS.Pack;
using Microsoft.Win32;
using System.IO;
using System;
namespace CMSIS.Pack
{
public interface IRepositoryProvider
{
/// <summary>Name of the provider</summary>
string Name { get; }
/// <summary>Full path to the folder containing the repository</summary>
IRepository Repository { get; }
}
/// <summary>Repository location provider for standard ARM/Keil MDK Installations</summary>
/// <remarks>
/// Eventually this should be "discovered" via MEF by the CMSIS.Pack system so that
/// applications don't need to know where repositories come from and providing a
/// common way to enumerate options to display for the user to choose.
/// </remarks>
public class MDKRepositoryProvider
: IRepositoryProvider
{
/// <summary>Default URI for the pack index</summary>
public const string DefaultIndexUriPath = "http://www.keil.com/pack/index.idx";
public MDKRepositoryProvider()
{
using( var hklm = RegistryKey.OpenBaseKey( RegistryHive.LocalMachine, RegistryView.Registry32 ) )
using( var key = hklm.OpenSubKey( MDKInstallKey ) )
{
Path = key.GetValue( "Path" ) as string;
Version = key.GetValue( "Version" ) as string;
var repoPath = System.IO.Path.Combine( Path, "Pack" );
PackRepositoryPath = Directory.Exists( repoPath ) ? repoPath : null;
Repository = new PackRepository( new Uri( DefaultIndexUriPath ), PackRepositoryPath );
}
}
public string Path { get; }
public string Version { get; }
public string PackRepositoryPath { get; }
public string Name => $"MDK {Version}";
public IRepository Repository { get; }
private const string MDKInstallKey = @"SOFTWARE\Keil\Products\MDK";
}
}

Просмотреть файл

@ -215,6 +215,9 @@ namespace CMSIS.Pack.PackDescription
[XmlEnum( "Milandr:99" )]
Milandr99,
[XmlEnum( "MindMotion:132" )]
MindMotion132,
/// <remarks/>
[XmlEnum( "NetSilicon:67" )]
NetSilicon67,
@ -283,6 +286,9 @@ namespace CMSIS.Pack.PackDescription
[XmlEnum( "Texas Instruments:16" )]
TexasInstruments16,
[XmlEnum( "TexasInstruments:16" )]
TexasInstruments16_2,
/// <remarks/>
[XmlEnum( "Toshiba:92" )]
Toshiba92,
@ -302,6 +308,9 @@ namespace CMSIS.Pack.PackDescription
/// <remarks/>
[XmlEnum( "NXP (founded by Philips):11" )]
NXPfoundedbyPhilips11,
[XmlEnum("Zilog:89")]
Zilog89,
}
/// <remarks/>
@ -395,7 +404,14 @@ namespace CMSIS.Pack.PackDescription
/// <remarks/>
[XmlEnum( "Cortex-A72")]
CortexA72,
#region Added in CMSIS-Pack v5.0.0
[XmlEnum]
ARMV8MBL,
[XmlEnum]
ARMV8MML,
#endregion
/// <remarks/>
other,
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -17,9 +17,6 @@ namespace CMSIS.Pack
/// </remarks>
public class PackIndex
{
/// <summary>Default URI for the pack index</summary>
public const string DefaultIndexUriPath = "http://www.keil.com/pack/index.idx";
public PackIndex( )
{
}
@ -33,12 +30,6 @@ namespace CMSIS.Pack
public IEnumerable<IPackIndexEntry> Packs => Packs_.AsReadOnly( );
private readonly List<IPackIndexEntry> Packs_ = new List<IPackIndexEntry>();
/// <summary>Download and parse the index file from the Default location <see cref="DefaultIndexUriPath"/></summary>
/// <returns>Task for the Asynchronous operation</returns>
public Task LoadAsync( ) => LoadAsync( new Uri( DefaultIndexUriPath ) );
public Task LoadAsync( IProgress<FileDownloadProgress> progressSink ) => LoadAsync( new Uri( DefaultIndexUriPath ), progressSink );
/// <summary>Download and parse the index asynchronously from a URL</summary>
/// <param name="indexUrl">URL of the index file to download</param>
/// <returns>Task for the Asynchronous operation</returns>
@ -115,8 +106,7 @@ namespace CMSIS.Pack
, ConformanceLevel = ConformanceLevel.Fragment
};
using( var strm = new StringReader( indexContent ) )
using( var rdr = XmlReader.Create( strm, settings ) )
using( var rdr = XmlReader.Create( new StringReader( indexContent ), settings ) )
{
// Despite having an xml doc processing instruction the index file is *NOT*
// valid XML. It has multiple pdsc elements at the root, which is invalid

Просмотреть файл

@ -87,10 +87,13 @@ namespace CMSIS.Pack
/// <returns>string containing the XML content of the description</returns>
public async Task<string> GetPackageDescriptionDocumentAsync()
{
using( var client = new HttpClient( ) )
using( var client = new HttpClient( ) { BaseAddress = Url } )
using( var response = await client.GetAsync( PdscName ) )
{
client.BaseAddress = Url;
return await client.GetStringAsync( PdscName );
if( response.StatusCode != System.Net.HttpStatusCode.OK )
return null;
return await response.Content.ReadAsStringAsync( );
}
}
@ -99,6 +102,9 @@ namespace CMSIS.Pack
public async Task<Package> GetPackageDescriptionAsync( )
{
var xml = await GetPackageDescriptionDocumentAsync( );
if( string.IsNullOrWhiteSpace( xml ) )
return null;
return await Package.ParseAsync( xml );
}

Просмотреть файл

@ -16,6 +16,7 @@ namespace CMSIS.Pack
/// </remarks>
public class PackRepository
: IRepository
, IDisposable
{
/// <summary>Constructs a new <see cref="PackRepository"/></summary>
/// <param name="source">Uri of the source repository to download files from</param>
@ -30,15 +31,18 @@ namespace CMSIS.Pack
PackIdxWatcher.Changed += ( s, e ) => Updated( this, new RepositoryUpdateEventArgs( ) );
}
/// <summary>Constructs a new repository backed by the specified local path and downloading from the <see cref="PackIndex.DefaultIndexUriPath"/> source Uri</summary>
/// <param name="localPath">Full path of the local repository</param>
public PackRepository( string localPath )
: this( new Uri( PackIndex.DefaultIndexUriPath ), localPath )
{
}
/// <summary>Last time the repository's index was updated</summary>
public DateTime LastUpdatedTimeUTC => File.GetLastWriteTimeUtc( Path.Combine( LocalPath, "pack.idx" ) );
public DateTime LastUpdatedTimeUTC
{
get
{
var path = RepositoryIndexPath;
if( File.Exists( path ) )
return File.GetLastWriteTimeUtc( RepositoryIndexPath );
else
return new DateTime( );
}
}
public string WebRoot { get; }
@ -48,6 +52,10 @@ namespace CMSIS.Pack
public string LocalPath { get; }
public string RepositoryIndexPath => Path.Combine( LocalPath, "pack.idx" );
public string DownloadIndexPath => Path.Combine( WebRoot, "index.idx" );
public event EventHandler<RepositoryUpdateEventArgs> Updated = delegate { };
public IEnumerable<IRepositoryPackage> Packs => Packs_.AsEnumerable( );
@ -69,17 +77,17 @@ namespace CMSIS.Pack
Updated( this, new RepositoryUpdateEventArgs( RepositoryState.DownloadingIndex, null ) );
Packs_ = new List<IRepositoryPackage>( );
var index = new PackIndex( );
await index.LoadAsync( Path.Combine( WebRoot, "index.idx" ) );
await index.LoadAsync( DownloadIndexPath );
foreach( var pack in index.Packs )
{
var repositoryPack = new RepositoryPackage( this, pack, await GetInstallState( pack ) );
var repositoryPack = new RepositoryPackage( this, pack, await GetInstallStateAsync( pack ) );
Packs_.Add( repositoryPack );
}
}
public Task UpdateLocalFromSourceAsync( ) => Task.FromResult<object>( null );
private Task<PackInstallState> GetInstallState( IPackIndexEntry pack )
private Task<PackInstallState> GetInstallStateAsync( IPackIndexEntry pack )
{
return Task.Run( ( ) =>
{
@ -95,5 +103,42 @@ namespace CMSIS.Pack
}
private readonly FileSystemWatcher PackIdxWatcher;
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose( bool disposing )
{
if( !disposedValue )
{
if( disposing )
{
PackIdxWatcher.Dispose( );
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
}
}
#if PackRepository_HAS_FINALIZER
// ~PackRepository() {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
#endif
// This code added to correctly implement the disposable pattern.
public void Dispose( )
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose( true );
#if PackRepository_HAS_FINALIZER
GC.SuppressFinalize(this);
#endif
}
#endregion
}
}

Просмотреть файл

@ -24,7 +24,7 @@ namespace CMSIS.Pack
public IPackIndexEntry Details { get; }
public IRepository Repository { get; private set; }
public IRepository Repository { get; }
public PackInstallState InstallState { get; private set; }
@ -40,7 +40,19 @@ namespace CMSIS.Pack
public async Task<string> GetPackageDescriptionDocumentAsync( )
{
using( var strm = File.OpenText( Path.Combine( Repository.WebRoot, PdscName ) ) )
var path = Path.Combine( Repository.WebRoot, PdscName );
if( !File.Exists( path ) )
{
// download the PDSC file to the repo's .Web location
var retVal = await Details.GetPackageDescriptionDocumentAsync( );
if( !string.IsNullOrWhiteSpace( retVal ) )
{
File.WriteAllText( path, retVal );
}
return retVal;
}
using( var strm = File.OpenText( path ) )
{
return await strm.ReadToEndAsync( );
}
@ -49,10 +61,14 @@ namespace CMSIS.Pack
public async Task<Package> GetPackageDescriptionAsync( )
{
string content = await GetPackageDescriptionDocumentAsync( );
if( string.IsNullOrWhiteSpace( content ) )
{
return null;
}
return await Package.ParseAsync( content );
}
public async Task Download( IProgress<FileDownloadProgress> progressSink )
public async Task DownloadAsync( IProgress<FileDownloadProgress> progressSink )
{
if( InstallState == PackInstallState.Downloaded )
return;
@ -73,7 +89,7 @@ namespace CMSIS.Pack
InstallState = PackInstallState.Downloaded;
}
public async Task InstallPack( IProgress<PackInstallProgress> progressSink )
public async Task InstallPackAsync( IProgress<PackInstallProgress> progressSink )
{
if( InstallState == PackInstallState.Installed )
return;

Просмотреть файл

@ -11,8 +11,8 @@ namespace CMSIS.Pack
// Deviations from the official spec are:
// 1) Trailing 0s on Minor and Patch are ignored
// 2) Patch is optional, if not present a default of 0 is assumed
// 3) The hyphen prerelease delimiter is optional if the first
// character of the prerelease identifier is a letter
// 3) The hyphen pre-release delimiter is optional if the first
// character of the pre-release identifier is a letter
//
// This utility class provides for relaxed parsing to generate
// a full SemanticVersion that, when converted back to a string

Просмотреть файл

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetmfPackInstaller", "NetmfPackInstaller\NetmfPackInstaller.csproj", "{4D6FE417-4296-4C77-8B3E-26976A1F8C08}"
EndProject
@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\Unit
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SemVer.NET", "SemVer.NET\SemVer.NET.csproj", "{1FAE553D-F158-4B0C-A935-09332ECE2A51}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ValidatePackSchema", "ValidatePackSchema\ValidatePackSchema.csproj", "{B662F887-AAB6-4B73-B986-B8425E8EF0E8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -33,6 +35,10 @@ Global
{1FAE553D-F158-4B0C-A935-09332ECE2A51}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1FAE553D-F158-4B0C-A935-09332ECE2A51}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1FAE553D-F158-4B0C-A935-09332ECE2A51}.Release|Any CPU.Build.0 = Release|Any CPU
{B662F887-AAB6-4B73-B986-B8425E8EF0E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B662F887-AAB6-4B73-B986-B8425E8EF0E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B662F887-AAB6-4B73-B986-B8425E8EF0E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B662F887-AAB6-4B73-B986-B8425E8EF0E8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Просмотреть файл

@ -1,4 +1,5 @@
using System.Windows;
using CMSIS.Pack;
using System.Windows;
using System.Windows.Controls;
namespace NetmfPackInstaller
@ -19,7 +20,7 @@ namespace NetmfPackInstaller
if( DataContext != null )
return;
var viewModel = new PackRepositoryViewModel( );
var viewModel = new PackRepositoryViewModel( RepositoryProvider.Repository );
DataContext = viewModel;
await viewModel.LoadAsync( );
}
@ -35,5 +36,10 @@ namespace NetmfPackInstaller
if( overflowGrid != null )
overflowGrid.Visibility = Visibility.Collapsed;
}
// For now there is only one provider of repositories for an installed MDK
// eventually others may be supported if more third party tools start supporting
// the CMSIS-PACK format.
private IRepositoryProvider RepositoryProvider = new MDKRepositoryProvider( );
}
}

Просмотреть файл

@ -11,6 +11,7 @@ namespace NetmfPackInstaller
{
Initialized,
DownloadingPdsc,
PdscNotAvailable,
Ready
}
@ -32,7 +33,7 @@ namespace NetmfPackInstaller
// get the PDSC async, parse to get description
PackageDescription = await PackageRef.GetPackageDescriptionAsync( );
State = PackReferenceState.Ready;
State = PackageDescription == null ? PackReferenceState.PdscNotAvailable : PackReferenceState.Ready;
}
public PackReferenceState State

Просмотреть файл

@ -19,14 +19,12 @@ namespace NetmfPackInstaller
public class PackRepositoryViewModel
: ViewModelBase
{
public PackRepositoryViewModel()
public PackRepositoryViewModel( IRepository repository )
{
// for now, just hard code location of local repository
// and use the default cloud URL
Repository = new PackRepository(@"c:\Keil_v5\ARM\Pack");
Repository = repository;
State = LoadState.LoadingIndex;
Packs = new ObservableCollection<PackReferenceViewModel>( );
RefreshIndexCommand_ = new RelayCommand( RefreshIndexAsync, CanRefreshIndex );
RefreshIndexCommand = new RelayCommand( RefreshIndexAsync, CanRefreshIndex );
}
internal async Task LoadAsync( )
@ -44,15 +42,11 @@ namespace NetmfPackInstaller
State = LoadState.Ready;
}
public ICommand RefreshIndexCommand
{
get { return RefreshIndexCommand_; }
}
private readonly RelayCommand RefreshIndexCommand_;
public ICommand RefreshIndexCommand { get; }
public DateTime LastUpdated { get { return Repository.LastUpdatedTimeUTC.ToLocalTime(); } }
public DateTime LastUpdated => Repository.LastUpdatedTimeUTC.ToLocalTime( );
public ObservableCollection<PackReferenceViewModel> Packs { get; private set; }
public ObservableCollection<PackReferenceViewModel> Packs { get; }
public LoadState State
{
@ -65,17 +59,14 @@ namespace NetmfPackInstaller
}
private LoadState State__;
private bool CanRefreshIndex( )
{
return State == LoadState.Ready;
}
private bool CanRefreshIndex( ) => State == LoadState.Ready;
private async void RefreshIndexAsync( )
{
await Repository.UpdateLocalFromSourceAsync( );
}
private readonly PackRepository Repository;
private readonly IRepository Repository;
private readonly Dispatcher Dispatcher = Dispatcher.CurrentDispatcher;
}
}

Просмотреть файл

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,77 @@
#define MERGE_VENDOR_ENUMS
using CMSIS.Pack;
using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using System.Xml.Schema;
namespace ValidatePackSchema
{
class Program
{
// map of the schema version numbers to the Resource name of the schema file
static SchemaMap SchemaVersionMap = new SchemaMap
{
// Version | Schema resource
new SchemaMapEntry( "1.0" , "ValidatePackSchema.PACK_1_3_0.xsd" ), // + schema versions prior to 1.3.0 not available on GitHub
new SchemaMapEntry( "1.2" , "ValidatePackSchema.PACK_1_3_0.xsd" ), // | nor from Keil.com/pack. Thus, this uses the earliest
new SchemaMapEntry( "1.1" , "ValidatePackSchema.PACK_1_3_0.xsd" ), // | available schema for pack descriptions with older schema
new SchemaMapEntry( "1.3" , "ValidatePackSchema.PACK_1_3_0.xsd" ), // + version attributes
new SchemaMapEntry( "1.3.3" , "ValidatePackSchema.PACK_1_3_3.xsd" ),
new SchemaMapEntry( "1.4" , "ValidatePackSchema.PACK_1_4_0.xsd" ),
new SchemaMapEntry( "1.4.2" , "ValidatePackSchema.PACK_1_4_2.xsd" ),
new SchemaMapEntry( "1.4.6" , "ValidatePackSchema.PACK_1_4_6.xsd" ),
};
static IRepositoryProvider RepoProvider = new MDKRepositoryProvider( );
// This app is used to display the schema validation failures for the
// descriptions present in an MDK repository's .Web location
static void Main( string[ ] args )
{
// workaround buggy in-field PDSC files by re-writing the
// schemas to contain a set of enumerated values for the
// DeviceVendorEnum that is the union of the values from
// all the schema versions.
#if MERGE_VENDOR_ENUMS
SchemaVersionMap.MergeVendorEnums( );
#endif
foreach( var pdsc in Directory.EnumerateFiles( RepoProvider.Repository.WebRoot, "*.pdsc" ) )
{
ActivePackDescription = pdsc;
var doc = XDocument.Load( pdsc );
ActiveSchemaVersion = ( from package in doc.Elements( "package" )
let version = package.Attribute( "schemaVersion" )
where version != null
select version.Value
).FirstOrDefault( );
SchemaMapEntry mapEntry;
if( !SchemaVersionMap.TryGetValue( ActiveSchemaVersion, out mapEntry ) )
{
Console.Error.WriteLine( $"ERROR: {pdsc}: Unknown schemaVersion='{ActiveSchemaVersion}'" );
}
else
{
var schemaSet = new XmlSchemaSet( );
schemaSet.Add( mapEntry.Schema );
doc.Validate( schemaSet, ValidationHandler );
}
}
if( System.Diagnostics.Debugger.IsAttached )
Console.ReadLine( );
}
static string ActiveSchemaVersion;
static string ActivePackDescription;
private static void ValidationHandler( object sender, ValidationEventArgs e )
{
// Unfortunately "({e.Exception.LineNumber},{e.Exception.LinePosition})" always ends up as (0,0)
Console.Error.WriteLine( $"ERROR: using Schema version {ActiveSchemaVersion} with {ActivePackDescription}: {e.Message}" );
}
}
}

Просмотреть файл

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle( "ValidatePackSchema" )]
[assembly: AssemblyDescription( "" )]
[assembly: AssemblyConfiguration( "" )]
[assembly: AssemblyCompany( "" )]
[assembly: AssemblyProduct( "ValidatePackSchema" )]
[assembly: AssemblyCopyright( "Copyright © 2016" )]
[assembly: AssemblyTrademark( "" )]
[assembly: AssemblyCulture( "" )]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible( false )]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid( "b662f887-aab6-4b73-b986-b8425e8ef0e8" )]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion( "1.0.0.0" )]
[assembly: AssemblyFileVersion( "1.0.0.0" )]

Просмотреть файл

@ -0,0 +1,106 @@
using System;
using System.Linq;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml;
using System.IO;
namespace ValidatePackSchema
{
internal class SchemaMapEntry
{
public SchemaMapEntry( string version, string resourceName )
{
Version = version;
PackResourceName = resourceName;
LazySchemaDoc = new Lazy<XDocument>( LoadSchemaDoc );
LazySchema = new Lazy<XmlSchema>( LoadSchema );
}
public string Version { get; }
public string PackResourceName { get; }
public XDocument SchemaDoc => LazySchemaDoc.Value;
public XmlSchema Schema => LazySchema.Value;
private XDocument LoadSchemaDoc( )
{
using( var strm = Assembly.GetExecutingAssembly( ).GetManifestResourceStream( PackResourceName ) )
{
return XDocument.Load( strm );
}
}
private XmlSchema LoadSchema( )
{
using( var rdr = new StringReader( SchemaDoc.ToString( ) ) )
{
return XmlSchema.Read( rdr, ValidationHandler );
}
}
private static void ValidationHandler( object sender, ValidationEventArgs e )
{
// Unfortunately "({e.Exception.LineNumber},{e.Exception.LinePosition})" always ends up as (0,0)
Console.Error.WriteLine( $"ERROR: {e.Exception.SourceUri}: {e.Message}" );
}
private Lazy<XDocument> LazySchemaDoc;
private Lazy<XmlSchema> LazySchema;
}
class SchemaMap
: KeyedCollection<string, SchemaMapEntry>
{
protected override string GetKeyForItem( SchemaMapEntry item ) => item.Version;
public bool TryGetValue( string ver, out SchemaMapEntry entry )
{
entry = null;
if( Dictionary == null )
return false;
return Dictionary.TryGetValue( ver, out entry );
}
/// <summary>Works around errant PSDC files by merging all DeviceVendorEnum sets</summary>
/// <remarks>
/// Many PDSC files in the real world contain DeviceVendorEnum values not listed in the
/// schema version the PSDC claims to be from. This, will try and deal with the issue
/// by merging all known values from all of the available schemas. Then, replacing all
/// of the schemas nodes with a newly created one containing the full list.
/// </remarks>
public void MergeVendorEnums()
{
// find all the xs:restrictions whose child xs:enumerations elements should be replaced
var restrictions = from entry in Dictionary.Values
from simpleType in entry.SchemaDoc.Descendants( XsSimpleType )
let nameAttrib = simpleType.Attribute("name")
where nameAttrib != null && nameAttrib.Value == "DeviceVendorEnum"
from restriction in simpleType.Descendants( XsRestriction )
select restriction;
// construct a new set of enumeration elements that is the union of
// all the of enumerations from all the schemas
var newEnums = ( from restriction in restrictions
from enumeration in restriction.Descendants( XsEnumeration )
select enumeration.Attribute( "value" ).Value
).Distinct( )
.Select( value => new XElement( XsEnumeration, new XAttribute( "value", value ) ) )
.ToArray();
// replace the enumeration sets in each schema
foreach( var restriction in restrictions )
{
restriction.ReplaceNodes( newEnums );
}
}
const string XSDNamespace = "http://www.w3.org/2001/XMLSchema";
XName XsSimpleType = XName.Get( "simpleType", XSDNamespace );
XName XsRestriction = XName.Get( "restriction", XSDNamespace );
XName XsEnumeration = XName.Get( "enumeration", XSDNamespace );
}
}

Просмотреть файл

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B662F887-AAB6-4B73-B986-B8425E8EF0E8}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ValidatePackSchema</RootNamespace>
<AssemblyName>ValidatePackSchema</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SchemaMap.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<EmbeddedResource Include="PACK_1_4_6.xsd">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="PACK_1_4_2.xsd">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="PACK_1_4_0.xsd">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="PACK_1_3_3.xsd">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="PACK_1_3_0.xsd">
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CMSIS.Pack\CMSIS.Pack.csproj">
<Project>{145d7231-c105-41be-b646-5d400097c744}</Project>
<Name>CMSIS.Pack</Name>
</ProjectReference>
<ProjectReference Include="..\SemVer.NET\SemVer.NET.csproj">
<Project>{1fae553d-f158-4b0c-a935-09332ece2a51}</Project>
<Name>SemVer.NET</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>