Renamed Tomas.Common to Tomas.Core

- Imported CSTNet parser to kernal under Globalization namespace
- Added System.Diagnostics to global usings
- Split version systems between kernal and terminal emulator (see changelog)
This commit is contained in:
Tony Bark 2023-01-07 11:22:38 -05:00
parent 7b56b93edd
commit dc2176b26d
20 changed files with 300 additions and 28 deletions

View file

@ -2,10 +2,10 @@
## v23.0
- Calendar versioning, `YY.MINOR.MICRO`
- Split versioning systems between kernal and terminal
- Calendar versioning, `YY.MINOR.MICRO`, for kernal
- Semantic versioning for terminal
- If the file system is activate, system activity will be logged
- Build number based on commit hash
Due to the huge time skip and architectural changes, I've (retroactively) switched to calendar versioning with ``v0.1`` now known as ``v20.1`` as well.

View file

@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33205.214
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tomas.Common", "Tomas.Common\Tomas.Common.csproj", "{C50F3A6F-CFF4-4725-A1A5-21C5A2BC3321}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tomas.Core", "Tomas.Core\Tomas.Core.csproj", "{C50F3A6F-CFF4-4725-A1A5-21C5A2BC3321}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{59C9B3FC-B1EE-4C23-9BD9-D33074BF1334}"
ProjectSection(SolutionItems) = preProject

View file

@ -1,2 +1,3 @@
global using System.Diagnostics.CodeAnalysis;
global using System.Diagnostics;
global using Tomas.Interface;

View file

@ -9,11 +9,4 @@
<ProjectReference Include="..\Tomas.Interface\Tomas.Interface.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="GitInfo" Version="2.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View file

@ -1,3 +1,5 @@
global using System.Diagnostics.CodeAnalysis;
global using System.Diagnostics;
global using Tomas.Common.Programs;
global using Tomas.Interface;
global using Tomas.Kernel.Programs;

View file

@ -0,0 +1,98 @@
// This project is licensed under the BSD 3-Clause license.
// See the LICENSE file in the project root for more information.
namespace Tomas.Kernel.Globalization;
public class CST
{
const char CARET = '^';
const string LF = "\u000A";
const string CR = "\u000D";
const string CRLF = "\u000D\u000A";
const string LS = "\u2028";
/// <summary>
/// Gets the value from the digit-based key.
/// </summary>
/// <returns>Returns the entry</returns>
public static string Parse(string content, int key) => Parse(content, key.ToString());
/// <summary>
/// Gets the value from the string-based key.
/// </summary>
/// <returns>Returns the entry</returns>
public static string Parse(string content, string key)
{
var entries = NormalizeEntries(content);
return GetEntry(entries, key);
}
/// <summary>
/// Replaces the document's line endings with the native system line endings.
/// </summary>
/// <remarks>This stage ensures there are no crashes during parsing.</remarks>
/// <param name="content">The content of the document.</param>
/// <returns>The document's content with native system line endings.</returns>
static IEnumerable<string> NormalizeEntries(string content)
{
// Check if the document already uses native system line endings.
if (!content.Contains(Environment.NewLine))
{
// If not, check for and replace other line ending types.
if (content.Contains(LF))
content = content.Replace(LF, Environment.NewLine);
if (content.Contains(CR))
content = content.Replace(CR, Environment.NewLine);
if (content.Contains(CRLF))
content = content.Replace(CRLF, Environment.NewLine);
if (content.Contains(LS))
content = content.Replace(LS, Environment.NewLine);
}
// Split the content by the caret and newline characters.
var lines = content.Split(new[] { $"{CARET}{Environment.NewLine}" },
StringSplitOptions.RemoveEmptyEntries);
// Filter out any lines that start with "//", "#", "/*", or end with "*/".
return lines.Where(line =>
!line.StartsWith("//") &&
!line.StartsWith("#") &&
!line.StartsWith("/*") &&
!line.EndsWith("*/"))
.AsEnumerable();
}
/// <summary>
/// Retrieves the value for the specified key from the given entries.
/// </summary>
/// <param name="entries">The entries to search through.</param>
/// <param name="key">The key to search for.</param>
/// <returns>The value for the specified key, or a default string if not found.</returns>
static string GetEntry(IEnumerable<string> entries, string key)
{
// Iterate through the entries.
foreach (var entry in entries)
{
// If the line doesn't start with the key, keep searching.
if (!entry.StartsWith(key))
continue;
// Locate the index of the caret character.
var startIndex = entry.IndexOf(CARET);
// Get the line from the caret character to the end of the string.
var line = entry[startIndex..];
// Return the line with the caret characters trimmed.
return line.TrimStart(CARET).TrimEnd(CARET);
}
// If no entry is found, return a default string.
return "***MISSING***";
}
}

View file

@ -0,0 +1,20 @@
// This project is licensed under the BSD 3-Clause license.
// See the LICENSE file in the project root for more information.
namespace Tomas.Kernel.Globalization;
public interface IUIText
{
/// <summary>
/// The base directory for the language files.
/// </summary>
string[] BasePath { get; set; }
/// <summary>
/// Get the text for the given id and key.
/// </summary>
/// <param name="id">The id of the text.</param>
/// <param name="key">The key of the text.</param>
/// <returns>The text for the given id and key.</returns>
string GetText(int id, int key);
}

View file

@ -0,0 +1,101 @@
// This project is licensed under the BSD 3-Clause license.
// See the LICENSE file in the project root for more information.
namespace Tomas.Kernel.Globalization;
public class UIText : IUIText
{
/// <summary>
/// The language of the text.
/// </summary>
string Language { get; set; } = "english";
/// <summary>
/// The base directory for the language files.
/// </summary>
public string[] BasePath { get; set; } = { AppContext.BaseDirectory, "uitext" };
/// <summary>
/// Constructor for the UIText class.
/// </summary>
public UIText() { }
/// <summary>
/// Constructor for the UIText class.
/// Loads the language file for the specified language.
/// </summary>
/// <param name="language">Language to load</param>
public UIText(string language)
{
Language = language;
}
/// <summary>
/// Constructor for the UIText class.
/// Loads the language file for the specified language and base directory.
/// </summary>
/// <param name="language">Language to load</param>
/// <param name="basePath">Base directory for the language files.</param>
public UIText(string language, params string[] baseBath)
{
Language = language;
BasePath = baseBath;
}
/// <summary>
/// Get the text for the given id and key.
/// </summary>
/// <param name="id">The id of the text.</param>
/// <param name="key">The key of the text.</param>
/// <returns>The text for the given id and key.</returns>
public string GetText(int id, int key) => GetText(id, key.ToString());
/// <summary>
/// Get the text for the given id and key.
/// </summary>
/// <param name="id">The id of the text.</param>
/// <param name="key">The key of the text.</param>
/// <returns>The text for the given id and key.</returns>
public string GetText(int id, string key)
{
// Combine the base path and language path to get the full path of the language file.
var basePath = Path.Combine(BasePath);
var langPath = Path.Combine(basePath, $"{Language}.dir");
// Get all the files in the language directory.
var files = Directory.GetFiles(langPath);
// Iterate through the files in the language directory.
foreach (var file in files)
{
// Skip files that do not have the ".cst" extension.
if (!file.Contains(".cst"))
continue;
// Get the id of the current file.
var ids = Path.GetFileName(file);
var second = ids.IndexOf("_", 1, StringComparison.InvariantCultureIgnoreCase);
if (second == -1)
continue;
ids = ids.Substring(1, second - 1);
// If the id of the current file does not match the id passed to the function,
// skip to the next file.
if (ids != id.ToString())
continue;
// Read the content of the current file.
var content = File.ReadAllText(file);
// Return the text for the specified key.
return CST.Parse(content, key);
}
// If no text is found, return a default string.
return "***MISSING***";
}
}

View file

@ -6,13 +6,13 @@ namespace Tomas.Kernel;
static class SysFS
{
// The root directory of the file system
const string ROOT_DIR = "0:\\";
public const string ROOT_DIR = "0:\\";
// The system directory, located in the root directory
static string SYSTEM_DIR = $"{ROOT_DIR}\\SYSTEM\\";
static string LOG_FILE = $"{SYSTEM_DIR}system.log";
const string FS_ERROR = "File system disabled.";
public const string FS_ERROR = "File system disabled.";
/// <summary>
/// An instance of the CosmosVFS class, used for accessing the virtual file system

View file

@ -1,13 +1,8 @@
// I license this project under the BSD 3-Clause license.
// See the LICENSE file in the project root for more information.
using System.Text;
namespace Tomas.Common;
namespace Tomas.Kernel;
/// <summary>
/// System metdata, such as name, version and build number.
/// </summary>
public struct SysMeta
internal struct SysMeta
{
/// <summary>
/// The name of the operating system.

View file

@ -25,10 +25,14 @@
<PackageReference Include="Cosmos.Build" Version="0-*" NoWarn="NU1604" />
<PackageReference Include="Cosmos.Debug.Kernel" Version="0-*" NoWarn="NU1604" />
<PackageReference Include="Cosmos.System2" Version="0-*" NoWarn="NU1604" />
<PackageReference Include="GitInfo" Version="2.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Tomas.Common\Tomas.Common.csproj" />
<ProjectReference Include="..\Tomas.Core\Tomas.Core.csproj" />
<ProjectReference Include="..\Tomas.Interface\Tomas.Interface.csproj" />
</ItemGroup>

View file

@ -0,0 +1 @@
0.1

View file

@ -1,2 +1,4 @@
global using System.Diagnostics.CodeAnalysis;
global using System.Diagnostics;
global using Tomas.Common.Programs;
global using Tomas.Interface;

View file

@ -6,10 +6,9 @@ namespace Tomas.Terminal.Programs;
public class About : IProgram
{
public bool Run(IShell shell)
{
Console.WriteLine($"{SysMeta.NAME} Terminal Emulator v{SysMeta.BuildNumber}{Environment.NewLine}"
+ "TOMAS (Tony's Managed Operating System) is a operating system written in C# using the COSMOS framework.");
return true;
}
public bool Run(IShell shell)
{
Console.WriteLine($"{TermMeta.NAME} Terminal Emulator v{TermMeta.VERSION}");
return true;
}
}

View file

@ -0,0 +1,48 @@
// I license this project under the BSD 3-Clause license.
// See the LICENSE file in the project root for more information.
using System.Text;
namespace Tomas.Common;
/// <summary>
/// System metdata, such as name, version and build number.
/// </summary>
public struct TermMeta
{
/// <summary>
/// The name of the operating system.
/// </summary>
public const string NAME = "TOMAS Emulator";
/// <summary>
/// The version of the operating system, in the Calendar Versioning format: "yy.minor.patch".
/// The year, minor, and patch version numbers are automatically extracted from the Git repository
/// using the ThisAssembly.Git.SemVer object.
/// </summary>
public const string VERSION = $"{ThisAssembly.Git.SemVer.Major}.{ThisAssembly.Git.SemVer.Minor}.{ThisAssembly.Git.SemVer.Patch}";
/// <summary>
/// The build number of the operating system, generated from the commit hash.
/// The build number is a 6-digit number, with the first 3 digits being the first 3 digits of the commit hash
/// converted to a uint, and the last 3 digits being the last 3 digits of the commit hash converted to a uint.
/// </summary>
public static string BuildNumber = $"Build {BuildNumFromCommit}";
/// <summary>
/// Generates the build number from the commit hash.
/// </summary>
/// <returns>The build number as a uint.</returns>
static uint BuildNumFromCommit
{
get
{
// Get the bytes of the commit hash as a UTF-8 encoded string
var commit = Encoding.UTF8.GetBytes(ThisAssembly.Git.Commit);
// Convert the first 4 bytes of the commit hash to a uint and return it modulo 1000000
// (this will give us a 6-digit number with the first 3 digits being the first 3 digits of the commit hash
// and the last 3 digits being the last 3 digits of the commit hash)
return BitConverter.ToUInt32(commit, 0) % 1000000;
}
}
}

View file

@ -8,7 +8,15 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Tomas.Common\Tomas.Common.csproj" />
<PackageReference Include="GitInfo" Version="2.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NLua" Version="1.6.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Tomas.Core\Tomas.Core.csproj" />
<ProjectReference Include="..\Tomas.Interface\Tomas.Interface.csproj" />
</ItemGroup>