Annotation of OpenXM_contrib2/asir2018/builtin/ctrl.c, Revision 1.6
1.1 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
47: *
1.6 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2018/builtin/ctrl.c,v 1.5 2020/08/26 06:40:36 noro Exp $
1.1 noro 49: */
50: #include "ca.h"
51: #include "parse.h"
52: #include <string.h>
53: #if defined(VISUAL) || defined(__MINGW32__)
54: #include <windows.h>
55: #include <winnls.h>
56: #else
57: #include <locale.h>
58: #include <unistd.h>
59: #include <sys/types.h>
60: #include <sys/socket.h>
61: #include <sys/wait.h>
62: #include <sys/utsname.h>
63: #endif
64:
65: static struct {
66: char *type;
67: char *kernel;
68: char *name;
69: char *arch;
70: char *release;
71: char *full;
72: char *lang;
1.4 ohara 73: #if defined(VISUAL)
74: int ver_major;
75: int ver_minor;
76: int ver_build;
77: #endif
1.1 noro 78: } sysinfo;
79:
80: void Pctrl();
81: void Psysinfo(LIST *rp);
82: static void get_sysinfo();
83:
84: struct ftab ctrl_tab[] = {
85: {"ctrl",Pctrl,-2},
86: {"asir_env",Pctrl,-2},
87: {"sysinfo", Psysinfo, 0},
88: {0,0,0},
89: };
90:
91: extern int error_in_timer;
92: extern int prtime,nez,echoback,bigfloat,evalef;
93: extern int debug_up;
94: extern int GC_max_heap_size,Verbose,hideargs,hex_output,do_server_in_X11;
95: extern int do_message,do_terse;
96: extern int ox_batch,ox_check,ox_exchange_mathcap;
97: extern int f4_nocheck;
98: extern int StrassenSize;
99: extern int outputstyle;
100: extern int fortran_output;
101: extern int real_digit;
102: extern int real_binary;
103: extern int allow_laurent;
104: #if defined(INTERVAL)
105: extern int zerorewrite;
106: extern int Itvplot;
107: #endif
108: extern int double_output;
109: extern int use_new_hensel;
110: extern int print_quote;
111: extern int show_crossref;
112: extern Obj user_defined_prompt;
113: extern int asir_setenv;
114: extern int show_orderspec;
115: extern int no_debug_on_error;
116: extern int diag_period;
117: extern int weight_check;
118: extern char **ASIRLOADPATH;
119: extern int ASIRLOADPATH_LEN;
120: extern int No_ox_reset;
121: extern int plot_by_bigfloat;
122: extern int debug_plot;
1.5 noro 123: extern int debug_pari;
1.1 noro 124:
125: static struct keyval {
126: char *key;
127: int *val;
128: char *desc;
129: } ctrls[] = {
130: {"StrassenSize",&StrassenSize,"Determines the parameter in Strassen-Winograd matrix multiplication algorithm."},
131: {"allow_laurent",&allow_laurent,"If set to 1, negative exponents are allowed in monomials."},
132: {"asir_setenv",&asir_setenv,"Not used."},
133: {"bigfloat",&bigfloat,"If set to 1, MPFR bigfloat functions are used for floating point evaluation." },
134: {"cputime",&prtime,"If set to 1, the CPU time at the toplevel is shown." },
135: {"debug_up",&debug_up,"If set to 1, some debug messages are printed in special functions for univariate polynomials."},
136: {"debug_window",&do_server_in_X11,"If set to 1, an input window for debugging remote server are shown."},
137: {"diag_period",&diag_period,"Determines the frequency of the intermediate inter-reduction in nd_gr()."},
138: {"double_output",&double_output,"If set to 1, floating point numbers are printed in the style ddd.ddd."},
139: {"echo",&echoback,"If set to 1, characters read by the input function are printed." },
140: {"error_in_timer",&error_in_timer,"If set to 1, the usual error handler is executed when the timer is expired."},
141: {"evalef",&evalef,"If set to 1, elementary functions are evaluated immediately."},
142: {"f4_nocheck",&f4_nocheck,"If set to 1, correctness check of the result of modular computation are omitted in nd_f4()."},
143: {"fake_ox_reset",&No_ox_reset,"Determines the treatment of OX reset request for a server which does not implement the reset protocol."},
144: {"fortran_output",&fortran_output,"If set to 1, ** is used instead of ^ for representing the power."},
145: {"hex",&hex_output,"If set to 1, integers are printed by the hexadecimal notation."},
146: {"hideargs",&hideargs,"If set to 1, the arguments of a function call are not printed."},
147: {"message",&do_message,"If set to 1, an opening message is printed in ox_asir and ox_plot."},
148: {"new_hensel",&use_new_hensel,"If set to 1, a function hensel2() is used in the univariate factorizer over Q."},
149: {"nez",&nez,"If set to 1, a new version of EZGCD implementation is used." },
150: {"no_debug_on_error",&no_debug_on_error,"If set to 1, the debug mode is not used."},
151: {"no_ox_reset",&No_ox_reset,"Determines the treatment of OX reset request for a server which does not implement the reset protocol."},
152: {"no_prompt",&do_quiet,"If set to 1, prompts are not shown."},
153: {"outputstyle",&outputstyle,"If set to 1, structured data such as matrices and vectors are printed in the style mat(...), vect(...)."},
154: {"ox_batch",&ox_batch,"If set to 1, the OX stream are not flushed at each sending of an OX data."},
155: {"ox_check",&ox_check,"If set to 1, mathcap check is done for OpenXM date communication."},
156: {"ox_exchange_mathcap",&ox_exchange_mathcap,"If set to 1, mathcaps are exchanged."},
157: {"print_quote",&print_quote,"Determines the behavior of the printed form of a quote."},
158: {"quiet_mode",&do_quiet,"If set to 1, the copyright notices are not printed at the beginning of the session."},
159: {"real_binary",&real_binary,"If set to 1, a floating point number is printed by the binary notation."},
160: {"real_digit",&real_digit,"Determines the number of digits to appear after the decimal point."},
161: {"show_crossref",&show_crossref,"If set to 1, cross-references are shown when a program file is loaded."},
162: {"show_orderspec",&show_orderspec,"If set to 1, the specification of a composite term order is printed upon its creation."},
163: {"terse",&do_terse,"If set to 1, messages are not printed when user-defined callbacks are executed."},
164: {"verbose",&Verbose,"If set to 1, a warning is printed if a function is redefined."},
165: {"weight_check",&weight_check,"If set to 1, an overflow check for the given weight vector is done before starting the Groebner basis computation."},
166: #if defined(DO_PLOT)
167: {"plot_by_bigfloat",&plot_by_bigfloat,"If set to 1, computation is done by using MPFR bigfloat functions in ox_plot."},
168: {"debug_plot",&debug_plot,"If set to 1, ox_plot is executed with the message window."},
169: #endif
170: #if defined(INTERVAL)
171: {"zerorewrite",&zerorewrite,""},
172: {"itvplotsize",&Itvplot,""},
173: #endif
1.5 noro 174: {"debug_pari",&debug_pari,"If set to 1, ox_pari is executed with the message window."},
1.1 noro 175: {0,0},
176: };
177:
178: LIST create_control_value(char *keystr,Obj value,char *descstr,int withdesc)
179: {
180: STRING key,desc;
181: NODE nd;
182: LIST list;
183:
184: MKSTR(key,keystr);
185: if ( withdesc ) {
186: MKSTR(desc,descstr);
187: nd = mknode(3,key,value,desc);
188: } else nd = mknode(2,key,value);
189: MKLIST(list,nd);
190: return list;
191: }
192:
193: extern Z ox_pari_stream;
194: extern int ox_pari_stream_initialized;
195: extern P ox_pari_starting_function;
196:
197: LIST create_control_values(int withdesc)
198: {
199: int n,i;
200: NODE top,top1,nd,node,p;
201: LIST list,l;
202: STRING s;
203: char *descstr;
204: Z val;
205: Q adj;
206: int nm,dv;
207: Z num,den;
208:
209: n = sizeof(ctrls)/sizeof(struct keyval)-1;
210: top = 0;
211: for ( i = n-1; i >= 0; i-- ) {
1.2 noro 212: STOZ(*(ctrls[i].val),val);
1.1 noro 213: list = create_control_value(ctrls[i].key,(Obj)val,ctrls[i].desc,withdesc);
214: MKNODE(top1,list,top); top = top1;
215: }
216: /* adj */
1.2 noro 217: Risa_GC_get_adj(&nm,&dv); UTOZ(nm,num); UTOZ(dv,den); divq((Q)num,(Q)den,&adj);
1.1 noro 218: descstr = "Determines the parameter for Boehm's GC.";
219: list = create_control_value("adj",(Obj)adj,descstr,withdesc);
220: MKNODE(top1,list,top); top = top1;
221:
222: /* prompt */
223: descstr = "Determines the user-defined prompt.";
224: list = create_control_value("prompt",(Obj)user_defined_prompt,descstr,withdesc);
225: MKNODE(top1,list,top); top = top1;
226:
227: /* loadpath */
228: node = 0;
229: if( ASIRLOADPATH[0] ) {
230: for(i=0; ASIRLOADPATH[i]; i++);
231: for(i--,p=NULL; i>=0; i--,p=node) {
232: MKSTR(s,ASIRLOADPATH[i]);
233: MKNODE(node,s,p);
234: }
235: }
236: MKLIST(l,node);
1.3 noro 237: descstr = "List of paths in ASIRLOADPATH.";
1.1 noro 238: list = create_control_value("loadpath",(Obj)l,descstr,withdesc);
239: MKNODE(top1,list,top); top = top1;
240:
241: /* oxpari_id */
242: if(!ox_pari_stream_initialized) {
1.2 noro 243: STOZ(-1,val);
1.1 noro 244: } else val = ox_pari_stream;
245: descstr = "Id of ox_pari.";
246: list = create_control_value("oxpari_id",(Obj)val,descstr,withdesc);
247: MKNODE(top1,list,top); top = top1;
248:
249: /* oxpari_start */
250: val = (Z)ox_pari_starting_function;
251: descstr = "oxpari starting function.";
252: list = create_control_value("oxpari_start",(Obj)val,descstr,withdesc);
253: MKNODE(top1,list,top); top = top1;
254:
255: MKLIST(list,top);
256: return list;
257: }
258:
259: void Pctrl(NODE arg,Obj *rp)
260: {
261: int t,i,n,desc=0;
262: int nm,dv;
263: Z num,den,z;
264: Q c;
265: char *key;
266: char buf[BUFSIZ];
267: char *str;
268: STRING s;
269: NODE node,p,opt;
270: LIST list;
271: P f;
272: Obj value;
273:
274: if ( !arg ) {
275: if ( current_option ) {
276: for ( opt = current_option; opt; opt = NEXT(opt) ) {
277: p = BDY((LIST)BDY(opt));
278: key = BDY((STRING)BDY(p));
279: value = (Obj)BDY(NEXT(p));
280: if ( !strcmp(key,"desc") && value ) {
281: desc = value ? 1 : 0;
282: break;
283: }
284: }
285: }
286: *rp = (Obj)create_control_values(desc);
287: return;
288: }
289: key = BDY((STRING)ARG0(arg));
290: if ( !strcmp(key,"adj") ) {
291: /* special treatment is necessary for "adj" */
292: if ( argc(arg) == 1 ) {
293: Risa_GC_get_adj(&nm,&dv);
1.2 noro 294: UTOZ(dv,num);
295: UTOZ(nm,den);
1.1 noro 296: divq((Q)num,(Q)den,(Q *)rp);
297: } else {
298: absq((Q)ARG1(arg),&c);
299: if ( !c )
300: error("ctrl : adj : invalid argument");
301: nmq(c,&num);
302: dnq(c,&den);
1.2 noro 303: Risa_GC_set_adj(ZTOS(den),ZTOS(num));
1.1 noro 304: *rp = (Obj)c;
305: }
306: return;
307: } else if ( !strcmp(key,"prompt") ) {
308: /* special treatment is necessary for "prompt" */
309: if ( argc(arg) == 1 ) {
310: if ((!do_quiet) && (user_defined_prompt == (Obj)0)) *rp=(Obj)ONE;
311: else *rp = (Obj)user_defined_prompt;
312: } else {
313: c = (Q)ARG1(arg);
314: if ( !c ) {
315: do_quiet = 1;
316: user_defined_prompt = 0;
317: *rp = 0;
318: } else if ( OID(c) == O_STR ) {
319: str = BDY((STRING)c);
320: for ( i = 0, n = 0; str[i]; i++ )
321: if ( str[i] == '%' )
322: n++;
323: if ( n >= 2 )
324: error("ctrl : prompt : invalid prompt specification");
325: do_quiet = 1;
326: user_defined_prompt = (Obj)c;
327: *rp = (Obj)c;
328: } else if ( NUM(c) && RATN(c) && UNIQ(c) ) {
329: user_defined_prompt = 0;
330: do_quiet = 0;
331: } else {
332: error("ctrl : prompt : invalid argument");
333: }
334: }
335: return;
336: } else if ( !strcmp(key,"loadpath") ) {
337: *rp = 0;
338: if ( argc(arg) == 1 ) {
339: if( ASIRLOADPATH[0] ) {
340: for(i=0; ASIRLOADPATH[i]; i++) {
341: }
342: for(i--,p=NULL; i>=0; i--,p=node) {
343: MKSTR(s,ASIRLOADPATH[i]);
344: MKNODE(node,s,p);
345: }
346: MKLIST(list,node);
347: *rp = (Obj)list;
348: }
349: } else {
350: list = (LIST)ARG1(arg);
351: if ( OID(list) == O_LIST ) {
352: for(i=0,p=BDY(list); p; i++,p=NEXT(p)) {
353: s=(STRING)BDY(p);
354: if(!s || OID(s)!=O_STR) {
355: error("ctrl : loadpath : invalid argument");
356: }
357: }
358: if(i >= ASIRLOADPATH_LEN) {
359: ASIRLOADPATH_LEN = i+1;
360: ASIRLOADPATH = (char **)MALLOC(sizeof(char *)*ASIRLOADPATH_LEN);
361: }
362: for(i=0,p=BDY(list); p; i++,p=NEXT(p)) {
363: ASIRLOADPATH[i] = (char *)BDY((STRING)BDY(p));
364: }
365: ASIRLOADPATH[i] = NULL;
366: }else {
367: error("ctrl : loadpath : invalid argument");
368: }
369: }
370: return;
371: } else if ( !strcmp(key,"oxpari_id") ) {
372: if ( argc(arg) == 1 ) {
373: if(!ox_pari_stream_initialized) {
1.2 noro 374: STOZ(-1,z);
1.1 noro 375: *rp = (Obj)z;
376: }else {
377: *rp = (Obj)ox_pari_stream;
378: }
379: }else {
380: c = (Q)ARG1(arg);
381: if ( !c || ( NUM(c) && INT(c) && sgnq(c)>0 ) ) {
382: ox_pari_stream_initialized = 1;
383: ox_pari_stream = (Z)c;
384: *rp = (Obj)c;
385: }else {
1.2 noro 386: STOZ(-1,z);
1.1 noro 387: *rp = (Obj)z;
388: }
389: }
390: return;
391: } else if ( !strcmp(key,"oxpari_start") ) {
392: if ( argc(arg) == 1 ) {
393: *rp = (Obj)ox_pari_starting_function;
394: } else {
395: f = (P)ARG1(arg);
396: if ( !f || OID(f) == O_P) {
397: ox_pari_starting_function = f;
398: *rp = (Obj)f;
399: }else {
400: *rp = 0;
401: }
402: }
403: return;
404: }
405: for ( i = 0; ctrls[i].key; i++ )
406: if ( !strcmp(key,ctrls[i].key) )
407: break;
408: if ( ctrls[i].key ) {
409: if ( argc(arg) == 1 )
410: t = *ctrls[i].val;
411: else
1.2 noro 412: *ctrls[i].val = t = ZTOS((Q)ARG1(arg));
413: STOZ(t,z);
1.1 noro 414: *rp = (Obj)z;
415: } else {
416: sprintf(buf,"ctrl : %s : no such key",key);
417: error(buf);
418: }
419: }
420:
421: void Psysinfo(LIST *rp)
422: {
423: int i;
424: NODE n,p;
425: STRING s[7];
426:
427: get_sysinfo();
428: MKSTR(s[0],sysinfo.type); MKSTR(s[1],sysinfo.kernel); MKSTR(s[2],sysinfo.name);
429: MKSTR(s[3],sysinfo.arch); MKSTR(s[4],sysinfo.release); MKSTR(s[5],sysinfo.full);
430: MKSTR(s[6],sysinfo.lang);
431: for(i=6,p=NULL; i>=0; i--,p=n) {
432: MKNODE(n,s[i],p);
433: }
434: MKLIST(*rp,n);
435: }
436:
437: #if !defined(VISUAL) && !defined(__MINGW32__)
438:
439: static char *get_lang()
440: {
441: char *c, *p, *q;
442: c = setlocale(LC_ALL, NULL); /* saving current locale */
443: p = setlocale(LC_ALL, "");
1.6 ! noro 444: if ( p != 0 ) {
! 445: q = (char *)MALLOC(strlen(p)+1);
! 446: strcpy(q,p);
! 447: } else {
! 448: q = (char *)MALLOC(2);
! 449: strcpy(q,"C");
! 450: }
1.1 noro 451: setlocale(LC_ALL, c); /* restoring current locale */
452: return q;
453: }
454:
455: static char *myuname(char *option)
456: {
457: char buf[BUFSIZ];
458: char *s;
459: int fd[2], status, pid;
460: *buf = 0;
461: if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0) {
462: *buf = 0; return NULL;
463: }
464: pid = fork();
465: if (pid < 0) {
466: return NULL;
467: }else if (pid == 0) {
468: dup2(fd[1], 1);
469: close(2);
470: execlp("uname", "uname", option, NULL);
471: }
472: waitpid(pid, &status, 0);
473: if (status) { /* error */
474: return NULL;
475: }
476: s = buf;
477: if( !read(fd[0], s, BUFSIZ-1) || (s = strchr(s, '\n')) ) {
478: *s = 0;
479: }
480: close(fd[0]);
481: close(fd[1]);
482: s = (char *)MALLOC(strlen(buf)+1);
483: strcpy(s, buf);
484: return s;
485: }
486:
487: static void get_sysinfo()
488: {
489: static struct utsname u;
490: static int initialized = 0;
491: if (initialized) {
492: return;
493: }
494: initialized = 1;
495: uname(&u);
496: sysinfo.kernel = u.sysname;
497: #if defined(__DARWIN__)
498: sysinfo.type = "macosx";
499: sysinfo.name = sysinfo.kernel;
500: #else
501: sysinfo.type = "unix";
502: sysinfo.name = myuname("-o"); // not work on Darwin
503: if (!sysinfo.name) {
504: sysinfo.name = sysinfo.kernel;
505: }
506: #endif
507: sysinfo.arch = u.machine;
508: sysinfo.release= u.release;
509: sysinfo.full = myuname("-a");
510: sysinfo.lang = get_lang();
511: }
512:
513: #else
514:
515: /* http://msdn.microsoft.com/ja-jp/library/windows/desktop/ms724834%28v=vs.85%29.aspx */
516: static char *osnameNT(int major, int minor)
517: {
518: if ((major == 3 && minor == 51) || (major == 4 && minor == 0)) {
519: return "WindowsNT";
520: }else if (major == 5 && minor == 0) {
521: return "Windows2000";
522: }else if (major == 5 && minor == 1) {
523: return "WindowsXP";
524: }else if (major == 5 && minor == 2) {
525: return "Windows2003 Server";
526: }else if (major == 6 && minor == 0) {
527: return "WindowsVista";
528: }else if (major == 6 && minor == 1) {
529: return "Windows7";
530: }else if (major == 6 && minor == 2) {
531: return "Windows8";
532: }else if (major == 6 && minor == 3) {
533: return "Windows8.1";
1.4 ohara 534: }else if (major == 10 && minor == 0) {
535: return "Windows10";
1.1 noro 536: }
537: return "unknown";
538: }
539:
540: static char *osname95(int major, int minor)
541: {
542: if (major == 4 && minor == 0) {
543: return "Windows95";
544: }else if (major == 4 && minor == 10) {
545: return "Windows98";
546: }else if (major == 4 && minor == 90) {
547: return "WindowsMe";
548: }
549: return "unknown";
550: }
551:
552: static char *get_lang()
553: {
554: char lang[BUFSIZ];
555: char *s;
556: if(GetLocaleInfo(GetUserDefaultLCID(), LOCALE_SISO639LANGNAME, lang, BUFSIZ)) {
557: s = (char *)MALLOC(strlen(lang)+1);
558: strcpy(s,lang);
559: return s;
560: }
561: return "en"; // English
562: }
563:
1.4 ohara 564: void get_version_win8(int *major,int *minor,int *build)
565: {
566: char *res;
567: char fname[4096]; /* fullpath of kernel32.dll (_MAX_PATH==260)*/
568: char cmd[4096];
569: int size;
570: char *version_string;
571: struct LANGANDCODEPAGE {
572: WORD language;
573: WORD codepage;
574: }* lang;
575: sprintf(fname,"%s\\system32\\kernel32.dll", getenv("SYSTEMROOT"));
576: size=GetFileVersionInfoSize(fname,0);
577: res = (char *)MALLOC(size+1);
578: if(GetFileVersionInfo(fname,0,size+1,res)) {
579: VerQueryValue(res,"\\VarFileInfo\\Translation",&lang,&size);
580: sprintf(cmd,"\\StringFileInfo\\%04x%04x\\ProductVersion",lang->language,lang->codepage);
581: VerQueryValue(res,cmd,&version_string,&size);
582: sscanf(version_string,"%d.%d.%d.",major,minor,build);
583: }
584: }
585:
1.1 noro 586: static void get_sysinfo()
587: {
588: int arch64 = 0;
589: char buf[BUFSIZ];
590: OSVERSIONINFO v;
591: char *s;
592: static int initialized = 0;
593:
594: if (initialized) {
595: return;
596: }
597: initialized = 1;
598:
599: v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
600: GetVersionEx(&v);
1.4 ohara 601: /* Windows8 == version 6.2 */
602: if (v.dwPlatformId == VER_PLATFORM_WIN32_NT
603: && v.dwMajorVersion == 6 && v.dwMinorVersion >= 2) {
604: get_version_win8(&v.dwMajorVersion, &v.dwMinorVersion, &v.dwBuildNumber);
605: }
606: sysinfo.ver_major=v.dwMajorVersion;
607: sysinfo.ver_minor=v.dwMinorVersion;
608: sysinfo.ver_build=v.dwBuildNumber;
1.1 noro 609:
610: sysinfo.type = "windows";
611: sysinfo.arch = "x86";
612: sprintf(buf, "%d.%d.%d", v.dwMajorVersion, v.dwMinorVersion, v.dwBuildNumber);
613: s = (char *)MALLOC(strlen(buf)+1);
614: strcpy(s, buf);
615: sysinfo.release = s;
616:
617: if (v.dwPlatformId == VER_PLATFORM_WIN32_NT) {
618: sysinfo.kernel = "WindowsNT";
619: sysinfo.name = osnameNT(v.dwMajorVersion, v.dwMinorVersion);
620:
621: #if defined(_WIN64)
622: sysinfo.arch = "x86_64";
623: #else
624: // IsWow64Process exists on WindowsXP SP2 or later
625: if(GetProcAddress(GetModuleHandle("kernel32.dll"), "IsWow64Process")) {
626: IsWow64Process(GetCurrentProcess(),&arch64);
627: if(arch64) {
628: sysinfo.arch = "x86_64";
629: }
630: }
631: #endif
632: }else { /* v.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS */
633: sysinfo.kernel = "Windows95";
634: sysinfo.name = osname95(v.dwMajorVersion, v.dwMinorVersion);
635: }
636: sprintf(buf, "%s %s %s %s %s", sysinfo.kernel, sysinfo.release, sysinfo.name, v.szCSDVersion, sysinfo.arch);
637: s = (char *)MALLOC(strlen(buf)+1);
638: strcpy(s, buf);
639: sysinfo.full = s;
640: sysinfo.lang = get_lang();
641: }
642:
643: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>