Ruby  3.4.0dev (2024-12-06 revision 892c46283a5ea4179500d951c9d4866c0051f27b)
version.c (892c46283a5ea4179500d951c9d4866c0051f27b)
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"
15 #include "ruby/ruby.h"
16 #include "version.h"
17 #include "vm_core.h"
18 #include "rjit.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 # ifndef RUBY_BRANCH_NAME
29 # define RUBY_BRANCH_NAME "master"
30 # endif
31 # define RUBY_REVISION_STR " "RUBY_BRANCH_NAME" "RUBY_REVISION
32 # else
33 # define RUBY_REVISION_STR " revision "RUBY_REVISION
34 # endif
35 #else
36 # define RUBY_REVISION "HEAD"
37 # define RUBY_REVISION_STR ""
38 #endif
39 #if !defined RUBY_RELEASE_DATETIME || RUBY_PATCHLEVEL != -1
40 # undef RUBY_RELEASE_DATETIME
41 # define RUBY_RELEASE_DATETIME RUBY_RELEASE_DATE
42 #endif
43 
44 #define PRINT(type) puts(ruby_##type)
45 #define MKSTR(type) rb_obj_freeze(rb_usascii_str_new_static(ruby_##type, sizeof(ruby_##type)-1))
46 #define MKINT(name) INT2FIX(ruby_##name)
47 
48 const int ruby_api_version[] = {
52 };
53 #define RUBY_VERSION \
54  STRINGIZE(RUBY_VERSION_MAJOR) "." \
55  STRINGIZE(RUBY_VERSION_MINOR) "." \
56  STRINGIZE(RUBY_VERSION_TEENY) ""
57 #ifndef RUBY_FULL_REVISION
58 # define RUBY_FULL_REVISION RUBY_REVISION
59 #endif
60 #ifdef YJIT_SUPPORT
61 #define YJIT_DESCRIPTION " +YJIT " STRINGIZE(YJIT_SUPPORT)
62 #else
63 #define YJIT_DESCRIPTION " +YJIT"
64 #endif
65 #if USE_MODULAR_GC
66 #define GC_DESCRIPTION " +GC"
67 #else
68 #define GC_DESCRIPTION ""
69 #endif
70 const char ruby_version[] = RUBY_VERSION;
71 const char ruby_revision[] = RUBY_FULL_REVISION;
72 const char ruby_release_date[] = RUBY_RELEASE_DATE;
73 const char ruby_platform[] = RUBY_PLATFORM;
74 const int ruby_patchlevel = RUBY_PATCHLEVEL;
75 const char ruby_description[] =
76  "ruby " RUBY_VERSION RUBY_PATCHLEVEL_STR " "
77  "(" RUBY_RELEASE_DATETIME RUBY_REVISION_STR ") "
78  "[" RUBY_PLATFORM "]";
79 static const int ruby_description_opt_point =
80  (int)(sizeof(ruby_description) - sizeof(" [" RUBY_PLATFORM "]"));
81 
82 const char ruby_copyright[] = "ruby - Copyright (C) "
83  RUBY_BIRTH_YEAR_STR "-" RUBY_RELEASE_YEAR_STR " "
85 const char ruby_engine[] = "ruby";
86 
87 // Might change after initialization
88 const char *rb_dynamic_description = ruby_description;
89 
91 void
92 Init_version(void)
93 {
94  enum {ruby_patchlevel = RUBY_PATCHLEVEL};
95  VALUE version = MKSTR(version);
96  VALUE ruby_engine_name = MKSTR(engine);
97  // MKSTR macro is a marker for fake.rb
98 
99  /*
100  * The running version of ruby
101  */
102  rb_define_global_const("RUBY_VERSION", /* MKSTR(version) */ version);
103  /*
104  * The date this ruby was released
105  */
106  rb_define_global_const("RUBY_RELEASE_DATE", MKSTR(release_date));
107  /*
108  * The platform for this ruby
109  */
110  rb_define_global_const("RUBY_PLATFORM", MKSTR(platform));
111  /*
112  * The patchlevel for this ruby. If this is a development build of ruby
113  * the patchlevel will be -1
114  */
115  rb_define_global_const("RUBY_PATCHLEVEL", MKINT(patchlevel));
116  /*
117  * The GIT commit hash for this ruby.
118  */
119  rb_define_global_const("RUBY_REVISION", MKSTR(revision));
120  /*
121  * The copyright string for ruby
122  */
123  rb_define_global_const("RUBY_COPYRIGHT", MKSTR(copyright));
124  /*
125  * The engine or interpreter this ruby uses.
126  */
127  rb_define_global_const("RUBY_ENGINE", /* MKSTR(engine) */ ruby_engine_name);
128  ruby_set_script_name(ruby_engine_name);
129  /*
130  * The version of the engine or interpreter this ruby uses.
131  */
132  rb_define_global_const("RUBY_ENGINE_VERSION", /* MKSTR(version) */ version);
133 
134  rb_provide("ruby2_keywords.rb");
135 }
136 
137 #if USE_RJIT
138 #define RJIT_OPTS_ON opt->rjit.on
139 #else
140 #define RJIT_OPTS_ON 0
141 #endif
142 
143 #if USE_YJIT
144 #define YJIT_OPTS_ON opt->yjit
145 #else
146 #define YJIT_OPTS_ON 0
147 #endif
148 
149 int ruby_mn_threads_enabled;
150 
151 #ifndef RB_DEFAULT_PARSER
152 #define RB_DEFAULT_PARSER RB_DEFAULT_PARSER_PRISM
153 #endif
154 static ruby_default_parser_enum default_parser = RB_DEFAULT_PARSER;
155 
156 ruby_default_parser_enum
157 rb_ruby_default_parser(void)
158 {
159  return default_parser;
160 }
161 
162 void
163 rb_ruby_default_parser_set(ruby_default_parser_enum parser)
164 {
165  default_parser = parser;
166 }
167 
168 static void
169 define_ruby_description(const char *const jit_opt)
170 {
171  static char desc[
172  sizeof(ruby_description)
173  + rb_strlen_lit(YJIT_DESCRIPTION)
174  + rb_strlen_lit(" +MN")
175  + rb_strlen_lit(" +PRISM")
176 #if USE_MODULAR_GC
177  + rb_strlen_lit(GC_DESCRIPTION)
178  // Assume the active GC name can not be longer than 20 chars
179  // so that we don't have to use strlen and remove the static
180  // qualifier from desc.
181  + RB_GC_MAX_NAME_LEN + 3
182 #endif
183 
184  ];
185 
186  int n = ruby_description_opt_point;
187  memcpy(desc, ruby_description, n);
188 # define append(s) (n += (int)strlcpy(desc + n, s, sizeof(desc) - n))
189  if (*jit_opt) append(jit_opt);
190  RUBY_ASSERT(n <= ruby_description_opt_point + (int)rb_strlen_lit(YJIT_DESCRIPTION));
191  if (ruby_mn_threads_enabled) append(" +MN");
192  if (rb_ruby_prism_p()) append(" +PRISM");
193 #if USE_MODULAR_GC
194  append(GC_DESCRIPTION);
195  if (rb_gc_modular_gc_loaded_p()) {
196  append("[");
197  append(rb_gc_active_gc_name());
198  append("]");
199  }
200 #endif
201  append(ruby_description + ruby_description_opt_point);
202 # undef append
203 
204  VALUE description = rb_obj_freeze(rb_usascii_str_new_static(desc, n));
205  rb_dynamic_description = desc;
206 
207  /*
208  * The full ruby version string, like <tt>ruby -v</tt> prints
209  */
210  rb_define_global_const("RUBY_DESCRIPTION", /* MKSTR(description) */ description);
211 }
212 
213 void
214 Init_ruby_description(ruby_cmdline_options_t *opt)
215 {
216  const char *const jit_opt =
217  RJIT_OPTS_ON ? " +RJIT" :
218  YJIT_OPTS_ON ? YJIT_DESCRIPTION :
219  "";
220  define_ruby_description(jit_opt);
221 }
222 
223 void
224 ruby_set_yjit_description(void)
225 {
226  rb_const_remove(rb_cObject, rb_intern("RUBY_DESCRIPTION"));
227  define_ruby_description(YJIT_DESCRIPTION);
228 }
229 
230 void
232 {
233  puts(rb_dynamic_description);
234 
235 #ifdef RUBY_LAST_COMMIT_TITLE
236  fputs("last_commit=" RUBY_LAST_COMMIT_TITLE, stdout);
237 #endif
238 #ifdef HAVE_MALLOC_CONF
239  if (malloc_conf) printf("malloc_conf=%s\n", malloc_conf);
240 #endif
241  fflush(stdout);
242 }
243 
244 void
246 {
247  PRINT(copyright);
248  fflush(stdout);
249 }
#define RUBY_ASSERT(...)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
Definition: assert.h:219
void ruby_set_script_name(VALUE name)
Identical to ruby_script(), except it takes the name as a Ruby String instance.
Definition: ruby.c:3035
VALUE rb_obj_freeze(VALUE obj)
Just calls rb_obj_freeze_inline() inside.
Definition: object.c:1260
void ruby_show_copyright(void)
Prints the copyright notice of the CRuby interpreter to stdout.
Definition: version.c:245
void ruby_show_version(void)
Prints the version information of the CRuby interpreter to stdout.
Definition: version.c:231
void rb_provide(const char *feature)
Declares that the given feature is already provided by someone else.
Definition: load.c:715
#define rb_strlen_lit(str)
Length of a string literal.
Definition: string.h:1692
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:1138
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:3279
ID rb_intern(const char *name)
Finds or creates a symbol of the given name.
Definition: symbol.c:823
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:3740
const int ruby_api_version[3]
API versions, in { major, minor, teeny } order.
Definition: version.c:48
const char ruby_engine[]
This is just "ruby" for us.
Definition: version.c:85
#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:73
const char ruby_version[]
Stringised version.
Definition: version.c:70
#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:82
const char ruby_release_date[]
Date of release, in a C string.
Definition: version.c:72
const int ruby_patchlevel
This is a monotonic increasing integer that describes specific "patch" level.
Definition: version.c:74
const char ruby_description[]
This is what ruby -v prints to the standard error.
Definition: version.c:75
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40