"Charlie Gordon" <[email protected]> wrote: (14/04/2009 11:28)
>I don't think this is going in the right direction: >- Command line arguments should not be changed >- Why restrict this behaviour to full paths with a drive letter ? >- instead of matching filename extensions in a case independent manner ? > You miss the point. Look at the GCC specs for commandlines, as I was told to do. How do you propose to handle .s and .S on Windows? The patch would bloat uncontrollably if any attempt was made to solve this that way, and code for that exists already, the written arguments' case is taken literally by TCC. As TCC tends to use lower case commands and filespecs, except where upper case is required, the simplest thing to do is make the DOS paths lower case, while testing for existing lowercase to disable the patch if any is found. I'm a newcomer to C, and TCC, yet was urged to jump in the deep end and suggest a solution! So that is what I did, and I had to figure out the best placement of the patch for myself. And it works. If you want to specify an exact case for an extension, you can. All this patch is meant to do is prevent DOS's all-caps habits from breaking filespecs as normally expected by TCC, while being irrelevant to non-windows users, and being easily bypassed by Windows users. >Also more importantly, do not pass char arguments to tolower/toupper and >islower/isupper functions. 'char' may be signed whereas these functions >expect >an int parameter with a value among those of type unsigned char or EOF. >The argument to these functions should at least be cast to (unsigned char), >and so should the value you compare their result to. > >> if (*p != toupper(*p)) > >if ((unsigned char)*p != toupper((unsigned char)*p) > >> *p = tolower(*p); > >*p = tolower((unsigned char)*p); > >If you don't like the resulting code (quite ugly in my opinion), >you should use a temporary variable: > >int c = (unsigned char)*p; >if (toupper(c) != c) ... > >*p = tolower(c); > I went with advice given, as best I could. As the variable isn't assigned any negative values it's not going to be an issue, as I guess was why I was advised as I was. Actually I forgot the unsigned char bit but even so, it compiled without error or warning and it worked. Not sure why you put all those "unsigned char"s in there like that, or want an extra variable, I just tried "unsigned char *p;" as the initial declaration and it worked fine. (See Dave Dodge's mail in the earlier thread, he does the same). >But all things considered, I still argue that the correct approach to the >problem >you are trying to fix, is to perform case insensitive matching on filename >extensions >wherever these occur. A simple way to do this is to identify all >occurrences of such >matching and use call function with a platform dependent implementation. > No, logically it's the same thing. Though while I could have forced case only on the TEST value that made no sense in practise, as DOS already does force case in shortname paths! I would have not have solved the problem by doing the same thing, or its inverse. And to do so goes right against the GCC specs that TCC is emulating. The correct way is to force lower case for this singular instance to reverse Windows' forced upper case. Keep it simple. If further refined exceptions must be made, add them. For example, as .c requires preprocessing, while .S as opposed to .s also requires it for assembler code, it might be worth adding a line to re-forece the singular extension .s to upper case on Windows to invoke the right response from TCC. But in the interests of keeping code size down, it seems wise to limit the patch's behaviour to a simple easily predicted action that is extremely easy to over-ride in the extremely limited situations where it can even act at all. :) This I have done. _______________________________________________ Tinycc-devel mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/tinycc-devel
