Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

external-mksh: Commit

external/mksh


Commit MetaInfo

Revisiónc9786cca2575e0a592b5da15094590f283b665ae (tree)
Tiempo2018-02-09 02:07:54
AutorElliott Hughes <enh@goog...>
Commiterandroid-build-merger

Log Message

Merge "Upgrade to mksh R56c." am: 0c3dc4139a
am: 7b388008f5

Change-Id: I662a7b4e9feb6b9b8c11e13eeeeb81f55460c725

Cambiar Resumen

Diferencia incremental

--- a/Android.bp
+++ b/Android.bp
@@ -108,7 +108,7 @@ cc_defaults {
108108 "-DHAVE_SYS_ERRLIST_DECL=0",
109109 "-DHAVE_SYS_SIGLIST_DECL=1",
110110 "-DHAVE_PERSISTENT_HISTORY=0",
111- "-DMKSH_BUILD_R=562",
111+ "-DMKSH_BUILD_R=563",
112112
113113 // Additional flags
114114 "-DMKSH_DEFAULT_PROFILEDIR=\"/system/etc\"",
--- a/src/Build.sh
+++ b/src/Build.sh
@@ -1,5 +1,5 @@
11 #!/bin/sh
2-srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.727 2017/08/29 13:38:28 tg Exp $'
2+srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.731 2018/01/13 21:38:06 tg Exp $'
33 #-
44 # Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
55 # 2011, 2012, 2013, 2014, 2015, 2016, 2017
@@ -796,6 +796,8 @@ Harvey)
796796 add_cppflags -DMKSH_ASSUME_UTF8
797797 HAVE_ISSET_MKSH_ASSUME_UTF8=1
798798 HAVE_ISOFF_MKSH_ASSUME_UTF8=0
799+ add_cppflags -DMKSH__NO_SYMLINK
800+ check_categories="$check_categories nosymlink"
799801 add_cppflags -DMKSH_NO_CMDLINE_EDITING
800802 add_cppflags -DMKSH__NO_SETEUGID
801803 oswarn=' and will currently not work'
@@ -819,6 +821,20 @@ Interix)
819821 IRIX*)
820822 : "${HAVE_SETLOCALE_CTYPE=0}"
821823 ;;
824+Jehanne)
825+ add_cppflags -DMKSH_ASSUME_UTF8
826+ HAVE_ISSET_MKSH_ASSUME_UTF8=1
827+ HAVE_ISOFF_MKSH_ASSUME_UTF8=0
828+ add_cppflags -DMKSH__NO_SYMLINK
829+ check_categories="$check_categories nosymlink"
830+ add_cppflags -DMKSH_NO_CMDLINE_EDITING
831+ add_cppflags -DMKSH_DISABLE_REVOKE_WARNING
832+ add_cppflags '-D_PATH_DEFPATH=\"/cmd\"'
833+ add_cppflags '-DMKSH_DEFAULT_EXECSHELL=\"/cmd/mksh\"'
834+ add_cppflags '-DMKSH_DEFAULT_PROFILEDIR=\"/cfg/mksh\"'
835+ add_cppflags '-DMKSH_ENVDIR=\"/env\"'
836+ SRCS="$SRCS jehanne.c"
837+ ;;
822838 Linux)
823839 case $CC in
824840 *tendracc*) ;;
@@ -947,6 +963,8 @@ Plan9)
947963 add_cppflags -DMKSH_ASSUME_UTF8
948964 HAVE_ISSET_MKSH_ASSUME_UTF8=1
949965 HAVE_ISOFF_MKSH_ASSUME_UTF8=0
966+ add_cppflags -DMKSH__NO_SYMLINK
967+ check_categories="$check_categories nosymlink"
950968 add_cppflags -DMKSH_NO_CMDLINE_EDITING
951969 add_cppflags -DMKSH__NO_SETEUGID
952970 oswarn=' and will currently not work'
@@ -2409,7 +2427,7 @@ addsrcs '!' HAVE_STRLCPY strlcpy.c
24092427 addsrcs USE_PRINTF_BUILTIN printf.c
24102428 test 1 = "$USE_PRINTF_BUILTIN" && add_cppflags -DMKSH_PRINTF_BUILTIN
24112429 test 1 = "$HAVE_CAN_VERB" && CFLAGS="$CFLAGS -verbose"
2412-add_cppflags -DMKSH_BUILD_R=562
2430+add_cppflags -DMKSH_BUILD_R=563
24132431
24142432 $e $bi$me: Finished configuration testing, now producing output.$ao
24152433
@@ -2733,6 +2751,7 @@ MKSH_DISABLE_DEPRECATED disable code paths scheduled for later removal
27332751 MKSH_DISABLE_EXPERIMENTAL disable code not yet comfy for (LTS) snapshots
27342752 MKSH_DISABLE_TTY_WARNING shut up warning about ctty if OS cant be fixed
27352753 MKSH_DONT_EMIT_IDSTRING omit RCS IDs from binary
2754+MKSH_EARLY_LOCALE_TRACKING track utf8-mode from POSIX locale, for SuSE
27362755 MKSH_MIDNIGHTBSD01ASH_COMPAT set -o sh: additional compatibility quirk
27372756 MKSH_NOPROSPECTOFWORK disable jobs, co-processes, etc. (do not use)
27382757 MKSH_NOPWNAM skip PAM calls, for -static on glibc or Solaris
--- a/src/check.t
+++ b/src/check.t
@@ -1,4 +1,4 @@
1-# $MirOS: src/bin/mksh/check.t,v 1.797 2017/08/29 13:38:29 tg Exp $
1+# $MirOS: src/bin/mksh/check.t,v 1.801 2018/01/14 01:47:33 tg Exp $
22 # -*- mode: sh -*-
33 #-
44 # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@@ -30,7 +30,7 @@
3030 # (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
3131
3232 expected-stdout:
33- @(#)MIRBSD KSH R56 2017/08/29
33+ @(#)MIRBSD KSH R56 2018/01/14
3434 description:
3535 Check base version of full shell
3636 stdin:
@@ -39,7 +39,7 @@ name: KSH_VERSION
3939 category: !shell:legacy-yes
4040 ---
4141 expected-stdout:
42- @(#)LEGACY KSH R56 2017/08/29
42+ @(#)LEGACY KSH R56 2018/01/14
4343 description:
4444 Check base version of legacy shell
4545 stdin:
@@ -3328,7 +3328,7 @@ stdin:
33283328 echo B
33293329 ) &
33303330 ' &
3331- sleep 2
3331+ sleep 5
33323332 echo Left overs: *
33333333 expected-stdout:
33343334 A
@@ -3392,7 +3392,7 @@ stdin:
33923392 (sleep 1; foo) &
33933393 foo
33943394 ' &
3395- sleep 2
3395+ sleep 5
33963396 echo Left overs: *
33973397 expected-stdout:
33983398 hi
@@ -6702,7 +6702,7 @@ name: regression-65
67026702 description:
67036703 check for a regression with sleep builtin and signal mask
67046704 category: !nojsig
6705-time-limit: 3
6705+time-limit: 5
67066706 stdin:
67076707 sleep 1
67086708 echo blub |&
@@ -9026,6 +9026,15 @@ expected-stdout:
90269026 .c:a b.c d..:
90279027 .d:a b.c d..:
90289028 ---
9029+name: arrassign-eol
9030+description:
9031+ Commands after array assignments are not permitted
9032+stdin:
9033+ foo=(a b) env
9034+expected-exit: e != 0
9035+expected-stderr-pattern:
9036+ /syntax error: unexpected 'env'/
9037+---
90299038 name: arrassign-fnc-none
90309039 description:
90319040 Check locality of array access inside a function
--- a/src/edit.c
+++ b/src/edit.c
@@ -5,7 +5,7 @@
55
66 /*-
77 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
8- * 2011, 2012, 2013, 2014, 2015, 2016, 2017
8+ * 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
99 * mirabilos <m@mirbsd.org>
1010 *
1111 * Provided that these terms and disclaimer and all copyright notices
@@ -28,7 +28,7 @@
2828
2929 #ifndef MKSH_NO_CMDLINE_EDITING
3030
31-__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.340 2017/08/27 23:33:50 tg Exp $");
31+__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.342 2018/01/14 00:03:00 tg Exp $");
3232
3333 /*
3434 * in later versions we might use libtermcap for this, but since external
@@ -312,12 +312,12 @@ x_glob_hlp_add_qchar(char *cp)
312312 */
313313 switch (ord(ch)) {
314314 case QCHAR:
315- case ord('$'):
316- case ord('*'):
317- case ord('?'):
318- case ord('['):
319- case ord('\\'):
320- case ord('`'):
315+ case ORD('$'):
316+ case ORD('*'):
317+ case ORD('?'):
318+ case ORD('['):
319+ case ORD('\\'):
320+ case ORD('`'):
321321 *dp++ = QCHAR;
322322 break;
323323 }
@@ -650,11 +650,11 @@ x_cf_glob(int *flagsp, const char *buf, int buflen, int pos, int *startp,
650650 if (*s == '\\' && s[1])
651651 s++;
652652 else if (ctype(*s, C_QUEST | C_DOLAR) ||
653- ord(*s) == ord('*') || ord(*s) == ord('[') ||
653+ ord(*s) == ORD('*') || ord(*s) == ORD('[') ||
654654 /* ?() *() +() @() !() but two already checked */
655- (ord(s[1]) == ord('(' /*)*/) &&
656- (ord(*s) == ord('+') || ord(*s) == ord('@') ||
657- ord(*s) == ord('!')))) {
655+ (ord(s[1]) == ORD('(' /*)*/) &&
656+ (ord(*s) == ORD('+') || ord(*s) == ORD('@') ||
657+ ord(*s) == ORD('!')))) {
658658 /*
659659 * just expand based on the extglob
660660 * or parameter
@@ -3688,7 +3688,7 @@ vi_hook(int ch)
36883688 return (1);
36893689 cmdlen = 0;
36903690 argc1 = 0;
3691- if (ctype(ch, C_DIGIT) && ord(ch) != ord('0')) {
3691+ if (ctype(ch, C_DIGIT) && ord(ch) != ORD('0')) {
36923692 argc1 = ksh_numdig(ch);
36933693 state = VARG1;
36943694 } else {
@@ -3743,7 +3743,7 @@ vi_hook(int ch)
37433743
37443744 case VEXTCMD:
37453745 argc2 = 0;
3746- if (ctype(ch, C_DIGIT) && ord(ch) != ord('0')) {
3746+ if (ctype(ch, C_DIGIT) && ord(ch) != ORD('0')) {
37473747 argc2 = ksh_numdig(ch);
37483748 state = VARG2;
37493749 return (0);
@@ -4128,7 +4128,7 @@ vi_cmd(int argcnt, const char *cmd)
41284128 redraw_line(true);
41294129 break;
41304130
4131- case ord('@'):
4131+ case ORD('@'):
41324132 {
41334133 static char alias[] = "_\0";
41344134 struct tbl *ap;
@@ -4169,7 +4169,7 @@ vi_cmd(int argcnt, const char *cmd)
41694169 }
41704170 break;
41714171
4172- case ord('a'):
4172+ case ORD('a'):
41734173 modified = 1;
41744174 hnum = hlast;
41754175 if (vs->linelen != 0)
@@ -4177,7 +4177,7 @@ vi_cmd(int argcnt, const char *cmd)
41774177 insert = INSERT;
41784178 break;
41794179
4180- case ord('A'):
4180+ case ORD('A'):
41814181 modified = 1;
41824182 hnum = hlast;
41834183 del_range(0, 0);
@@ -4185,7 +4185,7 @@ vi_cmd(int argcnt, const char *cmd)
41854185 insert = INSERT;
41864186 break;
41874187
4188- case ord('S'):
4188+ case ORD('S'):
41894189 vs->cursor = domovebeg();
41904190 del_range(vs->cursor, vs->linelen);
41914191 modified = 1;
@@ -4193,14 +4193,14 @@ vi_cmd(int argcnt, const char *cmd)
41934193 insert = INSERT;
41944194 break;
41954195
4196- case ord('Y'):
4196+ case ORD('Y'):
41974197 cmd = "y$";
41984198 /* ahhhhhh... */
41994199
42004200 /* FALLTHROUGH */
4201- case ord('c'):
4202- case ord('d'):
4203- case ord('y'):
4201+ case ORD('c'):
4202+ case ORD('d'):
4203+ case ORD('y'):
42044204 if (*cmd == cmd[1]) {
42054205 c1 = *cmd == 'c' ? domovebeg() : 0;
42064206 c2 = vs->linelen;
@@ -4239,7 +4239,7 @@ vi_cmd(int argcnt, const char *cmd)
42394239 }
42404240 break;
42414241
4242- case ord('p'):
4242+ case ORD('p'):
42434243 modified = 1;
42444244 hnum = hlast;
42454245 if (vs->linelen != 0)
@@ -4253,7 +4253,7 @@ vi_cmd(int argcnt, const char *cmd)
42534253 return (-1);
42544254 break;
42554255
4256- case ord('P'):
4256+ case ORD('P'):
42574257 modified = 1;
42584258 hnum = hlast;
42594259 any = 0;
@@ -4266,25 +4266,25 @@ vi_cmd(int argcnt, const char *cmd)
42664266 return (-1);
42674267 break;
42684268
4269- case ord('C'):
4269+ case ORD('C'):
42704270 modified = 1;
42714271 hnum = hlast;
42724272 del_range(vs->cursor, vs->linelen);
42734273 insert = INSERT;
42744274 break;
42754275
4276- case ord('D'):
4276+ case ORD('D'):
42774277 yank_range(vs->cursor, vs->linelen);
42784278 del_range(vs->cursor, vs->linelen);
42794279 if (vs->cursor != 0)
42804280 vs->cursor--;
42814281 break;
42824282
4283- case ord('g'):
4283+ case ORD('g'):
42844284 if (!argcnt)
42854285 argcnt = hlast;
42864286 /* FALLTHROUGH */
4287- case ord('G'):
4287+ case ORD('G'):
42884288 if (!argcnt)
42894289 argcnt = 1;
42904290 else
@@ -4297,21 +4297,21 @@ vi_cmd(int argcnt, const char *cmd)
42974297 }
42984298 break;
42994299
4300- case ord('i'):
4300+ case ORD('i'):
43014301 modified = 1;
43024302 hnum = hlast;
43034303 insert = INSERT;
43044304 break;
43054305
4306- case ord('I'):
4306+ case ORD('I'):
43074307 modified = 1;
43084308 hnum = hlast;
43094309 vs->cursor = domovebeg();
43104310 insert = INSERT;
43114311 break;
43124312
4313- case ord('j'):
4314- case ord('+'):
4313+ case ORD('j'):
4314+ case ORD('+'):
43154315 case CTRL_N:
43164316 if (grabhist(modified, hnum + argcnt) < 0)
43174317 return (-1);
@@ -4321,8 +4321,8 @@ vi_cmd(int argcnt, const char *cmd)
43214321 }
43224322 break;
43234323
4324- case ord('k'):
4325- case ord('-'):
4324+ case ORD('k'):
4325+ case ORD('-'):
43264326 case CTRL_P:
43274327 if (grabhist(modified, hnum - argcnt) < 0)
43284328 return (-1);
@@ -4332,7 +4332,7 @@ vi_cmd(int argcnt, const char *cmd)
43324332 }
43334333 break;
43344334
4335- case ord('r'):
4335+ case ORD('r'):
43364336 if (vs->linelen == 0)
43374337 return (-1);
43384338 modified = 1;
@@ -4350,13 +4350,13 @@ vi_cmd(int argcnt, const char *cmd)
43504350 }
43514351 break;
43524352
4353- case ord('R'):
4353+ case ORD('R'):
43544354 modified = 1;
43554355 hnum = hlast;
43564356 insert = REPLACE;
43574357 break;
43584358
4359- case ord('s'):
4359+ case ORD('s'):
43604360 if (vs->linelen == 0)
43614361 return (-1);
43624362 modified = 1;
@@ -4367,7 +4367,7 @@ vi_cmd(int argcnt, const char *cmd)
43674367 insert = INSERT;
43684368 break;
43694369
4370- case ord('v'):
4370+ case ORD('v'):
43714371 if (!argcnt) {
43724372 if (vs->linelen == 0)
43734373 return (-1);
@@ -4390,7 +4390,7 @@ vi_cmd(int argcnt, const char *cmd)
43904390 vs->linelen = strlen(vs->cbuf);
43914391 return (2);
43924392
4393- case ord('x'):
4393+ case ORD('x'):
43944394 if (vs->linelen == 0)
43954395 return (-1);
43964396 modified = 1;
@@ -4401,7 +4401,7 @@ vi_cmd(int argcnt, const char *cmd)
44014401 del_range(vs->cursor, vs->cursor + argcnt);
44024402 break;
44034403
4404- case ord('X'):
4404+ case ORD('X'):
44054405 if (vs->cursor > 0) {
44064406 modified = 1;
44074407 hnum = hlast;
@@ -4414,13 +4414,13 @@ vi_cmd(int argcnt, const char *cmd)
44144414 return (-1);
44154415 break;
44164416
4417- case ord('u'):
4417+ case ORD('u'):
44184418 t = vs;
44194419 vs = undo;
44204420 undo = t;
44214421 break;
44224422
4423- case ord('U'):
4423+ case ORD('U'):
44244424 if (!modified)
44254425 return (-1);
44264426 if (grabhist(modified, ohnum) < 0)
@@ -4429,19 +4429,19 @@ vi_cmd(int argcnt, const char *cmd)
44294429 hnum = ohnum;
44304430 break;
44314431
4432- case ord('?'):
4432+ case ORD('?'):
44334433 if (hnum == hlast)
44344434 hnum = -1;
44354435 /* ahhh */
44364436
44374437 /* FALLTHROUGH */
4438- case ord('/'):
4438+ case ORD('/'):
44394439 c3 = 1;
44404440 srchlen = 0;
44414441 lastsearch = *cmd;
44424442 /* FALLTHROUGH */
4443- case ord('n'):
4444- case ord('N'):
4443+ case ORD('n'):
4444+ case ORD('N'):
44454445 if (lastsearch == ' ')
44464446 return (-1);
44474447 if (lastsearch == '?')
@@ -4468,7 +4468,7 @@ vi_cmd(int argcnt, const char *cmd)
44684468 return (0);
44694469 }
44704470 break;
4471- case ord('_'):
4471+ case ORD('_'):
44724472 {
44734473 bool inspace;
44744474 char *p, *sp;
@@ -4520,7 +4520,7 @@ vi_cmd(int argcnt, const char *cmd)
45204520 }
45214521 break;
45224522
4523- case ord('~'):
4523+ case ORD('~'):
45244524 {
45254525 char *p;
45264526 int i;
@@ -4544,7 +4544,7 @@ vi_cmd(int argcnt, const char *cmd)
45444544 break;
45454545 }
45464546
4547- case ord('#'):
4547+ case ORD('#'):
45484548 {
45494549 int ret = x_do_comment(vs->cbuf, vs->cbufsize,
45504550 &vs->linelen);
@@ -4554,7 +4554,7 @@ vi_cmd(int argcnt, const char *cmd)
45544554 }
45554555
45564556 /* AT&T ksh */
4557- case ord('='):
4557+ case ORD('='):
45584558 /* Nonstandard vi/ksh */
45594559 case CTRL_E:
45604560 print_expansions(vs, 1);
@@ -4574,7 +4574,7 @@ vi_cmd(int argcnt, const char *cmd)
45744574 return (-1);
45754575 /* FALLTHROUGH */
45764576 /* AT&T ksh */
4577- case ord('\\'):
4577+ case ORD('\\'):
45784578 /* Nonstandard vi/ksh */
45794579 case CTRL_F:
45804580 complete_word(1, argcnt);
@@ -4582,7 +4582,7 @@ vi_cmd(int argcnt, const char *cmd)
45824582
45834583
45844584 /* AT&T ksh */
4585- case ord('*'):
4585+ case ORD('*'):
45864586 /* Nonstandard vi/ksh */
45874587 case CTRL_X:
45884588 expand_word(1);
@@ -4590,8 +4590,8 @@ vi_cmd(int argcnt, const char *cmd)
45904590
45914591
45924592 /* mksh: cursor movement */
4593- case ord('['):
4594- case ord('O'):
4593+ case ORD('['):
4594+ case ORD('O'):
45954595 state = VPREFIX2;
45964596 if (vs->linelen != 0)
45974597 vs->cursor++;
@@ -4611,19 +4611,19 @@ domove(int argcnt, const char *cmd, int sub)
46114611 unsigned int bcount;
46124612
46134613 switch (ord(*cmd)) {
4614- case ord('b'):
4614+ case ORD('b'):
46154615 if (!sub && vs->cursor == 0)
46164616 return (-1);
46174617 ncursor = backword(argcnt);
46184618 break;
46194619
4620- case ord('B'):
4620+ case ORD('B'):
46214621 if (!sub && vs->cursor == 0)
46224622 return (-1);
46234623 ncursor = Backword(argcnt);
46244624 break;
46254625
4626- case ord('e'):
4626+ case ORD('e'):
46274627 if (!sub && vs->cursor + 1 >= vs->linelen)
46284628 return (-1);
46294629 ncursor = endword(argcnt);
@@ -4631,7 +4631,7 @@ domove(int argcnt, const char *cmd, int sub)
46314631 ncursor++;
46324632 break;
46334633
4634- case ord('E'):
4634+ case ORD('E'):
46354635 if (!sub && vs->cursor + 1 >= vs->linelen)
46364636 return (-1);
46374637 ncursor = Endword(argcnt);
@@ -4639,15 +4639,15 @@ domove(int argcnt, const char *cmd, int sub)
46394639 ncursor++;
46404640 break;
46414641
4642- case ord('f'):
4643- case ord('F'):
4644- case ord('t'):
4645- case ord('T'):
4642+ case ORD('f'):
4643+ case ORD('F'):
4644+ case ORD('t'):
4645+ case ORD('T'):
46464646 fsavecmd = *cmd;
46474647 fsavech = cmd[1];
46484648 /* FALLTHROUGH */
4649- case ord(','):
4650- case ord(';'):
4649+ case ORD(','):
4650+ case ORD(';'):
46514651 if (fsavecmd == ' ')
46524652 return (-1);
46534653 i = ksh_eq(fsavecmd, 'F', 'f');
@@ -4661,7 +4661,7 @@ domove(int argcnt, const char *cmd, int sub)
46614661 ncursor++;
46624662 break;
46634663
4664- case ord('h'):
4664+ case ORD('h'):
46654665 case CTRL_H:
46664666 if (!sub && vs->cursor == 0)
46674667 return (-1);
@@ -4670,8 +4670,8 @@ domove(int argcnt, const char *cmd, int sub)
46704670 ncursor = 0;
46714671 break;
46724672
4673- case ord(' '):
4674- case ord('l'):
4673+ case ORD(' '):
4674+ case ORD('l'):
46754675 if (!sub && vs->cursor + 1 >= vs->linelen)
46764676 return (-1);
46774677 if (vs->linelen != 0) {
@@ -4681,27 +4681,27 @@ domove(int argcnt, const char *cmd, int sub)
46814681 }
46824682 break;
46834683
4684- case ord('w'):
4684+ case ORD('w'):
46854685 if (!sub && vs->cursor + 1 >= vs->linelen)
46864686 return (-1);
46874687 ncursor = forwword(argcnt);
46884688 break;
46894689
4690- case ord('W'):
4690+ case ORD('W'):
46914691 if (!sub && vs->cursor + 1 >= vs->linelen)
46924692 return (-1);
46934693 ncursor = Forwword(argcnt);
46944694 break;
46954695
4696- case ord('0'):
4696+ case ORD('0'):
46974697 ncursor = 0;
46984698 break;
46994699
4700- case ord('^'):
4700+ case ORD('^'):
47014701 ncursor = domovebeg();
47024702 break;
47034703
4704- case ord('|'):
4704+ case ORD('|'):
47054705 ncursor = argcnt;
47064706 if (ncursor > vs->linelen)
47074707 ncursor = vs->linelen;
@@ -4709,14 +4709,14 @@ domove(int argcnt, const char *cmd, int sub)
47094709 ncursor--;
47104710 break;
47114711
4712- case ord('$'):
4712+ case ORD('$'):
47134713 if (vs->linelen != 0)
47144714 ncursor = vs->linelen;
47154715 else
47164716 ncursor = 0;
47174717 break;
47184718
4719- case ord('%'):
4719+ case ORD('%'):
47204720 ncursor = vs->cursor;
47214721 while (ncursor < vs->linelen &&
47224722 (i = bracktype(vs->cbuf[ncursor])) == 0)
@@ -4784,22 +4784,22 @@ bracktype(int ch)
47844784 {
47854785 switch (ord(ch)) {
47864786
4787- case ord('('):
4787+ case ORD('('):
47884788 return (1);
47894789
4790- case ord('['):
4790+ case ORD('['):
47914791 return (2);
47924792
4793- case ord('{'):
4793+ case ORD('{'):
47944794 return (3);
47954795
4796- case ord(')'):
4796+ case ORD(')'):
47974797 return (-1);
47984798
4799- case ord(']'):
4799+ case ORD(']'):
48004800 return (-2);
48014801
4802- case ord('}'):
4802+ case ORD('}'):
48034803 return (-3);
48044804
48054805 default:
--- a/src/eval.c
+++ b/src/eval.c
@@ -2,7 +2,7 @@
22
33 /*-
44 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
5- * 2011, 2012, 2013, 2014, 2015, 2016, 2017
5+ * 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
66 * mirabilos <m@mirbsd.org>
77 *
88 * Provided that these terms and disclaimer and all copyright notices
@@ -23,7 +23,7 @@
2323
2424 #include "sh.h"
2525
26-__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.215 2017/08/28 23:27:51 tg Exp $");
26+__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.219 2018/01/14 01:29:47 tg Exp $");
2727
2828 /*
2929 * string expansion
@@ -320,21 +320,21 @@ expand(
320320 case COMASUB:
321321 case COMSUB:
322322 *dp++ = '(';
323- c = ord(')');
323+ c = ORD(')');
324324 break;
325325 case FUNASUB:
326326 case FUNSUB:
327327 case VALSUB:
328328 *dp++ = '{';
329329 *dp++ = c == VALSUB ? '|' : ' ';
330- c = ord('}');
330+ c = ORD('}');
331331 break;
332332 }
333333 while (*sp != '\0') {
334334 Xcheck(ds, dp);
335335 *dp++ = *sp++;
336336 }
337- if (c == ord('}'))
337+ if ((unsigned int)c == ORD('}'))
338338 *dp++ = ';';
339339 *dp++ = c;
340340 } else {
@@ -436,11 +436,11 @@ expand(
436436 if (stype)
437437 sp += slen;
438438 switch (stype & STYPE_SINGLE) {
439- case ord('#') | STYPE_AT:
439+ case ORD('#') | STYPE_AT:
440440 x.str = shf_smprintf("%08X",
441441 (unsigned int)hash(str_val(st->var)));
442442 break;
443- case ord('Q') | STYPE_AT: {
443+ case ORD('Q') | STYPE_AT: {
444444 struct shf shf;
445445
446446 shf_sopen(NULL, 0, SHF_WR|SHF_DYNAMIC, &shf);
@@ -448,7 +448,7 @@ expand(
448448 x.str = shf_sclose(&shf);
449449 break;
450450 }
451- case ord('0'): {
451+ case ORD('0'): {
452452 char *beg, *mid, *end, *stg;
453453 mksh_ari_t from = 0, num = -1, flen, finc = 0;
454454
@@ -456,13 +456,13 @@ expand(
456456 mid = beg + (wdscan(sp, ADELIM) - sp);
457457 stg = beg + (wdscan(sp, CSUBST) - sp);
458458 mid[-2] = EOS;
459- if (ord(mid[-1]) == ord(/*{*/ '}')) {
459+ if (ord(mid[-1]) == ORD(/*{*/ '}')) {
460460 sp += mid - beg - 1;
461461 end = NULL;
462462 } else {
463463 end = mid +
464464 (wdscan(mid, ADELIM) - mid);
465- if (ord(end[-1]) != ord(/*{*/ '}'))
465+ if (ord(end[-1]) != ORD(/*{*/ '}'))
466466 /* more than max delimiters */
467467 goto unwind_substsyn;
468468 end[-2] = EOS;
@@ -495,8 +495,8 @@ expand(
495495 strndupx(x.str, beg, num, ATEMP);
496496 goto do_CSUBST;
497497 }
498- case ord('/') | STYPE_AT:
499- case ord('/'): {
498+ case ORD('/') | STYPE_AT:
499+ case ORD('/'): {
500500 char *s, *p, *d, *sbeg, *end;
501501 char *pat = NULL, *rrep = null;
502502 char fpat = 0, *tpat1, *tpat2;
@@ -506,7 +506,7 @@ expand(
506506 p = s + (wdscan(sp, ADELIM) - sp);
507507 d = s + (wdscan(sp, CSUBST) - sp);
508508 p[-2] = EOS;
509- if (ord(p[-1]) == ord(/*{*/ '}'))
509+ if (ord(p[-1]) == ORD(/*{*/ '}'))
510510 d = NULL;
511511 else
512512 d[-2] = EOS;
@@ -547,11 +547,11 @@ expand(
547547 }
548548
549549 /* first see if we have any match at all */
550- if (ord(fpat) == ord('#')) {
550+ if (ord(fpat) == ORD('#')) {
551551 /* anchor at the beginning */
552552 tpat1 = shf_smprintf("%s%c*", pat, MAGIC);
553553 tpat2 = tpat1;
554- } else if (ord(fpat) == ord('%')) {
554+ } else if (ord(fpat) == ORD('%')) {
555555 /* anchor at the end */
556556 tpat1 = shf_smprintf("%c*%s", MAGIC, pat);
557557 tpat2 = pat;
@@ -569,7 +569,7 @@ expand(
569569 goto end_repl;
570570 end = strnul(s);
571571 /* now anchor the beginning of the match */
572- if (ord(fpat) != ord('#'))
572+ if (ord(fpat) != ORD('#'))
573573 while (sbeg <= end) {
574574 if (gmatchx(sbeg, tpat2, false))
575575 break;
@@ -578,11 +578,11 @@ expand(
578578 }
579579 /* now anchor the end of the match */
580580 p = end;
581- if (ord(fpat) != ord('%'))
581+ if (ord(fpat) != ORD('%'))
582582 while (p >= sbeg) {
583583 bool gotmatch;
584584
585- c = *p;
585+ c = ord(*p);
586586 *p = '\0';
587587 gotmatch = tobool(gmatchx(sbeg, pat, false));
588588 *p = c;
@@ -622,8 +622,8 @@ expand(
622622 afree(ws, ATEMP);
623623 goto do_CSUBST;
624624 }
625- case ord('#'):
626- case ord('%'):
625+ case ORD('#'):
626+ case ORD('%'):
627627 /* ! DOBLANK,DOBRACE */
628628 f = (f & DONTRUNCOMMAND) |
629629 DOPAT | DOTILDE |
@@ -637,10 +637,10 @@ expand(
637637 */
638638 if (!Flag(FSH)) {
639639 *dp++ = MAGIC;
640- *dp++ = ord(0x80 | '@');
640+ *dp++ = ORD(0x80 | '@');
641641 }
642642 break;
643- case ord('='):
643+ case ORD('='):
644644 /*
645645 * Tilde expansion for string
646646 * variables in POSIX mode is
@@ -664,7 +664,7 @@ expand(
664664 f &= ~(DOBLANK|DOGLOB|DOBRACE);
665665 tilde_ok = 1;
666666 break;
667- case ord('?'):
667+ case ORD('?'):
668668 if (*sp == CSUBST)
669669 errorf("%s: parameter null or not set",
670670 st->var->name);
@@ -699,8 +699,8 @@ expand(
699699 if (f & DOBLANK)
700700 doblank--;
701701 switch (st->stype & STYPE_SINGLE) {
702- case ord('#'):
703- case ord('%'):
702+ case ORD('#'):
703+ case ORD('%'):
704704 if (!Flag(FSH)) {
705705 /* Append end-pattern */
706706 *dp++ = MAGIC;
@@ -730,7 +730,7 @@ expand(
730730 doblank++;
731731 st = st->prev;
732732 continue;
733- case ord('='):
733+ case ORD('='):
734734 /*
735735 * Restore our position and substitute
736736 * the value of st->var (may not be
@@ -763,17 +763,17 @@ expand(
763763 st = st->prev;
764764 word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
765765 continue;
766- case ord('?'):
766+ case ORD('?'):
767767 dp = Xrestpos(ds, dp, st->base);
768768
769769 errorf(Tf_sD_s, st->var->name,
770770 debunk(dp, dp, strlen(dp) + 1));
771771 break;
772- case ord('0'):
773- case ord('/') | STYPE_AT:
774- case ord('/'):
775- case ord('#') | STYPE_AT:
776- case ord('Q') | STYPE_AT:
772+ case ORD('0'):
773+ case ORD('/') | STYPE_AT:
774+ case ORD('/'):
775+ case ORD('#') | STYPE_AT:
776+ case ORD('Q') | STYPE_AT:
777777 dp = Xrestpos(ds, dp, st->base);
778778 type = XSUB;
779779 word = quote || (!*x.str && (f & DOSCALAR)) ? IFS_WORD : IFS_IWS;
@@ -791,19 +791,19 @@ expand(
791791 /* open pattern: *(foo|bar) */
792792 /* Next char is the type of pattern */
793793 make_magic = true;
794- c = *sp++ | 0x80;
794+ c = ord(*sp++) | 0x80U;
795795 break;
796796
797797 case SPAT:
798798 /* pattern separator (|) */
799799 make_magic = true;
800- c = '|';
800+ c = ORD('|');
801801 break;
802802
803803 case CPAT:
804804 /* close pattern */
805805 make_magic = true;
806- c = /*(*/ ')';
806+ c = ORD(/*(*/ ')');
807807 break;
808808 }
809809 break;
@@ -824,7 +824,7 @@ expand(
824824
825825 case XSUB:
826826 case XSUBMID:
827- if ((c = *x.str++) == 0) {
827+ if ((c = ord(*x.str++)) == 0) {
828828 type = XBASE;
829829 if (f & DOBLANK)
830830 doblank--;
@@ -837,7 +837,7 @@ expand(
837837 quote = 1;
838838 /* FALLTHROUGH */
839839 case XARG:
840- if ((c = *x.str++) == '\0') {
840+ if ((c = ord(*x.str++)) == '\0') {
841841 /*
842842 * force null words to be created so
843843 * set -- "" 2 ""; echo "$@" will do
@@ -855,13 +855,13 @@ expand(
855855 if ((f & DOHEREDOC)) {
856856 /* pseudo-field-split reliably */
857857 if (c == 0)
858- c = ' ';
858+ c = ORD(' ');
859859 break;
860860 }
861861 if ((f & DOSCALAR)) {
862862 /* do not field-split */
863863 if (x.split) {
864- c = ' ';
864+ c = ORD(' ');
865865 break;
866866 }
867867 if (c == 0)
@@ -873,7 +873,7 @@ expand(
873873 if (!quote && word == IFS_WS)
874874 continue;
875875 /* this is so we don't terminate */
876- c = ' ';
876+ c = ORD(' ');
877877 /* now force-emit a word */
878878 goto emit_word;
879879 }
@@ -893,33 +893,33 @@ expand(
893893 c = -1;
894894 } else if (newlines) {
895895 /* spit out saved NLs */
896- c = '\n';
896+ c = ORD('\n');
897897 --newlines;
898898 } else {
899899 while ((c = shf_getc(x.u.shf)) == 0 ||
900- ctype(c, C_NL)) {
900+ cinttype(c, C_NL)) {
901901 #ifdef MKSH_WITH_TEXTMODE
902- if (c == '\r') {
902+ if (c == ORD('\r')) {
903903 c = shf_getc(x.u.shf);
904904 switch (c) {
905- case '\n':
905+ case ORD('\n'):
906906 break;
907907 default:
908908 shf_ungetc(c, x.u.shf);
909909 /* FALLTHROUGH */
910910 case -1:
911- c = '\r';
911+ c = ORD('\r');
912912 break;
913913 }
914914 }
915915 #endif
916- if (c == '\n')
916+ if (c == ORD('\n'))
917917 /* save newlines */
918918 newlines++;
919919 }
920920 if (newlines && c != -1) {
921921 shf_ungetc(c, x.u.shf);
922- c = '\n';
922+ c = ORD('\n');
923923 --newlines;
924924 }
925925 }
@@ -1003,10 +1003,10 @@ expand(
10031003 /* mark any special second pass chars */
10041004 if (!quote)
10051005 switch (ord(c)) {
1006- case ord('['):
1007- case ord('!'):
1008- case ord('-'):
1009- case ord(']'):
1006+ case ORD('['):
1007+ case ORD('!'):
1008+ case ORD('-'):
1009+ case ORD(']'):
10101010 /*
10111011 * For character classes - doesn't hurt
10121012 * to have magic !,-,]s outside of
@@ -1014,29 +1014,29 @@ expand(
10141014 */
10151015 if (f & (DOPAT | DOGLOB)) {
10161016 fdo |= DOMAGIC;
1017- if (c == ord('['))
1017+ if ((unsigned int)c == ORD('['))
10181018 fdo |= f & DOGLOB;
10191019 *dp++ = MAGIC;
10201020 }
10211021 break;
1022- case ord('*'):
1023- case ord('?'):
1022+ case ORD('*'):
1023+ case ORD('?'):
10241024 if (f & (DOPAT | DOGLOB)) {
10251025 fdo |= DOMAGIC | (f & DOGLOB);
10261026 *dp++ = MAGIC;
10271027 }
10281028 break;
1029- case ord('{'):
1030- case ord('}'):
1031- case ord(','):
1029+ case ORD('{'):
1030+ case ORD('}'):
1031+ case ORD(','):
10321032 if ((f & DOBRACE) &&
1033- (ord(c) == ord('{' /*}*/) ||
1033+ (ord(c) == ORD('{' /*}*/) ||
10341034 (fdo & DOBRACE))) {
10351035 fdo |= DOBRACE|DOMAGIC;
10361036 *dp++ = MAGIC;
10371037 }
10381038 break;
1039- case ord('='):
1039+ case ORD('='):
10401040 /* Note first unquoted = for ~ */
10411041 if (!(f & DOTEMP) && (!Flag(FPOSIX) ||
10421042 (f & DOASNTILDE)) && !saw_eq) {
@@ -1044,13 +1044,13 @@ expand(
10441044 tilde_ok = 1;
10451045 }
10461046 break;
1047- case ord(':'):
1047+ case ORD(':'):
10481048 /* : */
10491049 /* Note unquoted : for ~ */
10501050 if (!(f & DOTEMP) && (f & DOASNTILDE))
10511051 tilde_ok = 1;
10521052 break;
1053- case ord('~'):
1053+ case ORD('~'):
10541054 /*
10551055 * tilde_ok is reset whenever
10561056 * any of ' " $( $(( ${ } are seen.
@@ -1133,7 +1133,7 @@ varsub(Expand *xp, const char *sp, const char *word,
11331133 * ${%var}, string width (-U: screen columns, +U: octets)
11341134 */
11351135 c = ord(sp[1]);
1136- if (stype == ord('%') && c == '\0')
1136+ if ((unsigned int)stype == ORD('%') && c == '\0')
11371137 return (-1);
11381138 if (ctype(stype, C_SUB2) && c != '\0') {
11391139 /* Can't have any modifiers for ${#...} or ${%...} */
@@ -1141,11 +1141,11 @@ varsub(Expand *xp, const char *sp, const char *word,
11411141 return (-1);
11421142 sp++;
11431143 /* Check for size of array */
1144- if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ord('*') ||
1145- ord(p[1]) == ord('@')) && ord(p[2]) == ord(']')) {
1144+ if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ORD('*') ||
1145+ ord(p[1]) == ORD('@')) && ord(p[2]) == ORD(']')) {
11461146 int n = 0;
11471147
1148- if (stype != ord('#'))
1148+ if ((unsigned int)stype != ORD('#'))
11491149 return (-1);
11501150 vp = global(arrayname(sp));
11511151 if (vp->flag & (ISSET|ARRAY))
@@ -1154,14 +1154,15 @@ varsub(Expand *xp, const char *sp, const char *word,
11541154 if (vp->flag & ISSET)
11551155 n++;
11561156 c = n;
1157- } else if (c == ord('*') || c == ord('@')) {
1158- if (stype != ord('#'))
1157+ } else if ((unsigned int)c == ORD('*') ||
1158+ (unsigned int)c == ORD('@')) {
1159+ if ((unsigned int)stype != ORD('#'))
11591160 return (-1);
11601161 c = e->loc->argc;
11611162 } else {
11621163 p = str_val(global(sp));
11631164 zero_ok = p != null;
1164- if (stype == ord('#'))
1165+ if ((unsigned int)stype == ORD('#'))
11651166 c = utflen(p);
11661167 else {
11671168 /* partial utf_mbswidth reimplementation */
@@ -1196,11 +1197,11 @@ varsub(Expand *xp, const char *sp, const char *word,
11961197 xp->str = shf_smprintf(Tf_d, c);
11971198 return (XSUB);
11981199 }
1199- if (stype == ord('!') && c != '\0' && *word == CSUBST) {
1200+ if ((unsigned int)stype == ORD('!') && c != '\0' && *word == CSUBST) {
12001201 sp++;
1201- if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ord('*') ||
1202- ord(p[1]) == ord('@')) && ord(p[2]) == ord(']')) {
1203- c = ord('!');
1202+ if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ORD('*') ||
1203+ ord(p[1]) == ORD('@')) && ord(p[2]) == ORD(']')) {
1204+ c = ORD('!');
12041205 stype = 0;
12051206 goto arraynames;
12061207 }
@@ -1214,12 +1215,12 @@ varsub(Expand *xp, const char *sp, const char *word,
12141215 /* Check for qualifiers in word part */
12151216 stype = 0;
12161217 c = word[slen + 0] == CHAR ? ord(word[slen + 1]) : 0;
1217- if (c == ord(':')) {
1218+ if ((unsigned int)c == ORD(':')) {
12181219 slen += 2;
12191220 stype = STYPE_DBL;
12201221 c = word[slen + 0] == CHAR ? ord(word[slen + 1]) : 0;
12211222 }
1222- if (!stype && c == ord('/')) {
1223+ if (!stype && (unsigned int)c == ORD('/')) {
12231224 slen += 2;
12241225 stype = c;
12251226 if (word[slen] == ADELIM &&
@@ -1227,8 +1228,9 @@ varsub(Expand *xp, const char *sp, const char *word,
12271228 slen += 2;
12281229 stype |= STYPE_DBL;
12291230 }
1230- } else if (stype == STYPE_DBL && (c == ord(' ') || c == ord('0'))) {
1231- stype |= ord('0');
1231+ } else if (stype == STYPE_DBL && ((unsigned int)c == ORD(' ') ||
1232+ (unsigned int)c == ORD('0'))) {
1233+ stype |= ORD('0');
12321234 } else if (ctype(c, C_SUB1)) {
12331235 slen += 2;
12341236 stype |= c;
@@ -1241,13 +1243,13 @@ varsub(Expand *xp, const char *sp, const char *word,
12411243 stype |= STYPE_DBL;
12421244 slen += 2;
12431245 }
1244- } else if (c == ord('@')) {
1246+ } else if ((unsigned int)c == ORD('@')) {
12451247 /* @x where x is command char */
12461248 switch (c = ord(word[slen + 2]) == CHAR ?
12471249 ord(word[slen + 3]) : 0) {
1248- case ord('#'):
1249- case ord('/'):
1250- case ord('Q'):
1250+ case ORD('#'):
1251+ case ORD('/'):
1252+ case ORD('Q'):
12511253 break;
12521254 default:
12531255 return (-1);
@@ -1261,50 +1263,50 @@ varsub(Expand *xp, const char *sp, const char *word,
12611263 return (-1);
12621264
12631265 c = ord(sp[0]);
1264- if (c == ord('*') || c == ord('@')) {
1266+ if ((unsigned int)c == ORD('*') || (unsigned int)c == ORD('@')) {
12651267 switch (stype & STYPE_SINGLE) {
12661268 /* can't assign to a vector */
1267- case ord('='):
1269+ case ORD('='):
12681270 /* can't trim a vector (yet) */
1269- case ord('%'):
1270- case ord('#'):
1271- case ord('?'):
1272- case ord('0'):
1273- case ord('/') | STYPE_AT:
1274- case ord('/'):
1275- case ord('#') | STYPE_AT:
1276- case ord('Q') | STYPE_AT:
1271+ case ORD('%'):
1272+ case ORD('#'):
1273+ case ORD('?'):
1274+ case ORD('0'):
1275+ case ORD('/') | STYPE_AT:
1276+ case ORD('/'):
1277+ case ORD('#') | STYPE_AT:
1278+ case ORD('Q') | STYPE_AT:
12771279 return (-1);
12781280 }
12791281 if (e->loc->argc == 0) {
12801282 xp->str = null;
12811283 xp->var = global(sp);
1282- state = c == ord('@') ? XNULLSUB : XSUB;
1284+ state = (unsigned int)c == ORD('@') ? XNULLSUB : XSUB;
12831285 } else {
12841286 xp->u.strv = (const char **)e->loc->argv + 1;
12851287 xp->str = *xp->u.strv++;
12861288 /* $@ */
1287- xp->split = tobool(c == ord('@'));
1289+ xp->split = tobool((unsigned int)c == ORD('@'));
12881290 state = XARG;
12891291 }
12901292 /* POSIX 2009? */
12911293 zero_ok = true;
1292- } else if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ord('*') ||
1293- ord(p[1]) == ord('@')) && ord(p[2]) == ord(']')) {
1294+ } else if ((p = cstrchr(sp, '[')) && (ord(p[1]) == ORD('*') ||
1295+ ord(p[1]) == ORD('@')) && ord(p[2]) == ORD(']')) {
12941296 XPtrV wv;
12951297
12961298 switch (stype & STYPE_SINGLE) {
12971299 /* can't assign to a vector */
1298- case ord('='):
1300+ case ORD('='):
12991301 /* can't trim a vector (yet) */
1300- case ord('%'):
1301- case ord('#'):
1302- case ord('?'):
1303- case ord('0'):
1304- case ord('/') | STYPE_AT:
1305- case ord('/'):
1306- case ord('#') | STYPE_AT:
1307- case ord('Q') | STYPE_AT:
1302+ case ORD('%'):
1303+ case ORD('#'):
1304+ case ORD('?'):
1305+ case ORD('0'):
1306+ case ORD('/') | STYPE_AT:
1307+ case ORD('/'):
1308+ case ORD('#') | STYPE_AT:
1309+ case ORD('Q') | STYPE_AT:
13081310 return (-1);
13091311 }
13101312 c = 0;
@@ -1314,28 +1316,28 @@ varsub(Expand *xp, const char *sp, const char *word,
13141316 for (; vp; vp = vp->u.array) {
13151317 if (!(vp->flag&ISSET))
13161318 continue;
1317- XPput(wv, c == ord('!') ? shf_smprintf(Tf_lu,
1318- arrayindex(vp)) :
1319+ XPput(wv, (unsigned int)c == ORD('!') ?
1320+ shf_smprintf(Tf_lu, arrayindex(vp)) :
13191321 str_val(vp));
13201322 }
13211323 if (XPsize(wv) == 0) {
13221324 xp->str = null;
1323- state = ord(p[1]) == ord('@') ? XNULLSUB : XSUB;
1325+ state = ord(p[1]) == ORD('@') ? XNULLSUB : XSUB;
13241326 XPfree(wv);
13251327 } else {
13261328 XPput(wv, 0);
13271329 xp->u.strv = (const char **)XPptrv(wv);
13281330 xp->str = *xp->u.strv++;
13291331 /* ${foo[@]} */
1330- xp->split = tobool(ord(p[1]) == ord('@'));
1332+ xp->split = tobool(ord(p[1]) == ORD('@'));
13311333 state = XARG;
13321334 }
13331335 } else {
13341336 xp->var = global(sp);
13351337 xp->str = str_val(xp->var);
13361338 /* can't assign things like $! or $1 */
1337- if ((stype & STYPE_SINGLE) == ord('=') && !*xp->str &&
1338- ctype(*sp, C_VAR1 | C_DIGIT))
1339+ if ((unsigned int)(stype & STYPE_SINGLE) == ORD('=') &&
1340+ !*xp->str && ctype(*sp, C_VAR1 | C_DIGIT))
13391341 return (-1);
13401342 state = XSUB;
13411343 }
@@ -1346,13 +1348,15 @@ varsub(Expand *xp, const char *sp, const char *word,
13461348 (((stype & STYPE_DBL) ? *xp->str == '\0' : xp->str == null) &&
13471349 (state != XARG || (ifs0 || xp->split ?
13481350 (xp->u.strv[0] == NULL) : !hasnonempty(xp->u.strv))) ?
1349- ctype(c, C_EQUAL | C_MINUS | C_QUEST) : c == ord('+')))) ||
1350- stype == (ord('0') | STYPE_DBL) || stype == (ord('#') | STYPE_AT) ||
1351- stype == (ord('Q') | STYPE_AT) || (stype & STYPE_CHAR) == ord('/'))
1351+ ctype(c, C_EQUAL | C_MINUS | C_QUEST) : (unsigned int)c == ORD('+')))) ||
1352+ (unsigned int)stype == (ORD('0') | STYPE_DBL) ||
1353+ (unsigned int)stype == (ORD('#') | STYPE_AT) ||
1354+ (unsigned int)stype == (ORD('Q') | STYPE_AT) ||
1355+ (unsigned int)(stype & STYPE_CHAR) == ORD('/'))
13521356 /* expand word instead of variable value */
13531357 state = XBASE;
13541358 if (Flag(FNOUNSET) && xp->str == null && !zero_ok &&
1355- (ctype(c, C_SUB2) || (state != XBASE && c != ord('+'))))
1359+ (ctype(c, C_SUB2) || (state != XBASE && (unsigned int)c != ORD('+'))))
13561360 errorf(Tf_parm, sp);
13571361 *stypep = stype;
13581362 *slenp = slen;
@@ -1491,7 +1495,7 @@ trimsub(char *str, char *pat, int how)
14911495 char *p, c;
14921496
14931497 switch (how & (STYPE_CHAR | STYPE_DBL)) {
1494- case ord('#'):
1498+ case ORD('#'):
14951499 /* shortest match at beginning */
14961500 for (p = str; p <= end; p += utf_ptradj(p)) {
14971501 c = *p; *p = '\0';
@@ -1503,7 +1507,7 @@ trimsub(char *str, char *pat, int how)
15031507 *p = c;
15041508 }
15051509 break;
1506- case ord('#') | STYPE_DBL:
1510+ case ORD('#') | STYPE_DBL:
15071511 /* longest match at beginning */
15081512 for (p = end; p >= str; p--) {
15091513 c = *p; *p = '\0';
@@ -1515,7 +1519,7 @@ trimsub(char *str, char *pat, int how)
15151519 *p = c;
15161520 }
15171521 break;
1518- case ord('%'):
1522+ case ORD('%'):
15191523 /* shortest match at end */
15201524 p = end;
15211525 while (p >= str) {
@@ -1531,7 +1535,7 @@ trimsub(char *str, char *pat, int how)
15311535 --p;
15321536 }
15331537 break;
1534- case ord('%') | STYPE_DBL:
1538+ case ORD('%') | STYPE_DBL:
15351539 /* longest match at end */
15361540 for (p = str; p <= end; p++)
15371541 if (gmatchx(p, pat, false)) {
@@ -1863,7 +1867,7 @@ alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo)
18631867 char *p = exp_start;
18641868
18651869 /* search for open brace */
1866- while ((p = strchr(p, MAGIC)) && ord(p[1]) != ord('{' /*}*/))
1870+ while ((p = strchr(p, MAGIC)) && ord(p[1]) != ORD('{' /*}*/))
18671871 p += 2;
18681872 brace_start = p;
18691873
@@ -1874,9 +1878,9 @@ alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo)
18741878 p += 2;
18751879 while (*p && count) {
18761880 if (ISMAGIC(*p++)) {
1877- if (ord(*p) == ord('{' /*}*/))
1881+ if (ord(*p) == ORD('{' /*}*/))
18781882 ++count;
1879- else if (ord(*p) == ord(/*{*/ '}'))
1883+ else if (ord(*p) == ORD(/*{*/ '}'))
18801884 --count;
18811885 else if (*p == ',' && count == 1)
18821886 comma = p;
@@ -1908,9 +1912,9 @@ alt_expand(XPtrV *wp, char *start, char *exp_start, char *end, int fdo)
19081912 count = 1;
19091913 for (p = brace_start + 2; p != brace_end; p++) {
19101914 if (ISMAGIC(*p)) {
1911- if (ord(*++p) == ord('{' /*}*/))
1915+ if (ord(*++p) == ORD('{' /*}*/))
19121916 ++count;
1913- else if ((ord(*p) == ord(/*{*/ '}') && --count == 0) ||
1917+ else if ((ord(*p) == ORD(/*{*/ '}') && --count == 0) ||
19141918 (*p == ',' && count == 1)) {
19151919 char *news;
19161920 int l1, l2, l3;
--- a/src/exec.c
+++ b/src/exec.c
@@ -23,7 +23,7 @@
2323
2424 #include "sh.h"
2525
26-__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.199 2017/08/07 21:16:31 tg Exp $");
26+__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.201 2017/10/11 21:09:24 tg Exp $");
2727
2828 #ifndef MKSH_DEFAULT_EXECSHELL
2929 #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
@@ -953,8 +953,12 @@ scriptexec(struct op *tp, const char **ap)
953953 }
954954 #ifdef __OS2__
955955 /*
956- * Search shell/interpreter name without directory in PATH
957- * if specified path does not exist
956+ * On OS/2, the directory structure differs from normal
957+ * Unix, which can make many scripts whose shebang
958+ * hardcodes the path to an interpreter fail (and there
959+ * might be no /usr/bin/env); for user convenience, if
960+ * the specified interpreter is not usable, do a PATH
961+ * search to find it.
958962 */
959963 if (mksh_vdirsep(sh) && !search_path(sh, path, X_OK, NULL)) {
960964 cp = search_path(_getname(sh), path, X_OK, NULL);
@@ -1168,11 +1172,7 @@ findcom(const char *name, int flags)
11681172 char *fpath;
11691173 union mksh_cchack npath;
11701174
1171- if (mksh_vdirsep(name)
1172-#ifdef MKSH_DOSPATH
1173- && (strcmp(name, T_builtin) != 0)
1174-#endif
1175- ) {
1175+ if (mksh_vdirsep(name)) {
11761176 insert = 0;
11771177 /* prevent FPATH search below */
11781178 flags &= ~FC_FUNC;
--- a/src/expr.c
+++ b/src/expr.c
@@ -2,7 +2,7 @@
22
33 /*-
44 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
5- * 2011, 2012, 2013, 2014, 2016, 2017
5+ * 2011, 2012, 2013, 2014, 2016, 2017, 2018
66 * mirabilos <m@mirbsd.org>
77 *
88 * Provided that these terms and disclaimer and all copyright notices
@@ -23,7 +23,7 @@
2323
2424 #include "sh.h"
2525
26-__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.100 2017/08/07 21:38:55 tg Exp $");
26+__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.103 2018/01/14 01:29:47 tg Exp $");
2727
2828 #define EXPRTOK_DEFNS
2929 #include "exprtok.h"
@@ -558,9 +558,11 @@ exprtoken(Expr_state *es)
558558
559559 /* skip whitespace */
560560 skip_spaces:
561- while (ctype(ord((c = *cp)), C_SPACE))
562- ++cp;
563- if (es->tokp == es->expression && c == ord('#')) {
561+ --cp;
562+ do {
563+ c = ord(*++cp);
564+ } while (ctype(c, C_SPACE));
565+ if (es->tokp == es->expression && (unsigned int)c == ORD('#')) {
564566 /* expression begins with # */
565567 /* switch to unsigned */
566568 es->natural = true;
@@ -575,7 +577,7 @@ exprtoken(Expr_state *es)
575577 do {
576578 c = ord(*++cp);
577579 } while (ctype(c, C_ALNUX));
578- if (c == ord('[')) {
580+ if ((unsigned int)c == ORD('[')) {
579581 size_t len;
580582
581583 len = array_ref_len(cp);
@@ -884,7 +886,7 @@ static int mb_ucsbsearch(const struct mb_ucsrange arr[], size_t elems,
884886
885887 /*
886888 * Generated from the Unicode Character Database, Version 10.0.0, by
887- * MirOS: contrib/code/Snippets/eawparse,v 1.10 2017/07/12 22:47:26 tg Exp $
889+ * MirOS: contrib/code/Snippets/eawparse,v 1.12 2017/09/06 16:05:45 tg Exp $
888890 */
889891
890892 static const struct mb_ucsrange mb_ucs_combining[] = {
@@ -895,16 +897,14 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
895897 { 0x05C1, 0x05C2 },
896898 { 0x05C4, 0x05C5 },
897899 { 0x05C7, 0x05C7 },
898- { 0x0600, 0x0605 },
899900 { 0x0610, 0x061A },
900901 { 0x061C, 0x061C },
901902 { 0x064B, 0x065F },
902903 { 0x0670, 0x0670 },
903- { 0x06D6, 0x06DD },
904+ { 0x06D6, 0x06DC },
904905 { 0x06DF, 0x06E4 },
905906 { 0x06E7, 0x06E8 },
906907 { 0x06EA, 0x06ED },
907- { 0x070F, 0x070F },
908908 { 0x0711, 0x0711 },
909909 { 0x0730, 0x074A },
910910 { 0x07A6, 0x07B0 },
@@ -914,7 +914,8 @@ static const struct mb_ucsrange mb_ucs_combining[] = {
914914 { 0x0825, 0x0827 },
915915 { 0x0829, 0x082D },
916916 { 0x0859, 0x085B },
917- { 0x08D4, 0x0902 },
917+ { 0x08D4, 0x08E1 },
918+ { 0x08E3, 0x0902 },
918919 { 0x093A, 0x093A },
919920 { 0x093C, 0x093C },
920921 { 0x0941, 0x0948 },
--- a/src/funcs.c
+++ b/src/funcs.c
@@ -38,7 +38,7 @@
3838 #endif
3939 #endif
4040
41-__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.350 2017/05/05 22:53:28 tg Exp $");
41+__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.353 2018/01/14 01:26:49 tg Exp $");
4242
4343 #if HAVE_KILLPG
4444 /*
@@ -594,7 +594,7 @@ c_print(const char **wp)
594594 static int
595595 s_get(void)
596596 {
597- return (*s_ptr++);
597+ return (ord(*s_ptr++));
598598 }
599599
600600 static void
@@ -751,9 +751,9 @@ do_whence(const char **wp, int fcflags, bool vflag, bool iscommand)
751751 bool
752752 valid_alias_name(const char *cp)
753753 {
754- if (ord(*cp) == ord('-'))
754+ if (ord(*cp) == ORD('-'))
755755 return (false);
756- if (ord(cp[0]) == ord('[') && ord(cp[1]) == ord('[') && !cp[2])
756+ if (ord(cp[0]) == ORD('[') && ord(cp[1]) == ORD('[') && !cp[2])
757757 return (false);
758758 while (*cp)
759759 if (ctype(*cp, C_ALIAS))
@@ -2304,9 +2304,9 @@ c_unset(const char **wp)
23042304 size_t n;
23052305
23062306 n = strlen(id);
2307- if (n > 3 && ord(id[n - 3]) == ord('[') &&
2308- ord(id[n - 2]) == ord('*') &&
2309- ord(id[n - 1]) == ord(']')) {
2307+ if (n > 3 && ord(id[n - 3]) == ORD('[') &&
2308+ ord(id[n - 2]) == ORD('*') &&
2309+ ord(id[n - 1]) == ORD(']')) {
23102310 strndupx(cp, id, n - 3, ATEMP);
23112311 id = cp;
23122312 optc = 3;
@@ -3539,7 +3539,7 @@ c_cat(const char **wp)
35393539 continue;
35403540 }
35413541 if (errno == EPIPE) {
3542- /* fake receiving signel */
3542+ /* fake receiving signal */
35433543 rv = ksh_sigmask(SIGPIPE);
35443544 } else {
35453545 /* an error occured during writing */
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -2,7 +2,7 @@
22
33 /*-
44 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
5- * 2012, 2013, 2014, 2015, 2016
5+ * 2012, 2013, 2014, 2015, 2016, 2018
66 * mirabilos <m@mirbsd.org>
77 *
88 * Provided that these terms and disclaimer and all copyright notices
@@ -23,7 +23,7 @@
2323
2424 #include "sh.h"
2525
26-__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.124 2017/08/08 14:30:10 tg Exp $");
26+__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.125 2018/01/05 20:08:34 tg Exp $");
2727
2828 #if HAVE_KILLPG
2929 #define mksh_killpg killpg
@@ -1545,7 +1545,9 @@ j_print(Job *j, int how, struct shf *shf)
15451545 Proc *p;
15461546 int state;
15471547 int status;
1548+#ifdef WCOREDUMP
15481549 bool coredumped;
1550+#endif
15491551 char jobchar = ' ';
15501552 char buf[64];
15511553 const char *filler;
@@ -1569,7 +1571,9 @@ j_print(Job *j, int how, struct shf *shf)
15691571 jobchar = '-';
15701572
15711573 for (p = j->proc_list; p != NULL;) {
1574+#ifdef WCOREDUMP
15721575 coredumped = false;
1576+#endif
15731577 switch (p->state) {
15741578 case PRUNNING:
15751579 memcpy(buf, "Running", 8);
@@ -1603,7 +1607,10 @@ j_print(Job *j, int how, struct shf *shf)
16031607 * kludge for not reporting 'normal termination
16041608 * signals' (i.e. SIGINT, SIGPIPE)
16051609 */
1606- if (how == JP_SHORT && !coredumped &&
1610+ if (how == JP_SHORT &&
1611+#ifdef WCOREDUMP
1612+ !coredumped &&
1613+#endif
16071614 (termsig == SIGINT || termsig == SIGPIPE)) {
16081615 buf[0] = '\0';
16091616 } else
@@ -1629,14 +1636,22 @@ j_print(Job *j, int how, struct shf *shf)
16291636 if (how == JP_SHORT) {
16301637 if (buf[0]) {
16311638 output = 1;
1639+#ifdef WCOREDUMP
16321640 shf_fprintf(shf, "%s%s ",
16331641 buf, coredumped ? " (core dumped)" : null);
1642+#else
1643+ shf_puts(buf, shf);
1644+ shf_putchar(' ', shf);
1645+#endif
16341646 }
16351647 } else {
16361648 output = 1;
16371649 shf_fprintf(shf, "%-20s %s%s%s", buf, p->command,
16381650 p->next ? "|" : null,
1639- coredumped ? " (core dumped)" : null);
1651+#ifdef WCOREDUMP
1652+ coredumped ? " (core dumped)" :
1653+#endif
1654+ null);
16401655 }
16411656
16421657 state = p->state;
--- a/src/lex.c
+++ b/src/lex.c
@@ -2,7 +2,7 @@
22
33 /*-
44 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
5- * 2011, 2012, 2013, 2014, 2015, 2016, 2017
5+ * 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
66 * mirabilos <m@mirbsd.org>
77 *
88 * Provided that these terms and disclaimer and all copyright notices
@@ -23,7 +23,7 @@
2323
2424 #include "sh.h"
2525
26-__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.239 2017/05/05 22:53:29 tg Exp $");
26+__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.247 2018/01/14 01:44:01 tg Exp $");
2727
2828 /*
2929 * states while lexing word
@@ -127,11 +127,11 @@ static int ignore_backslash_newline;
127127 static int
128128 getsc_i(void)
129129 {
130- o_getsc_r(o_getsc());
130+ o_getsc_r((unsigned int)(unsigned char)o_getsc());
131131 }
132132
133133 #if defined(MKSH_SMALL) && !defined(MKSH_SMALL_BUT_FAST)
134-#define getsc() ord(getsc_i())
134+#define getsc() getsc_i()
135135 #else
136136 static int getsc_r(int);
137137
@@ -141,7 +141,7 @@ getsc_r(int c)
141141 o_getsc_r(c);
142142 }
143143
144-#define getsc() ord(getsc_r(o_getsc()))
144+#define getsc() getsc_r((unsigned int)(unsigned char)o_getsc())
145145 #endif
146146
147147 #define STATE_BSIZE 8
@@ -220,12 +220,14 @@ yylex(int cf)
220220 } else {
221221 /* normal lexing */
222222 state = (cf & HEREDELIM) ? SHEREDELIM : SBASE;
223- while (ctype((c = getsc()), C_BLANK))
224- ;
223+ do {
224+ c = getsc();
225+ } while (ctype(c, C_BLANK));
225226 if (c == '#') {
226227 ignore_backslash_newline++;
227- while (!ctype((c = getsc()), C_NUL | C_LF))
228- ;
228+ do {
229+ c = getsc();
230+ } while (!ctype(c, C_NUL | C_LF));
229231 ignore_backslash_newline--;
230232 }
231233 ungetsc(c);
@@ -245,30 +247,32 @@ yylex(int cf)
245247 while (!((c = getsc()) == 0 ||
246248 ((state == SBASE || state == SHEREDELIM) && ctype(c, C_LEX1)))) {
247249 if (state == SBASE &&
248- subshell_nesting_type == ord(/*{*/ '}') &&
249- c == ord(/*{*/ '}'))
250+ subshell_nesting_type == ORD(/*{*/ '}') &&
251+ (unsigned int)c == ORD(/*{*/ '}'))
250252 /* possibly end ${ :;} */
251253 break;
252254 Xcheck(ws, wp);
253255 switch (state) {
254256 case SADELIM:
255- if (c == ord('('))
257+ if ((unsigned int)c == ORD('('))
256258 statep->nparen++;
257- else if (c == ord(')'))
259+ else if ((unsigned int)c == ORD(')'))
258260 statep->nparen--;
259- else if (statep->nparen == 0 && (c == ord(/*{*/ '}') ||
261+ else if (statep->nparen == 0 &&
262+ ((unsigned int)c == ORD(/*{*/ '}') ||
260263 c == (int)statep->ls_adelim.delimiter)) {
261264 *wp++ = ADELIM;
262265 *wp++ = c;
263- if (c == ord(/*{*/ '}') || --statep->ls_adelim.num == 0)
266+ if ((unsigned int)c == ORD(/*{*/ '}') ||
267+ --statep->ls_adelim.num == 0)
264268 POP_STATE();
265- if (c == ord(/*{*/ '}'))
269+ if ((unsigned int)c == ORD(/*{*/ '}'))
266270 POP_STATE();
267271 break;
268272 }
269273 /* FALLTHROUGH */
270274 case SBASE:
271- if (c == ord('[') && (cf & CMDASN)) {
275+ if ((unsigned int)c == ORD('[') && (cf & CMDASN)) {
272276 /* temporary */
273277 *wp = EOS;
274278 if (is_wdvarname(Xstring(ws, wp), false)) {
@@ -284,15 +288,6 @@ yylex(int cf)
284288 }
285289 afree(tmp, ATEMP);
286290 break;
287- } else {
288- Source *s;
289-
290- s = pushs(SREREAD,
291- source->areap);
292- s->start = s->str =
293- s->u.freeme = tmp;
294- s->next = source;
295- source = s;
296291 }
297292 }
298293 *wp++ = CHAR;
@@ -303,7 +298,7 @@ yylex(int cf)
303298 Sbase1: /* includes *(...|...) pattern (*+?@!) */
304299 if (ctype(c, C_PATMO)) {
305300 c2 = getsc();
306- if (c2 == ord('(' /*)*/)) {
301+ if ((unsigned int)c2 == ORD('(' /*)*/)) {
307302 *wp++ = OPAT;
308303 *wp++ = c;
309304 PUSH_STATE(SPATTERN);
@@ -314,7 +309,7 @@ yylex(int cf)
314309 /* FALLTHROUGH */
315310 Sbase2: /* doesn't include *(...|...) pattern (*+?@!) */
316311 switch (c) {
317- case ord('\\'):
312+ case ORD('\\'):
318313 getsc_qchar:
319314 if ((c = getsc())) {
320315 /* trailing \ is lost */
@@ -322,7 +317,7 @@ yylex(int cf)
322317 *wp++ = c;
323318 }
324319 break;
325- case ord('\''):
320+ case ORD('\''):
326321 open_ssquote_unless_heredoc:
327322 if ((cf & HEREDOC))
328323 goto store_char;
@@ -330,12 +325,12 @@ yylex(int cf)
330325 ignore_backslash_newline++;
331326 PUSH_STATE(SSQUOTE);
332327 break;
333- case ord('"'):
328+ case ORD('"'):
334329 open_sdquote:
335330 *wp++ = OQUOTE;
336331 PUSH_STATE(SDQUOTE);
337332 break;
338- case ord('$'):
333+ case ORD('$'):
339334 /*
340335 * processing of dollar sign belongs into
341336 * Subst, except for those which can open
@@ -344,9 +339,9 @@ yylex(int cf)
344339 subst_dollar_ex:
345340 c = getsc();
346341 switch (c) {
347- case ord('"'):
342+ case ORD('"'):
348343 goto open_sdquote;
349- case ord('\''):
344+ case ORD('\''):
350345 goto open_sequote;
351346 default:
352347 goto SubstS;
@@ -358,16 +353,16 @@ yylex(int cf)
358353
359354 Subst:
360355 switch (c) {
361- case ord('\\'):
356+ case ORD('\\'):
362357 c = getsc();
363358 switch (c) {
364- case ord('"'):
359+ case ORD('"'):
365360 if ((cf & HEREDOC))
366361 goto heredocquote;
367362 /* FALLTHROUGH */
368- case ord('\\'):
369- case ord('$'):
370- case ord('`'):
363+ case ORD('\\'):
364+ case ORD('$'):
365+ case ORD('`'):
371366 store_qchar:
372367 *wp++ = QCHAR;
373368 *wp++ = c;
@@ -385,12 +380,12 @@ yylex(int cf)
385380 break;
386381 }
387382 break;
388- case ord('$'):
383+ case ORD('$'):
389384 c = getsc();
390385 SubstS:
391- if (c == ord('(' /*)*/)) {
386+ if ((unsigned int)c == ORD('(' /*)*/)) {
392387 c = getsc();
393- if (c == ord('(' /*)*/)) {
388+ if ((unsigned int)c == ORD('(' /*)*/)) {
394389 *wp++ = EXPRSUB;
395390 PUSH_SRETRACE(SASPAREN);
396391 statep->nparen = 2;
@@ -407,8 +402,8 @@ yylex(int cf)
407402 memcpy(wp, sp, cz);
408403 wp += cz;
409404 }
410- } else if (c == ord('{' /*}*/)) {
411- if ((c = getsc()) == ord('|')) {
405+ } else if ((unsigned int)c == ORD('{' /*}*/)) {
406+ if ((unsigned int)(c = getsc()) == ORD('|')) {
412407 /*
413408 * non-subenvironment
414409 * value substitution
@@ -429,11 +424,11 @@ yylex(int cf)
429424 wp = get_brace_var(&ws, wp);
430425 c = getsc();
431426 /* allow :# and :% (ksh88 compat) */
432- if (c == ord(':')) {
427+ if ((unsigned int)c == ORD(':')) {
433428 *wp++ = CHAR;
434429 *wp++ = c;
435430 c = getsc();
436- if (c == ord(':')) {
431+ if ((unsigned int)c == ORD(':')) {
437432 *wp++ = CHAR;
438433 *wp++ = '0';
439434 *wp++ = ADELIM;
@@ -465,7 +460,7 @@ yylex(int cf)
465460 parse_adelim_slash:
466461 *wp++ = CHAR;
467462 *wp++ = c;
468- if ((c = getsc()) == ord('/')) {
463+ if ((unsigned int)(c = getsc()) == ORD('/')) {
469464 *wp++ = c2;
470465 *wp++ = c;
471466 } else
@@ -479,7 +474,7 @@ yylex(int cf)
479474 } else if (c == '@') {
480475 c2 = getsc();
481476 ungetsc(c2);
482- if (c2 == ord('/')) {
477+ if ((unsigned int)c2 == ORD('/')) {
483478 c2 = CHAR;
484479 goto parse_adelim_slash;
485480 }
@@ -528,7 +523,7 @@ yylex(int cf)
528523 ungetsc(c);
529524 }
530525 break;
531- case ord('`'):
526+ case ORD('`'):
532527 subst_gravis:
533528 PUSH_STATE(SBQUOTE);
534529 *wp++ = COMASUB;
@@ -572,11 +567,11 @@ yylex(int cf)
572567 break;
573568
574569 case SEQUOTE:
575- if (c == ord('\'')) {
570+ if ((unsigned int)c == ORD('\'')) {
576571 POP_STATE();
577572 *wp++ = CQUOTE;
578573 ignore_backslash_newline--;
579- } else if (c == ord('\\')) {
574+ } else if ((unsigned int)c == ORD('\\')) {
580575 if ((c2 = unbksl(true, getsc_i, ungetsc)) == -1)
581576 c2 = getsc();
582577 if (c2 == 0)
@@ -604,7 +599,7 @@ yylex(int cf)
604599 break;
605600
606601 case SSQUOTE:
607- if (c == ord('\'')) {
602+ if ((unsigned int)c == ORD('\'')) {
608603 POP_STATE();
609604 if ((cf & HEREDOC) || state == SQBRACE)
610605 goto store_char;
@@ -617,7 +612,7 @@ yylex(int cf)
617612 break;
618613
619614 case SDQUOTE:
620- if (c == ord('"')) {
615+ if ((unsigned int)c == ORD('"')) {
621616 POP_STATE();
622617 *wp++ = CQUOTE;
623618 } else
@@ -626,15 +621,15 @@ yylex(int cf)
626621
627622 /* $(( ... )) */
628623 case SASPAREN:
629- if (c == ord('('))
624+ if ((unsigned int)c == ORD('('))
630625 statep->nparen++;
631- else if (c == ord(')')) {
626+ else if ((unsigned int)c == ORD(')')) {
632627 statep->nparen--;
633628 if (statep->nparen == 1) {
634629 /* end of EXPRSUB */
635630 POP_SRETRACE();
636631
637- if ((c2 = getsc()) == ord(/*(*/ ')')) {
632+ if ((unsigned int)(c2 = getsc()) == ORD(/*(*/ ')')) {
638633 cz = strlen(sp) - 2;
639634 XcheckN(ws, wp, cz);
640635 memcpy(wp, sp + 1, cz);
@@ -666,7 +661,7 @@ yylex(int cf)
666661 goto Sbase2;
667662
668663 case SQBRACE:
669- if (c == ord('\\')) {
664+ if ((unsigned int)c == ORD('\\')) {
670665 /*
671666 * perform POSIX "quote removal" if the back-
672667 * slash is "special", i.e. same cases as the
@@ -675,26 +670,28 @@ yylex(int cf)
675670 * write QCHAR+c, otherwise CHAR+\+CHAR+c are
676671 * emitted (in heredocquote:)
677672 */
678- if ((c = getsc()) == ord('"') || c == ord('\\') ||
679- ctype(c, C_DOLAR | C_GRAVE) || c == ord(/*{*/ '}'))
673+ if ((unsigned int)(c = getsc()) == ORD('"') ||
674+ (unsigned int)c == ORD('\\') ||
675+ ctype(c, C_DOLAR | C_GRAVE) ||
676+ (unsigned int)c == ORD(/*{*/ '}'))
680677 goto store_qchar;
681678 goto heredocquote;
682679 }
683680 goto common_SQBRACE;
684681
685682 case SBRACE:
686- if (c == ord('\''))
683+ if ((unsigned int)c == ORD('\''))
687684 goto open_ssquote_unless_heredoc;
688- else if (c == ord('\\'))
685+ else if ((unsigned int)c == ORD('\\'))
689686 goto getsc_qchar;
690687 common_SQBRACE:
691- if (c == ord('"'))
688+ if ((unsigned int)c == ORD('"'))
692689 goto open_sdquote;
693- else if (c == ord('$'))
690+ else if ((unsigned int)c == ORD('$'))
694691 goto subst_dollar_ex;
695- else if (c == ord('`'))
692+ else if ((unsigned int)c == ORD('`'))
696693 goto subst_gravis;
697- else if (c != ord(/*{*/ '}'))
694+ else if ((unsigned int)c != ORD(/*{*/ '}'))
698695 goto store_char;
699696 POP_STATE();
700697 *wp++ = CSUBST;
@@ -703,16 +700,16 @@ yylex(int cf)
703700
704701 /* Same as SBASE, except (,|,) treated specially */
705702 case STBRACEKORN:
706- if (c == ord('|'))
703+ if ((unsigned int)c == ORD('|'))
707704 *wp++ = SPAT;
708- else if (c == ord('(')) {
705+ else if ((unsigned int)c == ORD('(')) {
709706 *wp++ = OPAT;
710707 /* simile for @ */
711708 *wp++ = ' ';
712709 PUSH_STATE(SPATTERN);
713710 } else /* FALLTHROUGH */
714711 case STBRACEBOURNE:
715- if (c == ord(/*{*/ '}')) {
712+ if ((unsigned int)c == ORD(/*{*/ '}')) {
716713 POP_STATE();
717714 *wp++ = CSUBST;
718715 *wp++ = /*{*/ '}';
@@ -721,20 +718,20 @@ yylex(int cf)
721718 break;
722719
723720 case SBQUOTE:
724- if (c == ord('`')) {
721+ if ((unsigned int)c == ORD('`')) {
725722 *wp++ = 0;
726723 POP_STATE();
727- } else if (c == ord('\\')) {
724+ } else if ((unsigned int)c == ORD('\\')) {
728725 switch (c = getsc()) {
729726 case 0:
730727 /* trailing \ is lost */
731728 break;
732- case ord('$'):
733- case ord('`'):
734- case ord('\\'):
729+ case ORD('$'):
730+ case ORD('`'):
731+ case ORD('\\'):
735732 *wp++ = c;
736733 break;
737- case ord('"'):
734+ case ORD('"'):
738735 if (statep->ls_bool) {
739736 *wp++ = c;
740737 break;
@@ -755,10 +752,10 @@ yylex(int cf)
755752
756753 /* LETEXPR: (( ... )) */
757754 case SLETPAREN:
758- if (c == ord(/*(*/ ')')) {
755+ if ((unsigned int)c == ORD(/*(*/ ')')) {
759756 if (statep->nparen > 0)
760757 --statep->nparen;
761- else if ((c2 = getsc()) == ord(/*(*/ ')')) {
758+ else if ((unsigned int)(c2 = getsc()) == ORD(/*(*/ ')')) {
762759 c = 0;
763760 *wp++ = CQUOTE;
764761 goto Done;
@@ -780,9 +777,9 @@ yylex(int cf)
780777 s->next = source;
781778 source = s;
782779 ungetsc('(' /*)*/);
783- return (ord('(' /*)*/));
780+ return (ORD('(' /*)*/));
784781 }
785- } else if (c == ord('('))
782+ } else if ((unsigned int)c == ORD('('))
786783 /*
787784 * parentheses inside quotes and
788785 * backslashes are lost, but AT&T ksh
@@ -798,26 +795,26 @@ yylex(int cf)
798795 * $ and `...` are not to be treated specially
799796 */
800797 switch (c) {
801- case ord('\\'):
798+ case ORD('\\'):
802799 if ((c = getsc())) {
803800 /* trailing \ is lost */
804801 *wp++ = QCHAR;
805802 *wp++ = c;
806803 }
807804 break;
808- case ord('\''):
805+ case ORD('\''):
809806 goto open_ssquote_unless_heredoc;
810- case ord('$'):
811- if ((c2 = getsc()) == ord('\'')) {
807+ case ORD('$'):
808+ if ((unsigned int)(c2 = getsc()) == ORD('\'')) {
812809 open_sequote:
813810 *wp++ = OQUOTE;
814811 ignore_backslash_newline++;
815812 PUSH_STATE(SEQUOTE);
816813 statep->ls_bool = false;
817814 break;
818- } else if (c2 == ord('"')) {
815+ } else if ((unsigned int)c2 == ORD('"')) {
819816 /* FALLTHROUGH */
820- case ord('"'):
817+ case ORD('"'):
821818 PUSH_SRETRACE(SHEREDQUOTE);
822819 break;
823820 }
@@ -831,7 +828,7 @@ yylex(int cf)
831828
832829 /* " in << or <<- delimiter */
833830 case SHEREDQUOTE:
834- if (c != ord('"'))
831+ if ((unsigned int)c != ORD('"'))
835832 goto Subst;
836833 POP_SRETRACE();
837834 dp = strnul(sp) - 1;
@@ -844,10 +841,10 @@ yylex(int cf)
844841 while ((c = *dp++)) {
845842 if (c == '\\') {
846843 switch ((c = *dp++)) {
847- case ord('\\'):
848- case ord('"'):
849- case ord('$'):
850- case ord('`'):
844+ case ORD('\\'):
845+ case ORD('"'):
846+ case ORD('$'):
847+ case ORD('`'):
851848 break;
852849 default:
853850 *wp++ = CHAR;
@@ -865,12 +862,12 @@ yylex(int cf)
865862
866863 /* in *(...|...) pattern (*+?@!) */
867864 case SPATTERN:
868- if (c == ord(/*(*/ ')')) {
865+ if ((unsigned int)c == ORD(/*(*/ ')')) {
869866 *wp++ = CPAT;
870867 POP_STATE();
871- } else if (c == ord('|')) {
868+ } else if ((unsigned int)c == ORD('|')) {
872869 *wp++ = SPAT;
873- } else if (c == ord('(')) {
870+ } else if ((unsigned int)c == ORD('(')) {
874871 *wp++ = OPAT;
875872 /* simile for @ */
876873 *wp++ = ' ';
@@ -900,7 +897,7 @@ yylex(int cf)
900897 iop->unit = c2 == 2 ? ksh_numdig(dp[1]) : c == '<' ? 0 : 1;
901898
902899 if (c == '&') {
903- if ((c2 = getsc()) != ord('>')) {
900+ if ((unsigned int)(c2 = getsc()) != ORD('>')) {
904901 ungetsc(c2);
905902 goto no_iop;
906903 }
@@ -911,22 +908,23 @@ yylex(int cf)
911908
912909 c2 = getsc();
913910 /* <<, >>, <> are ok, >< is not */
914- if (c == c2 || (c == ord('<') && c2 == ord('>'))) {
911+ if (c == c2 || ((unsigned int)c == ORD('<') &&
912+ (unsigned int)c2 == ORD('>'))) {
915913 iop->ioflag |= c == c2 ?
916- (c == ord('>') ? IOCAT : IOHERE) : IORDWR;
914+ ((unsigned int)c == ORD('>') ? IOCAT : IOHERE) : IORDWR;
917915 if (iop->ioflag == IOHERE) {
918- if ((c2 = getsc()) == ord('-'))
916+ if ((unsigned int)(c2 = getsc()) == ORD('-'))
919917 iop->ioflag |= IOSKIP;
920- else if (c2 == ord('<'))
918+ else if ((unsigned int)c2 == ORD('<'))
921919 iop->ioflag |= IOHERESTR;
922920 else
923921 ungetsc(c2);
924922 }
925- } else if (c2 == ord('&'))
926- iop->ioflag |= IODUP | (c == ord('<') ? IORDUP : 0);
923+ } else if ((unsigned int)c2 == ORD('&'))
924+ iop->ioflag |= IODUP | ((unsigned int)c == ORD('<') ? IORDUP : 0);
927925 else {
928- iop->ioflag |= c == ord('>') ? IOWRITE : IOREAD;
929- if (c == ord('>') && c2 == ord('|'))
926+ iop->ioflag |= (unsigned int)c == ORD('>') ? IOWRITE : IOREAD;
927+ if ((unsigned int)c == ORD('>') && (unsigned int)c2 == ORD('|'))
930928 iop->ioflag |= IOCLOB;
931929 else
932930 ungetsc(c2);
@@ -947,30 +945,32 @@ yylex(int cf)
947945 /* free word */
948946 Xfree(ws, wp);
949947 /* no word, process LEX1 character */
950- if ((c == ord('|')) || (c == ord('&')) || (c == ord(';')) ||
951- (c == ord('(' /*)*/))) {
948+ if (((unsigned int)c == ORD('|')) ||
949+ ((unsigned int)c == ORD('&')) ||
950+ ((unsigned int)c == ORD(';')) ||
951+ ((unsigned int)c == ORD('(' /*)*/))) {
952952 if ((c2 = getsc()) == c)
953- c = (c == ord(';')) ? BREAK :
954- (c == ord('|')) ? LOGOR :
955- (c == ord('&')) ? LOGAND :
956- /* c == ord('(' )) */ MDPAREN;
957- else if (c == ord('|') && c2 == ord('&'))
953+ c = ((unsigned int)c == ORD(';')) ? BREAK :
954+ ((unsigned int)c == ORD('|')) ? LOGOR :
955+ ((unsigned int)c == ORD('&')) ? LOGAND :
956+ /* (unsigned int)c == ORD('(' )) */ MDPAREN;
957+ else if ((unsigned int)c == ORD('|') && (unsigned int)c2 == ORD('&'))
958958 c = COPROC;
959- else if (c == ord(';') && c2 == ord('|'))
959+ else if ((unsigned int)c == ORD(';') && (unsigned int)c2 == ORD('|'))
960960 c = BRKEV;
961- else if (c == ord(';') && c2 == ord('&'))
961+ else if ((unsigned int)c == ORD(';') && (unsigned int)c2 == ORD('&'))
962962 c = BRKFT;
963963 else
964964 ungetsc(c2);
965965 #ifndef MKSH_SMALL
966966 if (c == BREAK) {
967- if ((c2 = getsc()) == ord('&'))
967+ if ((unsigned int)(c2 = getsc()) == ORD('&'))
968968 c = BRKEV;
969969 else
970970 ungetsc(c2);
971971 }
972972 #endif
973- } else if (c == ord('\n')) {
973+ } else if ((unsigned int)c == ORD('\n')) {
974974 if (cf & HEREDELIM)
975975 ungetsc(c);
976976 else {
@@ -1025,7 +1025,7 @@ yylex(int cf)
10251025
10261026 if ((cf & KEYWORD) && (p = ktsearch(&keywords, ident, h)) &&
10271027 (!(cf & ESACONLY) || p->val.i == ESAC ||
1028- p->val.i == ord(/*{*/ '}'))) {
1028+ (unsigned int)p->val.i == ORD(/*{*/ '}'))) {
10291029 afree(yylval.cp, ATEMP);
10301030 return (p->val.i);
10311031 }
@@ -1136,7 +1136,7 @@ readhere(struct ioword *iop)
11361136 if (!*eofp) {
11371137 /* end of here document marker, what to do? */
11381138 switch (c) {
1139- case ord(/*(*/ ')'):
1139+ case ORD(/*(*/ ')'):
11401140 if (!subshell_nesting_type)
11411141 /*-
11421142 * not allowed outside $(...) or (...)
@@ -1151,7 +1151,7 @@ readhere(struct ioword *iop)
11511151 * Allow EOF here to commands without trailing
11521152 * newlines (mksh -c '...') will work as well.
11531153 */
1154- case ord('\n'):
1154+ case ORD('\n'):
11551155 /* Newline terminates here document marker */
11561156 goto heredoc_found_terminator;
11571157 }
@@ -1580,7 +1580,7 @@ get_brace_var(XString *wsp, char *wp)
15801580
15811581 c2 = getsc();
15821582 ungetsc(c2);
1583- if (ord(c2) != ord(/*{*/ '}')) {
1583+ if (ord(c2) != ORD(/*{*/ '}')) {
15841584 ungetsc(c);
15851585 goto out;
15861586 }
@@ -1588,22 +1588,22 @@ get_brace_var(XString *wsp, char *wp)
15881588 goto ps_common;
15891589 case PS_SAW_BANG:
15901590 switch (ord(c)) {
1591- case ord('@'):
1592- case ord('#'):
1593- case ord('-'):
1594- case ord('?'):
1591+ case ORD('@'):
1592+ case ORD('#'):
1593+ case ORD('-'):
1594+ case ORD('?'):
15951595 goto out;
15961596 }
15971597 goto ps_common;
15981598 case PS_INITIAL:
15991599 switch (ord(c)) {
1600- case ord('%'):
1600+ case ORD('%'):
16011601 state = PS_SAW_PERCENT;
16021602 goto next;
1603- case ord('#'):
1603+ case ORD('#'):
16041604 state = PS_SAW_HASH;
16051605 goto next;
1606- case ord('!'):
1606+ case ORD('!'):
16071607 state = PS_SAW_BANG;
16081608 goto next;
16091609 }
@@ -1621,7 +1621,7 @@ get_brace_var(XString *wsp, char *wp)
16211621 break;
16221622 case PS_IDENT:
16231623 if (!ctype(c, C_ALNUX)) {
1624- if (ord(c) == ord('[')) {
1624+ if (ord(c) == ORD('[')) {
16251625 char *tmp, *p;
16261626
16271627 if (!arraysub(&tmp))
@@ -1676,9 +1676,9 @@ arraysub(char **strp)
16761676 c = getsc();
16771677 Xcheck(ws, wp);
16781678 *wp++ = c;
1679- if (ord(c) == ord('['))
1679+ if (ord(c) == ORD('['))
16801680 depth++;
1681- else if (ord(c) == ord(']'))
1681+ else if (ord(c) == ORD(']'))
16821682 depth--;
16831683 } while (depth > 0 && c && c != '\n');
16841684
--- a/src/main.c
+++ b/src/main.c
@@ -5,7 +5,7 @@
55
66 /*-
77 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
8- * 2011, 2012, 2013, 2014, 2015, 2016, 2017
8+ * 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
99 * mirabilos <m@mirbsd.org>
1010 *
1111 * Provided that these terms and disclaimer and all copyright notices
@@ -34,9 +34,7 @@
3434 #include <locale.h>
3535 #endif
3636
37-__RCSID("$MirOS: src/bin/mksh/main.c,v 1.342 2017/04/28 11:13:47 tg Exp $");
38-
39-extern char **environ;
37+__RCSID("$MirOS: src/bin/mksh/main.c,v 1.347 2018/01/13 21:45:07 tg Exp $");
4038
4139 #ifndef MKSHRC_PATH
4240 #define MKSHRC_PATH "~/.mkshrc"
@@ -52,6 +50,7 @@ void chvt_reinit(void);
5250 static void reclaim(void);
5351 static void remove_temps(struct temp *);
5452 static mksh_uari_t rndsetup(void);
53+static void init_environ(void);
5554 #ifdef SIGWINCH
5655 static void x_sigwinch(int);
5756 #endif
@@ -242,10 +241,6 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
242241 set_ifs(TC_IFSWS);
243242
244243 #ifdef __OS2__
245- for (i = 0; i < 3; ++i)
246- if (!isatty(i))
247- setmode(i, O_BINARY);
248-
249244 os2_init(&argc, &argv);
250245 #endif
251246
@@ -401,14 +396,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
401396 #endif
402397
403398 /* import environment */
404- if (environ != NULL) {
405- wp = (const char **)environ;
406- while (*wp != NULL) {
407- rndpush(*wp);
408- typeset(*wp, IMPORT | EXPORT, 0, 0, 0);
409- ++wp;
410- }
411- }
399+ init_environ();
412400
413401 /* override default PATH regardless of environment */
414402 #ifdef MKSH_DEFPATH_OVERRIDE
@@ -671,8 +659,7 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
671659 if (Flag(FLOGIN))
672660 include(substitute("$HOME/.profile", 0), 0, NULL, true);
673661 if (Flag(FTALKING)) {
674- cp = substitute(substitute("${ENV:-" MKSHRC_PATH "}",
675- 0), DOTILDE);
662+ cp = substitute("${ENV:-" MKSHRC_PATH "}", DOTILDE);
676663 if (cp[0] != '\0')
677664 include(cp, 0, NULL, true);
678665 }
@@ -1987,3 +1974,111 @@ x_mkraw(int fd, mksh_ttyst *ocb, bool forread)
19871974
19881975 mksh_tcset(fd, &cb);
19891976 }
1977+
1978+#ifdef MKSH_ENVDIR
1979+static void
1980+init_environ(void)
1981+{
1982+ char *xp;
1983+ ssize_t n;
1984+ XString xs;
1985+ struct shf *shf;
1986+ DIR *dirp;
1987+ struct dirent *dent;
1988+
1989+ if ((dirp = opendir(MKSH_ENVDIR)) == NULL) {
1990+ warningf(false, "cannot read environment from %s: %s",
1991+ MKSH_ENVDIR, cstrerror(errno));
1992+ return;
1993+ }
1994+ XinitN(xs, 256, ATEMP);
1995+ read_envfile:
1996+ errno = 0;
1997+ if ((dent = readdir(dirp)) != NULL) {
1998+ if (skip_varname(dent->d_name, true)[0] == '\0') {
1999+ xp = shf_smprintf(Tf_sSs, MKSH_ENVDIR, dent->d_name);
2000+ if (!(shf = shf_open(xp, O_RDONLY, 0, 0))) {
2001+ warningf(false,
2002+ "cannot read environment %s from %s: %s",
2003+ dent->d_name, MKSH_ENVDIR,
2004+ cstrerror(errno));
2005+ goto read_envfile;
2006+ }
2007+ afree(xp, ATEMP);
2008+ n = strlen(dent->d_name);
2009+ xp = Xstring(xs, xp);
2010+ XcheckN(xs, xp, n + 32);
2011+ memcpy(xp, dent->d_name, n);
2012+ xp += n;
2013+ *xp++ = '=';
2014+ while ((n = shf_read(xp, Xnleft(xs, xp), shf)) > 0) {
2015+ xp += n;
2016+ if (Xnleft(xs, xp) <= 0)
2017+ XcheckN(xs, xp, Xlength(xs, xp));
2018+ }
2019+ if (n < 0) {
2020+ warningf(false,
2021+ "cannot read environment %s from %s: %s",
2022+ dent->d_name, MKSH_ENVDIR,
2023+ cstrerror(shf_errno(shf)));
2024+ } else {
2025+ *xp = '\0';
2026+ xp = Xstring(xs, xp);
2027+ rndpush(xp);
2028+ typeset(xp, IMPORT | EXPORT, 0, 0, 0);
2029+ }
2030+ shf_close(shf);
2031+ }
2032+ goto read_envfile;
2033+ } else if (errno)
2034+ warningf(false, "cannot read environment from %s: %s",
2035+ MKSH_ENVDIR, cstrerror(errno));
2036+ closedir(dirp);
2037+ Xfree(xs, xp);
2038+}
2039+#else
2040+extern char **environ;
2041+
2042+static void
2043+init_environ(void)
2044+{
2045+ const char **wp;
2046+
2047+ if (environ == NULL)
2048+ return;
2049+
2050+ wp = (const char **)environ;
2051+ while (*wp != NULL) {
2052+ rndpush(*wp);
2053+ typeset(*wp, IMPORT | EXPORT, 0, 0, 0);
2054+ ++wp;
2055+ }
2056+}
2057+#endif
2058+
2059+#ifdef MKSH_EARLY_LOCALE_TRACKING
2060+void
2061+recheck_ctype(void)
2062+{
2063+ const char *ccp;
2064+
2065+ ccp = str_val(global("LC_ALL"));
2066+ if (ccp == null)
2067+ ccp = str_val(global("LC_CTYPE"));
2068+ if (ccp == null)
2069+ ccp = str_val(global("LANG"));
2070+ UTFMODE = isuc(ccp);
2071+#if HAVE_SETLOCALE_CTYPE
2072+ ccp = setlocale(LC_CTYPE, ccp);
2073+#if HAVE_LANGINFO_CODESET
2074+ if (!isuc(ccp))
2075+ ccp = nl_langinfo(CODESET);
2076+#endif
2077+ if (isuc(ccp))
2078+ UTFMODE = 1;
2079+#endif
2080+
2081+ if (Flag(FPOSIX))
2082+ warningf(true, "early locale tracking enabled UTF-8 mode while in POSIX mode, you are now noncompliant");
2083+}
2084+#endif
--- a/src/misc.c
+++ b/src/misc.c
@@ -32,7 +32,7 @@
3232 #include <grp.h>
3333 #endif
3434
35-__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.279 2017/08/07 21:39:25 tg Exp $");
35+__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.291 2018/01/14 00:03:03 tg Exp $");
3636
3737 #define KSH_CHVT_FLAG
3838 #ifdef MKSH_SMALL
@@ -696,14 +696,14 @@ has_globbing(const char *pat)
696696 if (!(c = *p++))
697697 return (false);
698698 /* some specials */
699- if (ord(c) == ord('*') || ord(c) == ord('?')) {
699+ if (ord(c) == ORD('*') || ord(c) == ORD('?')) {
700700 /* easy glob, accept */
701701 saw_glob = true;
702- } else if (ord(c) == ord('[')) {
702+ } else if (ord(c) == ORD('[')) {
703703 /* bracket expression; eat negation and initial ] */
704- if (ISMAGIC(p[0]) && ord(p[1]) == ord('!'))
704+ if (ISMAGIC(p[0]) && ord(p[1]) == ORD('!'))
705705 p += 2;
706- if (ISMAGIC(p[0]) && ord(p[1]) == ord(']'))
706+ if (ISMAGIC(p[0]) && ord(p[1]) == ORD(']'))
707707 p += 2;
708708 /* check next string part */
709709 s = p;
@@ -715,27 +715,27 @@ has_globbing(const char *pat)
715715 if (!(c = *s++))
716716 return (false);
717717 /* terminating bracket? */
718- if (ord(c) == ord(']')) {
718+ if (ord(c) == ORD(']')) {
719719 /* accept and continue */
720720 p = s;
721721 saw_glob = true;
722722 break;
723723 }
724724 /* sub-bracket expressions */
725- if (ord(c) == ord('[') && (
725+ if (ord(c) == ORD('[') && (
726726 /* collating element? */
727- ord(*s) == ord('.') ||
727+ ord(*s) == ORD('.') ||
728728 /* equivalence class? */
729- ord(*s) == ord('=') ||
729+ ord(*s) == ORD('=') ||
730730 /* character class? */
731- ord(*s) == ord(':'))) {
731+ ord(*s) == ORD(':'))) {
732732 /* must stop with exactly the same c */
733733 subc = *s++;
734734 /* arbitrarily many chars in betwixt */
735735 while ((c = *s++))
736736 /* but only this sequence... */
737737 if (c == subc && ISMAGIC(*s) &&
738- ord(s[1]) == ord(']')) {
738+ ord(s[1]) == ORD(']')) {
739739 /* accept, terminate */
740740 s += 2;
741741 break;
@@ -751,7 +751,7 @@ has_globbing(const char *pat)
751751 /* opening pattern */
752752 saw_glob = true;
753753 ++nest;
754- } else if (ord(c) == ord(/*(*/ ')')) {
754+ } else if (ord(c) == ORD(/*(*/ ')')) {
755755 /* closing pattern */
756756 if (nest)
757757 --nest;
@@ -785,24 +785,24 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
785785 continue;
786786 }
787787 switch (ord(*p++)) {
788- case ord('['):
788+ case ORD('['):
789789 /* BSD cclass extension? */
790- if (ISMAGIC(p[0]) && ord(p[1]) == ord('[') &&
791- ord(p[2]) == ord(':') &&
790+ if (ISMAGIC(p[0]) && ord(p[1]) == ORD('[') &&
791+ ord(p[2]) == ORD(':') &&
792792 ctype((pc = p[3]), C_ANGLE) &&
793- ord(p[4]) == ord(':') &&
794- ISMAGIC(p[5]) && ord(p[6]) == ord(']') &&
795- ISMAGIC(p[7]) && ord(p[8]) == ord(']')) {
793+ ord(p[4]) == ORD(':') &&
794+ ISMAGIC(p[5]) && ord(p[6]) == ORD(']') &&
795+ ISMAGIC(p[7]) && ord(p[8]) == ORD(']')) {
796796 /* zero-length match */
797797 --s;
798798 p += 9;
799799 /* word begin? */
800- if (ord(pc) == ord('<') &&
800+ if (ord(pc) == ORD('<') &&
801801 !ctype(sl, C_ALNUX) &&
802802 ctype(sc, C_ALNUX))
803803 break;
804804 /* word end? */
805- if (ord(pc) == ord('>') &&
805+ if (ord(pc) == ORD('>') &&
806806 ctype(sl, C_ALNUX) &&
807807 !ctype(sc, C_ALNUX))
808808 break;
@@ -813,7 +813,7 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
813813 return (0);
814814 break;
815815
816- case ord('?'):
816+ case ORD('?'):
817817 if (sc == 0)
818818 return (0);
819819 if (UTFMODE) {
@@ -822,7 +822,7 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
822822 }
823823 break;
824824
825- case ord('*'):
825+ case ORD('*'):
826826 if (p == pe)
827827 return (1);
828828 s--;
@@ -838,14 +838,14 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
838838 */
839839
840840 /* matches one or more times */
841- case 0x80|ord('+'):
841+ case ORD('+') | 0x80:
842842 /* matches zero or more times */
843- case 0x80|ord('*'):
843+ case ORD('*') | 0x80:
844844 if (!(prest = pat_scan(p, pe, false)))
845845 return (0);
846846 s--;
847847 /* take care of zero matches */
848- if (ord(p[-1]) == (0x80 | ord('*')) &&
848+ if (ord(p[-1]) == (0x80 | ORD('*')) &&
849849 do_gmatch(s, se, prest, pe, smin))
850850 return (1);
851851 for (psub = p; ; psub = pnext) {
@@ -863,16 +863,16 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
863863 return (0);
864864
865865 /* matches zero or once */
866- case 0x80|ord('?'):
866+ case ORD('?') | 0x80:
867867 /* matches one of the patterns */
868- case 0x80|ord('@'):
868+ case ORD('@') | 0x80:
869869 /* simile for @ */
870- case 0x80|ord(' '):
870+ case ORD(' ') | 0x80:
871871 if (!(prest = pat_scan(p, pe, false)))
872872 return (0);
873873 s--;
874874 /* Take care of zero matches */
875- if (ord(p[-1]) == (0x80 | ord('?')) &&
875+ if (ord(p[-1]) == (0x80 | ORD('?')) &&
876876 do_gmatch(s, se, prest, pe, smin))
877877 return (1);
878878 for (psub = p; ; psub = pnext) {
@@ -889,7 +889,7 @@ do_gmatch(const unsigned char *s, const unsigned char *se,
889889 return (0);
890890
891891 /* matches none of the patterns */
892- case 0x80|ord('!'):
892+ case ORD('!') | 0x80:
893893 if (!(prest = pat_scan(p, pe, false)))
894894 return (0);
895895 s--;
@@ -966,12 +966,12 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
966966 char *subp;
967967
968968 /* check for negation */
969- if (ISMAGIC(p[0]) && ord(p[1]) == ord('!')) {
969+ if (ISMAGIC(p[0]) && ord(p[1]) == ORD('!')) {
970970 p += 2;
971971 negated = true;
972972 }
973973 /* make initial ] non-MAGIC */
974- if (ISMAGIC(p[0]) && ord(p[1]) == ord(']'))
974+ if (ISMAGIC(p[0]) && ord(p[1]) == ORD(']'))
975975 ++p;
976976 /* iterate over bracket expression, debunk()ing on the fly */
977977 while ((c = *p++)) {
@@ -982,18 +982,18 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
982982 if (!(c = *p++))
983983 break;
984984 /* terminating bracket? */
985- if (ord(c) == ord(']')) {
985+ if (ord(c) == ORD(']')) {
986986 /* accept and return */
987987 return (found != negated ? p : NULL);
988988 }
989989 /* sub-bracket expressions */
990- if (ord(c) == ord('[') && (
990+ if (ord(c) == ORD('[') && (
991991 /* collating element? */
992- ord(*p) == ord('.') ||
992+ ord(*p) == ORD('.') ||
993993 /* equivalence class? */
994- ord(*p) == ord('=') ||
994+ ord(*p) == ORD('=') ||
995995 /* character class? */
996- ord(*p) == ord(':'))) {
996+ ord(*p) == ORD(':'))) {
997997 /* must stop with exactly the same c */
998998 subc = *p++;
999999 /* save away start of substring */
@@ -1002,7 +1002,7 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
10021002 while ((c = *p++))
10031003 /* but only this sequence... */
10041004 if (c == subc && ISMAGIC(*p) &&
1005- ord(p[1]) == ord(']')) {
1005+ ord(p[1]) == ORD(']')) {
10061006 /* accept, terminate */
10071007 p += 2;
10081008 break;
@@ -1015,7 +1015,7 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
10151015 debunk(subp, subp, p - s - 3 + 1);
10161016 cclass_common:
10171017 /* whither subexpression */
1018- if (ord(subc) == ord(':')) {
1018+ if (ord(subc) == ORD(':')) {
10191019 const struct cclass *cls = cclasses;
10201020
10211021 /* search for name in cclass list */
@@ -1055,9 +1055,9 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
10551055 }
10561056 }
10571057 /* range expression? */
1058- if (!(ISMAGIC(p[0]) && ord(p[1]) == ord('-') &&
1058+ if (!(ISMAGIC(p[0]) && ord(p[1]) == ORD('-') &&
10591059 /* not terminating bracket? */
1060- (!ISMAGIC(p[2]) || ord(p[3]) != ord(']')))) {
1060+ (!ISMAGIC(p[2]) || ord(p[3]) != ORD(']')))) {
10611061 /* no, check single match */
10621062 if (sc == c)
10631063 /* note: sc is never NUL */
@@ -1079,13 +1079,13 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
10791079 if (!(c = *p++))
10801080 break;
10811081 /* sub-bracket expressions */
1082- if (ord(c) == ord('[') && (
1082+ if (ord(c) == ORD('[') && (
10831083 /* collating element? */
1084- ord(*p) == ord('.') ||
1084+ ord(*p) == ORD('.') ||
10851085 /* equivalence class? */
1086- ord(*p) == ord('=') ||
1086+ ord(*p) == ORD('=') ||
10871087 /* character class? */
1088- ord(*p) == ord(':'))) {
1088+ ord(*p) == ORD(':'))) {
10891089 /* must stop with exactly the same c */
10901090 subc = *p++;
10911091 /* save away start of substring */
@@ -1094,7 +1094,7 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
10941094 while ((c = *p++))
10951095 /* but only this sequence... */
10961096 if (c == subc && ISMAGIC(*p) &&
1097- ord(p[1]) == ord(']')) {
1097+ ord(p[1]) == ORD(']')) {
10981098 /* accept, terminate */
10991099 p += 2;
11001100 break;
@@ -1106,14 +1106,14 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
11061106 strndupx(subp, s, p - s - 3, ATEMP);
11071107 debunk(subp, subp, p - s - 3 + 1);
11081108 /* whither subexpression */
1109- if (ord(subc) == ord(':')) {
1109+ if (ord(subc) == ORD(':')) {
11101110 /* oops, not a range */
11111111
11121112 /* match single previous char */
11131113 if (lc && (sc == lc))
11141114 found = true;
11151115 /* match hyphen-minus */
1116- if (ord(sc) == ord('-'))
1116+ if (ord(sc) == ORD('-'))
11171117 found = true;
11181118 /* handle cclass common part */
11191119 goto cclass_common;
@@ -1151,7 +1151,7 @@ gmatch_cclass(const unsigned char *pat, unsigned char sc)
11511151 /* otherwise, just go on with the pattern string */
11521152 }
11531153 /* if we broke here, the bracket expression was invalid */
1154- if (ord(sc) == ord('['))
1154+ if (ord(sc) == ORD('['))
11551155 /* initial opening bracket as literal match */
11561156 return (pat);
11571157 /* or rather no match */
@@ -1661,6 +1661,15 @@ do_realpath(const char *upath)
16611661 if (mksh_abspath(upath)) {
16621662 /* upath is an absolute pathname */
16631663 strdupx(ipath, upath, ATEMP);
1664+#ifdef MKSH_DOSPATH
1665+ } else if (mksh_drvltr(upath)) {
1666+ /* upath is a drive-relative pathname */
1667+ if (getdrvwd(&ldest, ord(*upath)))
1668+ return (NULL);
1669+ /* A:foo -> A:/cwd/foo; A: -> A:/cwd */
1670+ ipath = shf_smprintf(Tf_sss, ldest,
1671+ upath[2] ? "/" : "", upath + 2);
1672+#endif
16641673 } else {
16651674 /* upath is a relative pathname, prepend cwd */
16661675 if ((tp = ksh_get_wd()) == NULL || !mksh_abspath(tp))
@@ -1695,6 +1704,7 @@ do_realpath(const char *upath)
16951704 continue;
16961705 else if (len == 2 && tp[1] == '.') {
16971706 /* strip off last pathname component */
1707+ /*XXX consider a rooted pathname */
16981708 while (xp > Xstring(xs, xp))
16991709 if (mksh_cdirsep(*--xp))
17001710 break;
@@ -1762,11 +1772,23 @@ do_realpath(const char *upath)
17621772 * restart if symlink target is an absolute path,
17631773 * otherwise continue with currently resolved prefix
17641774 */
1775+#ifdef MKSH_DOSPATH
1776+ assemble_symlink:
1777+#endif
17651778 /* append rest of current input path to link target */
17661779 tp = shf_smprintf(Tf_sss, ldest, *ip ? "/" : "", ip);
17671780 afree(ipath, ATEMP);
17681781 ip = ipath = tp;
1769- if (!mksh_abspath(ldest)) {
1782+ if (!mksh_abspath(ipath)) {
1783+#ifdef MKSH_DOSPATH
1784+ /* symlink target might be drive-relative */
1785+ if (mksh_drvltr(ipath)) {
1786+ if (getdrvwd(&ldest, ord(*ipath)))
1787+ goto notfound;
1788+ ip += 2;
1789+ goto assemble_symlink;
1790+ }
1791+#endif
17701792 /* symlink target is a relative path */
17711793 xp = Xrestpos(xs, xp, pos);
17721794 } else
@@ -1775,7 +1797,7 @@ do_realpath(const char *upath)
17751797 /* symlink target is an absolute path */
17761798 xp = Xstring(xs, xp);
17771799 beginning_of_a_pathname:
1778- /* assert: mksh_cdirsep((ip == ipath)[0]) */
1800+ /* assert: mksh_abspath(ip == ipath) */
17791801 /* assert: xp == xs.beg => start of path */
17801802
17811803 /* exactly two leading slashes? (SUSv4 3.266) */
@@ -1783,6 +1805,14 @@ do_realpath(const char *upath)
17831805 /* keep them, e.g. for UNC pathnames */
17841806 Xput(xs, xp, '/');
17851807 }
1808+#ifdef MKSH_DOSPATH
1809+ /* drive letter? */
1810+ if (mksh_drvltr(ip)) {
1811+ /* keep it */
1812+ Xput(xs, xp, *ip++);
1813+ Xput(xs, xp, *ip++);
1814+ }
1815+#endif
17861816 }
17871817 }
17881818 /* otherwise (no symlink) merely go on */
@@ -1932,6 +1962,15 @@ make_path(const char *cwd, const char *file,
19321962 * .. ..
19331963 * ./foo foo
19341964 * foo/../../../bar ../../bar
1965+ * C:/foo/../.. C:/
1966+ * C:. C:
1967+ * C:.. C:..
1968+ * C:foo/../../blah C:../blah
1969+ *
1970+ * XXX consider a rooted pathname: we cannot really 'cd ..' for
1971+ * pathnames like: '/', 'c:/', '//foo', '//foo/', '/@unixroot/'
1972+ * (no effect), 'c:', 'c:.' (effect is retaining the '../') but
1973+ * we need to honour this throughout the shell
19351974 */
19361975 void
19371976 simplify_path(char *p)
@@ -1939,6 +1978,17 @@ simplify_path(char *p)
19391978 char *dp, *ip, *sp, *tp;
19401979 size_t len;
19411980 bool needslash;
1981+#ifdef MKSH_DOSPATH
1982+ bool needdot = true;
1983+
1984+ /* keep drive letter */
1985+ if (mksh_drvltr(p)) {
1986+ p += 2;
1987+ needdot = false;
1988+ }
1989+#else
1990+#define needdot true
1991+#endif
19421992
19431993 switch (*p) {
19441994 case 0:
@@ -1977,7 +2027,7 @@ simplify_path(char *p)
19772027 /* just continue with the next one */
19782028 continue;
19792029 else if (len == 2 && tp[1] == '.') {
1980- /* parent level, but how? */
2030+ /* parent level, but how? (see above) */
19812031 if (mksh_abspath(p))
19822032 /* absolute path, only one way */
19832033 goto strip_last_component;
@@ -2016,10 +2066,15 @@ simplify_path(char *p)
20162066 needslash = true;
20172067 /* try next component */
20182068 }
2019- if (dp == p)
2020- /* empty path -> dot */
2021- *dp++ = needslash ? '/' : '.';
2069+ if (dp == p) {
2070+ /* empty path -> dot (or slash, when absolute) */
2071+ if (needslash)
2072+ *dp++ = '/';
2073+ else if (needdot)
2074+ *dp++ = '.';
2075+ }
20222076 *dp = '\0';
2077+#undef needdot
20232078 }
20242079
20252080 void
@@ -2133,6 +2188,18 @@ c_cd(const char **wp)
21332188 return (2);
21342189 }
21352190
2191+#ifdef MKSH_DOSPATH
2192+ tryp = NULL;
2193+ if (mksh_drvltr(dir) && !mksh_cdirsep(dir[2]) &&
2194+ !getdrvwd(&tryp, ord(*dir))) {
2195+ dir = shf_smprintf(Tf_sss, tryp,
2196+ dir[2] ? "/" : "", dir + 2);
2197+ afree(tryp, ATEMP);
2198+ afree(allocd, ATEMP);
2199+ allocd = dir;
2200+ }
2201+#endif
2202+
21362203 #ifdef MKSH__NO_PATH_MAX
21372204 /* only a first guess; make_path will enlarge xs if necessary */
21382205 XinitN(xs, 1024, ATEMP);
--- a/src/os2.c
+++ b/src/os2.c
@@ -1,5 +1,5 @@
11 /*-
2- * Copyright (c) 2015
2+ * Copyright (c) 2015, 2017
33 * KO Myung-Hun <komh@chollian.net>
44 * Copyright (c) 2017
55 * mirabilos <m@mirbsd.org>
@@ -26,18 +26,18 @@
2626 #include "sh.h"
2727
2828 #include <klibc/startup.h>
29+#include <errno.h>
2930 #include <io.h>
3031 #include <unistd.h>
3132 #include <process.h>
3233
33-__RCSID("$MirOS: src/bin/mksh/os2.c,v 1.2 2017/04/29 22:04:29 tg Exp $");
34+__RCSID("$MirOS: src/bin/mksh/os2.c,v 1.8 2017/12/22 16:41:42 tg Exp $");
3435
3536 static char *remove_trailing_dots(char *);
3637 static int access_stat_ex(int (*)(), const char *, void *);
3738 static int test_exec_exist(const char *, char *);
3839 static void response(int *, const char ***);
3940 static char *make_response_file(char * const *);
40-static void env_slashify(void);
4141 static void add_temp(const char *);
4242 static void cleanup_temps(void);
4343 static void cleanup(void);
@@ -169,44 +169,12 @@ init_extlibpath(void)
169169 }
170170 }
171171
172-/*
173- * Convert backslashes of environmental variables to forward slahes.
174- * A backslash may be used as an escaped character when doing 'echo'.
175- * This leads to an unexpected behavior.
176- */
177-static void
178-env_slashify(void)
179-{
180- /*
181- * PATH and TMPDIR are used by OS/2 as well. That is, they may
182- * have backslashes as a directory separator.
183- * BEGINLIBPATH and ENDLIBPATH are special variables on OS/2.
184- */
185- const char *var_list[] = {
186- "PATH",
187- "TMPDIR",
188- "BEGINLIBPATH",
189- "ENDLIBPATH",
190- NULL
191- };
192- const char **var;
193- char *value;
194-
195- for (var = var_list; *var; var++) {
196- value = getenv(*var);
197-
198- if (value)
199- _fnslashify(value);
200- }
201-}
202-
203172 void
204173 os2_init(int *argcp, const char ***argvp)
205174 {
206175 response(argcp, argvp);
207176
208177 init_extlibpath();
209- env_slashify();
210178
211179 if (!isatty(STDIN_FILENO))
212180 setmode(STDIN_FILENO, O_BINARY);
@@ -361,49 +329,30 @@ real_exec_name(const char *name)
361329 return (real_name);
362330 }
363331
364-/* OS/2 can process a command line up to 32 KiB */
365-#define MAX_CMD_LINE_LEN 32768
366-
367332 /* make a response file to pass a very long command line */
368333 static char *
369334 make_response_file(char * const *argv)
370335 {
371336 char rsp_name_arg[] = "@mksh-rsp-XXXXXX";
372337 char *rsp_name = &rsp_name_arg[1];
373- int arg_len = 0;
374338 int i;
339+ int fd;
340+ char *result;
375341
376- for (i = 0; argv[i]; i++)
377- arg_len += strlen(argv[i]) + 1;
378-
379- /*
380- * If a length of command line is longer than MAX_CMD_LINE_LEN, then
381- * use a response file. OS/2 cannot process a command line longer
382- * than 32K. Of course, a response file cannot be recognised by a
383- * normal OS/2 program, that is, neither non-EMX or non-kLIBC. But
384- * it cannot accept a command line longer than 32K in itself. So
385- * using a response file in this case, is an acceptable solution.
386- */
387- if (arg_len > MAX_CMD_LINE_LEN) {
388- int fd;
389- char *result;
390-
391- if ((fd = mkstemp(rsp_name)) == -1)
392- return (NULL);
393-
394- /* write all the arguments except a 0th program name */
395- for (i = 1; argv[i]; i++) {
396- write(fd, argv[i], strlen(argv[i]));
397- write(fd, "\n", 1);
398- }
342+ if ((fd = mkstemp(rsp_name)) == -1)
343+ return (NULL);
399344
400- close(fd);
401- add_temp(rsp_name);
402- strdupx(result, rsp_name_arg, ATEMP);
403- return (result);
345+ /* write all the arguments except a 0th program name */
346+ for (i = 1; argv[i]; i++) {
347+ write(fd, argv[i], strlen(argv[i]));
348+ write(fd, "\n", 1);
404349 }
405350
406- return (NULL);
351+ close(fd);
352+ add_temp(rsp_name);
353+ strdupx(result, rsp_name_arg, ATEMP);
354+
355+ return (result);
407356 }
408357
409358 /* alias of execve() */
@@ -416,12 +365,12 @@ execve(const char *name, char * const *argv, char * const *envp)
416365 const char *exec_name;
417366 FILE *fp;
418367 char sign[2];
419- char *rsp_argv[3];
420- char *rsp_name_arg;
421368 int pid;
422369 int status;
423370 int fd;
424371 int rc;
372+ int saved_mode;
373+ int saved_errno;
425374
426375 /*
427376 * #! /bin/sh : append .exe
@@ -461,23 +410,41 @@ execve(const char *name, char * const *argv, char * const *envp)
461410 if (errno == ENOEXEC)
462411 return (-1);
463412
464- rsp_name_arg = make_response_file(argv);
413+ /*
414+ * Normal OS/2 programs expect that standard IOs, especially stdin,
415+ * are opened in text mode at the startup. By the way, on OS/2 kLIBC
416+ * child processes inherit a translation mode of a parent process.
417+ * As a result, if stdin is set to binary mode in a parent process,
418+ * stdin of child processes is opened in binary mode as well at the
419+ * startup. In this case, some programs such as sed suffer from CR.
420+ */
421+ saved_mode = setmode(STDIN_FILENO, O_TEXT);
465422
466- if (rsp_name_arg) {
467- rsp_argv[0] = argv[0];
468- rsp_argv[1] = rsp_name_arg;
469- rsp_argv[2] = NULL;
423+ pid = spawnve(P_NOWAIT, exec_name, argv, envp);
424+ saved_errno = errno;
470425
471- argv = rsp_argv;
472- }
426+ /* arguments too long? */
427+ if (pid == -1 && saved_errno == EINVAL) {
428+ /* retry with a response file */
429+ char *rsp_name_arg = make_response_file(argv);
473430
474- pid = spawnve(P_NOWAIT, exec_name, argv, envp);
431+ if (rsp_name_arg) {
432+ char *rsp_argv[3] = { argv[0], rsp_name_arg, NULL };
433+
434+ pid = spawnve(P_NOWAIT, exec_name, rsp_argv, envp);
435+ saved_errno = errno;
436+
437+ afree(rsp_name_arg, ATEMP);
438+ }
439+ }
475440
476- afree(rsp_name_arg, ATEMP);
441+ /* restore translation mode of stdin */
442+ setmode(STDIN_FILENO, saved_mode);
477443
478444 if (pid == -1) {
479445 cleanup_temps();
480446
447+ errno = saved_errno;
481448 return (-1);
482449 }
483450
@@ -557,3 +524,52 @@ cleanup(void)
557524 {
558525 cleanup_temps();
559526 }
527+
528+int
529+getdrvwd(char **cpp, unsigned int drvltr)
530+{
531+ PBYTE cp;
532+ ULONG sz;
533+ APIRET rc;
534+ ULONG drvno;
535+
536+ if (DosQuerySysInfo(QSV_MAX_PATH_LENGTH, QSV_MAX_PATH_LENGTH,
537+ &sz, sizeof(sz)) != 0) {
538+ errno = EDOOFUS;
539+ return (-1);
540+ }
541+
542+ /* allocate 'X:/' plus sz plus NUL */
543+ checkoktoadd((size_t)sz, (size_t)4);
544+ cp = aresize(*cpp, (size_t)sz + (size_t)4, ATEMP);
545+ cp[0] = ksh_toupper(drvltr);
546+ cp[1] = ':';
547+ cp[2] = '/';
548+ drvno = ksh_numuc(cp[0]) + 1;
549+ /* NUL is part of space within buffer passed */
550+ ++sz;
551+ if ((rc = DosQueryCurrentDir(drvno, cp + 3, &sz)) == 0) {
552+ /* success! */
553+ *cpp = cp;
554+ return (0);
555+ }
556+ afree(cp, ATEMP);
557+ *cpp = NULL;
558+ switch (rc) {
559+ case 15: /* invalid drive */
560+ errno = ENOTBLK;
561+ break;
562+ case 26: /* not dos disk */
563+ errno = ENODEV;
564+ break;
565+ case 108: /* drive locked */
566+ errno = EDEADLK;
567+ break;
568+ case 111: /* buffer overflow */
569+ errno = ENAMETOOLONG;
570+ break;
571+ default:
572+ errno = EINVAL;
573+ }
574+ return (-1);
575+}
--- a/src/sh.h
+++ b/src/sh.h
@@ -10,7 +10,7 @@
1010
1111 /*-
1212 * Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
13- * 2011, 2012, 2013, 2014, 2015, 2016, 2017
13+ * 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
1414 * mirabilos <m@mirbsd.org>
1515 *
1616 * Provided that these terms and disclaimer and all copyright notices
@@ -182,9 +182,9 @@
182182 #endif
183183
184184 #ifdef EXTERN
185-__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.841 2017/08/29 13:38:31 tg Exp $");
185+__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.858 2018/01/14 01:47:36 tg Exp $");
186186 #endif
187-#define MKSH_VERSION "R56 2017/08/29"
187+#define MKSH_VERSION "R56 2018/01/14"
188188
189189 /* arithmetic types: C implementation */
190190 #if !HAVE_CAN_INTTYPES
@@ -556,7 +556,7 @@ extern int __cdecl setegid(gid_t);
556556 * low-bit7 at least on cp1047 so YMMV
557557 */
558558 #define MAGIC KSH_BEL /* prefix for *?[!{,} during expand */
559-#define ISMAGIC(c) (ord(c) == ord(MAGIC))
559+#define ISMAGIC(c) (ord(c) == ORD(MAGIC))
560560
561561 EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */
562562
@@ -643,7 +643,7 @@ char *ucstrstr(char *, const char *);
643643 #endif
644644 #endif
645645
646-#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 562)
646+#if (!defined(MKSH_BUILDMAKEFILE4BSD) && !defined(MKSH_BUILDSH)) || (MKSH_BUILD_R != 563)
647647 #error Must run Build.sh to compile this.
648648 extern void thiswillneverbedefinedIhope(void);
649649 int
@@ -804,7 +804,7 @@ struct sretrace_info;
804804 struct yyrecursive_state;
805805
806806 EXTERN struct sretrace_info *retrace_info;
807-EXTERN int subshell_nesting_type;
807+EXTERN unsigned int subshell_nesting_type;
808808
809809 extern struct env {
810810 ALLOC_ITEM alloc_INT; /* internal, do not touch */
@@ -1469,7 +1469,26 @@ EXTERN char ifs0;
14691469 #define C_UNDER CiUNDER /* _ underscore */
14701470
14711471 /* identity transform of octet */
1472-#define ord(c) ((unsigned int)(unsigned char)(c))
1472+#if defined(DEBUG) && defined(__GNUC__) && !defined(__ICC) && \
1473+ !defined(__INTEL_COMPILER) && !defined(__SUNPRO_C)
1474+extern unsigned int eek_ord;
1475+#define ORD(c) ((size_t)(c) > 0xFF ? eek_ord : \
1476+ ((unsigned int)(unsigned char)(c)))
1477+#define ord(c) __builtin_choose_expr( \
1478+ __builtin_types_compatible_p(__typeof__(c), char) || \
1479+ __builtin_types_compatible_p(__typeof__(c), unsigned char), \
1480+ ((unsigned int)(unsigned char)(c)), ({ \
1481+ size_t ord_c = (c); \
1482+ \
1483+ if (ord_c > (size_t)0xFFU) \
1484+ internal_errorf("%s:%d:ord(%zX)", \
1485+ __FILE__, __LINE__, ord_c); \
1486+ ((unsigned int)(unsigned char)(ord_c)); \
1487+}))
1488+#else
1489+#define ord(c) ((unsigned int)(unsigned char)(c))
1490+#define ORD(c) ord(c) /* may evaluate arguments twice */
1491+#endif
14731492 #if defined(MKSH_EBCDIC) || defined(MKSH_FAUX_EBCDIC)
14741493 EXTERN unsigned short ebcdic_map[256];
14751494 EXTERN unsigned char ebcdic_rtt_toascii[256];
@@ -1492,20 +1511,22 @@ extern void ebcdic_init(void);
14921511 #ifdef MKSH_EBCDIC
14931512 #define ksh_isctrl(c) (ord(c) < 0x40 || ord(c) == 0xFF)
14941513 #else
1495-#define ksh_isctrl(c) ((ord(c) & 0x7F) < 0x20 || (c) == 0x7F)
1514+#define ksh_isctrl(c) ((ord(c) & 0x7F) < 0x20 || ord(c) == 0x7F)
14961515 #endif
14971516 /* new fast character classes */
14981517 #define ctype(c,t) tobool(ksh_ctypes[ord(c)] & (t))
1518+#define cinttype(c,t) ((c) >= 0 && (c) <= 0xFF ? \
1519+ tobool(ksh_ctypes[(unsigned char)(c)] & (t)) : false)
14991520 /* helper functions */
15001521 #define ksh_isdash(s) tobool(ord((s)[0]) == '-' && ord((s)[1]) == '\0')
15011522 /* invariant distance even in EBCDIC */
15021523 #define ksh_tolower(c) (ctype(c, C_UPPER) ? (c) - 'A' + 'a' : (c))
15031524 #define ksh_toupper(c) (ctype(c, C_LOWER) ? (c) - 'a' + 'A' : (c))
15041525 /* strictly speaking rtt2asc() here, but this works even in EBCDIC */
1505-#define ksh_numdig(c) (ord(c) - ord('0'))
1526+#define ksh_numdig(c) (ord(c) - ORD('0'))
15061527 #define ksh_numuc(c) (rtt2asc(c) - rtt2asc('A'))
15071528 #define ksh_numlc(c) (rtt2asc(c) - rtt2asc('a'))
1508-#define ksh_toctrl(c) asc2rtt(ord(c) == ord('?') ? 0x7F : rtt2asc(c) & 0x9F)
1529+#define ksh_toctrl(c) asc2rtt(ord(c) == ORD('?') ? 0x7F : rtt2asc(c) & 0x9F)
15091530 #define ksh_unctrl(c) asc2rtt(rtt2asc(c) ^ 0x40U)
15101531
15111532 /* Argument parsing for built-in commands and getopts command */
@@ -1599,7 +1620,7 @@ EXTERN mksh_ari_t x_lins E_INIT(24);
15991620 #define shf_fileno(shf) ((shf)->fd)
16001621 #define shf_setfileno(shf,nfd) ((shf)->fd = (nfd))
16011622 #define shf_getc_i(shf) ((shf)->rnleft > 0 ? \
1602- (shf)->rnleft--, *(shf)->rp++ : \
1623+ (shf)->rnleft--, (int)ord(*(shf)->rp++) : \
16031624 shf_getchar(shf))
16041625 #define shf_putc_i(c, shf) ((shf)->wnleft == 0 ? \
16051626 shf_putchar((uint8_t)(c), (shf)) : \
@@ -2500,6 +2521,7 @@ void shprintf(const char *, ...)
25002521 MKSH_A_FORMAT(__printf__, 1, 2);
25012522 int can_seek(int);
25022523 void initio(void);
2524+void recheck_ctype(void);
25032525 int ksh_dup2(int, int, bool);
25042526 short savefd(int);
25052527 void restfd(int, int);
@@ -2734,27 +2756,32 @@ extern int tty_init_fd(void); /* initialise tty_fd, tty_devtty */
27342756 #endif
27352757
27362758 #ifdef MKSH_DOSPATH
2759+#define mksh_drvltr(s) __extension__({ \
2760+ const char *mksh_drvltr_s = (s); \
2761+ (ctype(mksh_drvltr_s[0], C_ALPHA) && mksh_drvltr_s[1] == ':'); \
2762+})
27372763 #define mksh_abspath(s) __extension__({ \
27382764 const char *mksh_abspath_s = (s); \
27392765 (mksh_cdirsep(mksh_abspath_s[0]) || \
2740- (ctype(mksh_abspath_s[0], C_ALPHA) && \
2741- mksh_abspath_s[1] == ':')); \
2766+ (mksh_drvltr(mksh_abspath_s) && \
2767+ mksh_cdirsep(mksh_abspath_s[2]))); \
27422768 })
27432769 #define mksh_cdirsep(c) __extension__({ \
27442770 char mksh_cdirsep_c = (c); \
27452771 (mksh_cdirsep_c == '/' || mksh_cdirsep_c == '\\'); \
27462772 })
2747-#define mksh_sdirsep(s) __extension__({ \
2748- const char *mksh_sdirsep_s = (s); \
2749- ((char *)((ctype(mksh_sdirsep_s[0], C_ALPHA) && \
2750- mksh_sdirsep_s[1] == ':' && \
2751- !mksh_cdirsep(mksh_sdirsep_s[2])) ? \
2752- (mksh_sdirsep_s + 1) : strpbrk(mksh_sdirsep_s, "/\\"))); \
2773+#define mksh_sdirsep(s) strpbrk((s), "/\\")
2774+#define mksh_vdirsep(s) __extension__({ \
2775+ const char *mksh_vdirsep_s = (s); \
2776+ (((mksh_drvltr(mksh_vdirsep_s) && \
2777+ !mksh_cdirsep(mksh_vdirsep_s[2])) ? (!0) : \
2778+ (mksh_sdirsep(mksh_vdirsep_s) != NULL)) && \
2779+ (strcmp(mksh_vdirsep_s, T_builtin) != 0)); \
27532780 })
2754-#define mksh_vdirsep(s) (mksh_sdirsep((s)) != NULL)
2781+int getdrvwd(char **, unsigned int);
27552782 #else
2756-#define mksh_abspath(s) (ord((s)[0]) == ord('/'))
2757-#define mksh_cdirsep(c) (ord(c) == ord('/'))
2783+#define mksh_abspath(s) (ord((s)[0]) == ORD('/'))
2784+#define mksh_cdirsep(c) (ord(c) == ORD('/'))
27582785 #define mksh_sdirsep(s) strchr((s), '/')
27592786 #define mksh_vdirsep(s) vstrchr((s), '/')
27602787 #endif
--- a/src/shf.c
+++ b/src/shf.c
@@ -2,7 +2,7 @@
22
33 /*-
44 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
5- * 2012, 2013, 2015, 2016, 2017
5+ * 2012, 2013, 2015, 2016, 2017, 2018
66 * mirabilos <m@mirbsd.org>
77 * Copyright (c) 2015
88 * Daniel Richard G. <skunk@iSKUNK.ORG>
@@ -27,7 +27,7 @@
2727
2828 #include "sh.h"
2929
30-__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.95 2017/05/05 22:45:58 tg Exp $");
30+__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.97 2018/01/14 01:28:16 tg Exp $");
3131
3232 /* flags to shf_emptybuf() */
3333 #define EB_READSW 0x01 /* about to switch to reading */
@@ -554,7 +554,7 @@ shf_getchar(struct shf *shf)
554554 if (shf->rnleft == 0 && (shf_fillbuf(shf) == -1 || shf->rnleft == 0))
555555 return (-1);
556556 --shf->rnleft;
557- return (*shf->rp++);
557+ return (ord(*shf->rp++));
558558 }
559559
560560 /*
@@ -1253,7 +1253,7 @@ set_ifs(const char *s)
12531253 * Not only do they require all 8 bits instead of 7, if chars are
12541254 * signed, they will have negative integer values! Something like
12551255 * (c - 'A') could actually become (c + 63)! Use the ord() macro to
1256- * ensure you're getting a value in [0, 255].
1256+ * ensure you're getting a value in [0, 255] (ORD for constants).
12571257 * 4. '\n' is actually NL (0x15, U+0085) instead of LF (0x25, U+000A).
12581258 * EBCDIC has a proper newline character instead of "emulating" one
12591259 * with line feeds, although this is mapped to LF for our purposes.
--- a/src/syn.c
+++ b/src/syn.c
@@ -2,7 +2,8 @@
22
33 /*-
44 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009,
5- * 2011, 2012, 2013, 2014, 2015, 2016, 2017
5+ * 2011, 2012, 2013, 2014, 2015, 2016, 2017,
6+ * 2018
67 * mirabilos <m@mirbsd.org>
78 *
89 * Provided that these terms and disclaimer and all copyright notices
@@ -23,7 +24,7 @@
2324
2425 #include "sh.h"
2526
26-__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.124 2017/05/05 22:53:31 tg Exp $");
27+__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.127 2018/01/14 00:22:30 tg Exp $");
2728
2829 struct nesting_state {
2930 int start_token; /* token than began nesting (eg, FOR) */
@@ -35,7 +36,7 @@ struct yyrecursive_state {
3536 struct yyrecursive_state *next;
3637 struct ioword **old_herep;
3738 int old_symbol;
38- int old_nesting_type;
39+ unsigned int old_nesting_type;
3940 bool old_reject;
4041 };
4142
@@ -75,7 +76,10 @@ static int symbol; /* yylex value */
7576 #define ACCEPT (reject = false)
7677 #define token(cf) ((reject) ? (ACCEPT, symbol) : (symbol = yylex(cf)))
7778 #define tpeek(cf) ((reject) ? (symbol) : (REJECT, symbol = yylex(cf)))
78-#define musthave(c,cf) do { if (token(cf) != (c)) syntaxerr(NULL); } while (/* CONSTCOND */ 0)
79+#define musthave(c,cf) do { \
80+ if ((unsigned int)token(cf) != (unsigned int)(c)) \
81+ syntaxerr(NULL); \
82+} while (/* CONSTCOND */ 0)
7983
8084 static const char Tcbrace[] = "}";
8185 static const char Tesac[] = "esac";
@@ -91,7 +95,7 @@ yyparse(bool doalias)
9195 c = tpeek(0);
9296 if (c == 0 && !outtree)
9397 outtree = newtp(TEOF);
94- else if (!ctype(c, C_LF | C_NUL))
98+ else if (!cinttype(c, C_LF | C_NUL))
9599 syntaxerr(NULL);
96100 }
97101
@@ -330,7 +334,7 @@ get_command(int cf, int sALIAS)
330334 XPput(args, yylval.cp);
331335 break;
332336
333- case ord('(' /*)*/):
337+ case ORD('(' /*)*/):
334338 if (XPsize(args) == 0 && XPsize(vars) == 1 &&
335339 is_wdvarassign(yylval.cp)) {
336340 char *tcp;
@@ -386,18 +390,18 @@ get_command(int cf, int sALIAS)
386390 Leave:
387391 break;
388392
389- case ord('(' /*)*/): {
390- int subshell_nesting_type_saved;
393+ case ORD('(' /*)*/): {
394+ unsigned int subshell_nesting_type_saved;
391395 Subshell:
392396 subshell_nesting_type_saved = subshell_nesting_type;
393- subshell_nesting_type = ord(')');
394- t = nested(TPAREN, ord('('), ord(')'), sALIAS);
397+ subshell_nesting_type = ORD(')');
398+ t = nested(TPAREN, ORD('('), ORD(')'), sALIAS);
395399 subshell_nesting_type = subshell_nesting_type_saved;
396400 break;
397401 }
398402
399- case ord('{' /*}*/):
400- t = nested(TBRACE, ord('{'), ord('}'), sALIAS);
403+ case ORD('{' /*}*/):
404+ t = nested(TBRACE, ORD('{'), ORD('}'), sALIAS);
401405 break;
402406
403407 case MDPAREN:
@@ -407,8 +411,8 @@ get_command(int cf, int sALIAS)
407411 switch (token(LETEXPR)) {
408412 case LWORD:
409413 break;
410- case ord('(' /*)*/):
411- c = ord('(');
414+ case ORD('(' /*)*/):
415+ c = ORD('(');
412416 goto Subshell;
413417 default:
414418 syntaxerr(NULL);
@@ -554,8 +558,8 @@ dogroup(int sALIAS)
554558 */
555559 if (c == DO)
556560 c = DONE;
557- else if (c == ord('{'))
558- c = ord('}');
561+ else if ((unsigned int)c == ORD('{'))
562+ c = ORD('}');
559563 else
560564 syntaxerr(NULL);
561565 list = c_list(sALIAS, true);
@@ -610,8 +614,8 @@ caselist(int sALIAS)
610614 /* A {...} can be used instead of in...esac for case statements */
611615 if (c == IN)
612616 c = ESAC;
613- else if (c == ord('{'))
614- c = ord('}');
617+ else if ((unsigned int)c == ORD('{'))
618+ c = ORD('}');
615619 else
616620 syntaxerr(NULL);
617621 t = tl = NULL;
@@ -636,18 +640,17 @@ casepart(int endtok, int sALIAS)
636640 XPinit(ptns, 16);
637641 t = newtp(TPAT);
638642 /* no ALIAS here */
639- if (token(CONTIN | KEYWORD) != ord('('))
643+ if ((unsigned int)token(CONTIN | KEYWORD) != ORD('('))
640644 REJECT;
641645 do {
642646 switch (token(0)) {
643647 case LWORD:
644648 break;
645- case ord('}'):
649+ case ORD('}'):
646650 case ESAC:
647651 if (symbol != endtok) {
648- strdupx(yylval.cp,
649- symbol == ord('}') ? Tcbrace : Tesac,
650- ATEMP);
652+ strdupx(yylval.cp, (unsigned int)symbol ==
653+ ORD('}') ? Tcbrace : Tesac, ATEMP);
651654 break;
652655 }
653656 /* FALLTHROUGH */
@@ -659,23 +662,23 @@ casepart(int endtok, int sALIAS)
659662 REJECT;
660663 XPput(ptns, NULL);
661664 t->vars = (char **)XPclose(ptns);
662- musthave(ord(')'), 0);
665+ musthave(ORD(')'), 0);
663666
664667 t->left = c_list(sALIAS, true);
665668
666669 /* initialise to default for ;; or omitted */
667- t->u.charflag = ord(';');
670+ t->u.charflag = ORD(';');
668671 /* SUSv4 requires the ;; except in the last casepart */
669672 if ((tpeek(CONTIN|KEYWORD|sALIAS)) != endtok)
670673 switch (symbol) {
671674 default:
672675 syntaxerr(NULL);
673676 case BRKEV:
674- t->u.charflag = ord('|');
677+ t->u.charflag = ORD('|');
675678 if (0)
676679 /* FALLTHROUGH */
677680 case BRKFT:
678- t->u.charflag = ord('&');
681+ t->u.charflag = ORD('&');
679682 /* FALLTHROUGH */
680683 case BREAK:
681684 /* initialised above, but we need to eat the token */
@@ -711,14 +714,14 @@ function_body(char *name, int sALIAS,
711714 * only accepts an open-brace.
712715 */
713716 if (ksh_func) {
714- if (tpeek(CONTIN|KEYWORD|sALIAS) == ord('(' /*)*/)) {
717+ if ((unsigned int)tpeek(CONTIN|KEYWORD|sALIAS) == ORD('(' /*)*/)) {
715718 /* function foo () { //}*/
716719 ACCEPT;
717- musthave(ord(/*(*/ ')'), 0);
720+ musthave(ORD(/*(*/ ')'), 0);
718721 /* degrade to POSIX function */
719722 ksh_func = false;
720723 }
721- musthave(ord('{' /*}*/), CONTIN|KEYWORD|sALIAS);
724+ musthave(ORD('{' /*}*/), CONTIN|KEYWORD|sALIAS);
722725 REJECT;
723726 }
724727
@@ -810,8 +813,8 @@ static const struct tokeninfo {
810813 { "in", IN, true },
811814 { Tfunction, FUNCTION, true },
812815 { Ttime, TIME, true },
813- { "{", ord('{'), true },
814- { Tcbrace, ord('}'), true },
816+ { "{", ORD('{'), true },
817+ { Tcbrace, ORD('}'), true },
815818 { "!", BANG, true },
816819 { "[[", DBRACKET, true },
817820 /* Lexical tokens (0[EOF], LWORD and REDIR handled specially) */
@@ -823,7 +826,7 @@ static const struct tokeninfo {
823826 { "((", MDPAREN, false },
824827 { "|&", COPROC, false },
825828 /* and some special cases... */
826- { "newline", ord('\n'), false },
829+ { "newline", ORD('\n'), false },
827830 { NULL, 0, false }
828831 };
829832
@@ -998,9 +1001,9 @@ dbtestp_isa(Test_env *te, Test_meta meta)
9981001 ret = (uqword && !strcmp(yylval.cp,
9991002 dbtest_tokens[(int)TM_NOT])) ? TO_NONNULL : TO_NONOP;
10001003 else if (meta == TM_OPAREN)
1001- ret = c == ord('(') /*)*/ ? TO_NONNULL : TO_NONOP;
1004+ ret = (unsigned int)c == ORD('(') /*)*/ ? TO_NONNULL : TO_NONOP;
10021005 else if (meta == TM_CPAREN)
1003- ret = c == /*(*/ ord(')') ? TO_NONNULL : TO_NONOP;
1006+ ret = (unsigned int)c == /*(*/ ORD(')') ? TO_NONNULL : TO_NONOP;
10041007 else if (meta == TM_UNOP || meta == TM_BINOP) {
10051008 if (meta == TM_BINOP && c == REDIR &&
10061009 (yylval.iop->ioflag == IOREAD ||
@@ -1131,14 +1134,14 @@ yyrecursive(int subtype)
11311134 struct op *t;
11321135 char *cp;
11331136 struct yyrecursive_state *ys;
1134- int stok, etok;
1137+ unsigned int stok, etok;
11351138
11361139 if (subtype != COMSUB) {
1137- stok = ord('{');
1138- etok = ord('}');
1140+ stok = ORD('{');
1141+ etok = ORD('}');
11391142 } else {
1140- stok = ord('(');
1141- etok = ord(')');
1143+ stok = ORD('(');
1144+ etok = ORD(')');
11421145 }
11431146
11441147 ys = alloc(sizeof(struct yyrecursive_state), ATEMP);
--- a/src/tree.c
+++ b/src/tree.c
@@ -23,7 +23,7 @@
2323
2424 #include "sh.h"
2525
26-__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.93 2017/05/05 22:53:32 tg Exp $");
26+__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.95 2018/01/14 00:03:05 tg Exp $");
2727
2828 #define INDENT 8
2929
@@ -329,7 +329,7 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
329329 case EOS:
330330 return (--wp);
331331 case ADELIM:
332- if (ord(*wp) == ord(/*{*/ '}')) {
332+ if (ord(*wp) == ORD(/*{*/ '}')) {
333333 ++wp;
334334 goto wdvarput_csubst;
335335 }
@@ -342,21 +342,21 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
342342 c = ord(*wp++);
343343 if (opmode & WDS_TPUTS)
344344 switch (c) {
345- case ord('\n'):
345+ case ORD('\n'):
346346 if (quotelevel == 0) {
347- c = ord('\'');
347+ c = ORD('\'');
348348 shf_putc(c, shf);
349- shf_putc(ord('\n'), shf);
349+ shf_putc(ORD('\n'), shf);
350350 }
351351 break;
352352 default:
353353 if (quotelevel == 0)
354354 /* FALLTHROUGH */
355- case ord('"'):
356- case ord('`'):
357- case ord('$'):
358- case ord('\\'):
359- shf_putc(ord('\\'), shf);
355+ case ORD('"'):
356+ case ORD('`'):
357+ case ORD('$'):
358+ case ORD('\\'):
359+ shf_putc(ORD('\\'), shf);
360360 break;
361361 }
362362 shf_putc(c, shf);
@@ -365,7 +365,7 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
365365 case COMSUB:
366366 shf_puts("$(", shf);
367367 cs = ")";
368- if (ord(*wp) == ord('(' /*)*/))
368+ if (ord(*wp) == ORD('(' /*)*/))
369369 shf_putc(' ', shf);
370370 pSUB:
371371 while ((c = *wp++) != 0)
@@ -374,11 +374,11 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
374374 break;
375375 case FUNASUB:
376376 case FUNSUB:
377- c = ord(' ');
377+ c = ORD(' ');
378378 if (0)
379379 /* FALLTHROUGH */
380380 case VALSUB:
381- c = ord('|');
381+ c = ORD('|');
382382 shf_putc('$', shf);
383383 shf_putc('{', shf);
384384 shf_putc(c, shf);
@@ -403,14 +403,14 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
403403 break;
404404 case OSUBST:
405405 shf_putc('$', shf);
406- if (ord(*wp++) == ord('{'))
406+ if (ord(*wp++) == ORD('{'))
407407 shf_putc('{', shf);
408408 while ((c = *wp++) != 0)
409409 shf_putc(c, shf);
410410 wp = wdvarput(shf, wp, 0, opmode);
411411 break;
412412 case CSUBST:
413- if (ord(*wp++) == ord('}')) {
413+ if (ord(*wp++) == ORD('}')) {
414414 wdvarput_csubst:
415415 shf_putc('}', shf);
416416 }
@@ -420,11 +420,11 @@ wdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
420420 shf_putc('(', shf);
421421 break;
422422 case SPAT:
423- c = ord('|');
423+ c = ORD('|');
424424 if (0)
425425 /* FALLTHROUGH */
426426 case CPAT:
427- c = ord(/*(*/ ')');
427+ c = ORD(/*(*/ ')');
428428 shf_putc(c, shf);
429429 break;
430430 }
@@ -470,36 +470,37 @@ vfptreef(struct shf *shf, int indent, const char *fmt, va_list va)
470470 while ((c = ord(*fmt++))) {
471471 if (c == '%') {
472472 switch ((c = ord(*fmt++))) {
473- case ord('c'):
473+ case ORD('c'):
474474 /* character (octet, probably) */
475475 shf_putchar(va_arg(va, int), shf);
476476 break;
477- case ord('s'):
477+ case ORD('s'):
478478 /* string */
479479 shf_puts(va_arg(va, char *), shf);
480480 break;
481- case ord('S'):
481+ case ORD('S'):
482482 /* word */
483483 wdvarput(shf, va_arg(va, char *), 0, WDS_TPUTS);
484484 break;
485- case ord('d'):
485+ case ORD('d'):
486486 /* signed decimal */
487487 shf_fprintf(shf, Tf_d, va_arg(va, int));
488488 break;
489- case ord('u'):
489+ case ORD('u'):
490490 /* unsigned decimal */
491491 shf_fprintf(shf, "%u", va_arg(va, unsigned int));
492492 break;
493- case ord('T'):
493+ case ORD('T'):
494494 /* format tree */
495495 ptree(va_arg(va, struct op *), indent, shf);
496496 goto dont_trash_prevent_semicolon;
497- case ord(';'):
497+ case ORD(';'):
498498 /* newline or ; */
499- case ord('N'):
499+ case ORD('N'):
500500 /* newline or space */
501501 if (shf->flags & SHF_STRING) {
502- if (c == ord(';') && !prevent_semicolon)
502+ if ((unsigned int)c == ORD(';') &&
503+ !prevent_semicolon)
503504 shf_putc(';', shf);
504505 shf_putc(' ', shf);
505506 } else {
@@ -515,7 +516,7 @@ vfptreef(struct shf *shf, int indent, const char *fmt, va_list va)
515516 shf_putc(' ', shf);
516517 }
517518 break;
518- case ord('R'):
519+ case ORD('R'):
519520 /* I/O redirection */
520521 pioact(shf, va_arg(va, struct ioword *));
521522 break;
@@ -613,7 +614,7 @@ wdscan(const char *wp, int c)
613614 case ADELIM:
614615 if (c == ADELIM && nest == 0)
615616 return (wp + 1);
616- if (ord(*wp) == ord(/*{*/ '}'))
617+ if (ord(*wp) == ORD(/*{*/ '}'))
617618 goto wdscan_csubst;
618619 /* FALLTHROUGH */
619620 case CHAR:
@@ -808,7 +809,7 @@ vistree(char *dst, size_t sz, struct op *t)
808809 } else if (UTFMODE && rtt2asc(c) > 0x7F) {
809810 /* better not try to display broken multibyte chars */
810811 /* also go easy on the Unicode: no U+FFFD here */
811- c = ord('?');
812+ c = ORD('?');
812813 }
813814 *dst++ = c;
814815 goto vist_loop;
@@ -842,7 +843,7 @@ dumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
842843 shf_puts("EOS", shf);
843844 return (--wp);
844845 case ADELIM:
845- if (ord(*wp) == ord(/*{*/ '}')) {
846+ if (ord(*wp) == ORD(/*{*/ '}')) {
846847 shf_puts(/*{*/ "]ADELIM(})", shf);
847848 return (wp + 1);
848849 }
@@ -856,8 +857,8 @@ dumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
856857 case QCHAR:
857858 shf_puts("QCHAR<", shf);
858859 c = ord(*wp++);
859- if (quotelevel == 0 || c == ord('"') ||
860- c == ord('\\') || ctype(c, C_DOLAR | C_GRAVE))
860+ if (quotelevel == 0 || c == ORD('"') ||
861+ c == ORD('\\') || ctype(c, C_DOLAR | C_GRAVE))
861862 shf_putc('\\', shf);
862863 dumpchar(shf, c);
863864 goto closeandout;
--- a/src/var.c
+++ b/src/var.c
@@ -2,7 +2,7 @@
22
33 /*-
44 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
5- * 2011, 2012, 2013, 2014, 2015, 2016, 2017
5+ * 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
66 * mirabilos <m@mirbsd.org>
77 *
88 * Provided that these terms and disclaimer and all copyright notices
@@ -28,7 +28,7 @@
2828 #include <sys/sysctl.h>
2929 #endif
3030
31-__RCSID("$MirOS: src/bin/mksh/var.c,v 1.220 2017/07/26 23:02:28 tg Exp $");
31+__RCSID("$MirOS: src/bin/mksh/var.c,v 1.223 2018/01/13 23:55:15 tg Exp $");
3232
3333 /*-
3434 * Variables
@@ -136,7 +136,7 @@ initvar(void)
136136 struct tbl *tp;
137137
138138 ktinit(APERM, &specials,
139- /* currently 18 specials: 75% of 32 = 2^5 */
139+ /* currently 21 specials: 75% of 32 = 2^5 */
140140 5);
141141 while (i < V_MAX - 1) {
142142 tp = ktenter(&specials, initvar_names[i],
@@ -204,7 +204,7 @@ array_index_calc(const char *n, bool *arrayp, uint32_t *valp)
204204 }
205205 innermost_refflag = SRF_NOP;
206206
207- if (p != n && ord(*p) == ord('[') && (len = array_ref_len(p))) {
207+ if (p != n && ord(*p) == ORD('[') && (len = array_ref_len(p))) {
208208 char *sub, *tmp;
209209 mksh_ari_t rval;
210210
@@ -780,7 +780,7 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
780780 /* no variable name given */
781781 return (NULL);
782782 }
783- if (ord(*val) == ord('[')) {
783+ if (ord(*val) == ORD('[')) {
784784 if (new_refflag != SRF_NOP)
785785 errorf(Tf_sD_s, var,
786786 "reference variable can't be an array");
@@ -803,13 +803,13 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
803803 }
804804 val += len;
805805 }
806- if (ord(val[0]) == ord('=')) {
806+ if (ord(val[0]) == ORD('=')) {
807807 strndupx(tvar, var, val - var, ATEMP);
808808 ++val;
809809 } else if (set & IMPORT) {
810810 /* environment invalid variable name or no assignment */
811811 return (NULL);
812- } else if (ord(val[0]) == ord('+') && ord(val[1]) == ord('=')) {
812+ } else if (ord(val[0]) == ORD('+') && ord(val[1]) == ORD('=')) {
813813 strndupx(tvar, var, val - var, ATEMP);
814814 val += 2;
815815 vappend = true;
@@ -822,9 +822,9 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
822822 val = NULL;
823823 /* handle foo[*] => foo (whole array) mapping for R39b */
824824 len = strlen(tvar);
825- if (len > 3 && ord(tvar[len - 3]) == ord('[') &&
826- ord(tvar[len - 2]) == ord('*') &&
827- ord(tvar[len - 1]) == ord(']'))
825+ if (len > 3 && ord(tvar[len - 3]) == ORD('[') &&
826+ ord(tvar[len - 2]) == ORD('*') &&
827+ ord(tvar[len - 1]) == ORD(']'))
828828 tvar[len - 3] = '\0';
829829 }
830830
@@ -861,7 +861,7 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
861861 nameref_empty:
862862 errorf(Tf_sD_s, var, "empty nameref target");
863863 }
864- len = (ord(*ccp) == ord('[')) ? array_ref_len(ccp) : 0;
864+ len = (ord(*ccp) == ORD('[')) ? array_ref_len(ccp) : 0;
865865 if (ccp[len]) {
866866 /*
867867 * works for cases "no array", "valid array with
@@ -1071,7 +1071,7 @@ skip_varname(const char *s, bool aok)
10711071 do {
10721072 ++s;
10731073 } while (ctype(*s, C_ALNUX));
1074- if (aok && ord(*s) == ord('[') && (alen = array_ref_len(s)))
1074+ if (aok && ord(*s) == ORD('[') && (alen = array_ref_len(s)))
10751075 s += alen;
10761076 }
10771077 return (s);
@@ -1087,7 +1087,7 @@ skip_wdvarname(const char *s,
10871087 do {
10881088 s += 2;
10891089 } while (s[0] == CHAR && ctype(s[1], C_ALNUX));
1090- if (aok && s[0] == CHAR && ord(s[1]) == ord('[')) {
1090+ if (aok && s[0] == CHAR && ord(s[1]) == ORD('[')) {
10911091 /* skip possible array de-reference */
10921092 const char *p = s;
10931093 char c;
@@ -1098,9 +1098,9 @@ skip_wdvarname(const char *s,
10981098 break;
10991099 c = p[1];
11001100 p += 2;
1101- if (ord(c) == ord('['))
1101+ if (ord(c) == ORD('['))
11021102 depth++;
1103- else if (ord(c) == ord(']') && --depth == 0) {
1103+ else if (ord(c) == ORD(']') && --depth == 0) {
11041104 s = p;
11051105 break;
11061106 }
@@ -1294,9 +1294,29 @@ setspec(struct tbl *vp)
12941294 {
12951295 mksh_ari_u num;
12961296 char *s;
1297- int st;
1297+ int st = special(vp->name);
12981298
1299- switch ((st = special(vp->name))) {
1299+#ifdef MKSH_DOSPATH
1300+ switch (st) {
1301+ case V_PATH:
1302+ case V_TMPDIR:
1303+#ifdef __OS2__
1304+ case V_BEGINLIBPATH:
1305+ case V_ENDLIBPATH:
1306+#endif
1307+ /* convert backslashes to slashes for convenience */
1308+ if (!(vp->flag&INTEGER)) {
1309+ s = str_val(vp);
1310+ do {
1311+ if (*s == ORD('\\'))
1312+ *s = '/';
1313+ } while (*s++);
1314+ }
1315+ break;
1316+ }
1317+#endif
1318+
1319+ switch (st) {
13001320 #ifdef __OS2__
13011321 case V_BEGINLIBPATH:
13021322 case V_ENDLIBPATH:
@@ -1366,6 +1386,13 @@ setspec(struct tbl *vp)
13661386 }
13671387 vp->flag |= SPECIAL;
13681388 break;
1389+#ifdef MKSH_EARLY_LOCALE_TRACKING
1390+ case V_LANG:
1391+ case V_LC_ALL:
1392+ case V_LC_CTYPE:
1393+ recheck_ctype();
1394+ return;
1395+#endif
13691396 default:
13701397 /* do nothing, do not touch vp at all */
13711398 return;
@@ -1465,6 +1492,13 @@ unsetspec(struct tbl *vp)
14651492 /* AT&T ksh leaves previous value in place */
14661493 unspecial(vp->name);
14671494 break;
1495+#ifdef MKSH_EARLY_LOCALE_TRACKING
1496+ case V_LANG:
1497+ case V_LC_ALL:
1498+ case V_LC_CTYPE:
1499+ recheck_ctype();
1500+ return;
1501+#endif
14681502 }
14691503 }
14701504
@@ -1528,8 +1562,8 @@ array_ref_len(const char *cp)
15281562 char c;
15291563 int depth = 0;
15301564
1531- while ((c = *s++) && (ord(c) != ord(']') || --depth))
1532- if (ord(c) == ord('['))
1565+ while ((c = *s++) && (ord(c) != ORD(']') || --depth))
1566+ if (ord(c) == ORD('['))
15331567 depth++;
15341568 if (!c)
15351569 return (0);
@@ -1601,18 +1635,18 @@ set_array(const char *var, bool reset, const char **vals)
16011635 }
16021636 while ((ccp = vals[i])) {
16031637 #if 0 /* temporarily taken out due to regression */
1604- if (ord(*ccp) == ord('[')) {
1638+ if (ord(*ccp) == ORD('[')) {
16051639 int level = 0;
16061640
16071641 while (*ccp) {
1608- if (ord(*ccp) == ord(']') && --level == 0)
1642+ if (ord(*ccp) == ORD(']') && --level == 0)
16091643 break;
1610- if (ord(*ccp) == ord('['))
1644+ if (ord(*ccp) == ORD('['))
16111645 ++level;
16121646 ++ccp;
16131647 }
1614- if (ord(*ccp) == ord(']') && level == 0 &&
1615- ord(ccp[1]) == ord('=')) {
1648+ if (ord(*ccp) == ORD(']') && level == 0 &&
1649+ ord(ccp[1]) == ORD('=')) {
16161650 strndupx(cp, vals[i] + 1, ccp - (vals[i] + 1),
16171651 ATEMP);
16181652 evaluate(substitute(cp, 0), (mksh_ari_t *)&j,
--- a/src/var_spec.h
+++ b/src/var_spec.h
@@ -1,5 +1,5 @@
11 /*-
2- * Copyright (c) 2009, 2011, 2012, 2016
2+ * Copyright (c) 2009, 2011, 2012, 2016, 2018
33 * mirabilos <m@mirbsd.org>
44 *
55 * Provided that these terms and disclaimer and all copyright notices
@@ -19,7 +19,7 @@
1919 */
2020
2121 #if defined(VARSPEC_DEFNS)
22-__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.10 2016/11/11 23:31:39 tg Exp $");
22+__RCSID("$MirOS: src/bin/mksh/var_spec.h,v 1.11 2018/01/13 21:38:10 tg Exp $");
2323 #define FN(name) /* nothing */
2424 #elif defined(VARSPEC_ENUMS)
2525 #define FN(name) V_##name,
@@ -53,6 +53,11 @@ FN(HISTFILE)
5353 #endif
5454 FN(HISTSIZE)
5555 FN(IFS)
56+#ifdef MKSH_EARLY_LOCALE_TRACKING
57+FN(LANG)
58+FN(LC_ALL)
59+FN(LC_CTYPE)
60+#endif
5661 #ifdef __OS2__
5762 FN(LIBPATHSTRICT)
5863 #endif
Show on old repository browser