Ruby 4.0.0dev (2025-11-28 revision 4cd6661e1853930c8002174c4ccd14f927fcd33b)
version.c (4cd6661e1853930c8002174c4ccd14f927fcd33b)
1/**********************************************************************
2
3 version.c -
4
5 $Author$
6 created at: Thu Sep 30 20:08:01 JST 1993
7
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9
10**********************************************************************/
11
12#include "internal/cmdlineopt.h"
13#include "internal/parse.h"
14#include "internal/gc.h"
16#include "ruby/ruby.h"
17#include "version.h"
18#include "vm_core.h"
19#include "yjit.h"
20#include <stdio.h>
21
22#ifndef EXIT_SUCCESS
23#define EXIT_SUCCESS 0
24#endif
25
26#ifdef RUBY_REVISION
27# if RUBY_PATCHLEVEL == -1
28# define RUBY_API_VERSION_NAME "master"
29# ifndef RUBY_BRANCH_NAME
30# define RUBY_BRANCH_NAME RUBY_API_VERSION_NAME
31# endif
32# define RUBY_REVISION_STR " "RUBY_BRANCH_NAME" "RUBY_REVISION
33# else
34# define RUBY_REVISION_STR " revision "RUBY_REVISION
35# endif
36#else
37# define RUBY_REVISION "HEAD"
38# define RUBY_REVISION_STR ""
39#endif
40#ifndef RUBY_API_VERSION_NAME
41# define RUBY_API_VERSION_NAME RUBY_API_VERSION_STR
42#endif
43#if !defined RUBY_RELEASE_DATETIME || RUBY_PATCHLEVEL != -1
44# undef RUBY_RELEASE_DATETIME
45# define RUBY_RELEASE_DATETIME RUBY_RELEASE_DATE
46#endif
47
48#define PRINT(type) puts(ruby_##type)
49#define MKSTR(type) rb_obj_freeze(rb_usascii_str_new_static(ruby_##type, sizeof(ruby_##type)-1))
50#define MKINT(name) INT2FIX(ruby_##name)
51
52#define RUBY_API_VERSION_STR \
53 STRINGIZE(RUBY_API_VERSION_MAJOR) "." \
54 STRINGIZE(RUBY_API_VERSION_MINOR) "." \
55 ""
61#define RUBY_VERSION \
62 STRINGIZE(RUBY_VERSION_MAJOR) "." \
63 STRINGIZE(RUBY_VERSION_MINOR) "." \
64 STRINGIZE(RUBY_VERSION_TEENY) ""
65#ifndef RUBY_FULL_REVISION
66# define RUBY_FULL_REVISION RUBY_REVISION
67#endif
68#ifdef YJIT_SUPPORT
69#define YJIT_DESCRIPTION " +YJIT " STRINGIZE(YJIT_SUPPORT)
70#else
71#define YJIT_DESCRIPTION " +YJIT"
72#endif
73#ifdef ZJIT_SUPPORT
74#define ZJIT_DESCRIPTION " +ZJIT " STRINGIZE(ZJIT_SUPPORT)
75#else
76#define ZJIT_DESCRIPTION " +ZJIT"
77#endif
78#if USE_MODULAR_GC
79#define GC_DESCRIPTION " +GC"
80#else
81#define GC_DESCRIPTION ""
82#endif
83const char ruby_version[] = RUBY_VERSION;
84const char ruby_revision[] = RUBY_FULL_REVISION;
85const char ruby_release_date[] = RUBY_RELEASE_DATE;
86const char ruby_platform[] = RUBY_PLATFORM;
87const int ruby_patchlevel = RUBY_PATCHLEVEL;
88const char ruby_api_version_name[] = RUBY_API_VERSION_NAME;
89const char ruby_description[] =
90 "ruby " RUBY_VERSION RUBY_PATCHLEVEL_STR " "
91 "(" RUBY_RELEASE_DATETIME RUBY_REVISION_STR ") "
92 "[" RUBY_PLATFORM "]";
93static const int ruby_description_opt_point =
94 (int)(sizeof(ruby_description) - sizeof(" [" RUBY_PLATFORM "]"));
95
96const char ruby_copyright[] = "ruby - Copyright (C) "
97 RUBY_BIRTH_YEAR_STR "-" RUBY_RELEASE_YEAR_STR " "
99const char ruby_engine[] = "ruby";
100
101// Might change after initialization
102const char *rb_dynamic_description = ruby_description;
103
104static inline void
105define_ruby_const(VALUE mod, const char *name, VALUE value, bool toplevel)
106{
107 if (toplevel) {
108 rb_define_global_const(name, value);
109 name += rb_strlen_lit("RUBY_");
110 }
111 rb_define_const(mod, name, value);
112}
113
114/* RDoc needs rb_define_const */
115#define rb_define_const(mod, name, value) \
116 define_ruby_const(mod, (mod == mRuby ? "RUBY_" name : name), value, (mod == mRuby))
117
118void
119Init_Ruby_module(void)
120{
121 rb_define_module("Ruby");
122}
123
125void
126Init_version(void)
127{
128 /*
129 * The Ruby[rdoc-ref:Ruby] module that contains portable information among
130 * implementations.
131 *
132 * The constants defined here are aliased in the toplevel with
133 * +RUBY_+ prefix.
134 */
135 VALUE mRuby = rb_define_module("Ruby");
136
137 enum {ruby_patchlevel = RUBY_PATCHLEVEL};
138 VALUE version = MKSTR(version);
139 VALUE ruby_engine_name = MKSTR(engine);
140 // MKSTR macro is a marker for fake.rb
141
142 /*
143 * The running version of ruby
144 */
145 rb_define_const(mRuby, "VERSION", /* MKSTR(version) */ version);
146 /*
147 * The date this ruby was released
148 */
149 rb_define_const(mRuby, "RELEASE_DATE", MKSTR(release_date));
150 /*
151 * The platform for this ruby
152 */
153 rb_define_const(mRuby, "PLATFORM", MKSTR(platform));
154 /*
155 * The patchlevel for this ruby. If this is a development build of ruby
156 * the patchlevel will be -1
157 */
158 rb_define_const(mRuby, "PATCHLEVEL", MKINT(patchlevel));
159 /*
160 * The GIT commit hash for this ruby.
161 */
162 rb_define_const(mRuby, "REVISION", MKSTR(revision));
163 /*
164 * The copyright string for ruby
165 */
166 rb_define_const(mRuby, "COPYRIGHT", MKSTR(copyright));
167 /*
168 * The engine or interpreter this ruby uses.
169 */
170 rb_define_const(mRuby, "ENGINE", /* MKSTR(engine) */ ruby_engine_name);
171 ruby_set_script_name(ruby_engine_name);
172 /*
173 * The version of the engine or interpreter this ruby uses.
174 */
175 rb_define_const(mRuby, "ENGINE_VERSION", /* MKSTR(version) */ version);
176
177 rb_provide("ruby2_keywords.rb");
178}
179
180#if USE_YJIT
181#define YJIT_OPTS_ON opt->yjit
182#else
183#define YJIT_OPTS_ON 0
184#endif
185
186#if USE_ZJIT
187#define ZJIT_OPTS_ON opt->zjit
188#else
189#define ZJIT_OPTS_ON 0
190#endif
191
192int ruby_mn_threads_enabled;
193
194#ifndef RB_DEFAULT_PARSER
195#define RB_DEFAULT_PARSER RB_DEFAULT_PARSER_PRISM
196#endif
197static ruby_default_parser_enum default_parser = RB_DEFAULT_PARSER;
198
199ruby_default_parser_enum
200rb_ruby_default_parser(void)
201{
202 return default_parser;
203}
204
205void
206rb_ruby_default_parser_set(ruby_default_parser_enum parser)
207{
208 default_parser = parser;
209}
210
211static void
212define_ruby_description(const char *const jit_opt)
213{
214#define JIT_DESCRIPTION YJIT_DESCRIPTION ZJIT_DESCRIPTION
215
216 static char desc[
217 sizeof(ruby_description)
218 + rb_strlen_lit(JIT_DESCRIPTION)
219 + rb_strlen_lit(" +MN")
220 + rb_strlen_lit(" +PRISM")
221#if USE_MODULAR_GC
222 + rb_strlen_lit(GC_DESCRIPTION)
223 // Assume the active GC name can not be longer than 20 chars
224 // so that we don't have to use strlen and remove the static
225 // qualifier from desc.
226 + RB_GC_MAX_NAME_LEN + 3
227#endif
228
229 ];
230
231 int n = ruby_description_opt_point;
232 memcpy(desc, ruby_description, n);
233# define append(s) (n += (int)strlcpy(desc + n, s, sizeof(desc) - n))
234 if (*jit_opt) append(jit_opt);
235 RUBY_ASSERT(n <= ruby_description_opt_point + (int)rb_strlen_lit(JIT_DESCRIPTION));
236 if (ruby_mn_threads_enabled) append(" +MN");
237 if (rb_ruby_prism_p()) append(" +PRISM");
238#if USE_MODULAR_GC
239 append(GC_DESCRIPTION);
240 if (rb_gc_modular_gc_loaded_p()) {
241 append("[");
242 append(rb_gc_active_gc_name());
243 append("]");
244 }
245#endif
246 append(ruby_description + ruby_description_opt_point);
247# undef append
248
249 VALUE mRuby = rb_path2class("Ruby");
250 VALUE description = rb_obj_freeze(rb_usascii_str_new_static(desc, n));
251 rb_dynamic_description = desc;
252
253 /*
254 * The full ruby version string, like <tt>ruby -v</tt> prints
255 */
256 rb_define_const(mRuby, "DESCRIPTION", /* MKSTR(description) */ description);
257#undef JIT_DESCRIPTION
258}
259
260void
261Init_ruby_description(ruby_cmdline_options_t *opt)
262{
263 const char *const jit_opt =
264 YJIT_OPTS_ON ? YJIT_DESCRIPTION :
265 ZJIT_OPTS_ON ? ZJIT_DESCRIPTION :
266 "";
267 define_ruby_description(jit_opt);
268}
269
270void
271ruby_set_yjit_description(void)
272{
273 VALUE mRuby = rb_path2class("Ruby");
274 rb_const_remove(rb_cObject, rb_intern("RUBY_DESCRIPTION"));
275 rb_const_remove(mRuby, rb_intern("DESCRIPTION"));
276 define_ruby_description(YJIT_DESCRIPTION);
277}
278
279void
280ruby_set_zjit_description(void)
281{
282 VALUE mRuby = rb_path2class("Ruby");
283 rb_const_remove(rb_cObject, rb_intern("RUBY_DESCRIPTION"));
284 rb_const_remove(mRuby, rb_intern("DESCRIPTION"));
285 define_ruby_description(ZJIT_DESCRIPTION);
286}
287
288void
290{
291 puts(rb_dynamic_description);
292
293#ifdef RUBY_LAST_COMMIT_TITLE
294 fputs("last_commit=" RUBY_LAST_COMMIT_TITLE, stdout);
295#endif
296#ifdef HAVE_MALLOC_CONF
297 if (malloc_conf) printf("malloc_conf=%s\n", malloc_conf);
298#endif
299 fflush(stdout);
300}
301
302void
304{
305 PRINT(copyright);
306 fflush(stdout);
307}
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
Definition assert.h:219
Ruby-level global variables / constants, visible from C.
VALUE rb_define_module(const char *name)
Defines a top-level module.
Definition class.c:1685
void ruby_set_script_name(VALUE name)
Identical to ruby_script(), except it takes the name as a Ruby String instance.
Definition ruby.c:3069
VALUE rb_obj_freeze(VALUE obj)
Just calls rb_obj_freeze_inline() inside.
Definition object.c:1329
void ruby_show_copyright(void)
Prints the copyright notice of the CRuby interpreter to stdout.
Definition version.c:303
void ruby_show_version(void)
Prints the version information of the CRuby interpreter to stdout.
Definition version.c:289
void rb_provide(const char *feature)
Declares that the given feature is already provided by someone else.
Definition load.c:705
#define rb_strlen_lit(str)
Length of a string literal.
Definition string.h:1691
VALUE rb_usascii_str_new_static(const char *ptr, long len)
Identical to rb_str_new_static(), except it generates a string of "US ASCII" encoding instead of "bin...
Definition string.c:1193
VALUE rb_path2class(const char *path)
Resolves a Q::W::E::R-style path string to the actual class it points.
Definition variable.c:494
VALUE rb_const_remove(VALUE space, ID name)
Identical to rb_mod_remove_const(), except it takes the name as ID instead of VALUE.
Definition variable.c:3557
void rb_define_global_const(const char *name, VALUE val)
Identical to rb_define_const(), except it defines that of "global", i.e.
Definition variable.c:4026
const int ruby_api_version[3]
API versions, in { major, minor, teeny } order.
Definition version.c:56
const char ruby_engine[]
This is just "ruby" for us.
Definition version.c:99
#define RUBY_API_VERSION_TEENY
Teeny version.
Definition version.h:76
const char ruby_platform[]
Target platform identifier, in a C string.
Definition version.c:86
const char ruby_version[]
Stringised version.
Definition version.c:83
#define RUBY_API_VERSION_MAJOR
Major version.
Definition version.h:64
#define RUBY_API_VERSION_MINOR
Minor version.
Definition version.h:70
#define RUBY_AUTHOR
Author of this project.
Definition version.h:32
const char ruby_copyright[]
Copyright notice.
Definition version.c:96
const char ruby_release_date[]
Date of release, in a C string.
Definition version.c:85
const int ruby_patchlevel
This is a monotonic increasing integer that describes specific "patch" level.
Definition version.c:87
const char ruby_description[]
This is what ruby -v prints to the standard error.
Definition version.c:89
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40