Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2003-09

building a command string

5 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

DONALD PEDDER

Hi all,

The previous compiler I used didn't have Exec or a way to get parameters, so I am currently fooling around with these new toys (needless to say, my old programs were pretty inflexible, with hard-coded filenames, etc.).
In particular, I am trying to build and execute a DOS command using a filename given as a parameter (as opposed to a hard-coded filename) which makes a backup copy of a file before I start fooling with the original file (in case of a program crash part-way through). I know someone will want to tell me I can write the program to do that directly, rather than using DOS, but I'm trying to learn how not to re-invent the wheel. :-) i.e. I'm trying to learn how to use the functionality that already exists there in the OS (copy just being one of the many commands available). I've got my program working with a hard-coded filename, I just haven't quite got it sorted with passing a filename to it.

Below is the current state of my code. I am getting "invalid TSS" at the point I have noted. I don't even know what a "TSS" is! I guess it's something to do with strings (I haven't used strings much before either - something else lacking in my previous compilers). I searched the doco, but couldn't find what I was looking for.

I originally tried this with paramstr rather than argv, but changed due to type mis-matches. I sorted out the types now, but there's obviously some piece of knowledge I am missing about argv/strings that is causing this not to work.

If someone can tell me how to fix the following, or alternatively tell me a better way to do this, that would be appreciated. Thanks.

I am currently using "testfile" as the parameter (hence the "dir test*").

Exec(GetEnv('COMSPEC'),'/c dir test*');
tempstr1:='/c copy';
tempstr2:=' ';
tempstr:=strcat(tempstr1,tempstr2);
writeln(tempstr,'*');
tempstr1:=tempstr;
tempstr2:=argv[1];
tempstr:=strcat(tempstr1,tempstr2);
writeln(tempstr,'*');
tempstr1:=tempstr;                         < program
tempstr2:=' ';                             < crashes
tempstr:=strcat(tempstr1,tempstr2);        < here
writeln(tempstr,'*');
tempstr1:=tempstr;
tempstr2:=argv[1];
tempstr:=strcat(tempstr1,tempstr2);
writeln(tempstr,'*');
tempstr1:=tempstr;
tempstr2:='.bak /v';
tempstr:=strcat(tempstr1,tempstr2);
writeln(tempstr,'*');
Exec(GetEnv('COMSPEC'),tempstr);
Exec(GetEnv('COMSPEC'),'/c dir test*');
Nikolay Nikolov
to DONALD PEDDER
DONALD PEDDER wrote 6 lines
Below is the current state of my code. I am getting "invalid TSS" at the point I have noted. I don't even know what a "TSS" is! I guess it's something to do with strings (I haven't used strings much before either - something else lacking in my previous compilers). I searched the doco, but couldn't find what I was looking for.

TSS has nothing to do with strings. TSS = Task Segment Selector. It's a structure used by the intel cpus in protected mode. The message "invalid TSS" is probably printed by the DPMI host. (usually cwsdpmi.exe, if you are using plain DOS and not a Windows DOS box.) Probably means that you messed things up in memory, which can happen quite often when using pointers and C-style "strings", etc...

Show quoted text 24 lines
Exec(GetEnv('COMSPEC'),'/c dir test*'); tempstr1:='/c copy'; tempstr2:=' '; tempstr:=strcat(tempstr1,tempstr2); writeln(tempstr,'*'); tempstr1:=tempstr; tempstr2:=argv[1]; tempstr:=strcat(tempstr1,tempstr2); writeln(tempstr,'*'); tempstr1:=tempstr; < program tempstr2:=' '; < crashes tempstr:=strcat(tempstr1,tempstr2); < here writeln(tempstr,'*'); tempstr1:=tempstr; tempstr2:=argv[1]; tempstr:=strcat(tempstr1,tempstr2); writeln(tempstr,'*'); tempstr1:=tempstr; tempstr2:='.bak /v'; tempstr:=strcat(tempstr1,tempstr2); writeln(tempstr,'*'); Exec(GetEnv('COMSPEC'),tempstr); Exec(GetEnv('COMSPEC'),'/c dir test*');
How about 1 line of code :-)
Exec(GetEnv('COMSPEC'), '/c copy '+ParamStr(1)+' '+ParamStr(1)+'.bak /v');

There's no need to even use Pascal for this kind of thing. You could use a .bat file:
copy %1 %1.bak /v

DONALD PEDDER
to Nikolay Nikolov
Exec(GetEnv('COMSPEC'), '/c copy '+ParamStr(1)+' '+ParamStr(1)+'.bak /v');

Now THIS is what I needed to know! Thank you. :-) I originally tried a writeln kind of syntax - '/c copy ',paramstr(1),' ',paramstr(1),'.bak /v'
- but that didn't work, hence my other attempts to build the string. I didn't know about the syntax you've told me - all I have to do is use a plus instead of a comma.
What other circumstances would I use this syntax? Is it like a back-apostrophe in Unix - evaluate this part before the rest?

There's no need to even use Pascal for this kind of thing. You could use a .bat file: copy %1 %1.bak /v

Right, and with my old programs - which had hard-coded filenames - that's what I had to do. I had to use a batch file to rename the appropriate files to the names the program was expecting, and then rename them again at the end. What I'm fiddling with now is moving that functionality into the program, so that I have JUST an exe, instead of an exe and a bat (this is one of the cool things about FPC). As I said, I know the functionality is there in the compiler for me to PROGRAM that stuff in, but it's much easier if I can just directly transfer what's in my bat file into the program and substitute paramstr as appropriate - that way I'm not re-inventing the wheel.

thanks,
DONALD.

E-mail -
BIG DON's Home-page - http://jedi.apana.org.au/~jims_son Pedder Passer Rating - http://jedi.apana.org.au/~jims_son/PPR AusNFL mailing-list - http://jedi.apana.org.au/mailman/listinfo/ausnfl

"What I always wanted is to be accepted, not understood" - MAN RAY

Nikolay Nikolov
to DONALD PEDDER
DONALD PEDDER wrote 12 lines
>Exec(GetEnv('COMSPEC'), '/c copy '+ParamStr(1)+' '+ParamStr(1)+'.bak /v'); > > Now THIS is what I needed to know! Thank you. :-) I originally tried a writeln kind of syntax - '/c copy ',paramstr(1),' ',paramstr(1),'.bak /v' - but that didn't work, hence my other attempts to build the string. I didn't know about the syntax you've told me - all I have to do is use a plus instead of a comma. What other circumstances would I use this syntax? Is it like a back-apostrophe in Unix - evaluate this part before the rest?

The plus concatenates strings, the comma separates procedure/function arguments. Write/writeln/read/readln accept variable number of arguments (due to compiler magic) so you can use the comma with it. But other procedures and functions accept only fixed number of arguments, e.g. Exec needs exactly 2 strings. (this isn't always the case, due to procedure/function overloading and the 'array of const' feature, but don't bother with that, for now)

Basically you can always do this:
  Writeln('Hello, ' + 'world!');
  Writeln('Hello, ', 'world!');
and they do the same thing.

Exec wants exactly two strings as parameters. In this case:

Exec(GetEnv('COMSPEC'), '/c copy '+ParamStr(1)+' '+ParamStr(1)+'.bak /v');

the first is

GetEnv('COMSPEC')

the second is

'/c copy '+ParamStr(1)+' '+ParamStr(1)+'.bak /v'

and they're separated by a comma, that's all. Writeln style procedures accept variable number of parameters (i.e. variable number of things separated by commas).

P.S. find a good book about pascal programming and learn how to use strings, they're cool. (And they don't exist in C) :)

DONALD PEDDER
to Nikolay Nikolov
The plus concatenates strings,

Okay, I see.

Basically you can always do this: Writeln('Hello, ' + 'world!'); Writeln('Hello, ', 'world!'); and they do the same thing.

I don't think I've ever seen the former. This is useful stuff to know! :-)

P.S. find a good book about pascal programming and learn how to use strings, they're cool. (And they don't exist in C) :)

Don't mention the C-word around me! ;-)

I have a Pascal book, but it only covers Standard Pascal, plus brief mention of some of the common extensions. Until I got the FPC, all I had was the standard stuff. I'm really enjoying having the extra flexibility - parameter passing, accessing the OS, strings, etc. (but it takes a little while to learn how to use the new toys).

thanks,
dp.