How can I use unqualified names? (Possibly hard or impossible?)

J

James Kanze

* James Kanze:
On Jul 26, 10:35 pm, "Alf P. Steinbach" <[email protected]>
wrote:
I've heard the name, but that's about it. I don't doubt
that I could learn them, if I had any reason to, but until
now, I've not had any reason to.
[snip]
In contrast it's trivial to write a typelist implementation
that provides basic functionality, and any C++ programmer
should be able to do so: any C++ programmer should be able
to just sit down and write it without any second thought.
Maybe. Given that all I know about it is the name, I can't
judge. I don't really even know what it does, exactly.
(I'm guessing that it's some sort of list of types, but I
don't really know what that means, or how it is used.)
Typelists were popularized by Andrei. I think he invented them
independently but they already had some history. What Andrei
did was to show how all the usual run time control structures
had analogs in template metaprogramming, and to build up from
that to a framework handling types just as for run time you
handle values.

If what he did was to show how all the usual run time control
structures had analogs in template metaprogramming, I think Todd
Veldhuizen and David Vandevoorde beat him to it. :)

If I understand what you're doing, at least in this case,
typelists are mainly a work-around for the absence of variadic
arguments for templates, which has been added to the next
version of the standard. (There's more to what you've written
than that, I know. But variadic arguments for templates and
macros would make it a lot, lot simpler, I think.)
 
M

Martin Eisenberg

Alf said:
What Andrei did was to show how all the usual run time control
structures had analogs in template metaprogramming, and to build
up from that to a framework handling types just as for run time
you handle values.

I believe that credit should go to Czarnecki and Eisenecker, whom
MC++D also references.


Martin
 
A

Alf P. Steinbach

* Martin Eisenberg:
I believe that credit should go to Czarnecki and Eisenecker, whom
MC++D also references.

As I wrote and you snipped, typelists already had some history.

The game of credit (and of snippage) is very silly.

I've never heard of Czarnecki and Eisenecker, and I doubt any reader here will
be helped by that reference. On the other hand, readers might find it useful to
know what Andrei did, in order to decide whether to buy that book. It also
contains a lot of generic implementations of patterns, which perhaps was its
main innovation, and at least a main reason for its popularity, but, due to the
game of credit etc. (uh oh, those wouldn't be /patterns/ anymore, bye GoF!),
goes to pains to point out that patterns cannot be generically implemented. :)


Cheers & hth.,

- Alf
 
A

Alf P. Steinbach

* Alf P. Steinbach:
Original problem: a pack of options that may contain a great many simple
numerical and bitset options (defined by external API), and that should
be (1) extensible for at least two levels, like class derivation, (2)
easy to define, (3) easily constructible specifying only those options
of interest, defaulting on the rest, (4) clean notation for accessing
options, with compile time checking, and (5) if possible as efficient as
possible access of options.

I extended the solution posted else-thread so that it now supports arbitrary
levels of extension (I've only tested with two levels, though, as shown below).

That amounted to removing two lines, and inserting two lines. :)

So, for those interested in trying it out, or commenting,


<code>
#include <boost/mpl/clear.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/pop_front.hpp>

namespace cppx { namespace typelist {

typedef boost::mpl::list<>::type Empty;

template< class TypeList >
struct InheritLinearly_
{
typedef typename boost::mpl::inherit_linearly<
TypeList,
boost::mpl::inherit said:
>::type Type;
};

template< class TypeList >
struct Car_
{
typedef typename boost::mpl::front< TypeList >::type Type;
};

template< class TypeList >
struct Cdr_
{
typedef typename boost::mpl::pop_front< TypeList >::type Type;
};

#define CPPX_TYPELIST_ ::boost::mpl::list

} } // namespace cppx::typelist

namespace cppx { namespace options {

template< class T, class UniqueIdType >
class Value_
{
private:
T myValue;

public:
Value_(): myValue() {}
Value_( T const& v ): myValue( v ) {}

T const& value() const { return myValue; }
void setValue( T const& v ) { myValue = v; }

operator T const& () const { return value(); }

Value_& operator=( T const& v )
{
setValue( v ); return *this;
}
};

class NoBase {};

template< class SetterResult, class TopBase >
class NoBase_InheritTemplatedSetters_: public TopBase {};

template<
class OptionTypes,
class SetterResult,
class TopBase,
template said:
class InheritTemplatedSetters_;

template<
class SetterResult,
class TopBase,
template said:
class InheritTemplatedSetters_<
cppx::typelist::Empty, SetterResult, TopBase, OptionSetter_
: public TopBase
{};

template<
class OptionTypes,
class SetterResult,
class TopBase,
template said:
class InheritTemplatedSetters_
: public OptionSetter_<
typename cppx::typelist::Car_<OptionTypes>::Type,
SetterResult,
InheritTemplatedSetters_<
typename cppx::typelist::Cdr_<OptionTypes>::Type,
SetterResult,
TopBase,
OptionSetter_
{};

#define CPPX_OPTION( name ) OptionValue_##name

#define CPPX_DEFINE_OPTIONSETTER( name, type ) \
template< class OptionValue, class SetterResult, class Base > \
class OptionSetter_; \
\
template< class SetterResult, class Base > \
class OptionSetter_<CPPX_OPTION( name ), SetterResult, Base> \
: public Base \
{ \
public: \
type const& name() const \
{ return CPPX_OPTION( name )::value(); } \
\
SetterResult& name( type const& value ) \
{ \
CPPX_OPTION( name )::setValue( value ); \
return static_cast<SetterResult&>( *this ); \
} \
};

#define CPPX_DEFINE_OPTION_( name, type ) \
typedef ::cppx::eek:ptions::Value_< \
type, struct UniqueIdTypeFor_##name \
> CPPX_OPTION( name ); \
CPPX_DEFINE_OPTIONSETTER( name, type )

#define CPPX_DEFINE_OPTIONV( name, type, defValue ) \
class CPPX_OPTION( name ) \
: public ::cppx::eek:ptions::Value_< \
type, struct UniqueIdTypeFor_##name \
{ \
typedef ::cppx::eek:ptions::Value_< \
type, struct UniqueIdTypeFor_##name \
> Base; \
public: \
CPPX_OPTION( name )(): Base( defValue ) {} \
CPPX_OPTION( name )( type const& v ): Base( v ) {} \
}; \
CPPX_DEFINE_OPTIONSETTER( name, type )

#define CPPX_DEFINE_VALUECLASS( name, base ) \
class name##_Values \
: public base \
, public ::cppx::typelist::InheritLinearly_< \
name##_OptionTypes \
>::Type \
{};

#define CPPX_DEFINE_TEMPLATED_SETTERS_INHERITANCE( name, base ) \
template< class SetterResult, class TopBase > \
class name##_InheritTemplatedSetters_ \
: public ::cppx::eek:ptions::InheritTemplatedSetters_< \
name##_OptionTypes, \
SetterResult, \
base##_InheritTemplatedSetters_< \
SetterResult, TopBase \
OptionSetter_ \
{};

#define CPPX_DEFINE_OPTIONCLASS( name, base ) \
class name \
: public name##_InheritTemplatedSetters_< \
name, \
name##_Values \
{};

#define CPPX_DEFINE_VTANDO( name, base ) \
CPPX_DEFINE_VALUECLASS( name, base ) \
CPPX_DEFINE_TEMPLATED_SETTERS_INHERITANCE( name, base ) \
CPPX_DEFINE_OPTIONCLASS( name, base )

#define CPPX_DEFINE_1OPTIONCLASS( name, base, option1 ) \
typedef CPPX_TYPELIST_< \
CPPX_OPTION( option1 ) \
> name##_OptionTypes; \
CPPX_DEFINE_VTANDO( name, base )

#define CPPX_DEFINE_2OPTIONCLASS( name, base, option1, option2 ) \
typedef CPPX_TYPELIST_< \
CPPX_OPTION( option1 ), \
CPPX_OPTION( option2 ) \
> name##_OptionTypes; \
CPPX_DEFINE_VTANDO( name, base )

} } // namespace cppx::eek:ptions


//------------------------ Usage:

#include <iostream>

namespace blahblah {
namespace reallyLongName {
namespace california {
struct desert
{
CPPX_DEFINE_OPTION_( x, double )
CPPX_DEFINE_OPTIONV( y, double, 12345 )
CPPX_DEFINE_2OPTIONCLASS( Pos2Options, cppx::eek:ptions::NoBase, x, y )
};
}}} // namespace blahblah::reallyLongName::california

namespace blahblah {
namespace reallyLongName {
namespace texas {
struct rose
{
CPPX_DEFINE_OPTION_( z, double )
CPPX_DEFINE_1OPTIONCLASS( Pos3Options, california::desert::pos2Options, z )
};
}}} // namespace blahblah::reallyLongName::texas

namespace blahblah {
namespace reallyLongName {
namespace washington {
struct dc
{
CPPX_DEFINE_OPTIONV( a, double, 666 )
CPPX_DEFINE_1OPTIONCLASS( Pos4Options, texas::rose::pos3Options, a )
};
}}} // namespace blahblah::reallyLongName::washington

struct UserClass1
{
typedef ::blahblah::reallyLongName::california::desert::pos2Options
Pos2Options;

UserClass1( Pos2Options const& options )
{
using namespace std;
cout << options.x() << endl;
cout << options.y() << endl;
}
};

struct UserClass2: UserClass1
{
typedef ::blahblah::reallyLongName::texas::rose::pos3Options
Pos3Options;

UserClass2( Pos3Options const& options )
: UserClass1( options )
{
using namespace std;
cout << std::endl;
cout << options.x() << endl;
cout << options.y() << endl;
cout << options.z() << endl;
}
};

struct UserClass3: UserClass2
{
typedef ::blahblah::reallyLongName::washington::dc::pos4Options
Pos4Options;

UserClass3( Pos4Options const& options )
: UserClass2( options )
{
using namespace std;
cout << std::endl;
cout << options.x() << endl;
cout << options.y() << endl;
cout << options.z() << endl;
cout << options.a() << endl;
}
};

int main()
{
using namespace std;
typedef UserClass3::pos4Options Pos4Options;
UserClass3( Pos4Options().x( 3.14 ).z( 42 ) );

Pos4Options o;
cout << endl;
cout << typeid(o).name() << endl;
cout << "x: " << typeid(o.x(6)).name() << endl;
cout << "y: " << typeid(o.y(6)).name() << endl;
cout << "z: " << typeid(o.z(6)).name() << endl;
cout << "a: " << typeid(o.a(6)).name() << endl;
}
</code>


Cheers, & thanks to James for nudge in direction of using member routines,

- Alf


PS: Disclaimer: I haven't moved those changes back to the app I'm using this in.
So perhaps there are Issues. The only issue I know (I chose not to support that)
is that a base class can't be specified via any other name than the original.
 
J

James Kanze

* Martin Eisenberg:
As I wrote and you snipped, typelists already had some history.
The game of credit (and of snippage) is very silly.
I've never heard of Czarnecki and Eisenecker, and I doubt any
reader here will be helped by that reference.

Why not? They *are* the authors of one of the original
reference works concerning meta-programming.
On the other hand, readers might find it useful to know what
Andrei did, in order to decide whether to buy that book. It
also contains a lot of generic implementations of patterns,
which perhaps was its main innovation, and at least a main
reason for its popularity,

It would be interesting to know why one book becomes popular,
and another not. Maybe Andrei is a better writer than some
others.

Todd Veldhuizen had shown that templates in C++ formed a Turing
complete language as early as 1995; from personal discussions
with David Vandevoorde, I believe that he was doing similar work
at about the same time. In this regard, Andrei is more or less
a latecomer to the field. But perhaps is book presents a more
easily understandable synthesis than earlier works.
 
A

Alf P. Steinbach

* James Kanze:
* James Kanze:
As for maintenance: the input file for my AWK script looks
something like:
x double 3.14159
y int 42
# ...
It's hard for me to imagine anything easier to maintain---to add
a new attribute, it's one line. (In the form I actually use,
the AWK script is about twice as long, and the input has the
form:
[Option] # the class name...
x double 3.14159
y int 42
# ...
The results are two files, Option.hh and Option.cc.)
With C++ you add one line and modify the line that defines the
class, e.g., with JK as James Kanze macro prefix:
JK_DEF_OPT( x, 3.14159 )
JK_DEF_OPT( y, int, 42 )
JK_DEF_OPT_CLS_2( Option, nobase, x, y )
The result is generated code at the point of those macro
invocations, no extra files to care about and manage, no
generated files to remember to not modify.

You're still mentionning x and y twice:). So you have to
insert one line, and modify another; in my version (both macros
and AWK), you just insert a single line.

I thought about it and I think you're right. Especially with respect to later
switching over to some other option class generator it's better to just have a
single macro. So I created wrapper macros, so that I now write e.g.

CPPX_DEFINE_2OPTIONCLASS(
Params, Base::params,
is3State, bool, false,
isAuto, bool, true
)

Anyway: I'm supposing that the _2 in the last line specifies the
number of attributes. IMHO, that's error prone, but get rid of
that, and I think I could buy it.

I don't think one can get rid of that number without variadic macros, which are
currently non-standard, or perhaps Boost-like macro magic, which is
incomprehensible, counter-intuitive and probably would require supporing macro
definitions around each usage, making the notation more awkward.

I think the number, writing "2" or "3" or whatever, is very low cost.

If you use the wrong number you just get compilation error.


Cheers,

- Alf
 
J

Jerry Coffin

(e-mail address removed)>, (e-mail address removed)
says...

[ ... ]
I know that. I was using a Unix-like tool kit under MS-DOS in
the late 1908's. But I'm hardly a typical Windows user; I was
wondering what typical Windows developers use.

That's a tougher question -- I'm honestly not sure about typical
developers. Personally, I use a rather hodgepodge collection of
"stuff". In fact, it was only quite recently (with a switch to 64-bit
Windows) that I quit using some utilities that were written for MS-
DOS...

[ ... ]
Yes. I mentioned CygWin more as a placeholder for any Unix-like
tool kit, rather than with the idea of CygWin, and only CygWin.
I'm aware of at least three others: UWin, MSys and MKS (the
latter commercial, and rather expensive---although it wasn't too
expensive in the MS-DOS days), and I don't doubt that there are
others. (I'm still looking for one which integrates well,
however. Most of them seem to go out of their way to make it
difficult to use tools other than those in the toolset. And if
I'm running Windows, and not Linux, on a machine, it's because I
want to use the Windows tools when appropriate.)

That's where I see a substantial difference between the set I
mentioned and something like Cygwin. It at least attempts to make
some concessions to looking and acting a little bit like it was
written for Windows. Cygwin, at least from my viewpoint, simply
attempts to act like Windows is just a rather strange version of Unix
that takes more than the usual porting effort -- but that it should
still do its best to BE Unix, regardless of the oddities of the
kernel on which it's running.
 
J

James Kanze

(e-mail address removed)>, (e-mail address removed)
says...
[ ... ]
That's where I see a substantial difference between the set I
mentioned and something like Cygwin. It at least attempts to
make some concessions to looking and acting a little bit like
it was written for Windows. Cygwin, at least from my
viewpoint, simply attempts to act like Windows is just a
rather strange version of Unix that takes more than the usual
porting effort -- but that it should still do its best to BE
Unix, regardless of the oddities of the kernel on which it's
running.

Exactly. And that's also a problem with most of the other
Unix-like tool kits I've used. Where as, if I wanted Unix, I'd
use Linux, and drop Windows entirely. What I want is Windows,
but with most of the tools I'm familiar with. I recognize that
they will have to work somewhat differently---it wouldn't bother
me too much if they adopted the / for options, for example,
rather than the -, and used \ for the directory separator (with
some other character---whatever is usual under Windows---for the
escape). Handling white space in filenames is a bit trickier,
and might require some compromises, but for the rest, there's no
real reason to pretend you're under Unix when you're not.
 
J

James Kanze

(e-mail address removed)>, (e-mail address removed)
says...

[...]
That's where I see a substantial difference between the set I
mentioned and something like Cygwin. It at least attempts to
make some concessions to looking and acting a little bit like
it was written for Windows.

I've looked a little bit more at it. I don't see a shell.
Using Unix-like tools means linking them together---the shell is
the glue. And the default Windows command interpreter (what
executes .bat files) is pretty weak. What do Windows users use
for this?
 
J

Jerry Coffin

(e-mail address removed)>, (e-mail address removed)
says...
[...]
That's where I see a substantial difference between the set I
mentioned and something like Cygwin. It at least attempts to
make some concessions to looking and acting a little bit like
it was written for Windows.

I've looked a little bit more at it. I don't see a shell.
Using Unix-like tools means linking them together---the shell is
the glue. And the default Windows command interpreter (what
executes .bat files) is pretty weak. What do Windows users use
for this?

It does actually include an sh.exe, but I'll admit I've never used it
(I haven't looked carefully to figure out why, but with Windows'
"Data Execution Prevention" turned it, it crashes quite
consistently).

The cmd.exe that's been used for quite a while isn't nearly as
"weak" as command.com used to be. Microsoft also has what they call
the Windows PowerShell, which is a free download from:

http://www.microsoft.com/windowsserver2003/technologies/management/po
wershell/download.mspx

This has quite a different character from the typical Unix shells
though, so even at best it'll take a while to get used to it.

Of course, there are quite a few other shells around for Windows as
well, but I haven't used any of them enough (at least recently) to
say much about them.
 
J

Jerry Coffin

(e-mail address removed)>, (e-mail address removed)
says...

[ ... ]
Exactly. And that's also a problem with most of the other
Unix-like tool kits I've used. Where as, if I wanted Unix, I'd
use Linux, and drop Windows entirely. What I want is Windows,
but with most of the tools I'm familiar with. I recognize that
they will have to work somewhat differently---it wouldn't bother
me too much if they adopted the / for options, for example,
rather than the -, and used \ for the directory separator (with
some other character---whatever is usual under Windows---for the
escape). Handling white space in filenames is a bit trickier,
and might require some compromises, but for the rest, there's no
real reason to pretend you're under Unix when you're not.

Windows normally leaves almost all parsing of command lines to the
individual programs, so there's almost never any need for escaping
things. White space in file names (or whatever) is normally just
handled by enclosing the string in double quotes.

That brings up the one situation where escaping is needed (at least
semi-routinely): if you want to include a quote in a quoted string,
you normally escape the included quote with a backslash.
 
G

Gerhard Fiedler

James said:
I've looked a little bit more at it. I don't see a shell. Using
Unix-like tools means linking them together---the shell is the glue.
And the default Windows command interpreter (what executes .bat
files) is pretty weak. What do Windows users use for this?

Typically cmd.exe; as Jerry says, it's not that weak, it's just that
most people don't know how to use it :)

(On a side note: If you want to surprise a typical Windows "power" user,
bring up a listing of the .exe files in the Windows system32 directory.
Most are command line tools, and many don't know a tenth of it.)

Besides what Jerry wrote, there are native builds of many Unix shells.
If you already know how to use them, this may be the way for you.

There's also 4NT from jpsoft.com, which is sort of a more powerful
cmd.exe, backwards compatible. But their extensions are custom and not
commonly known or used.

Also note that many Windows command line tools use or accept the dash as
option separator and the forward slash as path separator. (AFAIK all of
the Win32 API accepts the forward slash as path separator.)

Gerhard
 
J

James Kanze

(e-mail address removed)>, (e-mail address removed)
says...
[ ... ]
Exactly. And that's also a problem with most of the other
Unix-like tool kits I've used. Where as, if I wanted Unix,
I'd use Linux, and drop Windows entirely. What I want is
Windows, but with most of the tools I'm familiar with. I
recognize that they will have to work somewhat
differently---it wouldn't bother me too much if they adopted
the / for options, for example, rather than the -, and used
\ for the directory separator (with some other
character---whatever is usual under Windows---for the
escape). Handling white space in filenames is a bit
trickier, and might require some compromises, but for the
rest, there's no real reason to pretend you're under Unix
when you're not.
Windows normally leaves almost all parsing of command lines to
the individual programs, so there's almost never any need for
escaping things. White space in file names (or whatever) is
normally just handled by enclosing the string in double
quotes.

And filenames can't contain quotes:).

I rather like the Microsoft documentation in this regard
(http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx):
"Use almost any character in the current code page for a name
[...] except the following [...] -- Any other character that the
target file system does not allow." Very informative:). And
oh so useful---what is the "current code page" for a program
running as a demon (what Unix would call a cron job)? (But in a
certain sense, what more can they say? The problem is that the
filename conventions depend largely on the file server, and not
on the OS you're running under. And with SMB, you can use
pretty much anything as a server.)
That brings up the one situation where escaping is needed (at
least semi-routinely): if you want to include a quote in a
quoted string, you normally escape the included quote with a
backslash.

Which would be ambiguous in a filename---are you escaping the
quote, or is it a directory separator? Which is probably why
filenames can't contain quotes.

Actually, they probably are right in forbidding the usual
meta-characters ('<', '>', ':', '"', '/', '\\', '|', '?' and
'*') in filenames. And doing so explicitly, and expecting all
programs to handle anything else. Under Unix, the only
characters forbidden are '/' and '\0', but most programs will
mishandle a lot of others. (Although the real problem is
probably more because the shell does so much. Once you start
passing parameters from one shell to a subscript, etc., with
each sub-shell stripping out it's quotes and escapes, you
quickly loose track of how many escapes you need. Add to that
that there are about a dozen different shells, each with its own
particularities, and there are often subtle differences between
different versions or implementations of the same shell, and
it's almost enough to make you want to switch to perl:).)
 
J

James Kanze

Typically cmd.exe; as Jerry says, it's not that weak, it's
just that most people don't know how to use it :)

OK. It sounds like something I'll have to learn. (Starting in
September, I'll be working almost exclusively under Windows.)
(On a side note: If you want to surprise a typical Windows
"power" user, bring up a listing of the .exe files in the
Windows system32 directory. Most are command line tools, and
many don't know a tenth of it.)

ls /usr/bin will have the same effect on Unix users. Under
Linux (which for some stupid reason puts everything in
/usr/bin), even I don't know most of them (and I'm pretty much a
power user under Unix). Some I can guess, more or less, but
others... (a2p was always Ascii to Postscript---something to
output program sources to a Postscript printer. But the man
page on my current Linux says it's Awk to Perl. And I needed
the man pages to learn that lz is to list gzipped files, and js
to start Rhino, whatever that is. Unix naming traditions aren't
always obvious to outsiders, and sometimes not even to insiders
like myself.)
Besides what Jerry wrote, there are native builds of many Unix
shells. If you already know how to use them, this may be the
way for you.

It depends. I'm a team player, and if I'm writing scripts, my
collegues have to be able to understand them. Which means I
have to adapt to their language (both natural and programming),
and not vice versa.
There's also 4NT from jpsoft.com, which is sort of a more
powerful cmd.exe, backwards compatible. But their extensions
are custom and not commonly known or used.
Also note that many Windows command line tools use or accept
the dash as option separator and the forward slash as path
separator. (AFAIK all of the Win32 API accepts the forward
slash as path separator.)

Luckily:). At home, I'm using MSys (I wanted to try it, and
haven't had time yet to get rid of it, and install something
else), and its implementation of the shell converts any word
starting with a / to it's mapping of the root directory,
something starting with c:... One of my first attempts was "cl
/help", and the error message about a missing file rather
surprised me. And my libraries (which I use to parse argv and
argc) adapt to the local conventions---I had to modify them so
that they'd accept more than one character as the option
id. (Accepting the forward slash is a bit more fundamental,
since it allows avoiding the C string escape character, which is
also wide spread as an escape character in other contexts.)
 
J

James Kanze

Typically cmd.exe; as Jerry says, it's not that weak, it's just that
most people don't know how to use it :)

One last question for you and Jerry (although I know this isn't
really the right place): could you recommend a good book about
this shell? (I'll be visiting the local technical bookshop
tomorrow afternoon, and would buy it immediately if they have
it.)
 
J

Jerry Coffin

(e-mail address removed)>, (e-mail address removed)
says...
One last question for you and Jerry (although I know this isn't
really the right place): could you recommend a good book about
this shell? (I'll be visiting the local technical bookshop
tomorrow afternoon, and would buy it immediately if they have
it.)

There are lots of them, but I can't honestly recommend any of them.
I'd puzzled out most of what I know from the MSDN documentation (and
such) long before most of the books had been written, so I've never
really looked at them. In all honesty, I probably should take a look;
there are undoubtedly gaping holes in what I know on the subject...
 
G

Gerhard Fiedler

Jerry said:
There are lots of them, but I can't honestly recommend any of them.
I'd puzzled out most of what I know from the MSDN documentation (and
such) long before most of the books had been written, so I've never
really looked at them.

A long time ago I bought the "Windows 2000 Commands Pocket Reference"
(O'Reilly, http://oreilly.com/catalog/9780596001483/ -- they now also
have newer XP and Vista revisions). Inexpensive and useful if you like
paper. Otherwise there's the online help and your favorite search engine
:)

One quick thing: in a cmd.exe window click on the application icon and
select properties (or select the properties of a shortcut to a command
line program, like cmd.exe) and edit to your liking. If you do command
line work, the standard window is probably too small, and possibly
doesn't have the right colors.

Gerhard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top