ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
version.c
Go to the documentation of this file.
1
7#include <ascii-chat/version.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <ctype.h>
12#include <limits.h>
13#include <errno.h>
14
15// GCC/Clang: Use __attribute__((section)) to place string in custom section
16// ELF (Linux): .section_name format
17// Mach-O (macOS): __SEGMENT,__section format
18#if defined(__GNUC__) || defined(__clang__)
19
20#if defined(__APPLE__)
21// macOS Mach-O format: use __TEXT segment for read-only data
22__attribute__((used, section("__TEXT,__ascii_chat"))) const char ascii_chat_custom_section[] =
23 ASCII_CHAT_DOT_ASCII_CHAT_STRING;
24__attribute__((used, section("__TEXT,__comment"))) const char ascii_chat_comment_string[] =
25 ASCII_CHAT_DOT_COMMENT_STRING;
26__attribute__((used, section("__TEXT,__version"))) const char ascii_chat_version_string[] = ASCII_CHAT_VERSION_FULL;
27#define ASCII_CHAT_VERSION_GETTERS
28
29#elif defined(__linux__)
30// Linux ELF format: standard .section_name format
31__attribute__((used, section(".ascii_chat"))) const char ascii_chat_custom_section[] = ASCII_CHAT_DOT_ASCII_CHAT_STRING;
32__attribute__((used, section(".comment"))) const char ascii_chat_comment_string[] = ASCII_CHAT_DOT_COMMENT_STRING;
33__attribute__((used, section(".version"))) const char ascii_chat_version_string[] = ASCII_CHAT_VERSION_FULL;
34#define ASCII_CHAT_VERSION_GETTERS
35#endif
36
37#ifdef ASCII_CHAT_VERSION_GETTERS
38// Provide functions to get version info at runtime
39const char *ascii_chat_get_version(void) {
40 return ascii_chat_version_string;
41}
42const char *ascii_chat_get_comment(void) {
43 return ascii_chat_comment_string;
44}
45#endif
46
47#endif
48
49semantic_version_t version_parse(const char *version_string) {
50 semantic_version_t result = {0, 0, 0, false};
51
52 if (!version_string || version_string[0] == '\0') {
53 return result;
54 }
55
56 const char *p = version_string;
57
58 // Optionally skip 'v' prefix if present
59 if (p[0] == 'v' || p[0] == 'V') {
60 p++; // Skip 'v'
61 }
62
63 // Parse major version
64 char *endptr = NULL;
65 errno = 0; // Reset errno before strtol
66 long major = strtol(p, &endptr, 10);
67 if (errno == ERANGE || endptr == p || major < 0 || major > INT_MAX) {
68 return result; // Invalid major version or overflow
69 }
70 result.major = (int)major;
71 p = endptr;
72
73 // Version must have all three components (major.minor.patch)
74 if (*p != '.') {
75 return result; // Invalid: missing minor version
76 }
77 p++; // Skip dot
78
79 // Parse minor version
80 errno = 0; // Reset errno before strtol
81 long minor = strtol(p, &endptr, 10);
82 if (errno == ERANGE || endptr == p || minor < 0 || minor > INT_MAX) {
83 return result; // Invalid minor version or overflow
84 }
85 result.minor = (int)minor;
86 p = endptr;
87
88 // Version must have patch component
89 if (*p != '.') {
90 return result; // Invalid: missing patch version
91 }
92 p++; // Skip dot
93
94 // Parse patch version
95 errno = 0; // Reset errno before strtol
96 long patch = strtol(p, &endptr, 10);
97 if (errno == ERANGE || endptr == p || patch < 0 || patch > INT_MAX) {
98 return result; // Invalid patch version or overflow
99 }
100 result.patch = (int)patch;
101 p = endptr;
102
103 // Reject prerelease tags (e.g., "v1.2.3-beta") - must end after patch number
104 if (*p != '\0') {
105 return result; // Invalid: has extra characters after version
106 }
107
108 result.valid = true;
109 return result;
110}
111
112int version_compare(semantic_version_t a, semantic_version_t b) {
113 // Compare major version
114 if (a.major < b.major) {
115 return -1;
116 }
117 if (a.major > b.major) {
118 return 1;
119 }
120
121 // Major versions equal, compare minor
122 if (a.minor < b.minor) {
123 return -1;
124 }
125 if (a.minor > b.minor) {
126 return 1;
127 }
128
129 // Minor versions equal, compare patch
130 if (a.patch < b.patch) {
131 return -1;
132 }
133 if (a.patch > b.patch) {
134 return 1;
135 }
136
137 // All components equal
138 return 0;
139}
__attribute__((constructor))
Register fork handlers for common module.
Definition common.c:104
int version_compare(semantic_version_t a, semantic_version_t b)
Definition version.c:112
semantic_version_t version_parse(const char *version_string)
Definition version.c:49