Changeset 594
- Timestamp:
- 05/09/07 04:47:06 (1 year ago)
- Files:
-
- branches/tango/sss/build.d (modified) (1 diff)
- branches/tango/sss/conf.d (modified) (53 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/tango/sss/build.d
r592 r594 71 71 72 72 // add -oq if we don't have such a setting 73 if ( find(forceFlags, "-o") == -1) {73 if (locatePattern(forceFlags, "-o") == forceFlags.length) { 74 74 mkdirP("dsss_objs"); 75 75 bl ~= "-oqdsss_objs "; branches/tango/sss/conf.d
r589 r594 29 29 module sss.conf; 30 30 31 import tango.io.Console; 32 import tango.io.File; 33 import tango.io.FileConst; 31 34 import tango.io.FilePath; 32 33 import std.ctype; 34 import std.file; 35 import std.process; 36 import std.stdio; 37 import std.stream; 38 import std.string; 39 40 import std.c.stdlib; 35 import tango.io.FileSystem; 36 37 import tango.text.Ascii; 38 import tango.text.Util; 39 40 import tango.stdc.stdlib; 41 41 42 42 import sss.clean; … … 49 49 import bcd.windows.windows; 50 50 } 51 52 alias std.process.system system;53 alias std.string.find find;54 alias std.string.iswhite iswhite;55 51 56 52 /** The default config file name */ … … 132 128 char[] bname; 133 129 if (!whereAmI(argvz, installPrefix, bname)) { 134 writefln("Failed to determine DSSS' installed prefix.");130 Cout("Failed to determine DSSS' installed prefix.").newline; 135 131 exit(1); 136 132 } … … 141 137 142 138 // using this directory, find include and library directories 143 if (exists(installPrefix ~ std.path.sep ~ "sss" ~ std.path.sep ~ "main.d")) { 139 if ((new FilePath(installPrefix ~ FileConst.PathSeparatorChar ~ "sss" ~ 140 FileConst.PathSeparatorChar ~ "main.d")).exists()) { 144 141 // this is probably the build prefix 145 142 inSourceDir = true; 146 143 147 144 if (forcePrefix == "") { 148 forcePrefix = installPrefix ~ std.path.sep~ "inst";145 forcePrefix = installPrefix ~ FileConst.PathSeparatorChar ~ "inst"; 149 146 } else { 150 147 forcePrefix = canonPath(forcePrefix); 151 148 } 152 149 153 char[] sssBaseLoc = installPrefix ~ std.path.sep ~ "sss" ~ std.path.sep;150 char[] sssBaseLoc = installPrefix ~ FileConst.PathSeparatorChar ~ "sss" ~ FileConst.PathSeparatorChar; 154 151 stubDLoc = sssBaseLoc ~ "stub.d"; 155 152 dsssDllLoc = sssBaseLoc ~ "dssdll.d"; … … 158 155 version (Posix) { 159 156 dsss_build = installPrefix ~ 160 std.path.sep~ "rebuild" ~161 std.path.sep~ "rebuild";157 FileConst.PathSeparatorChar ~ "rebuild" ~ 158 FileConst.PathSeparatorChar ~ "rebuild"; 162 159 } else version (Windows) { 163 160 dsss_build = installPrefix ~ 164 std.path.sep~ "rebuild" ~165 std.path.sep~ "rebuild.exe";161 FileConst.PathSeparatorChar ~ "rebuild" ~ 162 FileConst.PathSeparatorChar ~ "rebuild.exe"; 166 163 } else { 167 164 static assert(0); … … 172 169 if (!candyDocPrefix.length) 173 170 candyDocPrefix = canonPath( 174 installPrefix ~ std.path.sep~171 installPrefix ~ FileConst.PathSeparatorChar ~ 175 172 "candydoc.tar.gz"); 176 173 } else { … … 184 181 } 185 182 186 char[] sssBaseLoc = forcePrefix ~ std.path.sep~187 "include" ~ std.path.sep~188 "d" ~ std.path.sep~189 "sss" ~ std.path.sep;183 char[] sssBaseLoc = forcePrefix ~ FileConst.PathSeparatorChar ~ 184 "include" ~ FileConst.PathSeparatorChar ~ 185 "d" ~ FileConst.PathSeparatorChar ~ 186 "sss" ~ FileConst.PathSeparatorChar; 190 187 stubDLoc = sssBaseLoc ~ "stub.d"; 191 188 dsssDllLoc = sssBaseLoc ~ "dsssdll.d"; … … 194 191 version (Posix) { 195 192 dsss_build = installPrefix ~ 196 std.path.sep~ "rebuild";193 FileConst.PathSeparatorChar ~ "rebuild"; 197 194 } else version (Windows) { 198 195 dsss_build = installPrefix ~ 199 std.path.sep~ "rebuild.exe";196 FileConst.PathSeparatorChar ~ "rebuild.exe"; 200 197 } else { 201 198 static assert(0); … … 203 200 204 201 // if we don't have rebuild next to us, try to use it without a path 205 if (! std.file.exists(dsss_build)) {202 if (!(new FilePath(dsss_build)).exists()) { 206 203 version (Posix) { 207 204 dsss_build = "rebuild"; … … 217 214 if (!candyDocPrefix.length) 218 215 candyDocPrefix = canonPath( 219 installPrefix ~ std.path.sep~220 ".." ~ std.path.sep~221 "share" ~ std.path.sep~222 "dsss" ~ std.path.sep~216 installPrefix ~ FileConst.PathSeparatorChar ~ 217 ".." ~ FileConst.PathSeparatorChar ~ 218 "share" ~ FileConst.PathSeparatorChar ~ 219 "dsss" ~ FileConst.PathSeparatorChar ~ 223 220 "candydoc.tar.gz"); 224 221 } 225 222 226 223 if (!binPrefix.length) 227 binPrefix = forcePrefix ~ std.path.sep~ "bin";224 binPrefix = forcePrefix ~ FileConst.PathSeparatorChar ~ "bin"; 228 225 if (!libPrefix.length) 229 libPrefix = forcePrefix ~ std.path.sep~ "lib";226 libPrefix = forcePrefix ~ FileConst.PathSeparatorChar ~ "lib"; 230 227 if (!includePrefix.length) 231 includePrefix = forcePrefix ~ std.path.sep~232 "include" ~ std.path.sep~228 includePrefix = forcePrefix ~ FileConst.PathSeparatorChar ~ 229 "include" ~ FileConst.PathSeparatorChar ~ 233 230 "d"; 234 231 if (!docPrefix.length) 235 docPrefix = forcePrefix ~ std.path.sep~236 "share" ~ std.path.sep~232 docPrefix = forcePrefix ~ FileConst.PathSeparatorChar ~ 233 "share" ~ FileConst.PathSeparatorChar ~ 237 234 "doc"; 238 235 if (!manifestPrefix.length) 239 manifestPrefix = forcePrefix ~ std.path.sep~240 "share" ~ std.path.sep~241 "dsss" ~ std.path.sep~236 manifestPrefix = forcePrefix ~ FileConst.PathSeparatorChar ~ 237 "share" ~ FileConst.PathSeparatorChar ~ 238 "dsss" ~ FileConst.PathSeparatorChar ~ 242 239 "manifest"; 243 240 if (!etcPrefix.length) 244 etcPrefix = forcePrefix ~ std.path.sep~241 etcPrefix = forcePrefix ~ FileConst.PathSeparatorChar ~ 245 242 "etc"; 246 243 if (!srcListPrefix.length) 247 244 srcListPrefix = canonPath( 248 installPrefix ~ std.path.sep~249 ".." ~ std.path.sep~250 "share" ~ std.path.sep~251 "dsss" ~ std.path.sep~245 installPrefix ~ FileConst.PathSeparatorChar ~ 246 ".." ~ FileConst.PathSeparatorChar ~ 247 "share" ~ FileConst.PathSeparatorChar ~ 248 "dsss" ~ FileConst.PathSeparatorChar ~ 252 249 "sources"); 253 250 … … 256 253 scratchPrefix = "/tmp"; 257 254 258 setEnvVar("DSSS", installPrefix ~ std.path.sep~ bname);255 setEnvVar("DSSS", installPrefix ~ FileConst.PathSeparatorChar ~ bname); 259 256 setEnvVar("PREFIX", forcePrefix); 260 257 setEnvVar("BIN_PREFIX", binPrefix); … … 275 272 setEnvVar("LD_LIBRARY_PATH", ldlibp); 276 273 } else version (Windows) { 277 scratchPrefix = canonPath(installPrefix ~ std.path.sep~278 ".." ~ std.path.sep~274 scratchPrefix = canonPath(installPrefix ~ FileConst.PathSeparatorChar ~ 275 ".." ~ FileConst.PathSeparatorChar ~ 279 276 "tmp"); 280 277 281 setEnvVar("DSSS", installPrefix ~ std.path.sep~ bname);278 setEnvVar("DSSS", installPrefix ~ FileConst.PathSeparatorChar ~ bname); 282 279 setEnvVar("PREFIX", forcePrefix); 283 280 setEnvVar("BIN_PREFIX", binPrefix); … … 294 291 } 295 292 296 dsss_build ~= " -Idsss_imports" ~ std.path.sep~297 " -I. -S." ~ std.path.sep~298 " -I" ~ includePrefix ~ " -S" ~ libPrefix ~ std.path.sep~ " " ~293 dsss_build ~= " -Idsss_imports" ~ FileConst.PathSeparatorChar ~ 294 " -I. -S." ~ FileConst.PathSeparatorChar ~ 295 " -I" ~ includePrefix ~ " -S" ~ libPrefix ~ FileConst.PathSeparatorChar ~ " " ~ 299 296 dsss_buildOptions ~ " "; 300 297 } … … 338 335 line[i] == '_') { 339 336 tok ~= line[i..i+1]; 340 } else if (is white(line[i])) {337 } else if (isSpace(line[i])) { 341 338 addToken(); 342 339 } else if (line[i] == '=' || … … 350 347 351 348 // trim whitespace of the setting 352 while (tok.length && is white(tok[0])) tok = tok[1..$];349 while (tok.length && isSpace(tok[0])) tok = tok[1..$]; 353 350 354 351 if (tok.length) addToken(); … … 371 368 char[] confFile; 372 369 373 if ( exists(configFName)) {370 if ((new FilePath(configFName)).exists()) { 374 371 if (genconfig) { 375 372 // this makes no sense 376 writefln("Will not generate a config file when a config file already exists.");373 Cout("Will not generate a config file when a config file already exists.").newline; 377 374 exit(1); 378 375 } … … 380 377 // before reading the config, distclean if it's changed 381 378 if (configF == configFName) { 382 if ( exists(configLBName)) {379 if ((new FilePath(configLBName)).exists()) { 383 380 if (fileNewer(configFName, configLBName)) { 384 381 // our config has changed … … 388 385 389 386 // copy in our new dsss.lastbuild 390 std.file.copy(configFName, configLBName);387 (new FilePath(configLBName)).copy(configFName); 391 388 } 392 389 393 390 // Read the config file 394 confFile = cast(char[]) std.file.read(configFName);391 confFile = cast(char[]) (new File(configFName)).read(); 395 392 } else { 396 393 // Generate the config file 397 394 if (buildElems.length == 0) { 398 395 // from nothing - just make every directory into a library 399 char[][] dires = listdir(".");396 char[][] dires = (new FilePath(".")).toList(); 400 397 foreach (dire; dires) { 401 if ( isdir(dire) &&398 if ((new FilePath(dire)).isDir() && 402 399 dire[0] != '.') { 403 400 confFile ~= "[" ~ dire ~ "]\n"; … … 408 405 // from a list 409 406 foreach (build; buildElems) { 410 if (! exists(build)) {411 writefln("File %s not found!", build);407 if (!(new FilePath(build)).exists()) { 408 Cout("File ")(build)(" not found!").newline; 412 409 } else { 413 410 confFile ~= "[" ~ build ~ "]\n"; … … 418 415 if (genconfig) { 419 416 // write it 420 std.file.write(configFName,confFile);417 (new File(configFName)).write(confFile); 421 418 } 422 419 … … 425 422 426 423 // Normalize it 427 confFile = replace(confFile, "\r", "");424 confFile = substitute(confFile, "\r", ""); 428 425 429 426 // Split it by lines … … 435 432 // set up the defaults for the top-level section 436 433 conf.settings[""] = null; 437 conf.settings[""]["name"] = getBaseName(getcwd());434 conf.settings[""]["name"] = (new FilePath(FileSystem.getDirectory())).file(); 438 435 conf.settings[""]["version"] = "latest"; 439 436 … … 457 454 if (!ignoreElse) { 458 455 // rewrite this line for later parsing 459 lines[i] = std.string.join(ntokens[2 .. $], " ");456 lines[i] = tango.text.Util.join(ntokens[2 .. $], " "); 460 457 depth--; 461 458 i--; … … 477 474 } 478 475 // didn't close! 479 writefln("DSSS config error: unclosed scope.");476 Cout("DSSS config error: unclosed scope.").newline; 480 477 exit(1); 481 478 } … … 497 494 tokens[$ - 1] == "]") { 498 495 // a section header 499 char[] path = std.string.join(tokens[1 .. ($ - 1)], "");496 char[] path = tango.text.Util.join(tokens[1 .. ($ - 1)], ""); 500 497 // allow \'s for badly-written conf files 501 path = std.string.replace(path, "\\", "/");498 path = tango.text.Util.replace(path.dup, '\\', '/'); 502 499 503 500 section = canonPath(path); … … 516 513 conf.settings[section]["target"] = section[1..$]; 517 514 518 } else if (! exists(section)) {519 writefln("WARNING: Section for nonexistant file %s.", section);515 } else if (!(new FilePath(section)).exists()) { 516 Cout("WARNING: Section for nonexistant file ")(section)(".").newline; 520 517 } else { 521 518 conf.sections ~= section; 522 519 523 if ( isdir(section)) {520 if ((new FilePath(section)).isDir()) { 524 521 conf.settings[section]["type"] = "library"; 525 522 526 523 // target according to the library naming convention 527 char[] pkg = std.string.replace(canonPath(section),528 "\\", "/");524 char[] pkg = tango.text.Util.replace(canonPath(section).dup, 525 '\\', '/'); 529 526 530 527 // LNC: … … 548 545 // swap out /'s 549 546 pkg = 550 std.string.replace(pkg, "/", "-");547 tango.text.Util.replace(pkg.dup, '/', '-'); 551 548 // name it 552 549 conf.settings[section]["target"] = … … 555 552 } else { 556 553 conf.settings[section]["type"] = "binary"; 557 conf.settings[section]["target"] = std.path.getName(section);554 conf.settings[section]["target"] = (new FilePath(section)).name(); 558 555 } 559 556 } … … 566 563 if (tokens[0] == "warn") { 567 564 // a warning 568 writefln("WARNING: %s", tokens[2]);565 Cout("WARNING: ")(tokens[2]).newline; 569 566 } else if (tokens[0] == "error") { 570 567 // an error 571 writefln("ERROR: %s", tokens[2]);568 Cout("ERROR: ")(tokens[2]).newline; 572 569 } 573 570 … … 575 572 tokens[1] == "=") { 576 573 // a setting 577 conf.settings[section][ std.string.tolower(tokens[0])] = expandEnvVars(tokens[2]);574 conf.settings[section][tango.text.Ascii.toLower(tokens[0])] = expandEnvVars(tokens[2]); 578 575 579 576 } else if (tokens.length == 1 && 580 577 isalnum(tokens[0][0])) { 581 578 // a setting with no value 582 conf.settings[section][ std.string.tolower(tokens[0])] = "";579 conf.settings[section][tango.text.Ascii.toLower(tokens[0])] = ""; 583 580 584 581 } else if (tokens.length == 4 && … … 586 583 tokens[2] == "=") { 587 584 // append to a setting 588 char[] setting = std.string.tolower(tokens[0]);585 char[] setting = tango.text.Ascii.toLower(tokens[0]); 589 586 if (setting in conf.settings[section]) { 590 587 conf.settings[section][setting] ~= " " ~ expandEnvVars(tokens[3]); … … 608 605 tokens[4] != ")" || 609 606 tokens[5] != "{")) { 610 writefln("DSSS config error: malformed version line.");607 Cout("DSSS config error: malformed version line.").newline; 611 608 exit(1); 612 609 } … … 645 642 646 643 } else { 647 writefln("DSSS config error: unrecognized line '%s'.", lines[i]);644 Cout("DSSS config error: unrecognized line '")(lines[i])("'.").newline; 648 645 exit(1); 649 646 … … 678 675 /* now check if this version is defined by making a .d file and 679 676 * building it */ 680 int ret = system(dsss_build ~ "-testversion=" ~ vertok);677 int ret = hcf.process.system(dsss_build ~ "-testversion=" ~ vertok); 681 678 682 679 if (ret == 0) { … … 716 713 char[][] exclude; 717 714 if ("exclude" in settings) { 718 exclude = split(settings["exclude"]); 715 exclude = tango.text.Util.delimit(settings["exclude"], 716 [' ', '\t', '\n', '\r']); 719 717 720 718 // canonicalize and un-Windows-ize the paths 721 719 for (int i = 0; i < exclude.length; i++) { 722 exclude[i] = std.string.replace(canonPath(exclude[i]),723 "\\", "/");720 exclude[i] = tango.text.Util.replace(canonPath(exclude[i]).dup, 721 '\\', '/'); 724 722 } 725 723 } … … 727 725 { 728 726 for (int i = 0; i < exclude.length; i++) { 729 if (fnmatch( std.string.replace(path, "\\", "/"), exclude[i])) {727 if (fnmatch(tango.text.Util.replace(path.dup, '\\', '/'), exclude[i])) { 730 728 return true; 731 729 } … … 745 743 746 744 // not excluded, get the list of files 747 char[][] dirFiles = listdir(ndir);745 char[][] dirFiles = (new FilePath(ndir)).toList(); 748 746 foreach (file; dirFiles) { 749 747 if (!file.length) continue; // shouldn't happen … … 753 751 754 752 // make this the full path 755 file = ndir ~ std.path.sep~ file;756 757 if ( isdir(file)) {753 file = ndir ~ FileConst.PathSeparatorChar ~ file; 754 755 if ((new FilePath(file)).isDir()) { 758 756 // perhaps recurse 759 757 addDir(file); 760 } else if ( std.string.tolower(getExt(file)) == "d") {758 } else if (tango.text.Ascii.toLower(getExt(file)) == "d") { 761 759 // or just add it 762 760 if (!excluded(file)) { … … 767 765 } 768 766 769 if ( isdir(target)) {767 if ((new FilePath(target)).isDir()) { 770 768 addDir(target, true); 771 769 } else { … … 784 782 785 783 // since parts of the script can potentially change the directory, store it 786 char[] origcwd = getcwd();784 char[] origcwd = FileSystem.getDirectory(); 787 785 788 786 // split the steps by ; 789 char[][] cmds = std.string.split(step, ";");787 char[][] cmds = tango.text.Util.split(step, ";"); 790 788 791 789 foreach (cmd; cmds) { 792 790 // clean cmd 793 while (cmd.length > 0 && is white(cmd[0])) cmd = cmd[1..$];794 while (cmd.length > 0 && is white(cmd[$-1])) cmd = cmd[0..($-1)];795 writefln("Command: %s", cmd);791 while (cmd.length > 0 && isSpace(cmd[0])) cmd = cmd[1..$]; 792 while (cmd.length > 0 && isSpace(cmd[$-1])) cmd = cmd[0..($-1)]; 793 Cout("Command: ")(cmd).newline; 796 794 797 795 // run it 798 char[] ext = std.string.tolower(getExt(cmd));799 if ( find(cmd, ' ') == -1&& ext == "d") {796 char[] ext = tango.text.Ascii.toLower(getExt(cmd)); 797 if (locate(cmd, ' ') == cmd.length && ext == "d") { 800 798 // if it's a .d file, -exec it 801 799 saySystemDie(dsss_build ~ "-full -exec " ~ cmd); … … 804 802 cmd[0..8] == "install ") { 805 803 // doing an install 806 char[][] comps = std.string.split(cmd); 804 char[][] comps = tango.text.Util.delimit(cmd, 805 [' ', '\t', '\n', '\r']); 807 806 if (comps.length != 3) continue; // FIXME: not valid 808 807 809 808 // do this install 810 809 // check for / or \ 811 int slloc = std.string.rfind(comps[1], '/');812 if (slloc == -1)813 s td.string.rfind(comps[1], '\\');810 int slloc = tango.text.Util.locatePrior(comps[1], '/'); 811 if (slloc == comps[1].length) 812 slloc = tango.text.Util.locatePrior(comps[1], '\\'); 814 813 815 814 // strip off the prefix from our manifest path 816 char[] manifestPath = comps[2] ~ std.path.sep;815 char[] manifestPath = comps[2] ~ FileConst.PathSeparatorChar; 817 816 if (manifestPath.length > forcePrefix.length && 818 817 manifestPath[0 .. forcePrefix.length] == forcePrefix) … … 834 833 cmd[0..3] == "cd ") { 835 834 // change directories 836 char[][] comps = std.string.split(cmd); 835 char[][] comps = tango.text.Util.delimit(cmd, 836 [' ', '\t', '\n', '\r']); 837 837 if (comps.length != 2) continue; // FIXME: not valid 838 838 839 839 // change our directory 840 chdir(comps[1]);840 FileSystem.setDirectory(comps[1]); 841 841 842 842 } else if (cmd.length > 5 && … … 846 846 847 847 cmd = cmd[5..$]; 848 if ( std.string.tolower(getExt(cmd)) == "d") {848 if (tango.text.Ascii.toLower(getExt(cmd)) == "d") { 849 849 proc = new PStream(dsss_build ~ "-full -exec " ~ cmd); 850 850 } else { … … 858 858 try { 859 859 proc.read(readc); 860 } catch ( ReadException e) {860 } catch (Exception e) { 861 861 break; 862 862 } … … 894 894 // 2) divide <section>.<setting> 895 895 char[] section, setting; 896 int dotloc = find(sset, '.');897 if (dotloc == -1) {896 int dotloc = locate(sset, '.'); 897 if (dotloc == sset.length) { 898 898 section = ""; 899 899 setting = sset; … … 930 930 } 931 931 932 chdir(origcwd);932 FileSystem.setDirectory(origcwd); 933 933 934 934 return manifest; … … 965 965 if (!found) { 966 966 // didn't match anything! 967 writefln("%s is not described in the configuration file.", be);967 Cout(be)(" is not described in the configuration file.").newline; 968 968 exit(1); 969 969 } … … 1017 1017 1018 1018 // cut off each dot one-by-one 1019 while ((dotloc = rfind(soversion, '.')) != -1) {1019 while ((dotloc = locatePrior(soversion, '.')) != soversion.length) { 1020 1020 soversion = soversion[0..dotloc]; 1021 1021 res ~= ("lib" ~ target ~ ".so." ~ soversion); … … 1054 1054 1055 1055 if (!tested) { 1056 int ret = system(dsss_build ~ "-libs-safe");1056 int ret = hcf.process.system(dsss_build ~ "-libs-safe"); 1057 1057 safe = (ret == 0); 1058 1058 tested = true; … … 1070 1070 if (!tested) { 1071 1071 // ask dsss_build 1072 int ret = system(dsss_build ~ "-shlib-support");1072 int ret = hcf.process.system(dsss_build ~ "-shlib-support"); 1073 1073 1074 1074 supported = (ret == 0); … … 1091 1091 void copyInFile(char[] file, char[] prefix, char[] from = "") 1092 1092 { 1093 if (! exists(prefix)) {1094 writefln("+ making directory %s", prefix);1093 if (!(new FilePath(prefix)).exists()) { 1094 Cout("+ making directory ")(prefix).newline; 1095 1095 mkdirP(prefix); 1096 1096 } 1097 1097 1098 writefln("+ copying %s", file);1098 Cout("+ copying ")(file).newline; 1099 1099 version (Posix) { 1100 char[] target = prefix ~ std.path.sep~ file;1100 char[] target = prefix ~ FileConst.PathSeparatorChar ~ file; 1101 1101 1102 1102 // preserve permissions … … 1104 1104 1105 1105 // but then guarantee the permissions we made aren't too bad (ignore errors) 1106 system("chmod a+rX " ~ target ~ " 2> /dev/null");1106 hcf.process.system("chmod a+rX " ~ target ~ " 2> /dev/null"); 1107 1107 1108 1108 } else { 1109 copy(from ~ file, prefix ~ std.path.sep~ file);1109 copy(from ~ file, prefix ~ FileConst.PathSeparatorChar ~ file); 1110 1110 } 1111 1111 } … … 1136 1136 return ret; 1137 1137 } 1138 1139 /** Is this character alphanumeric? */ 1140 bool isalnum(char c) 1141 { 1142 if ((c >= 'a' && c <= 'z') || 1143 (c >= 'A' && c <= 'Z') || 1144 (c >= '0' && c <= '9')) 1145 return true; 1146 return false; 1147 }
