--- a/Unix.st Sat Dec 23 12:49:50 1995 +0100
+++ b/Unix.st Sat Dec 23 14:54:00 1995 +0100
@@ -14,7 +14,8 @@
instanceVariableNames:''
classVariableNames:'HostName DomainName LastErrorNumber LastExecStatus OSSignals
SlowFork ForkFailed ErrorSignal AccessDeniedErrorSignal
- FileNotFoundErrorSignal'
+ FileNotFoundErrorSignal
+ LocaleInfo'
poolDictionaries:''
category:'System-Support'
!
@@ -162,6 +163,17 @@
# include <fcntl.h>
+# if defined(LINUX)
+# define HAS_LOCALECONV
+# endif
+
+# if defined (HAS_LOCALECONV)
+# ifndef _LOCALE_H_INCLUDED_
+# include <locale.h>
+# define _LOCALE_H_INCLUDED_
+# endif
+# endif
+
/*
* posix systems should define these ...
* but on some (older) systems, they are not.
@@ -197,7 +209,7 @@
# include <sys/param.h>
# endif
# ifndef MAXPATHLEN
-# ifdef FILENAME_MAX /* i.e. MSDOS_LIKE */
+# ifdef FILENAME_MAX /* i.e. MSDOS_LIKE */
# define MAXPATHLEN FILENAME_MAX
# else
# define MAXPATHLEN 1024
@@ -217,10 +229,10 @@
* sigaction dummies (you won't believe these call themself ``POSIC'' systems ...)
*/
# ifndef SA_RESTART
-# define SA_RESTART 0
+# define SA_RESTART 0
# endif
# ifndef SA_SIGINFO
-# define SA_SIGINFO 0
+# define SA_SIGINFO 0
# endif
#endif /* ! transputer */
@@ -404,7 +416,7 @@
do {
__BEGIN_INTERRUPTABLE__
child = __wait (&status);
- __END_INTERRUPTABLE__
+ __END_INTERRUPTABLE__
if (child < 0 && errno != EINTR) {
DPRINTF(("5: errno=%d\n", errno));
status = -1;
@@ -418,7 +430,7 @@
do {
__BEGIN_INTERRUPTABLE__
child = __waitpid (pid, &status, 0);
- __END_INTERRUPTABLE__
+ __END_INTERRUPTABLE__
} while ((child != pid) && (errno == EINTR));
if (child != pid) {
DPRINTF(("6: errno=%d\n", errno));
@@ -645,6 +657,11 @@
AccessDeniedErrorSignal
FileNotFoundErrorSignal
+
+ LocaleInfo <Dictionary> if non nil, that is taken instead of the operating
+ systems locale definitions (allows for overwriting
+ these, or provide a compatible info on systems which do
+ not support locales)
"
! !
@@ -1768,16 +1785,16 @@
exec:aPath withArguments:argArray fork:doFork
"Internal combined fork & exec;
If fork is false:
- execute the unix command specified by the argument, aPath, with
- arguments in argArray (no arguments, if nil).
- If successful, this method does not return and smalltalk is gone.
- If not successful, false is returned. Normal use is with forkForCommand.
+ execute the unix command specified by the argument, aPath, with
+ arguments in argArray (no arguments, if nil).
+ If successful, this method does not return and smalltalk is gone.
+ If not successful, false is returned. Normal use is with forkForCommand.
if its true:
for a child to do the above.
The id of the child process is returned; -1 if fork failed.
Notice: this used to be two separate ST-methods; however, in order to use
- vfork on some machines, it had to be merged into one, to avoid write
+ vfork on some machines, it had to be merged into one, to avoid write
accesses to ST/X memory from the vforked-child. The code below only does
read accesses."
@@ -1808,20 +1825,20 @@
id = fork();
#endif
if (id == 0) {
- execv(_stringVal(aPath), argv);
+ execv(_stringVal(aPath), argv);
/* should not be reached */
_exit(1);
}
free(argv);
RETURN (__MKSMALLINT(id));
} else {
- execv(_stringVal(aPath), argv);
- /*
- * should not be reached
- * (well, it is, if you pass a wrong command-path)
- */
- free(argv);
- RETURN ( false );
+ execv(_stringVal(aPath), argv);
+ /*
+ * should not be reached
+ * (well, it is, if you pass a wrong command-path)
+ */
+ free(argv);
+ RETURN ( false );
}
}
}
@@ -3191,12 +3208,12 @@
sigaction(THESIGNAL, &act, 0);
#else
# ifdef HAS_SIGVEC
- struct sigvec vec;
-
- vec.sv_flags = 0;
- sigemptyset(&vec.sv_mask);
- vec.sv_handler = __signalIoInterrupt;
- sigvec(THESIGNAL, &vec, NULL);
+ struct sigvec vec;
+
+ vec.sv_flags = 0;
+ sigemptyset(&vec.sv_mask);
+ vec.sv_handler = __signalIoInterrupt;
+ sigvec(THESIGNAL, &vec, NULL);
# else
signal(THESIGNAL, __signalIoInterrupt);
# endif
@@ -3372,7 +3389,7 @@
{
#ifdef HAS_SIGACTION
- struct sigaction act;
+ struct sigaction act;
act.sa_flags = SA_RESTART | SA_SIGINFO; /* <- if you add more, remember dummys at the top */
sigemptyset(&act.sa_mask);
@@ -3380,12 +3397,12 @@
sigaction(sigNr, &act, 0);
#else
# ifdef HAS_SIGVEC
- struct sigvec vec;
-
- vec.sv_flags = 0;
- sigemptyset(&vec.sv_mask);
- vec.sv_handler = handler;
- sigvec(sigNr, &vec, NULL);
+ struct sigvec vec;
+
+ vec.sv_flags = 0;
+ sigemptyset(&vec.sv_mask);
+ vec.sv_handler = handler;
+ sigvec(sigNr, &vec, NULL);
# else
signal(sigNr, handler);
# endif
@@ -3428,12 +3445,12 @@
sigaction(SIGALRM, &act, 0);
#else
# ifdef HAS_SIGVEC
- struct sigvec vec;
-
- vec.sv_flags = 0;
- sigemptyset(&vec.sv_mask);
- vec.sv_handler = __signalTimerInterrupt;
- sigvec(SIGALRM, &vec, NULL);
+ struct sigvec vec;
+
+ vec.sv_flags = 0;
+ sigemptyset(&vec.sv_mask);
+ vec.sv_handler = __signalTimerInterrupt;
+ sigvec(SIGALRM, &vec, NULL);
# else
signal(SIGALRM, __signalTimerInterrupt);
# endif
@@ -4350,6 +4367,286 @@
%}
.
^ true
+!
+
+getLocaleInfo
+ "return a dictionary filled with values from the locale information;
+ Not all fields may be present, depending on the OS's setup and capabilities.
+ Possible fields are:
+ decimalPoint <String>
+
+ thousandsSep <String>
+
+ internationalCurrencySymbol <String>
+
+ currencySymbol <String>
+
+ monetaryDecimalPoint <String>
+
+ monetaryThousandsSeparator <String>
+
+ positiveSign <String>
+
+ negativeSign <String>
+
+ internationalFractionalDigits <Integer>
+
+ fractionalDigits <Integer>
+
+ positiveSignPrecedesCurrencySymbol <Boolean>
+
+ negativeSignPrecedesCurrencySymbol <Boolean>
+
+ positiveSignSeparatedBySpaceFromCurrencySymbol <Boolean>
+
+ negativeSignSeparatedBySpaceFromCurrencySymbol <Boolean>
+
+ positiveSignPosition <Symbol>
+ one of: #parenthesesAround,
+ #signPrecedes,
+ #signSuceeds,
+ #signPrecedesCurrencySymbol,
+ #signSuceedsCurrencySymbol
+
+ negativeSignPosition <like above>
+
+ it is up to the application to deal with undefined values.
+
+ Notice, that (for now), the system does not use this information;
+ it should be used by applications as required.
+ "
+
+ |info val|
+
+ LocaleInfo notNil ifTrue:[
+ "/ return the internal info; useful on systems which do not
+ "/ support this.
+ ^ LocaleInfo
+ ].
+
+ info := IdentityDictionary new.
+%{
+ char *decimalPoint; /* something like "." (US) or "," (german) */
+ char *thousandsSep; /* something like "," (US) or "." (german) */
+ char *intCurrencySymbol; /* international currency symbol; something like "USD " "DM " */
+ char *currencySymbol; /* local currency symbol; something like "USD " "DM " */
+ char *monDecimalPoint; /* money: decimal point */
+ char *monThousandsSep; /* money: thousands sep */
+ char *positiveSign;
+ char *negativeSign;
+ int intFractDigits; /* money: international digits after decPoint */
+ int fractDigits; /* money: local digits after decPoint */
+ int csPosPrecedes; /* money: 1 if currency symbol precedes a positive value; 0 if it sceeds */
+ int csNegPrecedes; /* money: 1 if currency symbol precedes a negative value; 0 if it sceeds */
+ int csPosSepBySpace; /* money: 1 if currency symbol should be separated by a space from a positive value; 0 if no space */
+ int csNegSepBySpace; /* money: 1 if currency symbol should be separated by a space from a negative value; 0 if no space */
+ int csPosSignPosition; /* money: 0: ()'s around the value & currency symbol */
+ int csNegSignPosition; /* 1: sign precedes the value & currency symbol */
+ /* 2: sign succeeds the value & currency symbol */
+ /* 3: sign immediately precedes the currency symbol */
+ /* 4: sign immediately suceeds the currency symbol */
+
+#if defined(HAS_LOCALECONV)
+ struct lconv *conf;
+
+ conf = localeconv();
+ if (conf) {
+ decimalPoint = conf->decimal_point;
+ thousandsSep = conf->thousands_sep;
+ intCurrencySymbol = conf->int_curr_symbol;
+ currencySymbol = conf->currency_symbol;
+ monDecimalPoint = conf->mon_decimal_point;
+ monThousandsSep = conf->mon_thousands_sep;
+ positiveSign = conf->positive_sign;
+ negativeSign = conf->negative_sign;
+ intFractDigits = conf->int_frac_digits;
+ fractDigits = conf->frac_digits;
+ csPosPrecedes = conf->p_cs_precedes;
+ csNegPrecedes = conf->n_cs_precedes;
+ csPosSepBySpace = conf->p_sep_by_space;
+ csNegSepBySpace = conf->n_sep_by_space;
+ csPosSignPosition = conf->p_sign_posn;
+ csNegSignPosition = conf->n_sign_posn;
+ }
+#else
+ decimalPoint = (char *)0;
+ thousandsSep = (char *)0;
+ intCurrencySymbol = (char *)0;
+ currencySymbol = (char *)0;
+ monDecimalPoint = (char *)0;
+ monThousandsSep = (char *)0;
+ positiveSign = (char *)0;
+ negativeSign =(char *)0;
+ intFractDigits = -1;
+ fractDigits = -1;
+ csPosPrecedes = -1;
+ csNegPrecedes = -1;
+ csPosSepBySpace = -1;
+ csNegSepBySpace = -1;
+ csPosSignPosition = -1;
+ csNegSignPosition = -1;
+#endif
+ if (decimalPoint) {
+ val = _MKSTRING(decimalPoint);
+ __AT_PUT_(info, @symbol(decimalPoint), val);
+ }
+ if (thousandsSep) {
+ val = _MKSTRING(thousandsSep);
+ __AT_PUT_(info, @symbol(thousandsSeparator), val);
+ }
+ if (intCurrencySymbol) {
+ val = _MKSTRING(intCurrencySymbol);
+ __AT_PUT_(info, @symbol(internationCurrencySymbol), val);
+ }
+ if (currencySymbol) {
+ val = _MKSTRING(currencySymbol);
+ __AT_PUT_(info, @symbol(currencySymbol), val);
+ }
+ if (monDecimalPoint) {
+ val = _MKSTRING(monDecimalPoint);
+ __AT_PUT_(info, @symbol(monetaryDecimalPoint), val);
+ }
+ if (monThousandsSep) {
+ val = _MKSTRING(monThousandsSep);
+ __AT_PUT_(info, @symbol(monetaryThousandsSeparator), val);
+ }
+ if (positiveSign) {
+ val = _MKSTRING(positiveSign);
+ __AT_PUT_(info, @symbol(positiveSign), val);
+ }
+ if (negativeSign) {
+ val = _MKSTRING(negativeSign);
+ __AT_PUT_(info, @symbol(negativeSign), val);
+ }
+ if (intFractDigits >= 0) {
+ __AT_PUT_(info, @symbol(internationalFractionalDigits), __MKSMALLINT(intFractDigits));
+ }
+ if (fractDigits >= 0) {
+ __AT_PUT_(info, @symbol(fractionalDigits), __MKSMALLINT(fractDigits));
+ }
+ if (csPosPrecedes >= 0) {
+ if (csPosPrecedes == 0) {
+ val = false;
+ } else {
+ val = true;
+ }
+ __AT_PUT_(info, @symbol(positiveSignPrecedesCurrencySymbol), val );
+ }
+ if (csNegPrecedes >= 0) {
+ if (csNegPrecedes == 0) {
+ val = false;
+ } else {
+ val = true;
+ }
+ __AT_PUT_(info, @symbol(negativeSignPrecedesCurrencySymbol), val );
+ }
+ if (csPosSepBySpace >= 0) {
+ if (csPosSepBySpace == 0) {
+ val = false;
+ } else {
+ val = true;
+ }
+ __AT_PUT_(info, @symbol(positiveSignSeparatedBySpaceFromCurrencySymbol), val);
+ }
+ if (csNegSepBySpace >= 0) {
+ if (csNegSepBySpace == 0) {
+ val = false;
+ } else {
+ val = true;
+ }
+ __AT_PUT_(info, @symbol(negativeSignSeparatedBySpaceFromCurrencySymbol), val);
+ }
+ switch (csPosSignPosition) {
+ case 0:
+ val = @symbol(parenthesesAround);
+ break;
+
+ case 1:
+ val = @symbol(signPrecedes);
+ break;
+
+ case 2:
+ val = @symbol(signSuceeds);
+ break;
+
+ case 3:
+ val = @symbol(signPrecedesCurrencySymbol);
+ break;
+
+ case 4:
+ val = @symbol(signSuceedsCurrencySymbol);
+ break;
+
+ default:
+ val = nil;
+ }
+ if (val != nil) {
+ __AT_PUT_(info, @symbol(positiveSignPosition), val);
+ }
+
+ switch (csNegSignPosition) {
+ case 0:
+ val = @symbol(parenthesesAround);
+ break;
+
+ case 1:
+ val = @symbol(signPrecedes);
+ break;
+
+ case 2:
+ val = @symbol(signSuceeds);
+ break;
+
+ case 3:
+ val = @symbol(signPrecedesCurrencySymbol);
+ break;
+
+ case 4:
+ val = @symbol(signSuceedsCurrencySymbol);
+ break;
+
+ default:
+ val = nil;
+ }
+ if (val != nil) {
+ __AT_PUT_(info, @symbol(negativeSignPosition), val);
+ }
+%}.
+ ^ info
+
+ "
+ OperatingSystem getLocaleInfo
+ "
+
+ "Created: 23.12.1995 / 14:19:20 / cg"
+!
+
+setLocaleInfo:anInfoDictionary
+ "set the locale information; if set, this oerrides the OS's settings.
+ (internal in ST/X only - the OS's settings remain unaffected)
+ See description of fields in #getLocaleInfo.
+
+ Notice, that (for now), the system does not use this information;
+ it should be used by applications as required."
+
+ LocaleInfo := anInfoDictionary
+
+ "
+ |d|
+
+ d := IdentityDictionary new.
+ d at:#decimalPoint put:'.' .
+ d at:#thousandsSeparator put:',' .
+ d at:#currencySymbol put:'USD' .
+ d at:#monetaryDecimalPoint put:'.' .
+ d at:#monetaryThousandsSeparator put:'.' .
+ d at:#fractionalDigits put:2 .
+ d at:#positiveSign put:'+' .
+ d at:#negativeSign put:'-' .
+ d at:#positiveSignPrecedesCurrencySymbol put:true .
+ d at:#negativeSignPrecedesCurrencySymbol put:false .
+ OperatingSystem setLocaleInfo:d
+ "
! !
!OperatingSystem class methodsFor:'shared memory access'!
@@ -4479,29 +4776,29 @@
long t;
#ifdef ultrix /* mhmh - isnt this ifdef BSD ? */
-# define TIMEZONE tmPtr->tm_gmtoff
+# define TIMEZONE tmPtr->tm_gmtoff
#else
-# define TIMEZONE timezone
+# define TIMEZONE timezone
#endif
if (__bothSmallInteger(low, hi)) {
- t = (_intVal(hi) << 16) | _intVal(low);
- tmPtr = localtime(&t);
- hours = _MKSMALLINT(tmPtr->tm_hour);
- minutes = _MKSMALLINT(tmPtr->tm_min);
- seconds = _MKSMALLINT(tmPtr->tm_sec);
-
- year = _MKSMALLINT(tmPtr->tm_year + 1900);
- month = _MKSMALLINT(tmPtr->tm_mon + 1);
- day = _MKSMALLINT(tmPtr->tm_mday);
-
- if (tmPtr->tm_isdst == 0) {
+ t = (_intVal(hi) << 16) | _intVal(low);
+ tmPtr = localtime(&t);
+ hours = _MKSMALLINT(tmPtr->tm_hour);
+ minutes = _MKSMALLINT(tmPtr->tm_min);
+ seconds = _MKSMALLINT(tmPtr->tm_sec);
+
+ year = _MKSMALLINT(tmPtr->tm_year + 1900);
+ month = _MKSMALLINT(tmPtr->tm_mon + 1);
+ day = _MKSMALLINT(tmPtr->tm_mday);
+
+ if (tmPtr->tm_isdst == 0) {
dst = false;
- utcOffset = _MKSMALLINT(TIMEZONE);
- } else {
+ utcOffset = _MKSMALLINT(TIMEZONE);
+ } else {
dst = true;
#ifdef HAS_ALTZONE
- utcOffset = _MKSMALLINT(altzone);
+ utcOffset = _MKSMALLINT(altzone);
#else
utcOffset = _MKSMALLINT(TIMEZONE) + 3600;
#endif
@@ -4509,17 +4806,17 @@
}
%}.
year notNil ifTrue:[
- "I would love to have SELF-like inline objects ..."
- ret := Array new:8.
- ret at:1 put:year.
- ret at:2 put:month.
- ret at:3 put:day.
- ret at:4 put:hours.
- ret at:5 put:minutes.
- ret at:6 put:seconds.
- ret at:7 put:utcOffset.
- ret at:8 put:dst.
- ^ ret
+ "I would love to have SELF-like inline objects ..."
+ ret := Array new:8.
+ ret at:1 put:year.
+ ret at:2 put:month.
+ ret at:3 put:day.
+ ret at:4 put:hours.
+ ret at:5 put:minutes.
+ ret at:6 put:seconds.
+ ret at:7 put:utcOffset.
+ ret at:8 put:dst.
+ ^ ret
].
^ self primitiveFailed
!
@@ -5293,13 +5590,13 @@
} while ((ret < 0) && (errno == EINTR));
} else {
do {
- ret = select(maxF+1, &rset, &wset, &eset, &wt);
- /*
- * for now: dont loop; if we did, we had to adjust the vt-timeval;
- * could otherwise stay in this loop forever ...
- * Premature return (before the time expired) must be handled by the caller.
+ ret = select(maxF+1, &rset, &wset, &eset, &wt);
+ /*
+ * for now: dont loop; if we did, we had to adjust the vt-timeval;
+ * could otherwise stay in this loop forever ...
+ * Premature return (before the time expired) must be handled by the caller.
* A good solution is to update the wt-timeval and redo the select.
- */
+ */
} while (0 /* (ret < 0) && (errno == EINTR) */ );
}
__END_INTERRUPTABLE__
@@ -5376,6 +5673,6 @@
!OperatingSystem class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Attic/Unix.st,v 1.108 1995-12-23 11:10:30 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Attic/Unix.st,v 1.109 1995-12-23 13:54:00 cg Exp $'
! !
OperatingSystem initialize!