Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / locale / rexxhost.c
blobd8416602c4c42d690093fc478b9f5bd63ef6e939
1 #include <exec/types.h>
3 #ifdef __MORPHOS__
4 #define CVa2i(__p0) \
5 LP1(300, LONG , CVa2i, \
6 STRPTR , __p0, a0, \
7 , RexxSysBase, 0, 0, 0, 0, 0, 0)
9 #define CVi2az(__p0, __p1, __p2) \
10 LP3(318, LONG , CVi2az, \
11 STRPTR , __p0, a0, \
12 LONG , __p1, d0, \
13 LONG , __p2, d1, \
14 , RexxSysBase, 0, 0, 0, 0, 0, 0)
15 #endif
17 #include <proto/exec.h>
18 #include <proto/rexxsyslib.h>
19 #include <rexx/errors.h>
20 #include <aros/asmcall.h>
21 #include "locale_intern.h"
22 #include <proto/locale.h>
24 #include <string.h>
25 #include <stdlib.h>
28 static LONG rxGetCatalogStr(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
30 *resstr = GetCatalogStr((struct Catalog *)CVa2i(rxmsg->rm_Args[1]), atol(rxmsg->rm_Args[2]), rxmsg->rm_Args[3]);
31 return strlen(*resstr);
34 static LONG rxGetLocaleStr(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
36 *resstr = GetLocaleStr(locale, atol(rxmsg->rm_Args[1]));
37 return strlen(*resstr);
40 static LONG rxOpenCatalog(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
42 APTR cat = OpenCatalog(locale, rxmsg->rm_Args[1], OC_BuiltInLanguage, (ULONG)rxmsg->rm_Args[2], OC_Version, atol(rxmsg->rm_Args[3]), TAG_DONE);
43 return CVi2az(*resstr, (LONG)cat, 12);
46 static LONG rxCloseCatalog(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
48 CloseCatalog((struct Catalog *)CVa2i(rxmsg->rm_Args[1]));
49 return 0;
52 static LONG rxStrnCmp(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
54 LONG reslen = StrnCmp(locale, rxmsg->rm_Args[1], rxmsg->rm_Args[2], -1, atol(rxmsg->rm_Args[3]));
56 if (reslen < 0) { *resstr[0] = '-'; *resstr[1] = '1'; reslen = 2; }
57 else if (reslen > 0) { *resstr[0] = '1'; reslen = 1; }
58 else { *resstr[0] = '0'; reslen = 1; }
60 return reslen;
63 static LONG rxConvToLower(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
65 *resstr[0] = (UBYTE)ConvToLower(locale, *rxmsg->rm_Args[1]);
66 return 1;
69 static LONG rxConvToUpper(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
71 *resstr[0] = (UBYTE)ConvToUpper(locale, *rxmsg->rm_Args[1]);
72 return 1;
75 static LONG rxIsAlpha(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
77 if (IsAlpha(locale, *rxmsg->rm_Args[1])) *resstr[0] = '1';
78 else *resstr[0] = '0';
79 return 1;
82 static LONG rxIsSpace(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
84 if (IsSpace(locale, *rxmsg->rm_Args[1])) *resstr[0] = '1';
85 else *resstr[0] = '0';
86 return 1;
89 static LONG rxIsDigit(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
91 if (IsDigit(locale, *rxmsg->rm_Args[1])) *resstr[0] = '1';
92 else *resstr[0] = '0';
93 return 1;
96 static LONG rxIsGraph(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
98 if (IsGraph(locale, *rxmsg->rm_Args[1])) *resstr[0] = '1';
99 else *resstr[0] = '0';
100 return 1;
103 static LONG rxIsAlNum(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
105 if (IsAlNum(locale, *rxmsg->rm_Args[1])) *resstr[0] = '1';
106 else *resstr[0] = '0';
107 return 1;
110 static LONG rxIsCntrl(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
112 if (IsCntrl(locale, *rxmsg->rm_Args[1])) *resstr[0] = '1';
113 else *resstr[0] = '0';
114 return 1;
117 static LONG rxIsLower(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
119 if (IsLower(locale, *rxmsg->rm_Args[1])) *resstr[0] = '1';
120 else *resstr[0] = '0';
121 return 1;
124 static LONG rxIsPunct(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
126 if (IsPunct(locale, *rxmsg->rm_Args[1])) *resstr[0] = '1';
127 else *resstr[0] = '0';
128 return 1;
131 static LONG rxIsUpper(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
133 if (IsUpper(locale, *rxmsg->rm_Args[1])) *resstr[0] = '1';
134 else *resstr[0] = '0';
135 return 1;
138 static LONG rxIsPrint(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
140 if (IsPrint(locale, *rxmsg->rm_Args[1])) *resstr[0] = '1';
141 else *resstr[0] = '0';
142 return 1;
145 static LONG rxIsXDigit(struct LocaleBase *LocaleBase, struct Locale *locale, struct RexxMsg *rxmsg, STRPTR *resstr)
147 if (IsXDigit(locale, *rxmsg->rm_Args[1])) *resstr[0] = '1';
148 else *resstr[0] = '0';
149 return 1;
152 struct dispentry
154 CONST_STRPTR FuncName;
155 LONG (*Function)(struct LocaleBase *, struct Locale *, struct RexxMsg *, STRPTR *);
156 ULONG NumArgs;
159 /* MUST be alphabetically sorted! */
160 struct dispentry disptable[] = {
161 { "CLOSECATALOG", rxCloseCatalog, 1 },
162 { "CONVTOLOWER", rxConvToLower, 1 },
163 { "CONVTOUPPER", rxConvToUpper, 1 },
164 { "GETCATALOGSTR", rxGetCatalogStr, 3 },
165 { "GETLOCALESTR", rxGetLocaleStr, 1 }, /*** NEW ***/
166 { "ISALNUM", rxIsAlNum, 1 },
167 { "ISALPHA", rxIsAlpha, 1 },
168 { "ISCNTRL", rxIsCntrl, 1 },
169 { "ISDIGIT", rxIsDigit, 1 },
170 { "ISGRAPH", rxIsGraph, 1 },
171 { "ISLOWER", rxIsLower, 1 },
172 { "ISPRINT", rxIsPrint, 1 },
173 { "ISPUNCT", rxIsPunct, 1 },
174 { "ISSPACE", rxIsSpace, 1 },
175 { "ISUPPER", rxIsUpper, 1 },
176 { "ISXDIGIT", rxIsXDigit, 1 },
177 { "OPENCATALOG", rxOpenCatalog, 3 },
178 { "STRNCMP", rxStrnCmp, 3 }
181 int dispcomp(const void *name, const void *dispentry)
183 return stricmp(name, ((const struct dispentry *)dispentry)->FuncName);
187 /*****************************************************************************
189 NAME */
191 AROS_LH1(ULONG, RexxHost,
193 /* SYNOPSIS */
194 AROS_LHA(struct RexxMsg *, rxmsg, A0),
196 /* LOCATION */
197 struct LocaleBase *, LocaleBase, 5, Locale)
199 /* FUNCTION
200 locale.library rexxhost interface
202 *****************************************************************************/
204 AROS_LIBFUNC_INIT
206 struct Locale *locale = (struct Locale *)IntLB(LocaleBase)->lb_CurrentLocale;
207 struct dispentry *dispentry;
208 LONG reslen;
209 UBYTE resbuf[12];
210 STRPTR argstr = resbuf;
212 if (!RexxSysBase) return(ERR10_014);
213 if (!rxmsg || !IsRexxMsg(rxmsg) || !(rxmsg->rm_Action & RXFUNC) || !rxmsg->rm_Args[0]) return(ERR10_010);
215 if (!(dispentry = bsearch(rxmsg->rm_Args[0], disptable, sizeof(disptable)/sizeof(struct dispentry), sizeof(struct dispentry), dispcomp))) return(ERR10_001);
216 if ((rxmsg->rm_Action & RXARGMASK) != dispentry->NumArgs) return(ERR10_017);
218 reslen = dispentry->Function(LocaleBase, locale, rxmsg, &argstr);
220 if (!(argstr = CreateArgstring(argstr, reslen))) return(ERR10_003);
222 #ifdef __MORPHOS__
223 REG_A0 = (ULONG)argstr;
224 #else
225 #error register a0 must be set to argstr before returning...
226 #endif
228 return 0;
230 AROS_LIBFUNC_EXIT
231 } /* RexxHost */