. . .
01 ArLe pic x value x'11'.
01 ArRi pic x value x'10'.
01 ArUp pic x value x'1E'.
01 ArDo pic x value x'1F'.
. . .
. . .
*> enable display of ASCII symbols from x"00" to x"1F"
CALL STATIC "raw_output" USING 1
. . .
. . .
display ArLe at Line ...
display ArRi at Line ...
display ArUp at Line ...
display ArDo at Line ...
. . .
there is no need of any C wrapper.
I forgot to add that when compiling you need to have the pdcurses library available (raw_output is a pdcurses function)
for example use: cobc program.COB -lpdcurses
Some googling suggests two different possible solutions:
Using the Qodem terminal emulator, which appears to convert CP437 output to the intended UTF8 equivalent.
Replacing all instances of non-ASCII CP437 characters with their UTF8 equivalent. Maybe also changing the codepage to 65001. Maybe even replacing the DISPLAY's with manual calls to ncurses' add_wch.
Last edit: Edward Hart 2019-10-03
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Why would I want to use a modem emulator to accomplish a simple character display, and how would Qodem accomplish this?
2. How would you display a UTF8 character with GNU Cobol, when it won't even display the ASCII-7 set? Changing the codepage, if GNU Cobol even noticed, would mess up everything else in 265 WORKING programs. Replacing displays with manual calls to undocumented routines that aren't available without rebuilding, and recompiling everything, is hardly a solution.
Last edit: cdg 2019-10-06
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've just modded a simple program to display x"18" & x"19" and I get ^X & ^Y.
But I edited a text file to 18 19 18 19 0D 0A and typed it at a dos command
and got the up & down arrows as you'd expect - so what's going on.
I tried compiling the test under 3.0rc1 & still wrong.
This does sound rather stupid that it can't even display simple hex characters.
I went back to Cob 2.2 & still wrong - yet dos does it fine. ???
Last edit: David Wall 2019-10-02
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think I now have some understanding of what is happening. All curses libraries output control characters into caret notation. So, X"18" is translated to the two ASCII characters ^X. There is nothing that lets us easily undo this conversion. The only "correct" fix is to translate all input to/output from Unicode. GnuCOBOL should do this for you. However, it won't be able to for a long time. I didn't realise how extensively you used CP437 characters; that rules out any conversion of those to Unicode. That leaves one way to go: disabling the conversion to caret notation in the first place.
In ncurses, a "control character" depends on the locale. So we can fix the output by running Cygwin and doing set LC_ALL=en_US.CP437 (and maybe calling setlocale in the COBOL program as well).
In PDCurses, a "control character" is not locale-dependent - it always the ASCII control characters. Instead, we have to use the non-standard PDCurses function raw_output to disable the conversion to caret notation.
To access raw_output, we need a C shim, two lines of new COBOL code and two changes to your cobc.exe commands. NB: I haven't tested the following, but based on the entries of the FAQ, this should work.
Create raw_enable_output.c:
#include<pdcurses.h>intenable_raw_output(){raw_output(1);// GnuCOBOL assumes int return type of C functionsreturn0;}
Add to the start of your main COBOL program:
*> Force initialisation of PDCursesDISPLAYLOW-VALUEAT0101*> Prevent caret notationCALL "enable_raw_output"
Then, compile like
REM Compile the C shim with the headers/libraries needed by GnuCOBOL
cobc.exe -c enable_raw_output.c
REM Add the dll to your "cobc.exe -x" command:
cobc.exe -x prog1.cob prog2.cob ... enable_raw_output.dll
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Why not using an UTF8 enabled curses version and convert the box and arrow characters in the source file to utf8-encoding (it is a one click with notepad++)?
Note: this should work on any system with both ncurses and pdcurses - as long as those are configured to use utf8.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I didn't think it would be that easy. I was expecting to have to convince curses to accept non-ASCII characters and then have to convince a terminal emulator or cmd.exe to display them properly.
Last edit: Edward Hart 2019-10-03
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If you have an utf8 build of pdcurses then it completely ignores any setting of cmd.exe which normally cannot display utf8 (that's even true for Windows 10) and does it well. Any non UTF8 display obviously gets broken on the way. If previously hex constants were used those would have to be converted manually (preferably by copy+paste the unicode variant to the COBOL source which is saved with utf8 encoding).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The only "correct" fix is to translate all input to/output from Unicode.
Please explain how this is done
GnuCOBOL should do this for you. However, it won't be able to for a long time.
???
I didn't realise how extensively you used CP437 characters; that rules out any conversion of those to Unicode.
I don't extensively use CP437 characters. I use them in a few places. Arnold's GC31 now correctly displays the line-drawing characters, so we are just concerned with the arrow characters. But (as I understand it) Unicode uses two bytes for each character. If I have to convert all my text to Unicode, THAT would be a huge endeavor, affected not only program code but file layouts and contents. But if there is some way of displaying Unicode in a single instance, please inform us.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The only "correct" fix is to translate all input to/output from Unicode.
Please explain how this is done
GnuCOBOL should do this for you. However, it won't be able to for a long time.
The conversion is not something that would be done in COBOL sources - just in the GnuCOBOL runtime. It would require adding a codeset conversion library (e.g. iconv, libicu), detecting the active codeset (probably by some kind of compiler directive/configuration option), converting all characters sent to DISPLAY to Unicode and outputting them using curses wide-character functions (and vice-versa for ACCEPT). That would take some effort to design and implement (especially after considering portability), so it cannot be done soon.
But if there is some way of displaying Unicode in a single instance, please inform us.
I'll try to find one. The ncurses function add_wch looks promising, but I've not got anything working so far.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It turns out that, with ncurses and LANG set to en_GB.UTF-8, you can just copy-and-paste the Unicode characters into COBOL source and DISPLAY them normally:
*> Unicode character and its hexDISPLAY "↑ "&X"e28691"
Maybe this works on Windows and PDCurses, too?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The person asking the original question (how to display x"18" and x"19" with GNU Cobol) is not a C programmer, nor is he an expert in all the nuances of the GNU Cobol library. So your responses are not helpful.
"It turns out that, with ncurses and LANG set to en_GB.UTF-8, you can just copy-and-paste the Unicode characters into COBOL source and DISPLAY them normally:
*> Unicode character and its hex
DISPLAY "↑ " & X"e28691"
Maybe this works on Windows and PDCurses, too?"
Where would I set LANG to "en_GB.UTF-8"? How would I copy and paste Unicode characters when Notepad (and other text editors) respond to the arrows as commands? What effect would the LANG setting have on the rest of the text in my program(s)?
"Why not using an UTF8 enabled curses version and convert the box and arrow characters in the source file to utf8-encoding (it is a one click with notepad++)?
Note: this should work on any system with both ncurses and pdcurses - as long as those are configured to use utf8."
Because I don't have any control over which curses version I use, and I don't have Notepad++. And, if I did have "an UTF enabled curses version", What effect would it have on the rest of the text in my program(s)? I don't want to create a larger problem to solve a minor one.
"I didn't think it would be that easy."
So far, it's not easy for me.
"If you have an utf8 build of pdcurses then it completely ignores any setting of cmd.exe which normally cannot display utf8 (that's even true for Windows 10) and does it well. Any non UTF8 display obviously gets broken on the way. If previously hex constants were used those would have to be converted manually (preferably by copy+paste the unicode variant to the COBOL source which is saved with utf8 encoding)."
So, to display two hex characters that are part of the default code page, but ignored by curses, I should modify every hex character in every program? How exquisitely simple!
Last edit: cdg 2019-10-06
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
As it turns out, there are two very simple solutions to the problem, one that doesn't work (although it should), and one that does:
1) addrawch(24) and addrawch(25)should work, and it does work for some characters, but it displays the wrong character for the up and down arrows. (And, yes, my code page is 437).
2) addch(ACS_UARROW) and addch(ACS_DARROW) display the up and down arrows properly.
I couldn't get either to work directly from a Cobol program CALL, so I wrote a C "wrapper":
addch(ACS_UARROW) and addch(ACS_DARROW) display the up and down arrows properly.
I couldn't get either to work directly from a Cobol program CALL ...
That's because addch()may be a macro and ACS_UARROW/ACS_DARROW very likely is. Your c-wrapper is fine although you could change it to alternative formats, too:
You may even use something similar to print every special character. In this case you'd likely define a copybook that includes "internal magic characters" for the complete extended characters [see attachment] like
#if defined (HAVE_NCURSES_H)#include"ncurses.h"#elif defined (HAVE_PDCURSES_H)#include"pdcurses.h"#else#include"curses.h"#endifvoiddisplay_special(charopt){// if(opt=='1')addch(ACS_ULCORNER);elseif(opt=='2')addch(ACS_LLCORNER);// duplicate the magic characters from the copybook here}
To not need to take care of the special "non-cobol linking" each time and to be more portable I'd create a minimal wrapper program "SPECIALDISP" that just takes a PIC X (by reference) and calls the C programm. This way you can compile a single module:
cobc -b SPECIALDISP.COB wrap.c -DHAVE_PDCURSES_H -A "/DPDC_DLL_BUILD" -lpdcurses
and then call this COBOL program from everywhere without any special linking:
Additional benefit: if you ever want to adjust the table of characters or change to a different curses library (version) or even to a different technology you only have to adjust/recompile/relink a single program.
And for the special case of 'Bill Gray's PDCurses", depending on how it was built, two more macros are in order:
CHTYPE size (mandatory for 32-bit compatibility reasons):
32-bit 'chtype's - /DCHTYPE_32
64-bit 'chtype's - NONE (the default)
WIDE version (which is needed to fully integrate PDCurses with Windows):
/DPDC_WIDE (allows ACS and WACS; see 'curses.h' for details)
cobc -b SPECIALDISP.COB wrap.c -DHAVE_PDCURSES_H -A "/DPDC_DLL_BUILD" -lpdcurses
will become:
cobc -b SPECIALDISP.COB wrap.c -DHAVE_PDCURSES_H -A /DPDC_DLL_BUILD -A /DCHTYPE_32 -A /DPDC_WIDE" -lpdcurses (assuming 'pdcurses' has been built with those macros as well, not to forget 'GnuCOBOL' as well for 'screenio.c'). If PDC_WIDE is not provided, some characters may not display properly, or none at all, depending on the font used by the console.
Once more:
Bill Gray's PDCurses does not need UTF8=Y at all (at least on Windows).
From 'ncurses' perspective , the characters from your 'png' table work pretty well with 'ncursesw' in a Cygwin console (although very limited).
Cheers,
MM
Last edit: Mário Matos 2019-11-07
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
With Realia Cobol,
displays the up and down arrows.
With GNU Cobol, we get ^X and ^Y.
How can I display the left, right, up and down arrow characters with GNU Cobol?
You can simply use
there is no need of any C wrapper.
I forgot to add that when compiling you need to have the pdcurses library available (raw_output is a pdcurses function)
for example use:
cobc program.COB -lpdcurses
Please see also at
https://sourceforge.net/p/gnucobol/discussion/help/thread/7f9830a113/?limit=50#bf77
Last edit: Eugenio Di Lorenzo 2024-11-20
Does changing the command prompt code page work (e.g.
chcp 437
)?The active code page is current 437
Some googling suggests two different possible solutions:
Using the Qodem terminal emulator, which appears to convert CP437 output to the intended UTF8 equivalent.Maybe also changing the codepage to 65001. Maybe even replacing theDISPLAY
's with manual calls to ncurses'add_wch
.Last edit: Edward Hart 2019-10-03
2. How would you display a UTF8 character with GNU Cobol, when it won't even display the ASCII-7 set? Changing the codepage, if GNU Cobol even noticed, would mess up everything else in 265 WORKING programs. Replacing displays with manual calls to undocumented routines that aren't available without rebuilding, and recompiling everything, is hardly a solution.
Last edit: cdg 2019-10-06
I've just modded a simple program to display x"18" & x"19" and I get ^X & ^Y.
But I edited a text file to 18 19 18 19 0D 0A and typed it at a dos command
and got the up & down arrows as you'd expect - so what's going on.
I tried compiling the test under 3.0rc1 & still wrong.
This does sound rather stupid that it can't even display simple hex characters.
I went back to Cob 2.2 & still wrong - yet dos does it fine. ???
Last edit: David Wall 2019-10-02
I think I now have some understanding of what is happening. All curses libraries output control characters into caret notation. So,
X"18"
is translated to the two ASCII characters^X
. There is nothing that lets us easily undo this conversion. The only "correct" fix is to translate all input to/output from Unicode. GnuCOBOL should do this for you. However, it won't be able to for a long time. I didn't realise how extensively you used CP437 characters; that rules out any conversion of those to Unicode. That leaves one way to go: disabling the conversion to caret notation in the first place.In ncurses, a "control character" depends on the locale. So we can fix the output by running Cygwin and doing
set LC_ALL=en_US.CP437
(and maybe callingsetlocale
in the COBOL program as well).In PDCurses, a "control character" is not locale-dependent - it always the ASCII control characters. Instead, we have to use the non-standard PDCurses function
raw_output
to disable the conversion to caret notation.To access
raw_output
, we need a C shim, two lines of new COBOL code and two changes to yourcobc.exe
commands. NB: I haven't tested the following, but based on the entries of the FAQ, this should work.Create raw_enable_output.c:
Add to the start of your main COBOL program:
Then, compile like
Why not using an UTF8 enabled curses version and convert the box and arrow characters in the source file to utf8-encoding (it is a one click with notepad++)?
Note: this should work on any system with both ncurses and pdcurses - as long as those are configured to use utf8.
I didn't think it would be that easy. I was expecting to have to convince curses to accept non-ASCII characters and then have to convince a terminal emulator or cmd.exe to display them properly.
Last edit: Edward Hart 2019-10-03
If you have an utf8 build of pdcurses then it completely ignores any setting of cmd.exe which normally cannot display utf8 (that's even true for Windows 10) and does it well. Any non UTF8 display obviously gets broken on the way. If previously hex constants were used those would have to be converted manually (preferably by copy+paste the unicode variant to the COBOL source which is saved with utf8 encoding).
Please explain how this is done
???
I don't extensively use CP437 characters. I use them in a few places. Arnold's GC31 now correctly displays the line-drawing characters, so we are just concerned with the arrow characters. But (as I understand it) Unicode uses two bytes for each character. If I have to convert all my text to Unicode, THAT would be a huge endeavor, affected not only program code but file layouts and contents. But if there is some way of displaying Unicode in a single instance, please inform us.
The conversion is not something that would be done in COBOL sources - just in the GnuCOBOL runtime. It would require adding a codeset conversion library (e.g. iconv, libicu), detecting the active codeset (probably by some kind of compiler directive/configuration option), converting all characters sent to
DISPLAY
to Unicode and outputting them using curses wide-character functions (and vice-versa forACCEPT
). That would take some effort to design and implement (especially after considering portability), so it cannot be done soon.I'll try to find one. The ncurses function
add_wch
looks promising, but I've not got anything working so far.It turns out that, with ncurses and
LANG
set toen_GB.UTF-8
, you can just copy-and-paste the Unicode characters into COBOL source andDISPLAY
them normally:Maybe this works on Windows and PDCurses, too?
Yes, as long as you use the UTF8 version.
The person asking the original question (how to display x"18" and x"19" with GNU Cobol) is not a C programmer, nor is he an expert in all the nuances of the GNU Cobol library. So your responses are not helpful.
Where would I set LANG to "en_GB.UTF-8"? How would I copy and paste Unicode characters when Notepad (and other text editors) respond to the arrows as commands? What effect would the LANG setting have on the rest of the text in my program(s)?
Because I don't have any control over which curses version I use, and I don't have Notepad++. And, if I did have "an UTF enabled curses version", What effect would it have on the rest of the text in my program(s)? I don't want to create a larger problem to solve a minor one.
So far, it's not easy for me.
So, to display two hex characters that are part of the default code page, but ignored by curses, I should modify every hex character in every program? How exquisitely simple!
Last edit: cdg 2019-10-06
As it turns out, there are two very simple solutions to the problem, one that doesn't work (although it should), and one that does:
1) addrawch(24) and addrawch(25)should work, and it does work for some characters, but it displays the wrong character for the up and down arrows. (And, yes, my code page is 437).
2) addch(ACS_UARROW) and addch(ACS_DARROW) display the up and down arrows properly.
I couldn't get either to work directly from a Cobol program CALL, so I wrote a C "wrapper":
and invoked them from the Cobol program as follows:
The Cobol program needs to be compiled with
That's because
addch()
may be a macro andACS_UARROW
/ACS_DARROW
very likely is. Your c-wrapper is fine although you could change it to alternative formats, too:with
or
with
You may even use something similar to print every special character. In this case you'd likely define a copybook that includes "internal magic characters" for the complete extended characters [see attachment] like
and a portable C program to compile and use those
used by
To not need to take care of the special "non-cobol linking" each time and to be more portable I'd create a minimal wrapper program "SPECIALDISP" that just takes a
PIC X
(by reference
) and calls the C programm. This way you can compile a single module:cobc -b SPECIALDISP.COB wrap.c -DHAVE_PDCURSES_H -A "/DPDC_DLL_BUILD" -lpdcurses
and then call this COBOL program from everywhere without any special linking:
Additional benefit: if you ever want to adjust the table of characters or change to a different curses library (version) or even to a different technology you only have to adjust/recompile/relink a single program.
And for the special case of 'Bill Gray's PDCurses", depending on how it was built, two more macros are in order:
CHTYPE size (mandatory for 32-bit compatibility reasons):
32-bit 'chtype's - /DCHTYPE_32
64-bit 'chtype's - NONE (the default)
WIDE version (which is needed to fully integrate PDCurses with Windows):
/DPDC_WIDE (allows ACS and WACS; see 'curses.h' for details)
cobc -b SPECIALDISP.COB wrap.c -DHAVE_PDCURSES_H -A "/DPDC_DLL_BUILD" -lpdcurses
will become:
cobc -b SPECIALDISP.COB wrap.c -DHAVE_PDCURSES_H -A /DPDC_DLL_BUILD -A /DCHTYPE_32 -A /DPDC_WIDE" -lpdcurses (assuming 'pdcurses' has been built with those macros as well, not to forget 'GnuCOBOL' as well for 'screenio.c'). If PDC_WIDE is not provided, some characters may not display properly, or none at all, depending on the font used by the console.
Once more:
Bill Gray's PDCurses does not need UTF8=Y at all (at least on Windows).
From 'ncurses' perspective , the characters from your 'png' table work pretty well with 'ncursesw' in a Cygwin console (although very limited).
Cheers,
MM
Last edit: Mário Matos 2019-11-07