Sign in Join

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

Mailing lists / fpc-pascal / 2002-03

Special characters II

16 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

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

Bernhard Steffen

[...]

Show quoted text 5 lines
Codepages 437 and 850 are the DOS characters used in a command-shell window. Codepage ISO-8859-1 is the Windows character set used in Windows GUI applications. You can get into trouble if you use a Windows GUI editor for source code for applications that will run in a command-shell window, or vice versa.

[...]

I have a problem which seems to be related to this:

- I'm listing the directory (FindFirst/FindNext), doing something to the files and displaying the filename

- certain file names (those with special characters in it, like umlauts etc.) get displayed wrong (scrambled characters) - I guess this is due to codepage differences between GUI & console mode

- sometimes, I can't even access those files (assign/reset), using the filenames I got from FindFirst/FindNext
(no network / no files locked)

Although this is mostly a cosmetic bug, is there a way to fix it, like changing the codepage from within the program (no user interaction / configuration required)?

TIA
Bernhard

Michael Van Canneyt
to Bernhard Steffen
Bernhard Steffen wrote 24 lines
[...] > Codepages 437 and 850 are the DOS characters used in a command-shell > window. Codepage ISO-8859-1 is the Windows character set used in > Windows GUI applications. You can get into trouble if you use a > Windows GUI editor for source code for applications that will run > in a command-shell window, or vice versa. [...] I have a problem which seems to be related to this: - I'm listing the directory (FindFirst/FindNext), doing something to the files and displaying the filename - certain file names (those with special characters in it, like umlauts etc.) get displayed wrong (scrambled characters) - I guess this is due to codepage differences between GUI & console mode - sometimes, I can't even access those files (assign/reset), using the filenames I got from FindFirst/FindNext (no network / no files locked) Although this is mostly a cosmetic bug, is there a way to fix it, like changing the codepage from within the program (no user interaction / configuration required)?

Try using the CharToOEM function from the Windows unit. This will convert a windows string to a format
suitable for the console display.

This will of course not work from a go32v2 program, only from native Win32 programs.

Michael.

Bernhard Steffen
Try using the CharToOEM function from the Windows unit. This will convert a windows string to a format suitable for the console display.

That did the trick. Thanks!

This will of course not work from a go32v2 program, only from native Win32 programs.

no problem, since this program will be compiled for Win32 only

Bernhard

ron wilson
to Michael Van Canneyt: Try using the CharToOEM function from the Windows unit. This will convert a windows…

hi everyone!

i'm modifying a lexer for use in my telnet game proxy and i need to move the following variables into a type record so that i pass it as a variable and manage multiple telnet streams with the same lexer code. the current code uses globals (yuk).

yyinput, yyoutput : Text; (* input and output file *) yyline : String; (* current input line *) yylineno, yycolno : Integer; (* current input position *) yytext : String; (* matched text (should be considered r/o) *)
yyleng : Byte (* length of matched text *)

      absolute yytext;

the problem is that when i do this:

  type
    tyyvars = record
      yyinput, yyoutput : Text;        (* input and output file *)
      yyline            : String;      (* current input line *)
      yylineno, yycolno : Integer;     (* current input position *)
      yytext            : String;      (* matched text (should be considered

r/o) *)
yyleng : Byte (* length of matched text *)

        absolute yytext;
    end;

i get the following error:
Fatal: Syntax error, ; expected but identifier ABSOLUTE found

i'm still re-learning pascal and i dont recall what the identifer ABSOLUTE is for. i can't seem to find any documentation on the net that can tell me what it does. if i remove the absolute,

      yyleng            : Byte;

it compiles fine, but gives a range check error on execution. i think the problem is here. what function does the absolute identifier serve? what does the reference back to yytext mean? how can i repair the code? i'm using turbo pascal lex/yacc, which also works with freepascal: http://www.musikwissenschaft.uni-mainz.de/~ag/tply/tply.html sure, a lexer may be overkill, but its making my life a lot easier!

thanks in advance,

ron wilson.

ron wilson
to ron wilson

ok - i found some help on this, but its not solving my problem.

----- paste from
http://members.tripodnet.nl/electrickery/comp/tp30/tp30_22.html ----- Absolute may also be used to declare a variable "on top" of another variable, i.e. that a variable should start at the same address as another variable. When absolute is followed by the variable (or parameter) identifier, the new variable will start at the address of that variable (or parameter).

Example:

var
Str: string[32];
StrLen: Byte absolute Str;

The above declaration specifies that the variable StrLen should start at the same address as the variable Str, and since the first byte of a string variable gives the length of the string, StrLen will contain the length of Str.
----- end paste -----

so in my application, yyleng is referencing the length of the string, yytext, by using the absolute identifier. i thought i could change all references to yyleng to length(yytext), but the lexer often assigns yyleng manually (ugh!), e.g. yyleng:=n; OR inc(yyleng);.

ron wilson.

Earlier message 57 lines
-----Original Message----- From: Behalf Of ron wilson Sent: Monday, March 25, 2002 07:57 PM To: Subject: [fpc-pascal]absolute identifier hi everyone! i'm modifying a lexer for use in my telnet game proxy and i need to move the following variables into a type record so that i pass it as a variable and manage multiple telnet streams with the same lexer code. the current code uses globals (yuk). yyinput, yyoutput : Text; (* input and output file *) yyline : String; (* current input line *) yylineno, yycolno : Integer; (* current input position *) yytext : String; (* matched text (should be considered r/o) *) yyleng : Byte (* length of matched text *) absolute yytext; the problem is that when i do this: type tyyvars = record yyinput, yyoutput : Text; (* input and output file *) yyline : String; (* current input line *) yylineno, yycolno : Integer; (* current input position *) yytext : String; (* matched text (should be considered r/o) *) yyleng : Byte (* length of matched text *) absolute yytext; end; i get the following error: Fatal: Syntax error, ; expected but identifier ABSOLUTE found i'm still re-learning pascal and i dont recall what the identifer ABSOLUTE is for. i can't seem to find any documentation on the net that can tell me what it does. if i remove the absolute, yyleng : Byte; it compiles fine, but gives a range check error on execution. i think the problem is here. what function does the absolute identifier serve? what does the reference back to yytext mean? how can i repair the code? i'm using turbo pascal lex/yacc, which also works with freepascal: http://www.musikwissenschaft.uni-mainz.de/~ag/tply/tply.html sure, a lexer may be overkill, but its making my life a lot easier! thanks in advance, ron wilson.
Full_Name
to ron wilson: hi everyone! i'm modifying a lexer for use in my telnet game proxy and i need to move the…

Quoting ron wilson :

Show quoted text 14 lines
type tyyvars = record yyinput, yyoutput : Text; (* input and output file *) yyline : String; (* current input line *) yylineno, yycolno : Integer; (* current input position *) yytext : String; (* matched text (should be considered r/o) *) yyleng : Byte (* length of matched text *) absolute yytext; end; i get the following error: Fatal: Syntax error, ; expected but identifier ABSOLUTE found

This relies on two things. 1: you are using Pascal strings (255 chars, first char (position 0) is length of string) and 2: that the address in memory of yytext will be constant, hence globals. This is never going to work nicely, but a call to 'length(yytext);' gives the same value.

You could write a routine to do something with this info:

procedure populateyyvarsdata(var data: tyyvars);
begin
  data.yyleng := length(yytext);
end;

You could write this better as a class :

   type
     tyyvars = class(TPersistent)
     private
       fyytext            : String;
     public
       yyinput, yyoutput : Text;        (* input and output file *)
       yyline            : String;      (* current input line *)
       yylineno, yycolno : Integer;     (* current input position *)
       property yyleng : integer read getyyleng;
       property yytext : string read getyytext;
     end;

...

function getyyleng: integer;
begin
  result := length(fyytext);
end;
function getyytext: string;
begin
  result := fyytext;
end;

...

Because TPersistent is streamable, you should be able to pass it about as text. (ObjectBinaryToText and ObjectTextToBinary in Delphi.)

Just a thought anyways,

Matt

"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music." Kristian Wilson, Nintendo, Inc, 1989 -----BEGIN GEEK CODE BLOCK----- Version: 3.12 GCS d? s+++:+ a- C++ UL+ P L++ E---- W- N+ o+ K- w O- M V PS PE-- Y PGP- t- 5-- X- R- tv+ b+ DI++ D+ G e++ h--- r+++ y+++ ------END GEEK CODE BLOCK------
the reverend
to Full_Name

thanks for the help. i got it to work last night by using length(yytext) and removing all references to yyleng. any time the original code assigned yyleng:=n, i replaced with setlength(yytext,n). the code works fine. the only thing that is lost in function is the easy access to yyleng, but that's not really a great loss i don't think. i shouldn't be able to notice much of a performance hit.

the reverend
(: the goodguys :)
icq 83250263
http://thereverend.coastgames.com/tradewars/

Earlier message 91 lines
-----Original Message----- From: Behalf Of Full_Name Sent: Tuesday, March 26, 2002 4:49 AM To: Subject: Re: [fpc-pascal]absolute identifier Quoting ron wilson : > type > tyyvars = record > yyinput, yyoutput : Text; (* input and output file *) > yyline : String; (* current input line *) > yylineno, yycolno : Integer; (* current input position *) > yytext : String; (* matched text (should be > considered > r/o) *) > yyleng : Byte (* length of matched text *) > absolute yytext; > end; > > i get the following error: > Fatal: Syntax error, ; expected but identifier ABSOLUTE found This relies on two things. 1: you are using Pascal strings (255 chars, first char (position 0) is length of string) and 2: that the address in memory of yytext will be constant, hence globals. This is never going to work nicely, but a call to 'length(yytext);' gives the same value. You could write a routine to do something with this info: procedure populateyyvarsdata(var data: tyyvars); begin data.yyleng := length(yytext); end; You could write this better as a class : type tyyvars = class(TPersistent) private fyytext : String; public yyinput, yyoutput : Text; (* input and output file *) yyline : String; (* current input line *) yylineno, yycolno : Integer; (* current input position *) property yyleng : integer read getyyleng; property yytext : string read getyytext; end; ... function getyyleng: integer; begin result := length(fyytext); end; function getyytext: string; begin result := fyytext; end; ... Because TPersistent is streamable, you should be able to pass it about as text. (ObjectBinaryToText and ObjectTextToBinary in Delphi.) Just a thought anyways, Matt -- "Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music." Kristian Wilson, Nintendo, Inc, 1989 -----BEGIN GEEK CODE BLOCK----- Version: 3.12 GCS d? s+++:+ a- C++ UL+ P L++ E---- W- N+ o+ K- w O- M V PS PE-- Y PGP- t- 5-- X- R- tv+ b+ DI++ D+ G e++ h--- r+++ y+++ ------END GEEK CODE BLOCK------
Jonas Maebe
to ron wilson: ok - i found some help on this, but its not solving my problem. ----- paste from…
ron wilson wrote 5 lines
so in my application, yyleng is referencing the length of the string, yytext, by using the absolute identifier. i thought i could change all references to yyleng to length(yytext), but the lexer often assigns yyleng manually (ugh!), e.g. yyleng:=n; OR inc(yyleng);.

You can use setlength(yytext,n) and setlength(yytext,length(yytext)+1) in those cases. But when you're using ansistrings, make sure you do those length adaptions *before* you write anything past the previous end-of-string, since otherwise you'll get segmentation faults.

Jonas

Full_Name
to Jonas Maebe

Quoting Jonas Maebe :

Show quoted text 14 lines
On dinsdag, maart 26, 2002, at 04:43 , ron wilson wrote: > so in my application, yyleng is referencing the length of the string, > yytext, by using the absolute identifier. i thought i could change all > references to yyleng to length(yytext), but the lexer often assigns > yyleng > manually (ugh!), e.g. yyleng:=n; OR inc(yyleng);. You can use setlength(yytext,n) and setlength(yytext,length(yytext)+1) in those cases. But when you're using ansistrings, make sure you do those length adaptions *before* you write anything past the previous end-of-string, since otherwise you'll get segmentation faults.

This is why I suggested using a class earlier. If he used a property he could have an internal variable that did the job.

Actually, inc-ing an absolute is stupid in this respect, because pascal will not allow you to read past the end of the string anyway (not in Delphi 5)

try the following:

var
  s: string[10];
  sa: Byte absolute s;
  a: Integer;
procedure Test
begin
  s := '1234567890';
  Inc(sa);
  a := sa;
  s[a] := 'a';
  ShowMessage(IntToStr(Length(s)) + ' ' + s + ' ' + s[a]);
  Inc(sa);
  a := sa;
  s[a] := 'b';
  ShowMessage(IntToStr(Length(s)) + ' ' + s + ' ' + s[a]);
end;

The above works up to a point, but is really unstable. The second showmessage is unable to resolve s[a] to be a value.

"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music." Kristian Wilson, Nintendo, Inc, 1989 -----BEGIN GEEK CODE BLOCK----- Version: 3.12 GCS d? s+++:+ a- C++ UL+ P L++ E---- W- N+ o+ K- w O- M V PS PE-- Y PGP- t- 5-- X- R- tv+ b+ DI++ D+ G e++ h--- r+++ y+++ ------END GEEK CODE BLOCK------
ron wilson
to Jonas Maebe: You can use setlength(yytext,n) and setlength(yytext,length(yytext)+1) in those cases.…

how about for type casting?

  var
    buf: array[1..255] of char;
    buflen: byte;
    str: ansistring;
  ...
  str:=ansistring(buf);
  setlength(str,buflen);

should i setlength before typecasting?

thx,
ron wilson

Earlier message 26 lines
-----Original Message----- From: Behalf Of Jonas Maebe Sent: Wednesday, April 10, 2002 8:52 AM To: Subject: Re: [fpc-pascal]absolute identifier On dinsdag, maart 26, 2002, at 04:43 , ron wilson wrote: > so in my application, yyleng is referencing the length of the string, > yytext, by using the absolute identifier. i thought i could change all > references to yyleng to length(yytext), but the lexer often assigns > yyleng > manually (ugh!), e.g. yyleng:=n; OR inc(yyleng);. You can use setlength(yytext,n) and setlength(yytext,length(yytext)+1) in those cases. But when you're using ansistrings, make sure you do those length adaptions *before* you write anything past the previous end-of-string, since otherwise you'll get segmentation faults. Jonas
Carlo Kok
to ron wilson

----- Original Message -----

Earlier message 25 lines
From: "ron wilson" To: Sent: Wednesday, April 10, 2002 9:09 PM Subject: RE: [fpc-pascal]absolute identifier > how about for type casting? > > var > buf: array[1..255] of char; > buflen: byte; > str: ansistring; > ... > str:=ansistring(buf); > setlength(str,buflen); > > should i setlength before typecasting? That should not work. Better do something like: SetLength(Str, BufLen); Move(Buf, Str[1], BufLen); or SetString(Str, Pchar(@Buf), BufLen);
ron wilson
to Carlo Kok: ----- Original Message ----- From: "ron wilson" To: Sent: Wednesday, April 10, 2002 9:09…

it does work. i am using it right now. according to the documentation on ansistrings (i actually read them) typecasting is designed to do this... i could be wrong i guess.

ron wilson

Earlier message 38 lines
-----Original Message----- From: Behalf Of Carlo Kok Sent: Wednesday, April 10, 2002 2:16 PM To: Subject: Re: [fpc-pascal]absolute identifier ----- Original Message ----- From: "ron wilson" To: Sent: Wednesday, April 10, 2002 9:09 PM Subject: RE: [fpc-pascal]absolute identifier > how about for type casting? > > var > buf: array[1..255] of char; > buflen: byte; > str: ansistring; > ... > str:=ansistring(buf); > setlength(str,buflen); > > should i setlength before typecasting? That should not work. Better do something like: SetLength(Str, BufLen); Move(Buf, Str[1], BufLen); or SetString(Str, Pchar(@Buf), BufLen);
ron wilson
to Jonas Maebe: Just use "str := buf;", that should also work (even for shortstrings) and will take care…

thanks - ill do that instead. btw the code i posted works afiak.

ron wilson

Earlier message 29 lines
-----Original Message----- From: Behalf Of Jonas Maebe Sent: Wednesday, April 10, 2002 2:20 PM To: Subject: Re: [fpc-pascal]absolute identifier On woensdag, april 10, 2002, at 09:09 , ron wilson wrote: > how about for type casting? > > var > buf: array[1..255] of char; > buflen: byte; > str: ansistring; > ... > str:=ansistring(buf); > setlength(str,buflen); Just use "str := buf;", that should also work (even for shortstrings) and will take care of setting the length for you (as long as there aren't any #0 characters in that array). Jonas
Florian Klaempfl
to ron wilson
you wrote
thanks - ill do that instead. btw the code i posted works afiak.

Yes, it should and you don't need the setlength because the type cast code does the job for you.

Show quoted text 9 lines
how about for type casting? var buf: array[1..255] of char; buflen: byte; str: ansistring; ... str:=ansistring(buf); setlength(str,buflen);
ron wilson
to Florian Klaempfl

you are correct. the type cast works very well.

in my case, however, i do need the setlength, because i don't clear the buffer when i re-use it, i just set buflen:=0. so i have to set the length if the buffer has garbage data beyond the current buflen.

ron wilson

Earlier message 27 lines
-----Original Message----- From: Behalf Of Florian Klaempfl Sent: Thursday, April 11, 2002 5:42 AM To: Subject: RE: [fpc-pascal]absolute identifier At 14:54 10.04.02 -0500, you wrote: >thanks - ill do that instead. btw the code i posted works afiak. Yes, it should and you don't need the setlength because the type cast code does the job for you. > how about for type casting? > > var > buf: array[1..255] of char; > buflen: byte; > str: ansistring; > ... > str:=ansistring(buf); > setlength(str,buflen);