• Re: Can C #includes like this be made to work onVMS?

    From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Brian Schenkenberger on Tue Oct 15 15:54:34 2024
    On 10/15/2024 3:21 PM, Brian Schenkenberger wrote:
    On 2024-10-15 19:15:00 +0000, John Dallman said:
    In article <vemd23$1qdt1$1@dont-email.me>, mail@SendSpamHere.ORG (Brian
    Schenkenberger) wrote:
    I want to port a freeware package. It's C code is littered with
    includes like:

    #include "package_name/include_file.h"

    I've tried the DECC$***_INCLUDE logicals, the CC command quilifier
    /INCLUDE_DIRECTORY and logicals, rooted and otherwise, defining
    "package_name". Can't get the C compiler to find include_file.h.

    Don't try to define "package name". General C practice is to regard that
    as a directory name that the compiler should look for, used to collect
    specific headers together.

    Instead, try using the various ways of specifying where you want include
    files to be read from to indicate the directory that holds the
    "package_name" directory.

    The compiler should look for the directory called "package_nane" and the
    "include_file.h" within it.

    In the distribution, the includes are in a directory:

    [package_name.INCLUDE]

    and the source is in [package_name.SRC]

    I am hoping not to have to edit all of the sources to change the
    #include "..."s.

    $ define package_name [package_name.INCLUDE]

    should work.

    $ cc/include will not work with this weird setup. If you changed the
    includes to be:
    #include "include_file.h"
    or:
    #include "package_name/include/include_file.h" or
    then it would work.

    Writing some DCL that does an edit/edt/comm with a substitute on
    all .c files in a directory tree is not that hard to write. Doing it
    in Macro-32 may take a little longer even for you.

    :-)

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From John Dallman@21:1/5 to Schenkenberger on Tue Oct 15 20:15:00 2024
    In article <vemd23$1qdt1$1@dont-email.me>, mail@SendSpamHere.ORG (Brian Schenkenberger) wrote:

    I want to port a freeware package. It's C code is littered with
    includes like:

    #include "package_name/include_file.h"

    I've tried the DECC$***_INCLUDE logicals, the CC command quilifier /INCLUDE_DIRECTORY and logicals, rooted and otherwise, defining "package_name". Can't get the C compiler to find include_file.h.

    Don't try to define "package name". General C practice is to regard that
    as a directory name that the compiler should look for, used to collect
    specific headers together.

    Instead, try using the various ways of specifying where you want include
    files to be read from to indicate the directory that holds the
    "package_name" directory.

    The compiler should look for the directory called "package_nane" and the "include_file.h" within it.

    John

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Tue Oct 15 18:50:58 2024
    On 10/15/2024 3:54 PM, Arne Vajhøj wrote:
    On 10/15/2024 3:21 PM, Brian Schenkenberger wrote:
    On 2024-10-15 19:15:00 +0000, John Dallman said:
    In article <vemd23$1qdt1$1@dont-email.me>, mail@SendSpamHere.ORG (Brian
    Schenkenberger) wrote:
    I want to port a freeware package. It's C code is littered with
    includes like:

    #include "package_name/include_file.h"

    I've tried the DECC$***_INCLUDE logicals, the CC command quilifier
    /INCLUDE_DIRECTORY and logicals, rooted and otherwise, defining
    "package_name". Can't get the C compiler to find include_file.h.

    Don't try to define "package name". General C practice is to regard that >>> as a directory name that the compiler should look for, used to collect
    specific headers together.

    Instead, try using the various ways of specifying where you want include >>> files to be read from to indicate the directory that holds the
    "package_name" directory.

    The compiler should look for the directory called "package_nane" and the >>> "include_file.h" within it.

    In the distribution, the includes are in a directory:

    [package_name.INCLUDE]

    and the source is in [package_name.SRC]

    I am hoping not to have to edit all of the sources to change the
    #include "..."s.

    $ define package_name [package_name.INCLUDE]

    should work.

    $ cc/include will not work with this weird setup. If you changed the
    includes to be:
        #include "include_file.h"
    or:
        #include "package_name/include/include_file.h" or
    then it would work.

    Or move the include files to [package_name.INCLUDE.package_name].

    Any setup where the include path and file system path match
    are OK.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Tue Oct 15 19:48:41 2024
    On 10/15/2024 3:54 PM, Arne Vajhøj wrote:
    Writing some DCL that does an edit/edt/comm with a substitute on
    all .c files in a directory tree is not that hard to write.

    Demo:

    $ type z*.c

    DKA0:[arne]z1.c;1

    #include "a/something.h"

    DKA0:[arne]z2.c;1

    #include "a/something.h"

    DKA0:[arne]z3.c;1

    #include "a/something.h"
    $ type ab.com
    $ loop:
    $ fnm = f$search("z*.c")
    $ if fnm .eqs. "" then goto endloop
    $ define/user sys$input sys$command
    $ edit/edt/comm=ab.edt 'fnm'
    $ goto loop
    $ endloop:
    $ exit
    $ type ab.edt
    s\#include "a/\#include "b/\w
    ex
    $ @ab
    ...
    $ type z*.c

    DKA0:[arne]z1.c;2

    #include "b/something.h"

    DKA0:[arne]z2.c;2

    #include "b/something.h"

    DKA0:[arne]z3.c;2

    #include "b/something.h"
    $ type bc.com
    $ loop:
    $ fnm = f$search("z*.c")
    $ if fnm .eqs. "" then goto endloop
    $ define/user sys$input sys$command
    $ edit/tpu/init=bc.eve 'fnm'
    $ goto loop
    $ endloop:
    $ exit
    $ type bc.eve
    all replace "#include ""b/" "#include ""c/"
    exit
    $ @bc
    ...
    $ type z*.c

    DKA0:[arne]z1.c;3

    #include "c/something.h"

    DKA0:[arne]z2.c;3

    #include "c/something.h"

    DKA0:[arne]z3.c;3

    #include "c/something.h"
    $ type cd.com
    $ loop:
    $ fnm = f$search("z*.c")
    $ if fnm .eqs. "" then goto endloop
    $ define/user sys$input sys$command
    $ edit/tpu/comm=cd.tpu 'fnm'
    $ goto loop
    $ endloop:
    $ exit
    $ type cd.tpu
    eve_all_replace("#include ""c/", "#include ""d/");
    eve_exit();
    $ @cd
    ...
    $ type z*.c

    DKA0:[arne]z1.c;4

    #include "d/something.h"

    DKA0:[arne]z2.c;4

    #include "d/something.h"

    DKA0:[arne]z3.c;4

    #include "d/something.h"

    Arne

    PS: Yes - both gawk and Perl can probably do it in way fewer lines.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to Brian Schenkenberger on Tue Oct 15 19:35:55 2024
    On 10/15/24 2:21 PM, Brian Schenkenberger wrote:

    In the distribution, the includes are in a directory:

    [package_name.INCLUDE]

    and the source is in [package_name.SRC]

    I am hoping not to have to edit all of the sources to change the
    #include "..."s.

    Is there possibly a configuration step that copies package_name/include/
    up to package_name/ in preparation for a build?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Berryman@21:1/5 to Brian Schenkenberger on Wed Oct 16 00:35:39 2024
    On 10/15/24 1:21 PM, Brian Schenkenberger wrote:
    On 2024-10-15 19:15:00 +0000, John Dallman said:

    In article <vemd23$1qdt1$1@dont-email.me>, mail@SendSpamHere.ORG (Brian
    Schenkenberger) wrote:

    I want to port a freeware package. It's C code is littered with
    includes like:

    #include "package_name/include_file.h"

    I've tried the DECC$***_INCLUDE logicals, the CC command quilifier
    /INCLUDE_DIRECTORY and logicals, rooted and otherwise, defining
    "package_name". Can't get the C compiler to find include_file.h.

    Don't try to define "package name". General C practice is to regard that
    as a directory name that the compiler should look for, used to collect
    specific headers together.

    Instead, try using the various ways of specifying where you want include
    files to be read from to indicate the directory that holds the
    "package_name" directory.

    The compiler should look for the directory called "package_nane" and the
    "include_file.h" within it.

    John

    In the distribution, the includes are in a directory:

    [package_name.INCLUDE]

    and the source is in [package_name.SRC]

    I am hoping not to have to edit all of the sources to change the
    #include "..."s.


    Given what you have described, there are at least two ways to address this.

    1. By far the easiest is to $define package_name [package_name.include]
    which will use the normal C RTL rules for finding files.

    2. As an alternative, the following will also work.

    a. create/dir [package_name.include.package_name]
    and move all of the include files into that directory
    b. create first.h
    #pragma include_directory "./package_name/include"
    ^Z
    c. Do your compiles from the top_level directory
    CC/FIRST=first.h [.src]file.c

    I find it easiest to create a descrip.mms file to do this and let mms do
    the work.

    Mark Berryman

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed Oct 16 18:44:44 2024
    On 10/15/2024 7:48 PM, Arne Vajhøj wrote:
    $ type bc.eve
    all replace "#include ""b/" "#include ""c/"
    exit

    $ type cd.tpu
    eve_all_replace("#include ""c/", "#include ""d/");
    eve_exit();

    Just realized that one is custom not standard.

    !
    ! Replace all occurences of string with another string (without
    ! confirm).
    !
    ! High-level.
    !
    procedure eve_all_replace(fndstr,rplstr)
    local fnd_string,
    rpl_string,
    pos_mark,
    count_integer;
    if not (eve$prompt_string(fndstr,fnd_string,"Old string: ",
    "No old string given")) then
    return;
    endif;
    if not (eve$prompt_string(rplstr,rpl_string,"New string ",
    "No new string given")) then
    return;
    endif;
    pos_mark:=mark(none);
    set (screen_update, off);
    eve$all_replace(fnd_string,rpl_string,count_integer);
    position (pos_mark);
    set (screen_update, on);
    delete (pos_mark);
    message("Total of "+str(count_integer)+" replaces");
    endprocedure;
    !
    ! Replace all occurences of string with another string (without
    ! confirm).
    !
    ! Low-level.
    !
    procedure eve$all_replace(fndstr,rplstr,count)
    local find_mark;
    position (beginning_of(current_buffer));
    count:=0;
    loop
    find_mark:=search_quietly(fndstr, forward);
    exitif find_mark = 0;
    count:=count+1;
    position (find_mark);
    copy_text (rplstr);
    erase_character (length(fndstr));
    endloop;
    endprocedure;

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Oct 16 23:00:14 2024
    On Wed, 16 Oct 2024 18:44:44 -0400, Arne Vajhøj wrote:

    procedure eve_all_replace(fndstr,rplstr)
    local fnd_string,
    rpl_string, pos_mark, count_integer;
    if not (eve$prompt_string(fndstr,fnd_string,"Old string: ",
    "No old string given")) then
    return;

    When DEC introduced TPU/EVE, I raised my arms to the heavens in joy at
    finally being liberated from the suffering that was EDT. (Hate EDT. Hate,
    hate, hate.)

    Then I left it behind with VMS ... and a few decades later, finally found
    the time to get to grips with Emacs.

    In Emacs/ELisp, there is the distinction between a “function” (what TPU would call a “procedure”, I guess) and a “command”. A “function” only
    becomes a “command” when you insert the “(interactive ...)” directive near
    its start. This is a declarative construct that supplies the information
    Emacs uses to obtain the right arguments for the function automatically, including prompting the user as necessary, so your code doesn’t have to.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Oct 16 19:26:52 2024
    On 10/16/2024 7:00 PM, Lawrence D'Oliveiro wrote:
    On Wed, 16 Oct 2024 18:44:44 -0400, Arne Vajhøj wrote:
    procedure eve_all_replace(fndstr,rplstr)
    local fnd_string,
    rpl_string, pos_mark, count_integer;
    if not (eve$prompt_string(fndstr,fnd_string,"Old string: ",
    "No old string given")) then
    return;

    When DEC introduced TPU/EVE, I raised my arms to the heavens in joy at finally being liberated from the suffering that was EDT. (Hate EDT. Hate, hate, hate.)

    Then I left it behind with VMS ... and a few decades later, finally found
    the time to get to grips with Emacs.

    In Emacs/ELisp, there is the distinction between a “function” (what TPU would call a “procedure”, I guess) and a “command”. A “function” only
    becomes a “command” when you insert the “(interactive ...)” directive near
    its start. This is a declarative construct that supplies the information Emacs uses to obtain the right arguments for the function automatically, including prompting the user as necessary, so your code doesn’t have to.

    In EVE a procedure EVE_FOOBAR can be called with:
    * command FOOBAR ARG ! the EVE_ prefix makes it a command
    * command TPU EVE_FOOBAR(ARG) ! only interesting if it does not have the
    EVE_ prefix

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Oct 16 19:28:44 2024
    On 10/16/2024 7:00 PM, Lawrence D'Oliveiro wrote:
    When DEC introduced TPU/EVE, I raised my arms to the heavens in joy at finally being liberated from the suffering that was EDT. (Hate EDT. Hate, hate, hate.)

    I definitely prefer EVE over EDT.

    But there are a few reasons to use EDT:
    * it uses less memory
    * it has line mode

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Oct 16 20:11:15 2024
    On 10/16/2024 7:38 PM, Lawrence D'Oliveiro wrote:
    On Wed, 16 Oct 2024 19:26:52 -0400, Arne Vajhøj wrote:
    * command FOOBAR ARG ! the EVE_ prefix makes it a command

    But you still had to call eve$prompt_string and all that jazz.

    TPU is a procedural language.

    eve_all_replace calls eve$prompt_string and eve$all_replace.

    But that has not really anything to do with the command.

    command ALL REPLACE "A" "B"

    execute:

    EVE_ALL_REPLACE("A", "B");

    and the command execution does not care whether all code
    in EVE_ALL_REPLACE is inline or in separate procedures.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Oct 16 23:38:23 2024
    On Wed, 16 Oct 2024 19:26:52 -0400, Arne Vajhøj wrote:

    * command FOOBAR ARG ! the EVE_ prefix makes it a command

    But you still had to call eve$prompt_string and all that jazz.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Thu Oct 17 01:14:06 2024
    On Wed, 16 Oct 2024 20:11:15 -0400, Arne Vajhøj wrote:

    On 10/16/2024 7:38 PM, Lawrence D'Oliveiro wrote:

    On Wed, 16 Oct 2024 19:26:52 -0400, Arne Vajhøj wrote:

    * command FOOBAR ARG ! the EVE_ prefix makes it a command

    But you still had to call eve$prompt_string and all that jazz.

    TPU is a procedural language.

    So is ELisp. But it has a declarative mechanism to allow custom functions
    to hook easily into the standard editor framework. This includes the UI.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Craig A. Berry on Wed Oct 16 22:13:56 2024
    On 10/16/2024 9:34 PM, Craig A. Berry wrote:
    On 10/16/24 5:44 PM, Arne Vajhøj wrote:
    On 10/15/2024 7:48 PM, Arne Vajhøj wrote:
    $ type bc.eve
    all replace "#include ""b/" "#include ""c/"
    exit

    $ type cd.tpu
    eve_all_replace("#include ""c/", "#include ""d/");
    eve_exit();

    Just realized that one is custom not standard.

    procedure eve_all_replace(fndstr,rplstr)

    eve_all_replace may be custom, but as far as I know eve_global_replace
    is standard.

    Yes - it is.

    I wonder why I have that eve_all_replace.

      Here's an example of using TPU as a poor man's Perl:

    $ edit/tpu/nodisplay/noinitialization -
        /section=sys$library:eve$section.tpu$section -
        /command=sys$input/output=myfile.txt myfile.txt
    input_file := GET_INFO (COMMAND_LINE, "file_name");
    main_buffer:= CREATE_BUFFER ("main", input_file);
    POSITION (BEGINNING_OF (main_buffer));
    eve_global_replace("foo","bar");
    out_file := GET_INFO (COMMAND_LINE, "output_file");
    WRITE_FILE (main_buffer, out_file);
    quit;
    ^Z

    But yeah, Perl is way easier:

    $ perl -pi -e "s/foo/bar/g;" myfile.txt

    Of course.

    :-)

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to All on Wed Oct 16 20:34:49 2024
    On 10/16/24 5:44 PM, Arne Vajhøj wrote:
    On 10/15/2024 7:48 PM, Arne Vajhøj wrote:
    $ type bc.eve
    all replace "#include ""b/" "#include ""c/"
    exit

    $ type cd.tpu
    eve_all_replace("#include ""c/", "#include ""d/");
    eve_exit();

    Just realized that one is custom not standard.

    !
    !  Replace all occurences of string with another string (without
    !  confirm).
    !
    !  High-level.
    !
    procedure eve_all_replace(fndstr,rplstr)
    local fnd_string,
          rpl_string,
          pos_mark,
          count_integer;
    if not (eve$prompt_string(fndstr,fnd_string,"Old string: ",
                              "No old string given")) then
        return;
    endif;
    if not (eve$prompt_string(rplstr,rpl_string,"New string ",
                              "No new string given")) then
        return;
    endif;
    pos_mark:=mark(none);
    set (screen_update, off); eve$all_replace(fnd_string,rpl_string,count_integer);
    position (pos_mark);
    set (screen_update, on);
    delete (pos_mark);
    message("Total of "+str(count_integer)+" replaces");
    endprocedure;
    !
    !  Replace all occurences of string with another string (without
    !  confirm).
    !
    !  Low-level.
    !
    procedure eve$all_replace(fndstr,rplstr,count)
    local find_mark;
    position (beginning_of(current_buffer));
    count:=0;
    loop
        find_mark:=search_quietly(fndstr, forward);
        exitif find_mark = 0;
        count:=count+1;
        position (find_mark);
        copy_text (rplstr);
        erase_character (length(fndstr));
    endloop;
    endprocedure;


    eve_all_replace may be custom, but as far as I know eve_global_replace
    is standard. Here's an example of using TPU as a poor man's Perl:

    $ edit/tpu/nodisplay/noinitialization -
    /section=sys$library:eve$section.tpu$section -
    /command=sys$input/output=myfile.txt myfile.txt
    input_file := GET_INFO (COMMAND_LINE, "file_name");
    main_buffer:= CREATE_BUFFER ("main", input_file);
    POSITION (BEGINNING_OF (main_buffer));
    eve_global_replace("foo","bar");
    out_file := GET_INFO (COMMAND_LINE, "output_file");
    WRITE_FILE (main_buffer, out_file);
    quit;
    ^Z

    But yeah, Perl is way easier:

    $ perl -pi -e "s/foo/bar/g;" myfile.txt

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Fri Oct 18 09:36:18 2024
    On 10/16/2024 10:13 PM, Arne Vajhøj wrote:
    On 10/16/2024 9:34 PM, Craig A. Berry wrote:
    On 10/16/24 5:44 PM, Arne Vajhøj wrote:
    On 10/15/2024 7:48 PM, Arne Vajhøj wrote:
    $ type bc.eve
    all replace "#include ""b/" "#include ""c/"
    exit

    $ type cd.tpu
    eve_all_replace("#include ""c/", "#include ""d/");
    eve_exit();

    Just realized that one is custom not standard.

    procedure eve_all_replace(fndstr,rplstr)

    eve_all_replace may be custom, but as far as I know eve_global_replace
    is standard.

    Yes - it is.

    I wonder why I have that eve_all_replace.

    There are a small difference in prompt behavior (all replace does
    not prompt if I want to go to start and repeat). But that is
    pretty subtle. The implementation is very different. eve_global_replace
    calls eve_replace with a global variable set to change its behavior.

    Maybe eve_global_replace was added with the major EVE rewrite in 5.0
    and I kept eve_all_replace when I rewrote from 4.x to 5.x.

    Anybody that has a VMS 4.x system and could do:

    $ sear sys$examples:eve$edit.tpu eve_global_replace

    ?

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)