summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/gen-amdgpuids.py46
-rwxr-xr-xscripts/gen-man.py327
-rwxr-xr-xscripts/gen-pciids.py98
3 files changed, 471 insertions, 0 deletions
diff --git a/scripts/gen-amdgpuids.py b/scripts/gen-amdgpuids.py
new file mode 100755
index 0000000..d84c133
--- /dev/null
+++ b/scripts/gen-amdgpuids.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+
+import sys
+
+def main(amdgpu_ids_path: str):
+ with open(amdgpu_ids_path, 'r') as f:
+ full_text = f.read()
+
+ if full_text == '':
+ sys.exit(f'Error: {amdgpu_ids_path} file is empty')
+
+ products = []
+ for line in full_text.split('\n'):
+ if not line or line[0] == '#' or not ',\t' in line:
+ continue
+ device, revision, name = line.split(',\t', maxsplit=2)
+ products.append((device, revision, name))
+
+ code = """\
+// SPDX-License-Identifier: MIT
+// https://opensource.org/license/mit
+// Generated from https://gitlab.freedesktop.org/mesa/drm/-/raw/main/data/amdgpu.ids
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef struct FFArmGpuProduct
+{
+ const uint32_t id; // device << 8 | revision
+ const char* name;
+} FFArmGpuProduct;
+
+const FFArmGpuProduct ffAmdGpuProducts[] = {
+"""
+
+ for device, revision, name in products:
+ code += f" {{ 0x{device} << 8 | 0x{revision}, \"{name}\" }},\n"
+
+ code += "};\n"
+
+ print(code)
+
+if __name__ == '__main__':
+ len(sys.argv) == 2 or sys.exit('Usage: gen-amdgpuids.py </path/to/amdgpu.ids>')
+
+ main(sys.argv[1])
diff --git a/scripts/gen-man.py b/scripts/gen-man.py
new file mode 100755
index 0000000..f87a8b7
--- /dev/null
+++ b/scripts/gen-man.py
@@ -0,0 +1,327 @@
+#!/usr/bin/env python3
+
+"""
+Python script to generate a comprehensive man page for the command `fastfetch`.
+
+The generated man page content will be printed to stdout,
+so you will need to pipe it to a file if you want to save it.
+Example: python3 gen-man.py > fastfetch.1
+
+The command options are generated using a JSON file.
+For the JSON file format, see:
+https://github.com/fastfetch-cli/fastfetch/blob/dev/src/data/help.json
+"""
+
+from json import load
+from datetime import datetime, timezone
+from time import time
+from re import search
+from os import environ, path
+
+
+###### Text Decorations Tags ######
+
+startUnderline = r"\fI" # start underline text tag
+endUnderline = r"\fR" # end underline text tag
+
+startBold = r"\fB" # start bold text tag
+endBold = r"\fR" # end bold text tag
+
+
+###### Parameters ######
+
+# path to the current directory
+pathToCurrentDir = path.dirname(__file__)
+# path to the JSON option file
+pathToHelpFile = path.join(pathToCurrentDir, "../doc/help.json")
+# man page section
+manSection = 1
+# title (center header)
+titlePage = "FASTFETCH"
+# date (center footer)
+# format : "Month (abbreviation) Day Year"
+todayDate = datetime.fromtimestamp(
+ int(environ.get("SOURCE_DATE_EPOCH", time())),
+ tz=timezone.utc,
+).strftime("%b %d %Y")
+# file to fastfetch version (left footer)
+pathToVersionFile = path.join(pathToCurrentDir, "../CMakeLists.txt")
+
+
+###### Sections Text ######
+
+# text displayed in the "NAME" section
+nameSection = r"fastfetch \- A fast and feature-rich system information tool similar to neofetch"
+
+# text displayed in the "DESCRIPTION" section
+descriptionSection = r"""
+Fastfetch is a tool for displaying system information in a visually appealing way. Written primarily in C, it focuses on performance and customizability while providing functionality similar to neofetch.
+It supports Linux, Android, FreeBSD, macOS, and Windows 7 or newer.
+"""
+
+# text displayed at the beginning of the "OPTIONS" section
+optionSection = r"""
+Options are parsed in a case-insensitive manner. For example, \fB--logo-type\fR and \fB--LOGO-TYPE\fR are treated identically.
+
+Arguments in square brackets are optional. Optional boolean arguments default to 'true' when specified without a value.
+
+For more detailed information about a specific option, use:
+\fBfastfetch -h <option_name_without_dashes>\fR
+
+Any combination of options can be made permanent by generating a configuration file:
+\fBfastfetch <options> --gen-config\fR
+"""
+
+# text displayed in the "CONFIGURATION"
+configurationSection = f"""
+.SS Fetch Structure
+
+The structure defines which modules to display and in what order. It consists of module names separated by colons (:).
+For example: {startBold}title:separator:os:kernel:uptime{endBold}
+
+To list all available modules, use {startBold}--list-modules{endBold}
+
+
+.SS Config Files
+
+Fastfetch uses JSONC (JSON with Comments) for configuration files. These files must have the .jsonc extension.
+
+You can generate a default config file using {startBold}--gen-config{endBold}. By default, the config file is saved at {startBold}~/.config/fastfetch/config.jsonc{endBold}.
+
+The configuration/preset files are searched in the following locations (in order):
+
+{startBold}1.{endBold} Relative to the current working directory
+
+{startBold}2.{endBold} Relative to ~/.local/share/fastfetch/presets/
+
+{startBold}3.{endBold} Relative to /usr/share/fastfetch/presets/
+
+For detailed information on logo options, module configuration, and formatting, visit:
+{startBold}https://github.com/fastfetch-cli/fastfetch/wiki/Configuration{endBold}
+
+Fastfetch provides several built-in presets. List them with {startBold}--list-presets{endBold}.
+
+.SS JSON Schema
+A JSON schema is available for editor intelligence when editing the configuration file. Add the following line at the beginning of your config file:
+
+{startBold}"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json"{endBold}
+"""
+
+# text displayed in the "EXAMPLE" section
+exampleSection = f"""
+.SS Basic Usage
+{startBold}fastfetch{endBold}
+
+.SS Use a specific logo
+{startBold}fastfetch --logo arch{endBold}
+
+.SS Custom structure
+{startBold}fastfetch --structure title:os:kernel:uptime:memory{endBold}
+
+.SS Generate a config file
+{startBold}fastfetch --gen-config{endBold}
+
+.SS Use a preset
+{startBold}fastfetch --config neofetch{endBold}
+
+.SS Config File Example
+.nf
+// ~/.config/fastfetch/config.jsonc
+{{
+ "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
+ "logo": {{
+ "type": "auto",
+ "source": "arch"
+ }},
+ "display": {{
+ "separator": ": ",
+ "color": {{
+ "keys": "blue",
+ "title": "red"
+ }},
+ "key": {{
+ "width": 12
+ }}
+ }},
+ "modules": [
+ "title",
+ "separator",
+ "os",
+ "kernel",
+ "uptime",
+ {{
+ "type": "memory",
+ "format": "{{used}}/{{total}} ({{used_percent}}%)"
+ }}
+ ]
+}}
+.fi
+"""
+
+# text displayed in the "BUGS" section
+bugSection = "Please report bugs to: https://github.com/fastfetch-cli/fastfetch/issues"
+
+# text displayed in the "AUTHORS" section
+authorsSection = "Fastfetch is developed by a team of contributors on GitHub.\nVisit https://github.com/fastfetch-cli/fastfetch for more information."
+
+
+###### Argument decoration ######
+
+### optional arguments tags ###
+
+# if an optional argument is displayed as [?optArg] (with "optArg" underlined)
+# this value should be f"[?{startUnderline}"
+startOptionalArgument = f"[{startUnderline}"
+# if an optional argument is displayed as [?optArg] (with "optArg underlined")
+# this value should be f"{endUnderline}]"
+endOptionalArgument = f"{endUnderline}]"
+
+### mandatory arguments tags ###
+startMandatoryArgument = f"{startUnderline}"
+endMandatoryArgument = f"{endUnderline}"
+
+def main():
+
+ # importing the JSON file
+ with open(pathToHelpFile, 'r') as jsonFile:
+ helpFileData = load(jsonFile) # json.load
+
+
+ ######## Start printing the generated .1 file ########
+
+
+ ###### header, footer & config #####
+
+ print(f".TH FASTFETCH {manSection} ", end=" ")
+ print(f"\"{todayDate}\"", end=" ")
+
+ # version number
+ with open(pathToVersionFile, 'r') as versionFile:
+
+ # research version number in file with regex
+ for line in versionFile:
+ researchVersion = search(r"^\s*VERSION (\d+\.\d+\.\d+)$", line)
+ if (researchVersion):
+ print(f"\"Fastfetch {researchVersion.group(1)}\"", end=" ")
+ break
+
+ print(f"\"{titlePage}\"")
+
+
+ ###### Name ######
+
+ print(".SH NAME")
+ print(nameSection)
+
+
+ ##### Synopsis ######
+
+ print(".SH SYNOPSIS")
+ print(".B fastfetch")
+ print(f"[{startUnderline}OPTIONS{endUnderline}...]")
+
+
+ ###### Description ######
+
+ print(".SH DESCRIPTION")
+ print(descriptionSection)
+
+
+ ###### Configuration ######
+
+ print(".SH CONFIGURATION")
+ print(configurationSection)
+
+
+ ###### Options ######
+
+ print(".SH OPTIONS")
+ print(optionSection)
+ print()
+
+ # loop through every options sections
+ for key, value in helpFileData.items():
+
+ # print new subsection
+ print(f".SS {key}")
+
+ # loop through every option in a section
+ for option in value:
+ # list of existing keys for this option
+ keyList = option.keys()
+
+ # start a new "option" entry
+ print(".TP")
+ print(startBold, end="")
+
+ # short option (-opt)
+ if "short" in keyList:
+ print(fr"\-{ option['short'] }", end="")
+ # if also have a long option, print a comma
+ if "long" in keyList:
+ print(", ", end="")
+
+ # long option (--option)
+ if "long" in keyList:
+ print(fr"\-\-{ option['long'] }", end="")
+
+ print(endBold, end=" ")
+
+ # arguments
+ if "arg" in keyList:
+ # if argument is optional, print "[arg]"
+ if "optional" in option["arg"].keys() and option["arg"]["optional"]:
+ print(startOptionalArgument + option['arg']['type'] + endOptionalArgument, end="")
+
+ # if argument is mandatory, print "arg"
+ else:
+ print(startMandatoryArgument + option['arg']['type'] + endMandatoryArgument, end="")
+
+ # description
+ print()
+
+ # If desc is a list, join with newlines and proper spacing
+ if isinstance(option['desc'], list):
+ desc_text = "\n ".join(option['desc'])
+ print(f" {desc_text}")
+ else:
+ print(f" {option['desc']}")
+
+ # Add remarks if available
+ if "remark" in keyList:
+ print()
+ if isinstance(option['remark'], list):
+ for remark in option['remark']:
+ print(f" {remark}")
+ else:
+ print(f" {option['remark']}")
+
+ print()
+
+
+ ###### Examples ######
+
+ print(".SH EXAMPLES")
+ print(exampleSection)
+
+
+ ###### See Also ######
+
+ print(".SH \"SEE ALSO\"")
+ print(".BR neofetch (1)")
+
+
+ ###### Bugs ######
+
+ print(".SH BUGS")
+ print(bugSection)
+
+
+ ###### Authors ######
+
+ print(".SH AUTHORS")
+ print(authorsSection)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/gen-pciids.py b/scripts/gen-pciids.py
new file mode 100755
index 0000000..94ee297
--- /dev/null
+++ b/scripts/gen-pciids.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+
+import sys
+
+class PciDeviceModel:
+ def __init__(self, id: int, name: str):
+ self.id = id
+ self.name = name
+
+class PciVendorModel:
+ def __init__(self, id: int, name: str):
+ self.id = id
+ self.name = name
+ self.devices = []
+
+def main(keep_vendor_list: set, pci_ids_path: str):
+ vendors = []
+ with open(pci_ids_path, 'r') as f:
+ full_text = f.read()
+
+ if full_text == '':
+ sys.exit(f'Error: {pci_ids_path} file is empty')
+
+ dev_list_text = full_text[:full_text.rfind('\n\n\n')] # remove known classes
+ for line in dev_list_text.split('\n'):
+ if not line or line[0] == '#':
+ continue
+ if line[0] != '\t':
+ id, name = line.split(' ', maxsplit=1)
+ vendors.append(PciVendorModel(int(id, 16), name))
+ elif line[1] != '\t':
+ id, name = line[1:].split(' ', maxsplit=1)
+ vendors[-1].devices.append(PciDeviceModel(int(id, 16), name))
+
+ code = """\
+// SPDX-License-Identifier: BSD-3-Clause
+// https://opensource.org/license/BSD-3-Clause
+// Generated from https://pci-ids.ucw.cz/v2.2/pci.ids
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef struct FFPciDevice
+{
+ const uint32_t id;
+ const char* name;
+} FFPciDevice;
+
+typedef struct FFPciVendor
+{
+ const uint32_t id;
+ const char* name;
+ const FFPciDevice* devices;
+ const uint32_t nDevices;
+} FFPciVendor;
+"""
+
+ if keep_vendor_list:
+ vendors = [vendor for vendor in vendors if vendor.id in keep_vendor_list]
+
+ for vendor in vendors:
+ if vendor.devices:
+ piece = ',\n '.join('{{ 0x{:04X}, "{}" }}'.format(device.id, device.name.replace('"', '\\"')) for device in vendor.devices)
+ code += f"""
+// {vendor.name}
+static const FFPciDevice pciDevices_{vendor.id:04X}[] = {{
+ {piece},
+ {{}},
+}};
+"""
+
+ piece = ',\n '.join('{{ 0x{:04X}, "{}", {}, {} }}'.format(vendor.id, vendor.name.replace('"', '\\"'), vendor.devices and f"pciDevices_{vendor.id:04X}" or "NULL", len(vendor.devices)) for vendor in vendors)
+ code += f"""
+const FFPciVendor ffPciVendors[] = {{
+ {piece},
+ {{}},
+}};"""
+
+ print(code)
+
+if __name__ == '__main__':
+ len(sys.argv) == 2 or sys.exit('Usage: gen-pciids.py </path/to/pci.ids>')
+
+ # From <src/detection/gpu/gpu.c>
+ main({
+ 0x106b, # Apple
+ 0x1002, 0x1022, # AMD
+ 0x8086, 0x8087, 0x03e7, # Intel
+ 0x0955, 0x10de, 0x12d2, # Nvidia
+ 0x1ed5, # MThreads
+ 0x5143, # Qualcomm
+ 0x14c3, # MTK
+ 0x15ad, # VMware
+ 0x1af4, # RedHat
+ 0x1ab8, # Parallel
+ 0x1414, # Microsoft
+ 0x108e, # Oracle
+ }, sys.argv[1])