Copyright waiver under the Unlicense with BSD 3-Clause fallback.

This commit is contained in:
Tony Bark 2023-01-07 11:44:50 -05:00
parent dc2176b26d
commit 2794aa17f4
24 changed files with 572 additions and 473 deletions

View file

@ -9,15 +9,11 @@ TOMAS (**To**ny's **Ma**naged Operating **S**ystem) is a hobby operating system
### Prerequisites ### Prerequisites
- Windows 10 or later - Windows 10 or later
- Visual Studio 2022 - Visual Studio 2022
- .NET 6 or later - .NET 6 or later
- COSMOS User Kit v2022 or later - COSMOS User Kit v2022 or later
- VMWare Workstation Player - VMWare Workstation Player
## License ## License
This project is licensed under the BSD 3-Clause license - see the [LICENSE](LICENSE) file for details. In jurisdictions that recognize copyright waivers, I've [waived all copyright](UNLICENSE) and related or neighboring rights for to this project. In areas where these waivers are not recognized, [BSD-3-Clause](LICENSE) is enforced.

24
UNLICENSE Normal file
View file

@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org>

View file

@ -13,6 +13,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
..\LICENSE = ..\LICENSE ..\LICENSE = ..\LICENSE
..\README.md = ..\README.md ..\README.md = ..\README.md
TOMAS.sln.licenseheader = TOMAS.sln.licenseheader TOMAS.sln.licenseheader = TOMAS.sln.licenseheader
..\UNLICENSE = ..\UNLICENSE
EndProjectSection EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tomas.Interface", "Tomas.Interface\Tomas.Interface.csproj", "{DAA9EDF4-83C7-4271-9805-FD6CE29E1796}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tomas.Interface", "Tomas.Interface\Tomas.Interface.csproj", "{DAA9EDF4-83C7-4271-9805-FD6CE29E1796}"

View file

@ -1,4 +1,8 @@
extensions: designer.cs generated.cs extensions: designer.cs generated.cs
extensions: .cs .cpp .h .fs extensions: .cs .cpp .h .fs
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/

View file

@ -1,3 +1,9 @@
/*
In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
global using System.Diagnostics.CodeAnalysis; global using System.Diagnostics.CodeAnalysis;
global using System.Diagnostics; global using System.Diagnostics;
global using Tomas.Interface; global using Tomas.Interface;

View file

@ -1,13 +1,16 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
namespace Tomas.Common.Programs; waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
namespace Tomas.Core.Programs;
public class Clear : IProgram public class Clear : IProgram
{ {
public bool Run(IShell shell) public bool Run(IShell shell)
{ {
Console.Clear(); Console.Clear();
return true; return true;
} }
} }

View file

@ -1,7 +1,10 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
namespace Tomas.Common.Programs; waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
namespace Tomas.Core.Programs;
public class Commands : IProgram public class Commands : IProgram
{ {

View file

@ -1,15 +1,18 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
namespace Tomas.Common.Programs; waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
namespace Tomas.Core.Programs;
public class FenSay : IProgram public class FenSay : IProgram
{ {
/// <summary> /// <summary>
/// Fennec art by Todd Vargo /// Fennec art by Todd Vargo
/// </summary> /// </summary>
const string _fennec = @" \/ const string _fennec = @" \/
/\ /\ /\ /\
//\\_//\\ ____ //\\_//\\ ____
\_ _/ / / \_ _/ / /
@ -20,19 +23,19 @@ public class FenSay : IProgram
[ [ / \/ _/ [ [ / \/ _/
_[ [ \ /_/"; _[ [ \ /_/";
readonly string[] _phrases = readonly string[] _phrases =
{ {
"[SCREAMS IN FENNEC]", "[SCREAMS IN FENNEC]",
"Some people call me a coffee fox.", "Some people call me a coffee fox.",
"Drink Soda. It makes you see faster.", "Drink Soda. It makes you see faster.",
"10/10, Wouldn't Recommend." "10/10, Wouldn't Recommend."
}; };
public bool Run(IShell shell) public bool Run(IShell shell)
{ {
var rng = new Random(); var rng = new Random();
var phrases = _phrases[rng.Next(_phrases.Length)]; var phrases = _phrases[rng.Next(_phrases.Length)];
Console.WriteLine($"{phrases}{Environment.NewLine}{_fennec}"); Console.WriteLine($"{phrases}{Environment.NewLine}{_fennec}");
return true; return true;
} }
} }

View file

@ -1,14 +1,18 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
namespace Tomas.Interface; namespace Tomas.Interface;
public interface IProgram public interface IProgram
{ {
/// <summary> /// <summary>
/// The program's main entry point. Boolean behaves as an exit point. /// The program's main entry point. Boolean behaves as an exit point.
/// True and False are the equivalent to C's 0 and 1, i.e. "Success" and "Failure," respectfully. /// True and False are the equivalent to C's 0 and 1, i.e. "Success" and "Failure," respectfully.
/// </summary> /// </summary>
/// <param name="shell">Allows the program to interact with the shell.</param> /// <param name="shell">Allows the program to interact with the shell.</param>
/// <returns>Exit back to shell.</returns> /// <returns>Exit back to shell.</returns>
bool Run(IShell shell); bool Run(IShell shell);
} }

View file

@ -1,11 +1,14 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
namespace Tomas.Interface; namespace Tomas.Interface;
public interface IShell public interface IShell
{ {
string ReadLine { get; } string ReadLine { get; }
Dictionary<string, IProgram> Programs { get; } Dictionary<string, IProgram> Programs { get; }
} }

View file

@ -1,3 +1,9 @@
/*
In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
global using System.Diagnostics.CodeAnalysis; global using System.Diagnostics.CodeAnalysis;
global using System.Diagnostics; global using System.Diagnostics;
global using Tomas.Common.Programs; global using Tomas.Common.Programs;

View file

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

View file

@ -1,20 +1,23 @@
// This project is licensed under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
namespace Tomas.Kernel.Globalization; namespace Tomas.Kernel.Globalization;
public interface IUIText public interface IUIText
{ {
/// <summary> /// <summary>
/// The base directory for the language files. /// The base directory for the language files.
/// </summary> /// </summary>
string[] BasePath { get; set; } string[] BasePath { get; set; }
/// <summary> /// <summary>
/// Get the text for the given id and key. /// Get the text for the given id and key.
/// </summary> /// </summary>
/// <param name="id">The id of the text.</param> /// <param name="id">The id of the text.</param>
/// <param name="key">The key of the text.</param> /// <param name="key">The key of the text.</param>
/// <returns>The text for the given id and key.</returns> /// <returns>The text for the given id and key.</returns>
string GetText(int id, int key); string GetText(int id, int key);
} }

View file

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

View file

@ -1,6 +1,9 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
namespace Tomas.Kernel; namespace Tomas.Kernel;
public class Kernel : Os.Kernel public class Kernel : Os.Kernel

View file

@ -1,17 +1,20 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
namespace Tomas.Kernel.Programs; namespace Tomas.Kernel.Programs;
public class About : IProgram public class About : IProgram
{ {
public bool Run(IShell shell) public bool Run(IShell shell)
{ {
Console.WriteLine($"TOMAS v{SysMeta.VERSION} ({SysMeta.BuildNumber}) is a hobby operating system written in C# using the COSMOS framework.{Environment.NewLine}Commands:"); Console.WriteLine($"TOMAS v{SysMeta.VERSION} ({SysMeta.BuildNumber}) is a hobby operating system written in C# using the COSMOS framework.{Environment.NewLine}Commands:");
var progs = shell.Programs; var progs = shell.Programs;
foreach (var commands in progs.Keys) foreach (var commands in progs.Keys)
Console.WriteLine(commands); Console.WriteLine(commands);
return true; return true;
} }
} }

View file

@ -1,16 +1,19 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
namespace Tomas.Kernel; namespace Tomas.Kernel;
public class Shell : IShell public class Shell : IShell
{ {
// The symbol to display before the cursor when the shell is waiting for user input // The symbol to display before the cursor when the shell is waiting for user input
const char SYMBOL = '$'; const char SYMBOL = '$';
// A dictionary containing the programs available to the shell, with the keys being the program names // A dictionary containing the programs available to the shell, with the keys being the program names
// and the values being the program objects // and the values being the program objects
public Dictionary<string, IProgram> Programs => new() public Dictionary<string, IProgram> Programs => new()
{ {
{"about", new About() }, {"about", new About() },
{"fensay", new FenSay() }, {"fensay", new FenSay() },
@ -18,20 +21,20 @@ public class Shell : IShell
{"commands", new Commands() } {"commands", new Commands() }
}; };
// A property that allows the shell to read a line of input from the user // A property that allows the shell to read a line of input from the user
public string ReadLine public string ReadLine
{ {
get get
{ {
// Write the SYMBOL character to the console // Write the SYMBOL character to the console
Console.Write(SYMBOL); Console.Write(SYMBOL);
// Read a line of input from the user // Read a line of input from the user
var readl = Console.ReadLine(); var readl = Console.ReadLine();
// Return the line of input // Return the line of input
return readl; return readl;
} }
} }
} }

View file

@ -1,156 +1,159 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
namespace Tomas.Kernel; namespace Tomas.Kernel;
static class SysFS static class SysFS
{ {
// The root directory of the file system // The root directory of the file system
public const string ROOT_DIR = "0:\\"; public const string ROOT_DIR = "0:\\";
// The system directory, located in the root directory // The system directory, located in the root directory
static string SYSTEM_DIR = $"{ROOT_DIR}\\SYSTEM\\"; static string SYSTEM_DIR = $"{ROOT_DIR}\\SYSTEM\\";
static string LOG_FILE = $"{SYSTEM_DIR}system.log"; static string LOG_FILE = $"{SYSTEM_DIR}system.log";
public const string FS_ERROR = "File system disabled."; public const string FS_ERROR = "File system disabled.";
/// <summary> /// <summary>
/// An instance of the CosmosVFS class, used for accessing the virtual file system /// An instance of the CosmosVFS class, used for accessing the virtual file system
/// </summary> /// </summary>
static CosmosVFS fileSystem = new(); static CosmosVFS fileSystem = new();
/// <summary> /// <summary>
/// Initializes the file system by creating the system directory and sysinfo.txt file /// Initializes the file system by creating the system directory and sysinfo.txt file
/// and setting the IsFSActive property of the SysMeta class to true /// and setting the IsFSActive property of the SysMeta class to true
/// </summary> /// </summary>
public static void Initialize() public static void Initialize()
{ {
try try
{ {
var createSysFiles = "Creating system files."; var createSysFiles = "Creating system files.";
var setSysPref = "Writing system info."; var setSysPref = "Writing system info.";
var fsSuccess = "File system succesfully initialized."; var fsSuccess = "File system succesfully initialized.";
var sysInfoFile = "sysinfo.txt"; var sysInfoFile = "sysinfo.txt";
// Register the CosmosVFS instance as the virtual file system // Register the CosmosVFS instance as the virtual file system
VFSManager.RegisterVFS(fileSystem); VFSManager.RegisterVFS(fileSystem);
// Create the system directory // Create the system directory
if (!Directory.Exists(SYSTEM_DIR)) if (!Directory.Exists(SYSTEM_DIR))
fileSystem.CreateDirectory(SYSTEM_DIR); fileSystem.CreateDirectory(SYSTEM_DIR);
// Create the system.log file in the system directory // Create the system.log file in the system directory
if (!File.Exists($"{SYSTEM_DIR}{LOG_FILE}")) if (!File.Exists($"{SYSTEM_DIR}{LOG_FILE}"))
fileSystem.CreateFile($"{SYSTEM_DIR}{LOG_FILE}"); fileSystem.CreateFile($"{SYSTEM_DIR}{LOG_FILE}");
Console.WriteLine(createSysFiles); Console.WriteLine(createSysFiles);
File.AppendAllText(LOG_FILE, createSysFiles); File.AppendAllText(LOG_FILE, createSysFiles);
// Create the sysinfo.txt file in the system directory // Create the sysinfo.txt file in the system directory
if (!File.Exists($"{SYSTEM_DIR}{sysInfoFile}")) if (!File.Exists($"{SYSTEM_DIR}{sysInfoFile}"))
fileSystem.CreateFile($"{SYSTEM_DIR}{sysInfoFile}"); fileSystem.CreateFile($"{SYSTEM_DIR}{sysInfoFile}");
Console.WriteLine(setSysPref); Console.WriteLine(setSysPref);
File.AppendAllText(LOG_FILE, setSysPref); File.AppendAllText(LOG_FILE, setSysPref);
// Write the system name, version, and build number to the sysinfo.txt file // Write the system name, version, and build number to the sysinfo.txt file
File.WriteAllText($"{SYSTEM_DIR}sysinfo.txt", $"{SysMeta.NAME} v{SysMeta.VERSION} ({SysMeta.BuildNumber})"); File.WriteAllText($"{SYSTEM_DIR}sysinfo.txt", $"{SysMeta.NAME} v{SysMeta.VERSION} ({SysMeta.BuildNumber})");
Console.WriteLine(fsSuccess); Console.WriteLine(fsSuccess);
File.AppendAllText(LOG_FILE, fsSuccess); File.AppendAllText(LOG_FILE, fsSuccess);
// Set the IsFSActive property of the SysMeta class to true // Set the IsFSActive property of the SysMeta class to true
SysMeta.IsFSEnabled = true; SysMeta.IsFSEnabled = true;
// Read the contents of the sysinfo.txt file and print it to the console // Read the contents of the sysinfo.txt file and print it to the console
var systemInfo = File.ReadAllText($"{SYSTEM_DIR}sysinfo.txt"); var systemInfo = File.ReadAllText($"{SYSTEM_DIR}sysinfo.txt");
Console.WriteLine(systemInfo); Console.WriteLine(systemInfo);
} }
catch (Exception err) catch (Exception err)
{ {
// If an exception is caught, print an error message indicating that the file system failed to load // If an exception is caught, print an error message indicating that the file system failed to load
Console.WriteLine($"{err.Message}{Environment.NewLine}Warning: Error messages will not logged."); Console.WriteLine($"{err.Message}{Environment.NewLine}Warning: Error messages will not logged.");
} }
} }
/// <summary> /// <summary>
/// Creates a new directory at the specified path /// Creates a new directory at the specified path
/// </summary> /// </summary>
/// <param name="directory">directory</param> /// <param name="directory">directory</param>
public static void CreateDirectory(string directory) public static void CreateDirectory(string directory)
{ {
try try
{ {
// If file system isn't enabeld, throw exception // If file system isn't enabeld, throw exception
if (!SysMeta.IsFSEnabled) if (!SysMeta.IsFSEnabled)
throw new IOException(FS_ERROR); throw new IOException(FS_ERROR);
// Create the directory using the CosmosVFS instance // Create the directory using the CosmosVFS instance
if (!Directory.Exists($"{ROOT_DIR}\\{directory}")) if (!Directory.Exists($"{ROOT_DIR}\\{directory}"))
fileSystem.CreateDirectory($"{ROOT_DIR}\\{directory}"); fileSystem.CreateDirectory($"{ROOT_DIR}\\{directory}");
} }
catch (IOException err) catch (IOException err)
{ {
// If an exception is caught, print an error message indicating the error // If an exception is caught, print an error message indicating the error
Console.WriteLine(err.Message); Console.WriteLine(err.Message);
File.AppendAllText(LOG_FILE, err.Message); File.AppendAllText(LOG_FILE, err.Message);
} }
} }
/// <summary> /// <summary>
/// Creates a new file at the specified path /// Creates a new file at the specified path
/// </summary> /// </summary>
/// <param name="path">file path</param> /// <param name="path">file path</param>
/// <param name="file">file</param> /// <param name="file">file</param>
public static void CreateFile(string path, string file) public static void CreateFile(string path, string file)
{ {
try try
{ {
// If file system isn't enabeld, throw exception // If file system isn't enabeld, throw exception
if (!SysMeta.IsFSEnabled) if (!SysMeta.IsFSEnabled)
throw new IOException(FS_ERROR); throw new IOException(FS_ERROR);
// Create the file using the CosmosVFS instance // Create the file using the CosmosVFS instance
if (!File.Exists($"{ROOT_DIR}\\{path}\\{file}")) if (!File.Exists($"{ROOT_DIR}\\{path}\\{file}"))
fileSystem.CreateFile($"{ROOT_DIR}\\{path}\\{file}"); fileSystem.CreateFile($"{ROOT_DIR}\\{path}\\{file}");
} }
catch (IOException err) catch (IOException err)
{ {
// If an exception is caught, print an error message indicating the error // If an exception is caught, print an error message indicating the error
Console.WriteLine(err.Message); Console.WriteLine(err.Message);
File.AppendAllText(LOG_FILE, err.Message); File.AppendAllText(LOG_FILE, err.Message);
} }
} }
/// <summary> /// <summary>
/// Lists all directories in the specified path /// Lists all directories in the specified path
/// </summary> /// </summary>
/// <param name="path">path to directory</param> /// <param name="path">path to directory</param>
/// <returns>returns a list of directories</returns> /// <returns>returns a list of directories</returns>
public static string[] ListDirectories(string path) public static string[] ListDirectories(string path)
{ {
try try
{ {
// If file system isn't enabeld, throw exception // If file system isn't enabeld, throw exception
if (!SysMeta.IsFSEnabled) if (!SysMeta.IsFSEnabled)
throw new IOException(FS_ERROR); throw new IOException(FS_ERROR);
// Get the directories in the specified path using the Directory.GetDirectories method // Get the directories in the specified path using the Directory.GetDirectories method
var dirs = Directory.GetDirectories(path); var dirs = Directory.GetDirectories(path);
// Return the directories // Return the directories
return dirs; return dirs;
} }
catch (IOException err) catch (IOException err)
{ {
// If an exception is caught, print an error message indicating the error // If an exception is caught, print an error message indicating the error
Console.WriteLine(err.Message); Console.WriteLine(err.Message);
File.AppendAllText(LOG_FILE, err.Message); File.AppendAllText(LOG_FILE, err.Message);
throw; throw;
} }
} }
} }

View file

@ -1,3 +1,9 @@
/*
In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
using System.Text; using System.Text;
namespace Tomas.Kernel; namespace Tomas.Kernel;

View file

@ -1,3 +1,9 @@
/*
In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
global using System.Diagnostics.CodeAnalysis; global using System.Diagnostics.CodeAnalysis;
global using System.Diagnostics; global using System.Diagnostics;
global using Tomas.Common.Programs; global using Tomas.Common.Programs;

View file

@ -1,40 +1,43 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
namespace Tomas.Terminal; namespace Tomas.Terminal;
class Program class Program
{ {
static void Main() static void Main()
{
while (true)
{
var shell = new Shell();
var command = shell.ReadLine;
var programs = shell.Programs;
if (!programs.TryGetValue(command, out var program))
{
Console.WriteLine("Command Not Found.");
continue;
}
try
{
var start = program.Run(shell);
switch (start)
{ {
while (true) case true:
{ continue;
var shell = new Shell(); case false:
var command = shell.ReadLine; Console.WriteLine("Program closed unexpectedly.");
var programs = shell.Programs; continue;
if (!programs.TryGetValue(command, out var program))
{
Console.WriteLine("Command Not Found.");
continue;
}
try
{
var start = program.Run(shell);
switch (start)
{
case true:
continue;
case false:
Console.WriteLine("Program closed unexpectedly.");
continue;
}
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
}
} }
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
}
}
} }

View file

@ -1,14 +1,16 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
using Tomas.Common; and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
namespace Tomas.Terminal.Programs; namespace Tomas.Terminal.Programs;
public class About : IProgram public class About : IProgram
{ {
public bool Run(IShell shell) public bool Run(IShell shell)
{ {
Console.WriteLine($"{TermMeta.NAME} Terminal Emulator v{TermMeta.VERSION}"); Console.WriteLine($"{TermMeta.NAME} Terminal Emulator v{TermMeta.VERSION}");
return true; return true;
} }
} }

View file

@ -1,14 +1,18 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
using Tomas.Terminal.Programs; using Tomas.Terminal.Programs;
namespace Tomas.Terminal; namespace Tomas.Terminal;
public class Shell : IShell public class Shell : IShell
{ {
const char SYMBOL = '$'; const char SYMBOL = '$';
public Dictionary<string, IProgram> Programs => new() public Dictionary<string, IProgram> Programs => new()
{ {
{"about", new About()}, {"about", new About()},
{"fensay", new FenSay()}, {"fensay", new FenSay()},
@ -16,13 +20,13 @@ public class Shell : IShell
{"commands", new Commands()} {"commands", new Commands()}
}; };
public string ReadLine public string ReadLine
{ {
get get
{ {
Console.Write(SYMBOL); Console.Write(SYMBOL);
var readl = Console.ReadLine(); var readl = Console.ReadLine();
return readl; return readl;
} }
} }
} }

View file

@ -1,48 +1,52 @@
// I license this project under the BSD 3-Clause license. /*
// See the LICENSE file in the project root for more information. In jurisdictions that recognize copyright waivers, I've waived all copyright
and related or neighboring rights for to this project. In areas where these
waivers are not recognized, BSD-3-Clause is enforced.
See the (UN)LICENSE file in the project root for more information.
*/
using System.Text; using System.Text;
namespace Tomas.Common; namespace Tomas.Terminal;
/// <summary> /// <summary>
/// System metdata, such as name, version and build number. /// System metdata, such as name, version and build number.
/// </summary> /// </summary>
public struct TermMeta public struct TermMeta
{ {
/// <summary> /// <summary>
/// The name of the operating system. /// The name of the operating system.
/// </summary> /// </summary>
public const string NAME = "TOMAS Emulator"; public const string NAME = "TOMAS Emulator";
/// <summary> /// <summary>
/// The version of the operating system, in the Calendar Versioning format: "yy.minor.patch". /// 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 /// The year, minor, and patch version numbers are automatically extracted from the Git repository
/// using the ThisAssembly.Git.SemVer object. /// using the ThisAssembly.Git.SemVer object.
/// </summary> /// </summary>
public const string VERSION = $"{ThisAssembly.Git.SemVer.Major}.{ThisAssembly.Git.SemVer.Minor}.{ThisAssembly.Git.SemVer.Patch}"; public const string VERSION = $"{ThisAssembly.Git.SemVer.Major}.{ThisAssembly.Git.SemVer.Minor}.{ThisAssembly.Git.SemVer.Patch}";
/// <summary> /// <summary>
/// The build number of the operating system, generated from the commit hash. /// 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 /// 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. /// converted to a uint, and the last 3 digits being the last 3 digits of the commit hash converted to a uint.
/// </summary> /// </summary>
public static string BuildNumber = $"Build {BuildNumFromCommit}"; public static string BuildNumber = $"Build {BuildNumFromCommit}";
/// <summary> /// <summary>
/// Generates the build number from the commit hash. /// Generates the build number from the commit hash.
/// </summary> /// </summary>
/// <returns>The build number as a uint.</returns> /// <returns>The build number as a uint.</returns>
static uint BuildNumFromCommit static uint BuildNumFromCommit
{ {
get get
{ {
// Get the bytes of the commit hash as a UTF-8 encoded string // Get the bytes of the commit hash as a UTF-8 encoded string
var commit = Encoding.UTF8.GetBytes(ThisAssembly.Git.Commit); 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 // 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 // (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) // and the last 3 digits being the last 3 digits of the commit hash)
return BitConverter.ToUInt32(commit, 0) % 1000000; return BitConverter.ToUInt32(commit, 0) % 1000000;
} }
} }
} }