Discussion:
C... the only winning move is not to play...
(too old to reply)
V***@SendSpamHere.ORG
2014-02-09 23:17:04 UTC
Permalink
I've encountered a VMS library call prototype that is incorrect. How can
I override/overwrite the prototype in my source to make it correct? I've
used other routines from this library without issue save for this one. Is
there a #pragma that allows for or provides this? I've read the on-line
help but don't see anything under #pragma.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
JF Mezei
2014-02-10 00:09:12 UTC
Permalink
Post by V***@SendSpamHere.ORG
I've encountered a VMS library call prototype that is incorrect.
Since there are no new versions of VMS coming, it is probably quite safe
to simply edit the library module to correct the error.

Another way is to extrac the fault module to a local file. Correct it.
And your program #includes your local corrected copy instead of the
system provided one. Note that you want to do the #include early in case
it is included by other modules which might include the system library
copy if they don't see the symbols that signify the module was already
included.
Post by V***@SendSpamHere.ORG
How can
I override/overwrite the prototype in my source to make it correct?
If you try to redefine it, the compiler will complain about duplicate
and conflicting fiunction prototypes. I am not sure you can "#undef" a
function prototype as you can a simple symbol.
Stephen Hoffman
2014-02-10 00:15:10 UTC
Permalink
Post by V***@SendSpamHere.ORG
I've encountered a VMS library call prototype that is incorrect. How
can I override/overwrite the prototype in my source to make it correct?
I've used other routines from this library without issue save for this
one. Is there a #pragma that allows for or provides this? I've read
the on-line help but don't see anything under #pragma.
I'm assuming this is a VMS header for the system or for an RTL, and
probably something that was generated via SDL.

Hack it. Extract the header file, fix it, and either insert it back
under the same name, insert under a different name and #include
<foodef-other.h>, or pull it in via a #include "mylocalcopy.h" syntax.
This where the file was either edited directly, or maybe regenerated
via SDL processing on the SDI file from STARLETSD.TLB.

You could probably also do a symbol name fix-up via a patch or using
some linker arcana, but that's more work than its worth.

If you wanted to be slightly sneaky (and depending on the particular
call and the OpenVMS version), declare your replacement as a function
pointer under a different name and use a call to lib$find_image_symbol
to find the virtual address of the "real" function, and jump to that.

No, VMS C doesn't have anything akin to --wrap or related baggage
<http://wwwold.cs.umd.edu/Library/TRs/CS-TR-4585/CS-TR-4585.pdf>, and
the closest analog to the preloading (the lib$initialize psect)
wouldn't seem to get you closer to your goal.

Document the shenanigans locally for the code, and dispatch a bug
report along to HP so that you can record the bug report number in the
comments.
--
Pure Personal Opinion | HoffmanLabs LLC
V***@SendSpamHere.ORG
2014-02-10 02:09:14 UTC
Permalink
Post by Stephen Hoffman
Post by V***@SendSpamHere.ORG
I've encountered a VMS library call prototype that is incorrect. How
can I override/overwrite the prototype in my source to make it correct?
I've used other routines from this library without issue save for this
one. Is there a #pragma that allows for or provides this? I've read
the on-line help but don't see anything under #pragma.
I'm assuming this is a VMS header for the system or for an RTL, and
probably something that was generated via SDL.
Hack it. Extract the header file, fix it, and either insert it back
under the same name, insert under a different name and #include
<foodef-other.h>, or pull it in via a #include "mylocalcopy.h" syntax.
This where the file was either edited directly, or maybe regenerated
via SDL processing on the SDI file from STARLETSD.TLB.
You could probably also do a symbol name fix-up via a patch or using
some linker arcana, but that's more work than its worth.
If you wanted to be slightly sneaky (and depending on the particular
call and the OpenVMS version), declare your replacement as a function
pointer under a different name and use a call to lib$find_image_symbol
to find the virtual address of the "real" function, and jump to that.
No, VMS C doesn't have anything akin to --wrap or related baggage
<http://wwwold.cs.umd.edu/Library/TRs/CS-TR-4585/CS-TR-4585.pdf>, and
the closest analog to the preloading (the lib$initialize psect)
wouldn't seem to get you closer to your goal.
Document the shenanigans locally for the code, and dispatch a bug
report along to HP so that you can record the bug report number in the
comments.
Grrr... I have to build against VMS version variants back to V7.2 for this
particular project.

I guess that what I will do is make this code "fuglier" to work around the
bad prototype. The problem is basically an RTL with two mandatory args and
a litany of optional args. The C prototype only defines the two mandatory
args; it should have a third __optional_params in the prototype but, sadly,
it's been elided.

Strong typing is for weak minds!
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
David Froble
2014-02-10 02:38:27 UTC
Permalink
Post by V***@SendSpamHere.ORG
Strong typing is for weak minds!
Now you're starting to see things my way ....

:-) :-)
John E. Malmberg
2014-02-10 03:09:27 UTC
Permalink
Post by V***@SendSpamHere.ORG
Grrr... I have to build against VMS version variants back to V7.2 for this
particular project.
I guess that what I will do is make this code "fuglier" to work around the
bad prototype. The problem is basically an RTL with two mandatory args and
a litany of optional args. The C prototype only defines the two mandatory
args; it should have a third __optional_params in the prototype but, sadly,
it's been elided.
I expect that you have verified that there is not a special macro that
if defined that changes the prototype exposed for that call.

The CRTL does in places that so that source code that expects past
behavior, even if may not be according to the current standard continues
to work.

To reprototype foo() in foobar.h:

#define foo hide_foo
#include <foobar.h>
#undef foo
/* Fixed prototype */
type_x foo(arg_t, arg_t, ...);

If you have a reasonbly current C compiler (Alpha), there is a
/first_include option that can pull in a header file with these hacks.

On the vms-ports project, we are building a list of known issues and
work arounds, and would be interested in knowing which call is
miss-prototyped and needs to be worked around.

Regards,
-John
***@qsl.network
Personal Opinion Only
JF Mezei
2014-02-10 03:17:41 UTC
Permalink
Post by V***@SendSpamHere.ORG
Grrr... I have to build against VMS version variants back to V7.2 for this
particular project.
Do a "diff" on the faulty header on multiple versions to see if anything
significant has changed between versions for ANY function in that
header. If not, then you are safe in creating your own local copy that
you include instead of the one from the faulty system library.

Remember that the function prototypes only exist to please the
compiler's syntax checking. I doubt very much that it changes generated
code.

One suggestion which I have not checked/tested.

If you can't redefine SYS$BINTIM(), try this:

VAXMAN$BINTIN(int *binary, struct dsc$w_descriptor *string_time);
#define VAXMAN$BINTIM SYS$BINTIM

This might might work if the compiler does the function prototype
checking before symbol substitution. Again, untested.
V***@SendSpamHere.ORG
2014-02-10 11:55:15 UTC
Permalink
Post by JF Mezei
Post by V***@SendSpamHere.ORG
Grrr... I have to build against VMS version variants back to V7.2 for this
particular project.
Do a "diff" on the faulty header on multiple versions to see if anything
significant has changed between versions for ANY function in that
header. If not, then you are safe in creating your own local copy that
you include instead of the one from the faulty system library.
Remember that the function prototypes only exist to please the
compiler's syntax checking. I doubt very much that it changes generated
code.
Correct. However, I'm #include'ing the OpenVMS system supplied prototype
definitions with are WRONG! The problem has been remedied with V8.* but
they're farked pre-V8.*.
Post by JF Mezei
One suggestion which I have not checked/tested.
VAXMAN$BINTIN(int *binary, struct dsc$w_descriptor *string_time);
#define VAXMAN$BINTIM SYS$BINTIM
This might might work if the compiler does the function prototype
checking before symbol substitution. Again, untested.
Kludge... Oh, that's right, this is C the lingo of the kludge.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
Chris Scheers
2014-02-11 01:13:35 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by JF Mezei
Post by V***@SendSpamHere.ORG
Grrr... I have to build against VMS version variants back to V7.2 for this
particular project.
Do a "diff" on the faulty header on multiple versions to see if anything
significant has changed between versions for ANY function in that
header. If not, then you are safe in creating your own local copy that
you include instead of the one from the faulty system library.
Remember that the function prototypes only exist to please the
compiler's syntax checking. I doubt very much that it changes generated
code.
Correct. However, I'm #include'ing the OpenVMS system supplied prototype
definitions with are WRONG! The problem has been remedied with V8.* but
they're farked pre-V8.*.
My usual solution to these types of problems is to copy the correct
prototype file from the later system and put it in the include path.

This isn't a C specific problem. I have also had it with FORTRAN and
(IIRC) Ada.
--
-----------------------------------------------------------------------
Chris Scheers, Applied Synergy, Inc.

Voice: 817-237-3360 Internet: ***@applied-synergy.com
Fax: 817-237-3074
Stephen Hoffman
2014-02-11 13:59:47 UTC
Permalink
Post by Chris Scheers
My usual solution to these types of problems is to copy the correct
prototype file from the later system and put it in the include path.
This isn't a C specific problem. I have also had it with FORTRAN and
(IIRC) Ada.
In some discussions over on decuserve / EISNER::, Bart L. was wrestling
with some broken BASIC definitions, as well.

The headers for most of the OpenVMS definitions are common source,
which means that either the core SDL definition is broken, or the
particular SDL back-end was broken.

Given the definition changed across VMS versions, it's fairly likely
the core definitions were broken. That wouldn't be the first time that
happened.

You can re-generate the language-specific definitions from
STARLETSD.TLB, or (for those with access) check the source listings for
the SDL files involved. (If VMS were still active, there'd be a
reasonable case for just shipping out the SDL files. Shipping the SDL
SDI intermediate files struck me as an antiquated approach to work
around a non-problem, and — other than that the code already existed —
more effort than it was worth.)

With the C and C++ include-files logical name morass, fetching a
variant version of the errant include file is feasible. That
build-time change can be isolated, and the build can create the variant
include file from the system definition. Ugly, but workable. Fetch
the file from the library and then embed the source version number to
avoid potential hassles after upgrades. Fetch a new version of the
include when the version changes, if necessary.

But then VAXman does already have a workable workaround.
--
Pure Personal Opinion | HoffmanLabs LLC
hb
2014-02-10 08:35:45 UTC
Permalink
Post by V***@SendSpamHere.ORG
I've encountered a VMS library call prototype that is incorrect. How can
I override/overwrite the prototype in my source to make it correct? I've
used other routines from this library without issue save for this one. Is
there a #pragma that allows for or provides this? I've read the on-line
help but don't see anything under #pragma.
What's the problem? Something like ...
$ cre x.h
int foo (int,int);
[ Exit ]
$ cre x.c
#include "x.h"
int bar (void) { return foo(1,2,3)+foo(1,2,3,4); }
[ Exit ]
$ cc x

int bar (void) { return foo(1,2,3)+foo(1,2,3,4); }
........................^
%CC-E-TOOMANYARGS, In this statement, "foo" expects 2 arguments, but 3
are supplied.
at line number 2 in file DISK$USER:[USER]x.c;1

int bar (void) { return foo(1,2,3)+foo(1,2,3,4); }
...................................^
%CC-E-TOOMANYARGS, In this statement, "foo" expects 2 arguments, but 4
are supplied.
at line number 2 in file DISK$USER:[USER]x.c;1
$

You can just #define the function to something totally different, #undef
it later and add the correct prototype, like

# define foo(x,y) unusedAndUseless
#include "x.h"
# undef foo
int foo (int,int,...);
int bar (void) { return foo(1,2,3)+foo(1,2,3,4); }

$ cc x
$
V***@SendSpamHere.ORG
2014-02-10 12:11:06 UTC
Permalink
Post by hb
Post by V***@SendSpamHere.ORG
I've encountered a VMS library call prototype that is incorrect. How can
I override/overwrite the prototype in my source to make it correct? I've
used other routines from this library without issue save for this one. Is
there a #pragma that allows for or provides this? I've read the on-line
help but don't see anything under #pragma.
What's the problem? Something like ...
$ cre x.h
int foo (int,int);
[ Exit ]
$ cre x.c
#include "x.h"
int bar (void) { return foo(1,2,3)+foo(1,2,3,4); }
[ Exit ]
$ cc x
int bar (void) { return foo(1,2,3)+foo(1,2,3,4); }
.........................^
%CC-E-TOOMANYARGS, In this statement, "foo" expects 2 arguments, but 3
are supplied.
at line number 2 in file DISK$USER:[USER]x.c;1
int bar (void) { return foo(1,2,3)+foo(1,2,3,4); }
....................................^
%CC-E-TOOMANYARGS, In this statement, "foo" expects 2 arguments, but 4
are supplied.
at line number 2 in file DISK$USER:[USER]x.c;1
$
You can just #define the function to something totally different, #undef
it later and add the correct prototype, like
# define foo(x,y) unusedAndUseless
#include "x.h"
# undef foo
int foo (int,int,...);
int bar (void) { return foo(1,2,3)+foo(1,2,3,4); }
$ cc x
$
OK. The function is STR$CONCAT.

somewhere VMS pre-V8.*, where it's WRONG, WRONG, WRONG...

#define str$concat STR$CONCAT
#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string);

and later VMS versions, where it's workable,...

#define str$concat STR$CONCAT
#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string_1,
__optional_params);


Now, if you can include <str$routines.h> and make this go away, I'm wanting.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
j***@gmail.com
2014-02-10 12:38:24 UTC
Permalink
Apart from Hoffs suggestion to LFIS your way around the issue, you should be able to use pragma directives to dial back the compilers complaints at the point of each invocation of the poorly declared function.

EJ
JohnF
2014-02-10 12:49:58 UTC
Permalink
Post by V***@SendSpamHere.ORG
I've encountered a VMS library call prototype that is incorrect.
How can I override/overwrite the prototype in my source
to make it correct?
OK. The function is STR$CONCAT.
somewhere VMS pre-V8.*, where it's WRONG, WRONG, WRONG...
#define str$concat STR$CONCAT
#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string);
and later VMS versions, where it's workable,...
#define str$concat STR$CONCAT
#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string_1,
__optional_params);
Now, if you can include <str$routines.h> and make this go away, I'm wanting.
Is that actual entry point uppercase?
You might (or might not) be able to get away with
something like
#define STR$CONCAT dummy
#include <str$routines.h>
whereby the prototype refers to a dummy() func.
Then
#undef STR$CONCAT
#redefine str$concat STR$CONCAT
and prototype the actual func any way you like.

But I've got to ask: why would you/anybody use vms-specific
library stuff for ansi-standard functionality?
Besides job security, that is?
I recall some code I became responsible for, where after
reading through several pages of rms stuff, it dawned on
me the guy could just have done an fopen()/fprintf()'s.
It was ridiculous to write it the way he did.
I'm too lazy to look up what those optional args
might be doing for you, but the "real solution" here
is to replace str$concat() with ansi-standard strcat()
wherever possible. Modulo job security, that is.
--
John Forkosh ( mailto: ***@f.com where j=john and f=forkosh )
V***@SendSpamHere.ORG
2014-02-10 14:03:25 UTC
Permalink
Post by JohnF
Post by V***@SendSpamHere.ORG
I've encountered a VMS library call prototype that is incorrect.
How can I override/overwrite the prototype in my source
to make it correct?
OK. The function is STR$CONCAT.
somewhere VMS pre-V8.*, where it's WRONG, WRONG, WRONG...
#define str$concat STR$CONCAT
#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string);
and later VMS versions, where it's workable,...
#define str$concat STR$CONCAT
#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string_1,
__optional_params);
Now, if you can include <str$routines.h> and make this go away, I'm wanting.
Is that actual entry point uppercase?
You might (or might not) be able to get away with
something like
#define STR$CONCAT dummy
#include <str$routines.h>
whereby the prototype refers to a dummy() func.
Then
#undef STR$CONCAT
#redefine str$concat STR$CONCAT
and prototype the actual func any way you like.
Thanks John. Here's the KLUDGE written in KLUDGE, errr... C.

#define STR$CONCAT STR$CONCAT_is_badly_prototyped_in_STR$ROUTINES_header
#include <str$routines.h> // OpenVMS STR$ RTL prototype definitions
#undef STR$CONCAT
#define str$concat STR$CONCAT
unsigned int str$concat(struct dsc$descriptor_s*, struct dsc$descriptor_s*, __optional_params);
Post by JohnF
But I've got to ask: why would you/anybody use vms-specific
library stuff for ansi-standard functionality?
ANSI standard? ANSI-C standard? confusion?
Post by JohnF
Besides job security, that is?
I recall some code I became responsible for, where after
reading through several pages of rms stuff, it dawned on
me the guy could just have done an fopen()/fprintf()'s.
It was ridiculous to write it the way he did.
Maybe he wanted files that weren't streams? Index files? Perhaps, wanted
to avoid the wrapper overhead to the real services below? I don't know nor
do I care. *I* an writing VERY OpenVMS specific code. I don't want nor do
I need the *IXisms.
Post by JohnF
I'm too lazy to look up what those optional args
might be doing for you, but the "real solution" here
is to replace str$concat() with ansi-standard strcat()
wherever possible. Modulo job security, that is.
This has ABSOLUTELY NOTHING to do with JOB SECURITY. What's so difficult
to fathom about OpenVMS STR$CONCAT that you'd have to resort to strcat()?
And, FWIW, your beloved strcat() is really only STR$APPEND. STR$CONCAT is
capable of concatenating a number of strings into on string which is what
the poorly prototyped STR$CONCAT definition is causing your beloved "C" to
vomit.

When KLUDGE, errr... C, supports *dynamic* string descriptors and or the
whole of the OpenVMS infrastructure used null terminated strings a la *IX,
then, maybe, I'll use #include <strings.h>. OpenVMS code should/must use
OpenVMS interfaces. I don't need wrappers of KLUDGE, errr... C making the
code look *IX to appease the mindset that all the worlds the plain vanilla
of *IX.


The John way:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main()
{
char *a = {"a"};
char *is = {"is"};
char *space = {" "};
char *f_bomb = {"fucking"};
char *C = {"kludge"};
char *kludge = {"C"};
char *exclamations = {"!!!"};

char *dynstr;

int length = strlen(kludge);
length += strlen(space);
length += strlen(is);
length += strlen(space);
length += strlen(a);
length += strlen(space);
length += strlen(f_bomb);
length += strlen(space);
length += strlen(C);
length += strlen(exclamations);

dynstr = malloc (++length);

strcat(dynstr,kludge);
strcat(dynstr,space);
strcat(dynstr,is);
strcat(dynstr,space);
strcat(dynstr,a);
strcat(dynstr,space);
strcat(dynstr,f_bomb);
strcat(dynstr,space);
strcat(dynstr,C);
strcat(dynstr,exclamations);

printf("%s\n",dynstr);
}

The OpenVMS and VAXman way:

#define __NEW_STARLET new_and_improved_aint_that_much_better

#include <descrip.h>
#include <lib$routines.h>
#define STR$CONCAT STR$CONCAT_is_badly_prototyped_in_STR$ROUTINES_header
#include <str$routines.h> // OpenVMS STR$ RTL prototype definitions
#undef STR$CONCAT
#define str$concat STR$CONCAT
unsigned int str$concat(struct dsc$descriptor_s*, struct dsc$descriptor_s*, __optional_params);

main()
{
$DESCRIPTOR(a,"a");
$DESCRIPTOR(is,"is");
$DESCRIPTOR(space," ");
$DESCRIPTOR(f_bomb,"fucking");
$DESCRIPTOR(C,"kludge");
$DESCRIPTOR(kludge,"C");
$DESCRIPTOR(exclamations,"!!!");

struct dsc$descriptor_s dynstr = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_D, 0 };

STR$CONCAT(&dynstr,&kludge,&space,&is,&space,&a,&space,&f_bomb,&space,&C,&exclamations);
LIB$PUT_OUTPUT(&dynstr);
}
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
JohnF
2014-02-10 15:12:29 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by JohnF
Post by V***@SendSpamHere.ORG
I've encountered a VMS library call prototype that is incorrect.
How can I override/overwrite the prototype in my source
to make it correct?
OK. The function is STR$CONCAT.
somewhere VMS pre-V8.*, where it's WRONG, WRONG, WRONG...
#define str$concat STR$CONCAT
#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string);
and later VMS versions, where it's workable,...
#define str$concat STR$CONCAT
#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string_1,
__optional_params);
Now, if you can include <str$routines.h> and make this go away, I'm wanting.
Is that actual entry point uppercase?
You might (or might not) be able to get away with
something like
#define STR$CONCAT dummy
#include <str$routines.h>
whereby the prototype refers to a dummy() func.
Then
#undef STR$CONCAT
#redefine str$concat STR$CONCAT
and prototype the actual func any way you like.
Thanks John. Here's the KLUDGE written in KLUDGE, errr... C.
#define STR$CONCAT STR$CONCAT_badly_prototyped_in_STR$ROUTINES_header
#include <str$routines.h> // OpenVMS STR$ RTL prototype definitions
#undef STR$CONCAT
#define str$concat STR$CONCAT
unsigned int str$concat(struct dsc$descriptor_s*,
struct dsc$descriptor_s*, __optional_params);
Glad it worked for you. Sometimes you've
just got to out-stupid the machine:).
Post by V***@SendSpamHere.ORG
Post by JohnF
But I've got to ask: why would you/anybody use vms-specific
library stuff for ansi-standard functionality?
ANSI standard? ANSI-C standard? confusion?
Not sure if that's a question or a comment.
If the former, I kind of mean conforming to K&R, 2nd edition
of "The C Programming Language". There are later standards,
e.g., cc/standard=ansi89, but for maintaining old code it's
probably easier/safer to just stick with that unless you can't
for one reason or another.
Post by V***@SendSpamHere.ORG
Post by JohnF
Besides job security, that is?
I recall some code I became responsible for, where after
reading through several pages of rms stuff, it dawned on
me the guy could just have done an fopen()/fprintf()'s.
It was ridiculous to write it the way he did.
Maybe he wanted files that weren't streams? Index files?
No, no, nothing vms-specific. I read the code,
including open and fab. No rabs.
Post by V***@SendSpamHere.ORG
Perhaps, wanted
to avoid the wrapper overhead to the real services below?
I don't know nor do I care.
I an writing VERY OpenVMS specific code.
I don't want nor do I need the *IXisms.
Nothing I said, not strcat nor fopen/fprintf, is an x-ism.
All ansi standard, as above.
Works identically on vms, unix, windows, etc.
If not, the compiler can't call itself "C".
Post by V***@SendSpamHere.ORG
Post by JohnF
I'm too lazy to look up what those optional args
might be doing for you, but the "real solution" here
is to replace str$concat() with ansi-standard strcat()
wherever possible. Modulo job security, that is.
This has ABSOLUTELY NOTHING to do with JOB SECURITY.
I was just kidding around about all that.
Post by V***@SendSpamHere.ORG
What's so difficult
to fathom about OpenVMS STR$CONCAT that you'd have to resort to strcat()?
And, FWIW, your beloved strcat() is really only STR$APPEND. STR$CONCAT is
capable of concatenating a number of strings into on string which is what
the poorly prototyped STR$CONCAT definition is causing your beloved "C" to
vomit.
When KLUDGE, errr... C, supports *dynamic* string descriptors and or the
whole of the OpenVMS infrastructure used null terminated strings a la *IX,
then, maybe, I'll use #include <strings.h>. OpenVMS code should/must use
OpenVMS interfaces. I don't need wrappers of KLUDGE, errr... C making the
code look *IX to appease the mindset that all the worlds the plain vanilla
of *IX.
Nope...
char *words[] = { "a", "is", ..., "\000" },
*word, string[999]="\000";
int length = 0;
for ( word=words[0]; *word != '\000'; word++ ) {
int len=strlen(word);
if ( length+len >= 999 ) break; /* or realloc and cat */
strcat(string,word); length+=len; }
Or you could alloc/realloc string if you don't like
that 999.
But you already knew all that, right? You're just
intentionally making it look harder that necessary,
and maybe a little more vulgar than necessary, too
(note: gratuitous vulgarity can sometimes be a
giveaway as to what's going on).
Maybe this is still harder than the str$concat way,
maybe not. But you're right that in this particular
case, I wouldn't personally have chosen to use
vms library stuff. Try an fao example instead
(note: f=formatted). I'd probably use it for some
of the more complicated stuff of that sort.
Post by V***@SendSpamHere.ORG
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
char *a = {"a"};
char *is = {"is"};
char *space = {" "};
char *f_bomb = {"fucking"};
char *C = {"kludge"};
char *kludge = {"C"};
char *exclamations = {"!!!"};
char *dynstr;
int length = strlen(kludge);
length += strlen(space);
length += strlen(is);
length += strlen(space);
length += strlen(a);
length += strlen(space);
length += strlen(f_bomb);
length += strlen(space);
length += strlen(C);
length += strlen(exclamations);
dynstr = malloc (++length);
strcat(dynstr,kludge);
strcat(dynstr,space);
strcat(dynstr,is);
strcat(dynstr,space);
strcat(dynstr,a);
strcat(dynstr,space);
strcat(dynstr,f_bomb);
strcat(dynstr,space);
strcat(dynstr,C);
strcat(dynstr,exclamations);
printf("%s\n",dynstr);
}
#define __NEW_STARLET new_and_improved_aint_that_much_better
#include <descrip.h>
#include <lib$routines.h>
#define STR$CONCAT STR$CONCAT_is_badly_prototyped_in_STR$ROUTINES_header
#include <str$routines.h> // OpenVMS STR$ RTL prototype definitions
#undef STR$CONCAT
#define str$concat STR$CONCAT
unsigned int str$concat(struct dsc$descriptor_s*, struct dsc$descriptor_s*, __optional_params);
main()
{
$DESCRIPTOR(a,"a");
$DESCRIPTOR(is,"is");
$DESCRIPTOR(space," ");
$DESCRIPTOR(f_bomb,"fucking");
$DESCRIPTOR(C,"kludge");
$DESCRIPTOR(kludge,"C");
$DESCRIPTOR(exclamations,"!!!");
struct dsc$descriptor_s dynstr = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_D, 0 };
STR$CONCAT(&dynstr,&kludge,&space,&is,&space,&a,&space,&f_bomb,&space,&C,&exclamations);
LIB$PUT_OUTPUT(&dynstr);
}
--
John Forkosh ( mailto: ***@f.com where j=john and f=forkosh )
Stephen Hoffman
2014-02-10 15:35:14 UTC
Permalink
...There are later standards, e.g., cc/standard=ansi89, but for
maintaining old code it's probably easier/safer to just stick with that
unless you can't for one reason or another.
I'm somewhat ambivalent about the C diagnostics.

Certainly if the old C code is working and stable or if the customer is
willing to accept the existing instability and those funky code-smells,
then definitely stay with however the C code was built.

One potential reason for changing the standards compliance (well within
that "for one reason or another" mention): If the old code is acting
like much of the old C code that folks get called in to look at and is
somewhat flaky and with weird or transient or hard-to-debug errors,
then enabling the newer diagnostics can uncover latent errors.

I've had good success stabilizing old C code with just getting the
compiler diagnostics to pass. That can find the triggers for of all
sorts of flaky bugs and weird crashes.

Old K&R C code can be particularly flaky, in my experience.

/STANDARD=C89? If up-armoring the source code is on the menu, then go
/STANDARD=LATEST or /STANDARD=C99 if you can, and preferably with
/ENABLE=WARN QUESTCODE enabled.

If the code is security-relevent, I'd definitely crank up the
diagnostics <http://labs.hoffmanlabs.com/node/912>, and I'd also
explicitly locate and deprecate some of the older C calls
<http://labs.hoffmanlabs.com/node/1317>

If the applications are still flaky, then identifying and targetting a
few high-error-profile modules or routines within the code for rework
or rewrite.
--
Pure Personal Opinion | HoffmanLabs LLC
JohnF
2014-02-11 09:32:34 UTC
Permalink
Post by Stephen Hoffman
...There are later standards, e.g., cc/standard=ansi89, but for
maintaining old code it's probably easier/safer to just stick with that
unless you can't for one reason or another.
I'm somewhat ambivalent about the C diagnostics.
Certainly if the old C code is working and stable or if the customer is
willing to accept the existing instability and those funky code-smells,
then definitely stay with however the C code was built.
One potential reason for changing the standards compliance (well within
that "for one reason or another" mention): If the old code is acting
like much of the old C code that folks get called in to look at and is
somewhat flaky and with weird or transient or hard-to-debug errors,
then enabling the newer diagnostics can uncover latent errors.
I've had good success stabilizing old C code with just getting the
compiler diagnostics to pass. That can find the triggers for of all
sorts of flaky bugs and weird crashes.
Old K&R C code can be particularly flaky, in my experience.
Well, flakiness is an attribute of the code/programmer-who-wrote-it
rather than the standard. Well-written code won't be flaky, regardless
of what standards it conforms to. Of course, that's just axiomatically
true by the very definition of "well-written". If the old code you've
looked at is more flaky than later code, that just reflects badly
on the staff at that earlier time.
Post by Stephen Hoffman
/STANDARD=C89? If up-armoring the source code is on the menu, then go
/STANDARD=LATEST or /STANDARD=C99 if you can, and preferably with
/ENABLE=WARN QUESTCODE enabled.
If the code is security-relevent, I'd definitely crank up the
diagnostics <http://labs.hoffmanlabs.com/node/912>, and I'd also
explicitly locate and deprecate some of the older C calls
<http://labs.hoffmanlabs.com/node/1317>
If the applications are still flaky, then identifying and targetting a
few high-error-profile modules or routines within the code for rework
or rewrite.
I haven't found any general-purpose technique for successfully
dealing with flaky code. In a preceding post, I mentioned a guy
using rms where he could have just used fprintf. In the same
program he had a func that did use fopen/fgets on files with data
to be read. This was for a financial app that occcasionally had to
process "special issues" not following the regular rules.
But he forgot to fclose these files before returning. And the vms
account under which it was running had a files open limit of 50.
So if a portfolio being valued had more than 50 "special issues",
all subsequent fopen's failed, and the func just quietly returned
a 0.0 value without asserting any kind of error.
I never found this... until the port to unix was complete.
Then, during parallel testing,... well, you know the end of that
story. But the point is, how the heck could I have ever noticed
that bug just reading through the several hundred thousand lines
of code comprising the entire app??? It was easy enough to spot
once the parallel testing clued me in to what needed some careful
looking at. But pretty much impossible to just stumble upon
otherwise.
--
John Forkosh ( mailto: ***@f.com where j=john and f=forkosh )
Bill Gunshannon
2014-02-11 13:54:53 UTC
Permalink
Post by JohnF
Post by Stephen Hoffman
...There are later standards, e.g., cc/standard=ansi89, but for
maintaining old code it's probably easier/safer to just stick with that
unless you can't for one reason or another.
I'm somewhat ambivalent about the C diagnostics.
Certainly if the old C code is working and stable or if the customer is
willing to accept the existing instability and those funky code-smells,
then definitely stay with however the C code was built.
One potential reason for changing the standards compliance (well within
that "for one reason or another" mention): If the old code is acting
like much of the old C code that folks get called in to look at and is
somewhat flaky and with weird or transient or hard-to-debug errors,
then enabling the newer diagnostics can uncover latent errors.
I've had good success stabilizing old C code with just getting the
compiler diagnostics to pass. That can find the triggers for of all
sorts of flaky bugs and weird crashes.
Old K&R C code can be particularly flaky, in my experience.
Well, flakiness is an attribute of the code/programmer-who-wrote-it
rather than the standard. Well-written code won't be flaky, regardless
of what standards it conforms to. Of course, that's just axiomatically
true by the very definition of "well-written". If the old code you've
looked at is more flaky than later code, that just reflects badly
on the staff at that earlier time.
Yeah, like people who turn off Warnings rather than fixing the things they
Warn about.

bill
--
Bill Gunshannon | de-moc-ra-cy (di mok' ra see) n. Three wolves
***@cs.scranton.edu | and a sheep voting on what's for dinner.
University of Scranton |
Scranton, Pennsylvania | #include <std.disclaimer.h>
Paul Sture
2014-02-14 08:05:04 UTC
Permalink
Post by JohnF
Post by Stephen Hoffman
If the code is security-relevent, I'd definitely crank up the
diagnostics <http://labs.hoffmanlabs.com/node/912>, and I'd also
explicitly locate and deprecate some of the older C calls
<http://labs.hoffmanlabs.com/node/1317>
If the applications are still flaky, then identifying and targetting a
few high-error-profile modules or routines within the code for rework
or rewrite.
I haven't found any general-purpose technique for successfully
dealing with flaky code.
Once you get into the nitty gritty of an old project the module's author
name becomes a good guide :-)
Post by JohnF
In a preceding post, I mentioned a guy using rms where he could have just
used fprintf. In the same program he had a func that did use fopen/fgets
on files with data to be read. This was for a financial app that
occcasionally had to process "special issues" not following the regular
rules. But he forgot to fclose these files before returning. And the vms
account under which it was running had a files open limit of 50. So if a
portfolio being valued had more than 50 "special issues", all subsequent
fopen's failed, and the func just quietly returned a 0.0 value without
asserting any kind of error.
That could be an example of Cargo Cult Programming:

<http://www.catb.org/~esr/jargon/html/C/cargo-cult-programming.html>
<https://en.wikipedia.org/wiki/Cargo_cult_programming>

One of the problems rectifying such programming is that folks tend to
get wrapped up in the details of "the FABs and the RABs"* rather than
taking a step back and doing what you suggest: replacing the lot with
simple open/read/write/close statements using the HLL constructs available.

* aka talking bits and bytes rather than concentrating on the business
requirement
Post by JohnF
I never found this... until the port to unix was complete.
Then, during parallel testing,... well, you know the end of that
story. But the point is, how the heck could I have ever noticed
that bug just reading through the several hundred thousand lines
of code comprising the entire app??? It was easy enough to spot
once the parallel testing clued me in to what needed some careful
looking at. But pretty much impossible to just stumble upon
otherwise.
But once you've found that one example, a quick search through the
entire codebase for similar pieces of code becomes feasible.
Checking to see if that author (or whoever he/she copied from) has
made that mistake in other modules might be sensible too.



--
Paul Sture
V***@SendSpamHere.ORG
2014-02-10 15:43:58 UTC
Permalink
{...snip...}
Nope...
char *words[] = { "a", "is", ..., "\000" },
*word, string[999]="\000";
int length = 0;
for ( word=words[0]; *word != '\000'; word++ ) {
int len=strlen(word);
if ( length+len >= 999 ) break; /* or realloc and cat */
strcat(string,word); length+=len; }
Or you could alloc/realloc string if you don't like
that 999.
But you already knew all that, right? You're just
intentionally making it look harder that necessary,
and maybe a little more vulgar than necessary, too
(note: gratuitous vulgarity can sometimes be a
giveaway as to what's going on).
No, I was trying to parallel my examples The declaration of the strings was
not part of the problem; only a way to demonstrate it. If I knew what each
part of each string was going to be -- as in your example, an array thereof
-- there would be no reason to even use concat.

The issue is that a number of strings exist as OpenVMS string descriptors.
I call upon STR$CONCAT to concatenate them because I don't know what each
string will be. The target string is defined as an OpenVMS dynamic string
descriptor so it can dynamically resize to whatever is needed to house the
concatenated parts. OpenVMS and, specifically, the RTL libraries, handle
the dynamic strings quite well.

STR$CONCAT(&sentence,&word1,&word2,...,&wordN);

...is a whole world easier on the eyes and more understandably readable
than:

int length = 0;
for ( word=words[0]; *word != '\000'; word++ ) {
int len=strlen(word);
if ( length+len >= 999 ) break; /* or realloc and cat */
strcat(string,word); length+=len; }


Anyway, your suggestion worked and for that I am grateful.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
JohnF
2014-02-11 09:02:33 UTC
Permalink
Post by V***@SendSpamHere.ORG
{...snip...}
Nope...
char *words[] = { "a", "is", ..., "\000" },
*word, string[999]="\000";
int length = 0;
for ( word=words[0]; *word != '\000'; word++ ) {
int len=strlen(word);
if ( length+len >= 999 ) break; /* or realloc and cat */
strcat(string,word); length+=len; }
Or you could alloc/realloc string if you don't like
that 999.
But you already knew all that, right? You're just
intentionally making it look harder that necessary,
and maybe a little more vulgar than necessary, too
(note: gratuitous vulgarity can sometimes be a
giveaway as to what's going on).
No, I was trying to parallel my examples The declaration of the strings was
not part of the problem; only a way to demonstrate it. If I knew what each
part of each string was going to be -- as in your example, an array thereof
-- there would be no reason to even use concat.
The issue is that a number of strings exist as OpenVMS string descriptors.
I call upon STR$CONCAT to concatanate them
Okay, yeah, if the existing code is already chock-full of descriptors,
then I agree: use the library funcs that can deal with them directly.
And that's especially true if you're intent on staying vms-based anyway.
Post by V***@SendSpamHere.ORG
because I don't know what each
string will be. The target string is defined as an OpenVMS dynamic string
descriptor so it can dynamically resize to whatever is needed to house the
concatenated parts. OpenVMS and, specifically, the RTL libraries, handle
the dynamic strings quite well.
STR$CONCAT(&sentence,&word1,&word2,...,&wordN);
...is a whole world easier on the eyes and more understandably readable
int length = 0;
for ( word=words[0]; *word != '\000'; word++ ) {
int len=strlen(word);
if ( length+len >= 999 ) break; /* or realloc and cat */
strcat(string,word); length+=len; }
Aside: nobody seemed to notice the little bug I embedded in
that snippet, just to see how carefully it was being read.
That word++ won't do the necessary job.
More to the point (even though there's no longer any
real point to deal with), yeah, yours is still more readable,
but I'd assumed your actual situation involved a variable
number of elements to be concatanated, whereby
you'd need some kind of similar loop regardless.
Post by V***@SendSpamHere.ORG
Anyway, your suggestion worked and for that I am grateful.
Yeah, glad it helped. That other guy's (was it "hb"?) suggestion
to just copy the correct header is probably the generally wiser
solution, rather than embedding this silly-looking kludge into
your application code. But whatever works.
--
John Forkosh ( mailto: ***@f.com where j=john and f=forkosh )
V***@SendSpamHere.ORG
2014-02-11 14:24:26 UTC
Permalink
{...snip...}
More to the point (even though there's no longer any
real point to deal with), yeah, yours is still more readable,
but I'd assumed your actual situation involved a variable
number of elements to be concatanated, whereby
you'd need some kind of similar loop regardless.
One of the nicest things about dynamic string descriptors is that the RTLs
that will accept them will resize them as needed. So, for that STR$CONCAT
call, it's possible to:

STR$CONCAT(&my_dynstr_d, &str1_d, &str2_d, ... , strN_d, &my_dynstr_d);

... or ...

STR$CONCAT(&my_dynstr_d, &my_dynstr_d, &str1_d, &str2_d, ... , strN_d);

The first argument is the target string. Therefore, in the first example,
those various strings are prepended to the existing string in my_dynstr_d.
In the second example, those various strings are appended to my_dynstr_d.

I let the RTLs handle the string length computation and the "malloc()" and
"free()", in C-speak, making the code far cleaner.

One of the things I hate seeing in C code on VMS is (unless the callee is
expecting a string of exactly 255 bytes and you don't plan to do anything
else with it):

char buffer[255];
$DESCRIPTOR(buffer_d,buffer);
:
RTL$populate_descriptor(&buffer_d);
:
some C code possibly referencing buffer_d.dsc$a_pointer.
:

I let the RTL decide the buffer size needed and I let the RTL dynamically
allocate/reallocate it.

struct dsc$descriptor_s buffer_d = {0,DSC$K_DTYPE_T,DSC$K_CLASS_D,NULL};
:
RTL$populate_descriptor(&buffer_d);
:
some C code possibly referencing buffer_d.dsc$a_pointer.
:


And, even if it's a system service which will only accepts a fixed length
string descriptor of some length,...

struct dsc$descriptor_s dynstr_d = {0,DSC$K_DTYPE_T,DSC$K_CLASS_D,NULL};
:
STR$GET1_DX(&((unsigned short)255), &dynstr_d);
SYS$whatever(...,&dynstr_d),...);
:


The result can then be trimmed down by one of the STR$ RTLs and this string
descriptor can then be manipulated by any subsequent RTLs which do accept a
dynamic string descriptor.

:
STR$TRIM(&dynstr_d,&dynstr_d);
Post by V***@SendSpamHere.ORG
Anyway, your suggestion worked and for that I am grateful.
Yeah, glad it helped. That other guy's (was it "hb"?) suggestion
to just copy the correct header is probably the generally wiser
solution, rather than embedding this silly-looking kludge into
your application code. But whatever works.
The problem is that this code may, someday, be handed off to those for whom
it's been developed. They may not have mucked with header files to make it
work. And, who knows what will happen with a compiler update; it might re-
build the offending header.

[Note] Error checking should be added to your code if/when you use the RTLs
detailed herein.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
Chris Scheers
2014-02-11 18:13:22 UTC
Permalink
Post by V***@SendSpamHere.ORG
The problem is that this code may, someday, be handed off to those for whom
it's been developed. They may not have mucked with header files to make it
work. And, who knows what will happen with a compiler update; it might re-
build the offending header.
[Note] Error checking should be added to your code if/when you use the RTLs
detailed herein.
I guess I wasn't clear enough. In no way do I recommend copying the
headers from a later system and replacing the "system" headers on the
current system. As you point out, compiler/system updates can change
things on you. This may also break other working builds.

Put the copied headers in a local directory (perhaps the project source
directory) and modify the compile script (via command line, logical
name, etc.) to pick up the local copy before the (possibly incorrect)
system ones.

These copied headers then become part of the project and should be
handed off with the project.

If copyright issues come into play, the hand off instructions should
include information about where to get the correct headers instead of
the headers themselves.
--
-----------------------------------------------------------------------
Chris Scheers, Applied Synergy, Inc.

Voice: 817-237-3360 Internet: ***@applied-synergy.com
Fax: 817-237-3074
JF Mezei
2014-02-12 04:39:23 UTC
Permalink
Post by Chris Scheers
current system. As you point out, compiler/system updates can change
things on you. This may also break other working builds.
adding the optional arguments which are supported by the RTL won't break
other builds. Software which does not make use of the optional arguments
will continue to compile fine.

And if Mr VAXman's compiler kludge work on both the more recent and
fixed version and the older ones with the bad C header, then the kludge
will work when customers upgrade from older to newer VMS versions.

However, at this point, I find it highly unlikely that customers would
bother upgrading VMS versions. If they aren't at 8.3, they aren't likely
to upgrade to 8.3 before going off VMS to another platform.
Paul Sture
2014-02-14 08:22:56 UTC
Permalink
Post by JF Mezei
Post by Chris Scheers
current system. As you point out, compiler/system updates can change
things on you. This may also break other working builds.
adding the optional arguments which are supported by the RTL won't break
other builds. Software which does not make use of the optional arguments
will continue to compile fine.
And if Mr VAXman's compiler kludge work on both the more recent and
fixed version and the older ones with the bad C header, then the kludge
will work when customers upgrade from older to newer VMS versions.
However, at this point, I find it highly unlikely that customers would
bother upgrading VMS versions. If they aren't at 8.3, they aren't likely
to upgrade to 8.3 before going off VMS to another platform.
Are you sure about that, given that 8.3 is on the supported list?

--
Paul Sture
V***@SendSpamHere.ORG
2014-02-11 20:58:49 UTC
Permalink
Post by Chris Scheers
Post by V***@SendSpamHere.ORG
The problem is that this code may, someday, be handed off to those for whom
it's been developed. They may not have mucked with header files to make it
work. And, who knows what will happen with a compiler update; it might re-
build the offending header.
[Note] Error checking should be added to your code if/when you use the RTLs
detailed herein.
I guess I wasn't clear enough. In no way do I recommend copying the
headers from a later system and replacing the "system" headers on the
current system. As you point out, compiler/system updates can change
things on you. This may also break other working builds.
Put the copied headers in a local directory (perhaps the project source
directory) and modify the compile script (via command line, logical
name, etc.) to pick up the local copy before the (possibly incorrect)
system ones.
These copied headers then become part of the project and should be
handed off with the project.
If copyright issues come into play, the hand off instructions should
include information about where to get the correct headers instead of
the headers themselves.
C just need a new #pragma:

The current default being:

#pragma string_typing weak_minds

and replaceable with:

#pragma strong_typing do_what_you_want_with_the_others_just_leave_me_alone
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
Simon Clubley
2014-02-12 00:58:33 UTC
Permalink
Post by V***@SendSpamHere.ORG
#pragma string_typing weak_minds
#pragma strong_typing do_what_you_want_with_the_others_just_leave_me_alone
If you think C has strong typing, you should try Ada some time. :-)

Simon.
--
Simon Clubley, ***@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world
Bob Koehler
2014-02-13 14:18:28 UTC
Permalink
Post by Simon Clubley
If you think C has strong typing, you should try Ada some time. :-)
At least in Ada we don't have to sit arounf wondering what "}" means
on this line.
Simon Clubley
2014-02-13 17:58:30 UTC
Permalink
Post by Bob Koehler
Post by Simon Clubley
If you think C has strong typing, you should try Ada some time. :-)
At least in Ada we don't have to sit arounf wondering what "}" means
on this line.
Oh, I agree. :-)

In case it's not obvious from previous postings, I like Ada (and Wirth
style languages in general).

Simon.
--
Simon Clubley, ***@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world
V***@SendSpamHere.ORG
2014-02-13 18:52:12 UTC
Permalink
Post by Simon Clubley
Post by Bob Koehler
Post by Simon Clubley
If you think C has strong typing, you should try Ada some time. :-)
At least in Ada we don't have to sit arounf wondering what "}" means
on this line.
Oh, I agree. :-)
In case it's not obvious from previous postings, I like Ada (and Wirth
style languages in general).
If Ada is a Wirth style language, does that imply the C is a Wirthless style
language? :)
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
David Froble
2014-02-13 20:31:09 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by Simon Clubley
Post by Bob Koehler
Post by Simon Clubley
If you think C has strong typing, you should try Ada some time. :-)
At least in Ada we don't have to sit arounf wondering what "}" means
on this line.
Oh, I agree. :-)
In case it's not obvious from previous postings, I like Ada (and Wirth
style languages in general).
If Ada is a Wirth style language, does that imply the C is a Wirthless style
language? :)
You're making me laugh, on a cold winter day with snow coming down, and
I have an 800 ft driveway. An impressive achivement.

:-)
Bob Koehler
2014-02-13 20:49:11 UTC
Permalink
Post by V***@SendSpamHere.ORG
If Ada is a Wirth style language, does that imply the C is a Wirthless style
language? :)
Ooooh, I like it. :-)
BillPedersen
2014-02-13 20:50:38 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by Simon Clubley
Post by Bob Koehler
Post by Simon Clubley
If you think C has strong typing, you should try Ada some time. :-)
At least in Ada we don't have to sit arounf wondering what "}" means
on this line.
Oh, I agree. :-)
In case it's not obvious from previous postings, I like Ada (and Wirth
style languages in general).
If Ada is a Wirth style language, does that imply the C is a Wirthless style
language? :)
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG
Well I speak to machines with the voice of humanity.
Well, Brian, maybe not "Wirthless" just unWirthy.

Bill.
Paul Sture
2014-02-14 08:15:52 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by Simon Clubley
Post by Bob Koehler
Post by Simon Clubley
If you think C has strong typing, you should try Ada some time. :-)
At least in Ada we don't have to sit arounf wondering what "}" means
on this line.
Oh, I agree. :-)
In case it's not obvious from previous postings, I like Ada (and Wirth
style languages in general).
If Ada is a Wirth style language, does that imply the C is a Wirthless style
language? :)
Some would say that C doesn't have any sense of style at all.

It is surely no coincidence that the rise in the popularity of C came in the
same timeframe as that of the term "computer nerd" :-)

--
Paul Sture
V***@SendSpamHere.ORG
2014-02-13 18:40:56 UTC
Permalink
Post by Bob Koehler
Post by Simon Clubley
If you think C has strong typing, you should try Ada some time. :-)
At least in Ada we don't have to sit arounf wondering what "}" means
on this line.
ROTFLMFAO! :)
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
V***@SendSpamHere.ORG
2014-02-12 01:31:08 UTC
Permalink
Post by Simon Clubley
Post by V***@SendSpamHere.ORG
#pragma string_typing weak_minds
#pragma strong_typing do_what_you_want_with_the_others_just_leave_me_alone
If you think C has strong typing, you should try Ada some time. :-)
I did Ada for GE Astrospace/NASA Mars Observer Satellite program. I'd take
it over C.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
hb
2014-02-10 15:48:15 UTC
Permalink
Post by V***@SendSpamHere.ORG
Thanks John. Here's the KLUDGE written in KLUDGE, errr... C.
#define STR$CONCAT STR$CONCAT_is_badly_prototyped_in_STR$ROUTINES_header
#include <str$routines.h> // OpenVMS STR$ RTL prototype definitions
#undef STR$CONCAT
#define str$concat STR$CONCAT
unsigned int str$concat(struct dsc$descriptor_s*, struct dsc$descriptor_s*, __optional_params);
FWIW, you don't need to #re-define str$concat, it is already defined to
STR$CONCAT (if it weren't you would get a compiler warning, anyway).

Yes, this works around one problem with the VMS supplied C header files.

On the other hand, struct dsc$descriptor_s is usually only used for a
"Fixed-Length Descriptor", with suffix "_s" matching the suffix in
DSC$K_CLASS_S. STR$CONCAT accepts any descriptor, but that can't be
expressed in a C prototype. That's probably the reason why "they" used
"void *" rather than "struct dsc$descriptor *". The latter would require
some casts for the struct dsc$descriptor_d as destination type as well
as for struct dsc$descriptor_s as source type. But with "void *" it is
questionable whether there can be useful type checking at all.
V***@SendSpamHere.ORG
2014-02-10 16:31:36 UTC
Permalink
Post by hb
Post by V***@SendSpamHere.ORG
Thanks John. Here's the KLUDGE written in KLUDGE, errr... C.
#define STR$CONCAT STR$CONCAT_is_badly_prototyped_in_STR$ROUTINES_header
#include <str$routines.h> // OpenVMS STR$ RTL prototype definitions
#undef STR$CONCAT
#define str$concat STR$CONCAT
unsigned int str$concat(struct dsc$descriptor_s*, struct dsc$descriptor_s*, __optional_params);
FWIW, you don't need to #re-define str$concat, it is already defined to
STR$CONCAT (if it weren't you would get a compiler warning, anyway).
Yes, this works around one problem with the VMS supplied C header files.
On the other hand, struct dsc$descriptor_s is usually only used for a
"Fixed-Length Descriptor", with suffix "_s" matching the suffix in
DSC$K_CLASS_S. STR$CONCAT accepts any descriptor, but that can't be
expressed in a C prototype. That's probably the reason why "they" used
"void *" rather than "struct dsc$descriptor *". The latter would require
some casts for the struct dsc$descriptor_d as destination type as well
as for struct dsc$descriptor_s as source type. But with "void *" it is
questionable whether there can be useful type checking at all.
Like I said before: Strong typing is for weak minds.

FWIW, I can pass dynamic strings as well as static strings when the args
are define 'struct dsc$descriptor_s *". The compiler is not so congenial
when I define it just 'struct dsc$descriptor *' despite the fact that the
dsc$descriptor, dsc$descriptor_s and dsc$descriptor_d all look the same.
The C compiler doesn't see the dsc$b_class or dsc$b_dtype values. There
should be a way to provide for this but then... same old song...
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
David Froble
2014-02-11 07:55:40 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by JohnF
Post by V***@SendSpamHere.ORG
I've encountered a VMS library call prototype that is incorrect.
How can I override/overwrite the prototype in my source
to make it correct?
OK. The function is STR$CONCAT.
somewhere VMS pre-V8.*, where it's WRONG, WRONG, WRONG...
#define str$concat STR$CONCAT
#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string);
and later VMS versions, where it's workable,...
#define str$concat STR$CONCAT
#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string_1,
__optional_params);
Now, if you can include <str$routines.h> and make this go away, I'm wanting.
Is that actual entry point uppercase?
You might (or might not) be able to get away with
something like
#define STR$CONCAT dummy
#include <str$routines.h>
whereby the prototype refers to a dummy() func.
Then
#undef STR$CONCAT
#redefine str$concat STR$CONCAT
and prototype the actual func any way you like.
Thanks John. Here's the KLUDGE written in KLUDGE, errr... C.
#define STR$CONCAT STR$CONCAT_is_badly_prototyped_in_STR$ROUTINES_header
#include <str$routines.h> // OpenVMS STR$ RTL prototype definitions
#undef STR$CONCAT
#define str$concat STR$CONCAT
unsigned int str$concat(struct dsc$descriptor_s*, struct dsc$descriptor_s*, __optional_params);
Post by JohnF
But I've got to ask: why would you/anybody use vms-specific
library stuff for ansi-standard functionality?
ANSI standard? ANSI-C standard? confusion?
Post by JohnF
Besides job security, that is?
I recall some code I became responsible for, where after
reading through several pages of rms stuff, it dawned on
me the guy could just have done an fopen()/fprintf()'s.
It was ridiculous to write it the way he did.
Maybe he wanted files that weren't streams? Index files? Perhaps, wanted
to avoid the wrapper overhead to the real services below? I don't know nor
do I care. *I* an writing VERY OpenVMS specific code. I don't want nor do
I need the *IXisms.
Post by JohnF
I'm too lazy to look up what those optional args
might be doing for you, but the "real solution" here
is to replace str$concat() with ansi-standard strcat()
wherever possible. Modulo job security, that is.
This has ABSOLUTELY NOTHING to do with JOB SECURITY. What's so difficult
to fathom about OpenVMS STR$CONCAT that you'd have to resort to strcat()?
And, FWIW, your beloved strcat() is really only STR$APPEND. STR$CONCAT is
capable of concatenating a number of strings into on string which is what
the poorly prototyped STR$CONCAT definition is causing your beloved "C" to
vomit.
When KLUDGE, errr... C, supports *dynamic* string descriptors and or the
whole of the OpenVMS infrastructure used null terminated strings a la *IX,
then, maybe, I'll use #include <strings.h>. OpenVMS code should/must use
OpenVMS interfaces. I don't need wrappers of KLUDGE, errr... C making the
code look *IX to appease the mindset that all the worlds the plain vanilla
of *IX.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
char *a = {"a"};
char *is = {"is"};
char *space = {" "};
char *f_bomb = {"fucking"};
char *C = {"kludge"};
char *kludge = {"C"};
char *exclamations = {"!!!"};
char *dynstr;
int length = strlen(kludge);
length += strlen(space);
length += strlen(is);
length += strlen(space);
length += strlen(a);
length += strlen(space);
length += strlen(f_bomb);
length += strlen(space);
length += strlen(C);
length += strlen(exclamations);
dynstr = malloc (++length);
strcat(dynstr,kludge);
strcat(dynstr,space);
strcat(dynstr,is);
strcat(dynstr,space);
strcat(dynstr,a);
strcat(dynstr,space);
strcat(dynstr,f_bomb);
strcat(dynstr,space);
strcat(dynstr,C);
strcat(dynstr,exclamations);
printf("%s\n",dynstr);
}
#define __NEW_STARLET new_and_improved_aint_that_much_better
#include <descrip.h>
#include <lib$routines.h>
#define STR$CONCAT STR$CONCAT_is_badly_prototyped_in_STR$ROUTINES_header
#include <str$routines.h> // OpenVMS STR$ RTL prototype definitions
#undef STR$CONCAT
#define str$concat STR$CONCAT
unsigned int str$concat(struct dsc$descriptor_s*, struct dsc$descriptor_s*, __optional_params);
main()
{
$DESCRIPTOR(a,"a");
$DESCRIPTOR(is,"is");
$DESCRIPTOR(space," ");
$DESCRIPTOR(f_bomb,"fucking");
$DESCRIPTOR(C,"kludge");
$DESCRIPTOR(kludge,"C");
$DESCRIPTOR(exclamations,"!!!");
struct dsc$descriptor_s dynstr = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_D, 0 };
STR$CONCAT(&dynstr,&kludge,&space,&is,&space,&a,&space,&f_bomb,&space,&C,&exclamations);
LIB$PUT_OUTPUT(&dynstr);
}
Sorry to be laughing, but, string manipulation is SO simple in Basic ...
JF Mezei
2014-02-10 13:33:42 UTC
Permalink
Post by V***@SendSpamHere.ORG
#define str$concat STR$CONCAT
#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string_1,
__optional_params);
Now, if you can include <str$routines.h> and make this go away, I'm wanting.
Copy the 8.* module to the source directory.

#include "mystr$routines.h"
instead of

#include <str$routines>


This causes the ibclude to look in the current directory instead of
system library. So you are including your own copy instead of the system
copy. This should work in 7.2 to 8.* snce not much has changed in that
module (but you ca check to see if there are other changes).
Steven Schweda
2014-02-11 21:43:55 UTC
Permalink
Post by V***@SendSpamHere.ORG
OK. The function is STR$CONCAT.
At last.

I lost much interest in this thread when the first few
messages failed to reveal what the actual problem was, so I
may have missed something, but when I'm looking for
compatibility with old systems and/or header files, I usually
avoid defining __NEW_STARLET. I'm currently too lazy to
check a VAX at V7.x, but on my V8.3 Alpha system, that would
seem to select a simplified (and less troublesome?)
declaration of str$concat():

#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string_1,
__optional_params);
#else /* __OLD_STARLET */
unsigned int str$concat(__unknown_params);
#endif /* #ifdef __NEW_STARLET */

I like the type checking, but if defining __NEW_STARLET
kept me from getting the job done, then I might make it
optional (or dependent on __DECC_VER or __CRTL_VER or
something).
V***@SendSpamHere.ORG
2014-02-11 22:20:29 UTC
Permalink
Post by Steven Schweda
Post by V***@SendSpamHere.ORG
OK. The function is STR$CONCAT.
At last.
I lost much interest in this thread when the first few
messages failed to reveal what the actual problem was, so I
may have missed something, but when I'm looking for
compatibility with old systems and/or header files, I usually
avoid defining __NEW_STARLET. I'm currently too lazy to
check a VAX at V7.x, but on my V8.3 Alpha system, that would
seem to select a simplified (and less troublesome?)
#ifdef __NEW_STARLET
unsigned int str$concat(
void *destination_string,
void *source_string_1,
__optional_params);
#else /* __OLD_STARLET */
unsigned int str$concat(__unknown_params);
#endif /* #ifdef __NEW_STARLET */
I like the type checking, but if defining __NEW_STARLET
kept me from getting the job done, then I might make it
optional (or dependent on __DECC_VER or __CRTL_VER or
something).
__NEW_STARLET fixed up many of the "typing" issues. When it's defined, the
header's definitions more closely parallel documented argument definitions.
It's nowhere near perfect and there are still many too many (casts) needed
to make everything copacetic, but it's a start. It would all have been in
Macro if it were up to me but the customer said they can only read C.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
David Froble
2014-02-11 23:39:59 UTC
Permalink
Post by V***@SendSpamHere.ORG
It would all have been in
Macro if it were up to me but the customer said they can only read C.
They lie! I submit that anyone can read BASIC, but I do recall some
almost successful instances of trying to make it unreadable.

Throughtout this whole thread I've seen in my head:

A$ = B$ + C$ + D$ + E$ + F$ + G$ + H$ + I$ + J$ + K$ + L$ + ....

Basic, a language that knows how to work with strings ....

And no, I don't normally declare my variables ....
V***@SendSpamHere.ORG
2014-02-11 23:54:12 UTC
Permalink
Post by David Froble
Post by V***@SendSpamHere.ORG
It would all have been in
Macro if it were up to me but the customer said they can only read C.
They lie! I submit that anyone can read BASIC, but I do recall some
almost successful instances of trying to make it unreadable.
A$ = B$ + C$ + D$ + E$ + F$ + G$ + H$ + I$ + J$ + K$ + L$ + ....
Basic, a language that knows how to work with strings ....
And no, I don't normally declare my variables ....
This particular piece of C has some inner mode code. I'm extra careful with
that using C; however, I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
V***@SendSpamHere.ORG
2014-02-11 23:56:43 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by David Froble
Post by V***@SendSpamHere.ORG
It would all have been in
Macro if it were up to me but the customer said they can only read C.
They lie! I submit that anyone can read BASIC, but I do recall some
almost successful instances of trying to make it unreadable.
A$ = B$ + C$ + D$ + E$ + F$ + G$ + H$ + I$ + J$ + K$ + L$ + ....
Basic, a language that knows how to work with strings ....
And no, I don't normally declare my variables ....
This particular piece of C has some inner mode code. I'm extra careful with
that using C; however, I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
... and, to add, that little bit of string manipulation is a very very minute
part of the whole picture.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
JF Mezei
2014-02-12 04:42:34 UTC
Permalink
Post by V***@SendSpamHere.ORG
I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
But isn't kernel mode the default for you, and you only have to worry
about things breaking on those rare occasions when you jump to user mode
? :-)
V***@SendSpamHere.ORG
2014-02-12 12:39:15 UTC
Permalink
Post by JF Mezei
Post by V***@SendSpamHere.ORG
I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
But isn't kernel mode the default for you, and you only have to worry
about things breaking on those rare occasions when you jump to user mode
? :-)
Pretty much so. :)

I've been at SUPERVISOR mode in a lot of my time working on a DCL debugger
I've mentioned here a few times. I'd been called away from that in recent
weeks to work on RMS CDC (EXEC mode), coded an Excel spreadsheet generator
(USER mode) for a client that writes their app in COBOL (on OpenVMS), made
new Postscript forms and logos artwork (not really OpeNVMS but used there),
and setup and configured a *new* Itegrity Blade cluster even though nobody
has been buying Itegrity for OpenVMS as per HP's "suggestion".
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
Jan-Erik Soderholm
2014-02-12 13:35:11 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by JF Mezei
Post by V***@SendSpamHere.ORG
I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
But isn't kernel mode the default for you, and you only have to worry
about things breaking on those rare occasions when you jump to user mode
? :-)
Pretty much so. :)
I've been at SUPERVISOR mode in a lot of my time working on a DCL debugger
I've mentioned here a few times. I'd been called away from that in recent
weeks to work on RMS CDC (EXEC mode), coded an Excel spreadsheet generator
(USER mode) for a client that writes their app in COBOL (on OpenVMS),..
That is, coding COBOL to create files in Excel/XLS format?

I have done the same at my client, but I used the builtin
Excel tools (xlrd, xlwt) in the Python kit. Makes handling
of Excel files a breeze. Yes, you need some data transfer
from the Cobol apps to the Python Excel generator.

Jan-Erik.
Post by V***@SendSpamHere.ORG
made
new Postscript forms and logos artwork (not really OpeNVMS but used there),
and setup and configured a *new* Itegrity Blade cluster even though nobody
has been buying Itegrity for OpenVMS as per HP's "suggestion".
V***@SendSpamHere.ORG
2014-02-12 14:45:50 UTC
Permalink
Post by Jan-Erik Soderholm
Post by V***@SendSpamHere.ORG
Post by JF Mezei
Post by V***@SendSpamHere.ORG
I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
But isn't kernel mode the default for you, and you only have to worry
about things breaking on those rare occasions when you jump to user mode
? :-)
Pretty much so. :)
I've been at SUPERVISOR mode in a lot of my time working on a DCL debugger
I've mentioned here a few times. I'd been called away from that in recent
weeks to work on RMS CDC (EXEC mode), coded an Excel spreadsheet generator
(USER mode) for a client that writes their app in COBOL (on OpenVMS),..
That is, coding COBOL to create files in Excel/XLS format?
COBOL is not a programming language! ;)

It was all done in C, so that it is callable from their COBOL code (is that
the correct term for all that verbosity?), employing the class libraries of
Perl that handle Data::Table, Spreadsheet::WriteExcel, Excel::Writer::XLSX.
I had looked at the Python libs but my gray matter began to boil trying to
figure out how to exploit/call its classes from C. Also, they wanted logos
displayed on the Excel spreadsheet, so I also took advantage of its Image::*
class. The most annoying part was having to install PERL so that I could
build all of the classes.

Anyway, the customer now only needs to pass a descriptor to the data to be
put in the spreadsheet, a filename for the spreadsheet and the file name of
the logo (optional parameter) if desired.
Post by Jan-Erik Soderholm
I have done the same at my client, but I used the builtin
Excel tools (xlrd, xlwt) in the Python kit. Makes handling
of Excel files a breeze. Yes, you need some data transfer
from the Cobol apps to the Python Excel generator.
How do you invoke Python in/via COBOL?
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
Jan-Erik Soderholm
2014-02-12 17:00:04 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by Jan-Erik Soderholm
Post by V***@SendSpamHere.ORG
Post by JF Mezei
Post by V***@SendSpamHere.ORG
I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
But isn't kernel mode the default for you, and you only have to worry
about things breaking on those rare occasions when you jump to user mode
? :-)
Pretty much so. :)
I've been at SUPERVISOR mode in a lot of my time working on a DCL debugger
I've mentioned here a few times. I'd been called away from that in recent
weeks to work on RMS CDC (EXEC mode), coded an Excel spreadsheet generator
(USER mode) for a client that writes their app in COBOL (on OpenVMS),..
That is, coding COBOL to create files in Excel/XLS format?
COBOL is not a programming language! ;)
It was all done in C, so that it is callable from their COBOL code (is that
the correct term for all that verbosity?), employing the class libraries of
Perl that handle Data::Table, Spreadsheet::WriteExcel, Excel::Writer::XLSX.
I had looked at the Python libs but my gray matter began to boil trying to
figure out how to exploit/call its classes from C. Also, they wanted logos
displayed on the Excel spreadsheet, so I also took advantage of its Image::*
class. The most annoying part was having to install PERL so that I could
build all of the classes.
Anyway, the customer now only needs to pass a descriptor to the data to be
put in the spreadsheet, a filename for the spreadsheet and the file name of
the logo (optional parameter) if desired.
Post by Jan-Erik Soderholm
I have done the same at my client, but I used the builtin
Excel tools (xlrd, xlwt) in the Python kit. Makes handling
of Excel files a breeze. Yes, you need some data transfer
from the Cobol apps to the Python Excel generator.
How do you invoke Python in/via COBOL?
Not at all. The data is usualy in some Rdb table (written by the
Cobol applications) and some batch job runs Python and creates
the XLS files (using the Python Rdb interface and the Excel
tools). Sometimes the Cobol code submittes the batch job or
it can be done using a table trigger.

Another Cobol app writes data to a table and a table trigger
submittes a job that uses the Python PDF ("ReportLab") tools
to create PDF reports (accessed through the web server, WASD).

I'm sure Perl works fine also, but I personaly don't like Perl. :-)
Python feels more "modern" and structured.

Regards,
Jan-Erik.
V***@SendSpamHere.ORG
2014-02-12 20:31:24 UTC
Permalink
{...snip...}
Not at all. The data is usualy in some Rdb table (written by the
Cobol applications) and some batch job runs Python and creates
the XLS files (using the Python Rdb interface and the Excel
tools). Sometimes the Cobol code submittes the batch job or
it can be done using a table trigger.
Good grief. I hate COBOLlers LIB$SPAWNing shit all over the place. I hate
it even more when the LIB$SPAWN a SUBMIT command.
Another Cobol app writes data to a table and a table trigger
submittes a job that uses the Python PDF ("ReportLab") tools
to create PDF reports (accessed through the web server, WASD).
So, if I've read you right, you're running a Python script in a BATCH job to
convert tabled data to XLS.
I'm sure Perl works fine also, but I personaly don't like Perl. :-)
Python feels more "modern" and structured.
No real PERL (save to figure out how well the class libraries handled the
Excel output. I link those bits into C code which the customer can call
from their COBOL. The most COBOL I ever wrote was to show them how to do
the call. Strange, they'd never seen the:

INSPECT blah-blah TALLYING blah-blah-LEN FOR CHARACTERS BEFORE SPACES.

...syntax before I'd used it. I thank Google for that COBOL syntax.

They then invoke the call:

CALL "Table2Excel" USING BY DESCRIPTOR table-data-descriptor
BY DESCRIPTOR Excel-FILE(1:Excel-FILE-LEN)
BY DESCRIPTOR Image-FILE(1:Image-FILE-LEN)
BY DESCRIPTOR "Orange" <==header bg color
BY DESCRIPTOR "Black" <==header fg color
GIVING RET-STATUS.

There's no need for unnecessary process creation and waiting about for
that process to complete. It's all done, and quite quickly too, in the
context of the caller.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
David Froble
2014-02-13 00:06:46 UTC
Permalink
Post by V***@SendSpamHere.ORG
{...snip...}
Not at all. The data is usualy in some Rdb table (written by the
Cobol applications) and some batch job runs Python and creates
the XLS files (using the Python Rdb interface and the Excel
tools). Sometimes the Cobol code submittes the batch job or
it can be done using a table trigger.
Good grief. I hate COBOLlers LIB$SPAWNing shit all over the place. I hate
it even more when the LIB$SPAWN a SUBMIT command.
There can be conditions where spawning a sub-process or a detached
process is reasonable. With a SPAWN/NOWAIT you can move on to other
work while <whatever> completes in the background.
Post by V***@SendSpamHere.ORG
Another Cobol app writes data to a table and a table trigger
submittes a job that uses the Python PDF ("ReportLab") tools
to create PDF reports (accessed through the web server, WASD).
Don't know what "table trigger" is ???
Post by V***@SendSpamHere.ORG
So, if I've read you right, you're running a Python script in a BATCH job to
convert tabled data to XLS.
I'd stay out of the batch queues, but that's just me ...
Post by V***@SendSpamHere.ORG
I'm sure Perl works fine also, but I personaly don't like Perl. :-)
Python feels more "modern" and structured.
No real PERL (save to figure out how well the class libraries handled the
Excel output. I link those bits into C code which the customer can call
from their COBOL. The most COBOL I ever wrote was to show them how to do
INSPECT blah-blah TALLYING blah-blah-LEN FOR CHARACTERS BEFORE SPACES.
Never saw that one before ..
Post by V***@SendSpamHere.ORG
...syntax before I'd used it. I thank Google for that COBOL syntax.
CALL "Table2Excel" USING BY DESCRIPTOR table-data-descriptor
BY DESCRIPTOR Excel-FILE(1:Excel-FILE-LEN)
BY DESCRIPTOR Image-FILE(1:Image-FILE-LEN)
BY DESCRIPTOR "Orange" <==header bg color
BY DESCRIPTOR "Black" <==header fg color
GIVING RET-STATUS.
Knew there was a reason I avoid Cobol ...
Post by V***@SendSpamHere.ORG
There's no need for unnecessary process creation and waiting about for
that process to complete. It's all done, and quite quickly too, in the
context of the caller.
If it's quick, then yeah, I'd do it in line. If it's not so quick, I'd
consider a sub-process. Then there are places where the task is much
easier in a sub-process, such as executing a DCL procedure. I won't
write code when $ COPY A.A B.B is much simpler.
Jan-Erik Soderholm
2014-02-13 00:11:09 UTC
Permalink
Post by V***@SendSpamHere.ORG
{...snip...}
Not at all. The data is usualy in some Rdb table (written by the
Cobol applications) and some batch job runs Python and creates
the XLS files (using the Python Rdb interface and the Excel
tools). Sometimes the Cobol code submittes the batch job or
it can be done using a table trigger.
Good grief. I hate COBOLlers LIB$SPAWNing shit all over the place. I hate
it even more when the LIB$SPAWN a SUBMIT command.
There can be conditions where spawning a sub-process or a detached process
is reasonable. With a SPAWN/NOWAIT you can move on to other work while
<whatever> completes in the background.
Post by V***@SendSpamHere.ORG
Another Cobol app writes data to a table and a table trigger
submittes a job that uses the Python PDF ("ReportLab") tools
to create PDF reports (accessed through the web server, WASD).
Don't know what "table trigger" is ???
Are you asking what a trigger is?

http://en.wikipedia.org/wiki/Database_trigger
Post by V***@SendSpamHere.ORG
So, if I've read you right, you're running a Python script in a BATCH job to
convert tabled data to XLS.
I'd stay out of the batch queues, but that's just me...
I think they are a nice tool to get things done.
Paul Sture
2014-02-14 10:10:01 UTC
Permalink
Post by V***@SendSpamHere.ORG
{...snip...}
Not at all. The data is usualy in some Rdb table (written by the
Cobol applications) and some batch job runs Python and creates
the XLS files (using the Python Rdb interface and the Excel
tools). Sometimes the Cobol code submittes the batch job or
it can be done using a table trigger.
Good grief. I hate COBOLlers LIB$SPAWNing shit all over the place. I hate
it even more when the LIB$SPAWN a SUBMIT command.
If you do need to submit a job, you can do it straight from COBOL, though
our approach was to supply a wrapper routine to make it easy for the
typical coder, with suitable defaults for omitted parameters.

The problem with COBOL (OK, OK, *one* problem with COBOL) is that unlike
BASIC, FORTRAN etc, the VMS compiler doesn't come with system header files
to include at compile time.

Yes, you can write some reasonably simple DCL to extract stuff from the
libraries and generate COBOL variable definitions, but that's potentially
a time bomb across VMS versions. It was preferable to hard coding
status returns into each COBOL program (which was the way it was done
in the few system call examples in the manuals), but was far from perfect.

A neater solution is to write simple macro to pull those values in as
globals and let the linker do its stuff. E.g.

----
; UAIDEF.MAR

$uaidef GLOBAL ; define as global
.end
----

and in COBOL, variable definitions of the form:

01 ss$_normal pic 9(9) comp value external ss$_normal.
Post by V***@SendSpamHere.ORG
Another Cobol app writes data to a table and a table trigger
submittes a job that uses the Python PDF ("ReportLab") tools
to create PDF reports (accessed through the web server, WASD).
So, if I've read you right, you're running a Python script in a BATCH job to
convert tabled data to XLS.
I'm sure Perl works fine also, but I personaly don't like Perl. :-)
Python feels more "modern" and structured.
No real PERL (save to figure out how well the class libraries handled the
Excel output. I link those bits into C code which the customer can call
from their COBOL. The most COBOL I ever wrote was to show them how to do
INSPECT blah-blah TALLYING blah-blah-LEN FOR CHARACTERS BEFORE SPACES.
...syntax before I'd used it. I thank Google for that COBOL syntax.
Google wasn't around when I looked at the INSPECT...TALLY-HO stuff

CALL STR$TRIM using ...

was much more readable and a lot less typing too.
Post by V***@SendSpamHere.ORG
CALL "Table2Excel" USING BY DESCRIPTOR table-data-descriptor
BY DESCRIPTOR Excel-FILE(1:Excel-FILE-LEN)
BY DESCRIPTOR Image-FILE(1:Image-FILE-LEN)
BY DESCRIPTOR "Orange" <==header bg color
BY DESCRIPTOR "Black" <==header fg color
GIVING RET-STATUS.
That can be shortened by omitting the "BY DESCRIPTOR" on all lines but the
first. BY REFERENCE is the default if you don't specify anything, but once
you specify an argument type it becomes the default for the remaining
parameters.

Note that COBOL doesn't support anything but BY REFERENCE for receiving
routines. If you ever find yourself in the unlikely position of wanting
to do that LIB$ANALYZE_SDESC (or do I mean STR$ANALYZE_SDESC???) is your
friend.
Post by V***@SendSpamHere.ORG
There's no need for unnecessary process creation and waiting about for
that process to complete. It's all done, and quite quickly too, in the
context of the caller.
That's fine if it's quick, but back in the days of one VT per desk and
slow VAXen you risked tying down someone's terminal for an unacceptable
amount of time waiting for a report to finish. I converted a whole
slew of programs which did that to (optionally) submit a batch job and
free the terminal up immediately.

--
Paul Sture
JohnF
2014-02-12 15:34:35 UTC
Permalink
Post by V***@SendSpamHere.ORG
I've been at SUPERVISOR mode in a lot of my time working on
a DCL debugger I've mentioned here a few times.
If you don't mind me beating a dead horse (I seem to have
run out of little puppies to kick), I think dcl is what
all those str$functions we discussed were really written
for. That is, but for digital's desire to provide string
manipulation in dcl, they never would have bothered with
that str$library. The C headers and stuff were more of an
afterthought, i.e., as long as the library's there, might
as well let C link it. But all other things equal, when
writing C you're better advised to use standard C stuff
if possible.
Post by V***@SendSpamHere.ORG
I'd been called away from that in recent
weeks to work on RMS CDC (EXEC mode), coded an Excel spreadsheet generator
(USER mode) for a client that writes their app in COBOL (on OpenVMS), made
new Postscript forms and logos artwork (not really OpeNVMS but used there),
and setup and configured a *new* Itegrity Blade cluster even though nobody
has been buying Itegrity for OpenVMS as per HP's "suggestion".
Wow, you've got my head swimming with that "mixed metaphor".
--
John Forkosh ( mailto: ***@f.com where j=john and f=forkosh )
Stephen Hoffman
2014-02-12 17:04:59 UTC
Permalink
...I think dcl is what all those str$functions we discussed were really
written for. That is, but for digital's desire to provide string
manipulation in dcl, they never would have bothered with that
str$library. The C headers and stuff were more of an afterthought,
i.e., as long as the library's there, might as well let C link it. But
all other things equal, when writing C you're better advised to use
standard C stuff if possible.
Some history and discssions of general and related structures...

DCL has its own supervisor-mode world; getting stuff compiled and
linked into that environment is a little odd. (It and the XQP are
probably two of the weirder parts of VMS, in terms of its general
run-time environment, and around debugging it.)

FWIW, none of the VMS and none of the (user-mode) language RTLs are
intended to be callable from any inner-mode code. (There were (are)
some security-clobbering hacks latent in the RTL calls that allowed
inner-mode to sort-of kind-of work, for those folks that were inclined
to open up leaks across the per-mode memory management protections.
Not recommended.)

I don't have the OpenVMS source listings handy to confirm it, but I'd
be surprised if there were RTL calls around.

As for the include files, the VMS-provided header files are common
source. The same SDL source file generates C, BASIC, Fortran and
others, and — with the most recent versions of SDL — also now DCL
symbolic constants. C was added to this list over time, and
particularly around the addition of the SYS$STARLET_C and SYS$LIB_C
libraries into OpenVMS. STARLETSD.TLB was also used by various
languages.

In terms of the per-language support within OpenVMS, C was effectively
an afterthought for most of the environments, as the first C compiler
and VAXCRTL library support only arrived somewhere around V4.4 IIRC.
That was well after the other languages. C is also somewhat weird on
OpenVMS in that it now has two libraries; the traditional user-mode
library that most languages have, and also its own kernel-mode library
that was implemented as part of the C system programming support that
arrived around OpenVMS V6.1 IIRC.

The STR$ and LIB$ calls are generally old. Many of the core routines
are older than V4.4. It wouldn't surprise me to learn that the history
of this stuff goes back further than VAX-11/VMS too, as here's the
XPORT library for TOPS
<http://bitsavers.informatik.uni-stuttgart.de/pdf/dec/pdp10/TOPS10_softwareNotebooks/vol08/AA-J201A-TK_XPORT_Programmers_Guide_Apr81.pdf>


The STR$ and LIB$ calls are useful in Macro, Bliss, Fortran and various
other languages. (Various Fortran code was is still fond of using
space-padded fixed-length strings, too.) The OTS$ calls was largely
for the compilers, but was and is available for other use.

More to make it a little easier for me to find these details for some
hypothetical next time a discussion of ancient VMS calls and ancient
run-time libraries (RTLs) arises, there are all sorts of related
shenanigans around the break-up of the VMSRTL run-time library are in
play here, too. The ancient VMSRTL omnibus library has a long and
checkered career:
<http://archive.org/stream/bitsavers_decvaxvms2ReleaseNotesMar80_3242450/AA-D015C-TE_VMS_2.0_Release_Notes_Mar80_djvu.txt>
<http://archive.org/stream/bitsavers_decvaxvms3leaseNotesV3.0May82_5458871/AA-D015D-TE_VAX-VMS_Release_Notes_V3.0_May82_djvu.txt>
<http://www.ibiblio.org/pub/academic/computer-science/history/pdp-11/hardware/micronotes/numerical/micronote36.txt>.
This VMSRTL stuff was in common use prior to VAX/VMS V4.0, when that
RTL was broken up into hunks; into separate RTLs. For completeness,
this was all before C existed on VMS, too.
--
Pure Personal Opinion | HoffmanLabs LLC
Chris Scheers
2014-02-12 19:00:29 UTC
Permalink
Post by Stephen Hoffman
In terms of the per-language support within OpenVMS, C was effectively
an afterthought for most of the environments, as the first C compiler
and VAXCRTL library support only arrived somewhere around V4.4 IIRC.
That was well after the other languages. C is also somewhat weird on
OpenVMS in that it now has two libraries; the traditional user-mode
library that most languages have, and also its own kernel-mode library
that was implemented as part of the C system programming support that
arrived around OpenVMS V6.1 IIRC.
IIRC: C and Ada RTL support was added in V4.2.

IIRC (and I may well be wrong here), you could load compiler support on
earlier versions and get the RTLs.
--
-----------------------------------------------------------------------
Chris Scheers, Applied Synergy, Inc.

Voice: 817-237-3360 Internet: ***@applied-synergy.com
Fax: 817-237-3074
V***@SendSpamHere.ORG
2014-02-12 21:07:39 UTC
Permalink
{...snip...}
The STR$ and LIB$ calls are generally old. Many of the core routines
are older than V4.4. It wouldn't surprise me to learn that the history
If STR$ and LIB$ calls are generally old, then RTL calls are primordial
history.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
JohnF
2014-02-13 10:06:56 UTC
Permalink
Thanks for the "history and discussion" below
(you should maybe write a book, if there isn't already one)...
Post by Stephen Hoffman
...I think dcl is what all those str$functions we discussed were really
written for. That is, but for digital's desire to provide string
manipulation in dcl, they never would have bothered with that
str$library. The C headers and stuff were more of an afterthought,
i.e., as long as the library's there, might as well let C link it. But
all other things equal, when writing C you're better advised to use
standard C stuff if possible.
Some history and discssions of general and related structures...
DCL has its own supervisor-mode world; getting stuff compiled and
linked into that environment is a little odd. (It and the XQP are
probably two of the weirder parts of VMS, in terms of its general
run-time environment, and around debugging it.)
FWIW, none of the VMS and none of the (user-mode) language RTLs are
intended to be callable from any inner-mode code. (There were (are)
some security-clobbering hacks latent in the RTL calls that allowed
inner-mode to sort-of kind-of work, for those folks that were inclined
to open up leaks across the per-mode memory management protections.
Not recommended.)
I don't have the OpenVMS source listings handy to confirm it, but I'd
be surprised if there were RTL calls around.
As for the include files, the VMS-provided header files are common
source. The same SDL source file generates C, BASIC, Fortran and
others, and ? with the most recent versions of SDL ? also now DCL
symbolic constants. C was added to this list over time, and
particularly around the addition of the SYS$STARLET_C and SYS$LIB_C
libraries into OpenVMS. STARLETSD.TLB was also used by various
languages.
In terms of the per-language support within OpenVMS, C was effectively
an afterthought for most of the environments, as the first C compiler
and VAXCRTL library support only arrived somewhere around V4.4 IIRC.
That was well after the other languages. C is also somewhat weird on
OpenVMS in that it now has two libraries; the traditional user-mode
library that most languages have, and also its own kernel-mode library
that was implemented as part of the C system programming support that
arrived around OpenVMS V6.1 IIRC.
The STR$ and LIB$ calls are generally old. Many of the core routines
are older than V4.4. It wouldn't surprise me to learn that the history
of this stuff goes back further than VAX-11/VMS too, as here's the
XPORT library for TOPS
<http://bitsavers.informatik.uni-stuttgart.de/pdf/dec/pdp10/TOPS10_softwareNotebooks/vol08/AA-J201A-TK_XPORT_Programmers_Guide_Apr81.pdf>
The STR$ and LIB$ calls are useful in Macro, Bliss, Fortran and various
other languages. (Various Fortran code was is still fond of using
space-padded fixed-length strings, too.) The OTS$ calls was largely
for the compilers, but was and is available for other use.
More to make it a little easier for me to find these details for some
hypothetical next time a discussion of ancient VMS calls and ancient
run-time libraries (RTLs) arises, there are all sorts of related
shenanigans around the break-up of the VMSRTL run-time library are in
play here, too. The ancient VMSRTL omnibus library has a long and
<http://archive.org/stream/bitsavers_decvaxvms2ReleaseNotesMar80_3242450/AA-D015C-TE_VMS_2.0_Release_Notes_Mar80_djvu.txt>
<http://archive.org/stream/bitsavers_decvaxvms3leaseNotesV3.0May82_5458871/AA-D015D-TE_VAX-VMS_Release_Notes_V3.0_May82_djvu.txt>
<http://www.ibiblio.org/pub/academic/computer-science/history/pdp-11/hardware/micronotes/numerical/micronote36.txt>.
This VMSRTL stuff was in common use prior to VAX/VMS V4.0, when that
RTL was broken up into hunks; into separate RTLs. For completeness,
this was all before C existed on VMS, too.
--
John Forkosh ( mailto: ***@f.com where j=john and f=forkosh )
David Froble
2014-02-13 15:58:09 UTC
Permalink
Post by JohnF
Thanks for the "history and discussion" below
(you should maybe write a book, if there isn't already one)...
:-)

Where have you been? I believe he has written at least one book, and
maybe more ....

I think it was something like "Programming in DCL" ...
Paul Sture
2014-02-14 10:48:45 UTC
Permalink
Post by Stephen Hoffman
...I think dcl is what all those str$functions we discussed were really
written for. That is, but for digital's desire to provide string
manipulation in dcl, they never would have bothered with that
str$library. The C headers and stuff were more of an afterthought,
i.e., as long as the library's there, might as well let C link it. But
all other things equal, when writing C you're better advised to use
standard C stuff if possible.
<snip>
Post by Stephen Hoffman
In terms of the per-language support within OpenVMS, C was effectively
an afterthought for most of the environments, as the first C compiler
and VAXCRTL library support only arrived somewhere around V4.4 IIRC.
That was well after the other languages. C is also somewhat weird on
OpenVMS in that it now has two libraries; the traditional user-mode
library that most languages have, and also its own kernel-mode library
that was implemented as part of the C system programming support that
arrived around OpenVMS V6.1 IIRC.
There was a whole slew of new C stuff in the V6.2 Release Notes, locales
took many pages IIRC.
Post by Stephen Hoffman
The STR$ and LIB$ calls are generally old. Many of the core routines
are older than V4.4. It wouldn't surprise me to learn that the history
of this stuff goes back further than VAX-11/VMS too, as here's the
XPORT library for TOPS
<http://bitsavers.informatik.uni-stuttgart.de/pdf/dec/pdp10/TOPS10_softwareNotebooks/vol08/AA-J201A-TK_XPORT_Programmers_Guide_Apr81.pdf>
The STR$ and LIB$ calls are useful in Macro, Bliss, Fortran and various
other languages. (Various Fortran code was is still fond of using
space-padded fixed-length strings, too.) The OTS$ calls was largely
for the compilers, but was and is available for other use.
STR$ and LIB$ calls were definitely present and documented in V3.0/V3.1.


--
Paul Sture
Paul Sture
2014-02-14 10:28:21 UTC
Permalink
Post by JohnF
Post by V***@SendSpamHere.ORG
I've been at SUPERVISOR mode in a lot of my time working on
a DCL debugger I've mentioned here a few times.
If you don't mind me beating a dead horse (I seem to have
run out of little puppies to kick), I think dcl is what
all those str$functions we discussed were really written
for.
I always assumed they were moe generic than that. When I started at
my first VMS job the existing team had already written a library
of string handling routines in support of the FORTRAN IV compiler they
had. Fortunately we got a FORTRAN 77 compiler shortly after I joined
so I could ignore our home grown library for new projects, but still
had to deal with it for older stuff.

Incidentally, the reason a VAX was dismissed from consideration at my
previous employer was that at the time FORTRAN was the only compiler
available for VMS. The boss wanted our PDP replacement to support COBOL
and that was that. Somewhat amusingly we ended up using PL/I and were
paying for a totally unused COBOL compiler but that's another story.

--
Paul Sture
V***@SendSpamHere.ORG
2014-02-12 20:19:15 UTC
Permalink
Post by JohnF
Post by V***@SendSpamHere.ORG
I've been at SUPERVISOR mode in a lot of my time working on
a DCL debugger I've mentioned here a few times.
If you don't mind me beating a dead horse (I seem to have
run out of little puppies to kick), I think dcl is what
all those str$functions we discussed were really written
for. That is, but for digital's desire to provide string
manipulation in dcl, they never would have bothered with
that str$library. The C headers and stuff were more of an
afterthought, i.e., as long as the library's there, might
Not even close. There's no STR$anything in DCL. STR$ANALYZE_SDESC and
STR$COPY_DX exist in the CLI interface (CLI$ routines) but there NO STR$
WHATSOEVER in DCL itself.
Post by JohnF
as well let C link it. But all other things equal, when
writing C you're better advised to use standard C stuff
if possible.
Why? decc$strcat() provides me with nothing that I get from STR$CONCAT().
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
JF Mezei
2014-02-12 21:07:27 UTC
Permalink
Post by V***@SendSpamHere.ORG
Not even close. There's no STR$anything in DCL.
Quite easy to fix:

$STR$anything == "VAXman"

Then, you can no longer state there is no STR$ANYTHING in DCL :-)

Seriously though, Just because these routines are not "published" for
DCL users does not mean that they would not be used internally for
operarions such as $A = B + C (where all 3 variables are strings)

Although I believe it was Mr Hoff who stated that those routines are not
well suited for use at elevated levels.

However, when you look at lexical routines availabe in DCL, wouldn't
those use underlying RTL lexical functions ? ($FAO comes to mind)

Or is the distinction here between SYS$ and LIB$ routines ?
Stephen Hoffman
2014-02-12 21:56:04 UTC
Permalink
Post by JF Mezei
Although I believe it was Mr Hoff who stated that those routines are
not well suited for use at elevated levels.
Other than that the RTL calls generally don't work for and are
otherwise unsuited for use from inner-mode code, sure, have at.
In an eon or two past I would have preferred a hard error be returned,
alas the maintainers decided to jam the access and allow the code to
run, albeit with exposures.
Post by JF Mezei
However, when you look at lexical routines availabe in DCL, wouldn't
those use underlying RTL lexical functions ? ($FAO comes to mind)
The SYS$FAO and SYS$FAOL system services, you mean?
Post by JF Mezei
Or is the distinction here between SYS$ and LIB$ routines ?
Many eons ago, system services were theoretically all accessible from
kernel mode at IPL 0.

Some system service calls were documented as being caller's mode
services, which meant the VMS code didn't need inner-mode access.
IIRC, $FAO[L] is caller's mode.

Many other system service calls did and do need inner-mode access.

Many of the classic and most common system services are part of the
kernel, and those can generally be called from kernel mode code at IPL
0. Though for various calls, the inner-mode code might choose to
directly invoke the entry point "behind" the system service (usually an
EXE$ or a more recent EXE_STD$ call) and bypass the system service
entry point entirely. This to avoid the overhead of the system service
entry checks.

The run-time library calls were intended for user-mode use from user-
and third-party- and DEC-written applications and compilers and
related, and the system services provided features for the callers via
entry points into the operating system itself; IIRC, the entry vectors
used to be in system S0 space, but moved to process P1 space an eon
ago. System services were the foundation of the environment. RTL
calls didn't need to reside within the kernel and could be loaded by
applications and processes as needed, and usually didn't need to
execute in inner-mode. (The RTL calls that were originally found in
VMSRTL were split apart at V4, dividing the various calls into specific
separate shareable images based on their function — this because the
classic VMSRTL was becoming unwieldy for everybody involved. No sense
loading this increasingly-ginormous omnibus everything RTL into your
address space, when all you needed were this subset of calls from a few
smaller RTLs. Yes, installing the shareable images as shared did help
reduce memory use here, too.)

Things have gotten more complex and the demarcations murkier and the
kernel both rather more and somewhat less modular. Compromises, etc.

Over the years, there became some system service routines here that
weren't accessible for any of various reasons; usually involving
implementations via user-written system service interface — those calls
are generally not callable from kernel-mode. The ones I stumble into
most often are the security system services, and particularly those
that are implemented in SECURESHRP.EXE image.
--
Pure Personal Opinion | HoffmanLabs LLC
JohnF
2014-02-13 10:02:09 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by JohnF
Post by V***@SendSpamHere.ORG
I've been at SUPERVISOR mode in a lot of my time working on
a DCL debugger I've mentioned here a few times.
If you don't mind me beating a dead horse (I seem to have
run out of little puppies to kick), I think dcl is what
all those str$functions we discussed were really written
for. That is, but for digital's desire to provide string
manipulation in dcl, they never would have bothered with
that str$library. The C headers and stuff were more of an
afterthought, i.e., as long as the library's there, might
Not even close. There's no STR$anything in DCL. STR$ANALYZE_SDESC and
STR$COPY_DX exist in the CLI interface (CLI$ routines) but there NO STR$
WHATSOEVER in DCL itself.
Yeah, yeah, so they're f$lexical_functions in dcl.
I was guessing f$,str$'s are basically just different
names for the same entry points in the rtl library.
So I could be wrong about all that, but why would, say,
str$element not be f$element?
Post by V***@SendSpamHere.ORG
Post by JohnF
as well let C link it. But all other things equal, when
writing C you're better advised to use standard C stuff
if possible.
Why? decc$strcat() provides me with nothing that I get from STR$CONCAT().
--
John Forkosh ( mailto: ***@f.com where j=john and f=forkosh )
V***@SendSpamHere.ORG
2014-02-13 11:37:02 UTC
Permalink
Post by JF Mezei
Post by V***@SendSpamHere.ORG
Not even close. There's no STR$anything in DCL.
$STR$anything == "VAXman"
Then, you can no longer state there is no STR$ANYTHING in DCL :-)
Seriously though, Just because these routines are not "published" for
DCL users does not mean that they would not be used internally for
operarions such as $A = B + C (where all 3 variables are strings)
I stated, emphatically, that they do not appear in DCL because I've been in
the DCL source many times. Where they exist, minimally, is in the DCL CLI$
routines interface. It really doesn't take too much more than a perusal of
DCL.MAP to determine this.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
JF Mezei
2014-02-13 22:27:15 UTC
Permalink
Post by V***@SendSpamHere.ORG
I stated, emphatically, that they do not appear in DCL because I've been in
the DCL source many times.
Upon reading this, first image that came to mind: Mr VAXman in a "TRON"
like scenario, racing in DCL land :-)
V***@SendSpamHere.ORG
2014-02-13 11:57:11 UTC
Permalink
Post by JohnF
Post by V***@SendSpamHere.ORG
Post by JohnF
Post by V***@SendSpamHere.ORG
I've been at SUPERVISOR mode in a lot of my time working on
a DCL debugger I've mentioned here a few times.
If you don't mind me beating a dead horse (I seem to have
run out of little puppies to kick), I think dcl is what
all those str$functions we discussed were really written
for. That is, but for digital's desire to provide string
manipulation in dcl, they never would have bothered with
that str$library. The C headers and stuff were more of an
afterthought, i.e., as long as the library's there, might
Not even close. There's no STR$anything in DCL. STR$ANALYZE_SDESC and
STR$COPY_DX exist in the CLI interface (CLI$ routines) but there NO STR$
WHATSOEVER in DCL itself.
Yeah, yeah, so they're f$lexical_functions in dcl.
I was guessing f$,str$'s are basically just different
names for the same entry points in the rtl library.
So I could be wrong about all that, but why would, say,
str$element not be f$element?
Because it's not. While similar in function, it's not implemented by passing
F$element arguments to STR$ELEMENT. If that's what you believe, then believe
that decc$strcat invokes STR$CONCAT. ;)
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
JohnF
2014-02-13 13:15:40 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by JohnF
Post by V***@SendSpamHere.ORG
Post by JohnF
Post by V***@SendSpamHere.ORG
I've been at SUPERVISOR mode in a lot of my time working on
a DCL debugger I've mentioned here a few times.
If you don't mind me beating a dead horse (I seem to have
run out of little puppies to kick), I think dcl is what
all those str$functions we discussed were really written
for. That is, but for digital's desire to provide string
manipulation in dcl, they never would have bothered with
that str$library. The C headers and stuff were more of an
afterthought, i.e., as long as the library's there, might
Not even close. There's no STR$anything in DCL. STR$ANALYZE_SDESC and
STR$COPY_DX exist in the CLI interface (CLI$ routines) but there NO STR$
WHATSOEVER in DCL itself.
Yeah, yeah, so they're f$lexical_functions in dcl.
I was guessing f$,str$'s are basically just different
names for the same entry points in the rtl library.
So I could be wrong about all that, but why would, say,
str$element not be f$element?
Because it's not.
Okay, thanks for the correction (if not clarification).
Post by V***@SendSpamHere.ORG
While similar in function, it's not implemented by passing
F$element arguments to STR$ELEMENT. If that's what you believe,
then believe that decc$strcat invokes STR$CONCAT. ;)
I'm trying to str$ing together some witty remark about
believing a fundamentalist interpretation of the bible
versus a fundamentalist interpretation of vms internals,
but it's not coming to me.
--
John Forkosh ( mailto: ***@f.com where j=john and f=forkosh )
V***@SendSpamHere.ORG
2014-02-13 18:40:20 UTC
Permalink
Post by JohnF
Post by V***@SendSpamHere.ORG
Post by JohnF
Post by V***@SendSpamHere.ORG
Post by JohnF
Post by V***@SendSpamHere.ORG
I've been at SUPERVISOR mode in a lot of my time working on
a DCL debugger I've mentioned here a few times.
If you don't mind me beating a dead horse (I seem to have
run out of little puppies to kick), I think dcl is what
all those str$functions we discussed were really written
for. That is, but for digital's desire to provide string
manipulation in dcl, they never would have bothered with
that str$library. The C headers and stuff were more of an
afterthought, i.e., as long as the library's there, might
Not even close. There's no STR$anything in DCL. STR$ANALYZE_SDESC and
STR$COPY_DX exist in the CLI interface (CLI$ routines) but there NO STR$
WHATSOEVER in DCL itself.
Yeah, yeah, so they're f$lexical_functions in dcl.
I was guessing f$,str$'s are basically just different
names for the same entry points in the rtl library.
So I could be wrong about all that, but why would, say,
str$element not be f$element?
Because it's not.
Okay, thanks for the correction (if not clarification).
Post by V***@SendSpamHere.ORG
While similar in function, it's not implemented by passing
F$element arguments to STR$ELEMENT. If that's what you believe,
then believe that decc$strcat invokes STR$CONCAT. ;)
I'm trying to str$ing together some witty remark about
believing a fundamentalist interpretation of the bible
versus a fundamentalist interpretation of vms internals,
but it's not coming to me.
Dump the "bible" and read the "Book of Ruth" aka, OpenVMS Internals and Data
Structures.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
Paul Sture
2014-02-13 21:28:03 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by JohnF
I'm trying to str$ing together some witty remark about
believing a fundamentalist interpretation of the bible
versus a fundamentalist interpretation of vms internals,
but it's not coming to me.
Dump the "bible" and read the "Book of Ruth" aka, OpenVMS Internals and Data
Structures.
A belter of a response, sir!

--
Paul Sture
David Froble
2014-02-12 18:26:34 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by David Froble
Post by V***@SendSpamHere.ORG
It would all have been in
Macro if it were up to me but the customer said they can only read C.
They lie! I submit that anyone can read BASIC, but I do recall some
almost successful instances of trying to make it unreadable.
A$ = B$ + C$ + D$ + E$ + F$ + G$ + H$ + I$ + J$ + K$ + L$ + ....
Basic, a language that knows how to work with strings ....
And no, I don't normally declare my variables ....
This particular piece of C has some inner mode code. I'm extra careful with
that using C; however, I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
Ok, you win, you were right, should have been Macro-32

:-)
David Froble
2014-02-12 20:32:44 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by David Froble
Post by V***@SendSpamHere.ORG
It would all have been in
Macro if it were up to me but the customer said they can only read C.
They lie! I submit that anyone can read BASIC, but I do recall some
almost successful instances of trying to make it unreadable.
A$ = B$ + C$ + D$ + E$ + F$ + G$ + H$ + I$ + J$ + K$ + L$ + ....
Basic, a language that knows how to work with strings ....
And no, I don't normally declare my variables ....
This particular piece of C has some inner mode code. I'm extra careful with
that using C; however, I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
After thinking about this for a while, I must confess to curiosity.

I'm assuming that by "inner mode" that you're talking about kernel mode.
If not, then ignore the rest of this.

I've dabbled a bit at exec mode, mainly to allow some RTL code to use
SYSLCK when the user didn't have that priv. But I've never had the need
to run anything in kernel made.

What would you be doing that would require running in kernel mode? I'm
assuming that you're working on some type of application, and not
modifying something in VMS.

Rather curious ....


My understanding, and it's vague, is that you'd never want to invoke any
code that might throw an error while running in kernel mode. As Steve
mentioned elsewhere, that leaves out any of the language modules, RTL
modules, and such. I'd think that that would also exclude STR$CONCAT
and such.
Stephen Hoffman
2014-02-12 20:51:23 UTC
Permalink
Post by David Froble
After thinking about this for a while, I must confess to curiosity.
I'm assuming that by "inner mode" that you're talking about kernel mode.
Inner-mode code is supervisor-, executive- or kernel-mode. You could
reference interrupt mode if you wanted, though that's a subset of
kernel-mode environment.
Post by David Froble
If not, then ignore the rest of this.
Whoops. Ignore the rest.
Post by David Froble
I've dabbled a bit at exec mode, mainly to allow some RTL code to use
SYSLCK when the user didn't have that priv. But I've never had the
need to run anything in kernel made.
Code that performs device hardware access or that traverses OpenVMS
data structures. Certain forms of OpenVMS extensions are inner-mode.
Ancillary Control Processes (ACPs)
<http://labs.hoffmanlabs.com/node/213> involve user- and kernel-mode
code, too.

One of the classic examples of accessing inner-mode data structures
involves code that provides the caller with the analog of the SHOW
LOGICAL * command output, but there are many other triggers. There
are other (and dumber?) reasons. Here
<http://labs.hoffmanlabs.com/node/815> is some example kernel code that
patches a kernel data cell to allow a software kit to install.

Implicit privileges are provided to any code executing in executive and
kernel modes, as well. That code acquires at least SETPRV, CMKRNL,
SYSNAM, and SYSLCK, IIRC.
Post by David Froble
What would you be doing that would require running in kernel mode? I'm
assuming that you're working on some type of application, and not
modifying something in VMS.
VAXman has already indicated DCL and RMS-level chatter, which covers
supervisor and executive.
Post by David Froble
My understanding, and it's vague, is that you'd never want to invoke
any code that might throw an error while running in kernel mode.
Not true. You just need to handle all of those errors, or badness
typically ensues. Fielding an error in an inner mode is entirely
permissible, but you don't want to pass a fatal error through to
OpenVMS to deal with. Not unless you want to go fetch some coffee or
tea while you wait for the box to reboot.
Post by David Froble
As Steve mentioned elsewhere, that leaves out any of the language
modules, RTL modules, and such. I'd think that that would also exclude
STR$CONCAT and such.
Pretty much anything that has RTL VM services underneath it somewhere;
anything that mixes or shares data across modes.
--
Pure Personal Opinion | HoffmanLabs LLC
JF Mezei
2014-02-12 21:15:13 UTC
Permalink
Post by David Froble
What would you be doing that would require running in kernel mode?
Mr VAXman does everything in kernel mode, from shoveling snow to coding
stuff :-)

When a customer hires Mr VAXman, it is likely because they need
specialised work that they can't do on their own, and that specialised
work more than likely involves doing stuff you can't do in user mode.
Post by David Froble
modules, and such. I'd think that that would also exclude STR$CONCAT
and such.
Mr VAXman appears to have been hired to do <shock, horror> user mode C
code </shock, horror> to support COBOL programs.
V***@SendSpamHere.ORG
2014-02-12 23:00:38 UTC
Permalink
{...snip...}
Post by V***@SendSpamHere.ORG
This particular piece of C has some inner mode code. I'm extra careful with
that using C; however, I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
After thinking about this for a while, I must confess to curiosity.
I'm assuming that by "inner mode" that you're talking about kernel mode.
If not, then ignore the rest of this.
Correct.
I've dabbled a bit at exec mode, mainly to allow some RTL code to use
I've *MORE* than dabbled in recent months/years. ;)
SYSLCK when the user didn't have that priv. But I've never had the need
to run anything in kernel made.
What would you be doing that would require running in kernel mode? I'm
assuming that you're working on some type of application, and not
modifying something in VMS.
Rather curious ....
Well, remember, you asked...

http://www.attunity.com/products/attunity-cdc/rms-change-data-capture
http://www.attunity.com/products/attunity-cdc-ssis/rms-cdc-for-ssis
http://www.attunity.com/learning/video/attunity-rms-cdc-only-rms-solution-its-kind
http://www.enterpriseirregulars.com/25555/attunity-scores-a-win-with-rms-cdc-support/
http://www.attunity.com/news/attunity-announces-million-dollar-license-agreement-leading-communications-and-media-provider

I've been working with Hein van den Heuvel, who is now an Attunity employee,
since about 2009 when this project was conceived. There's not too much that
I don't know now about the inner workings of RMS as a result of this project.
It's been one of the most interesting and challenging VMS hacking projects I
have ever done.

STR$CONCAT was used for a recent "new feature" request. The control utility
is written in C. Not my choice but... The rest of the code is pure OpenVMS
internals magic written in Macro32 with bits of Macro64 or Itanium Assembler.
My understanding, and it's vague, is that you'd never want to invoke any
code that might throw an error while running in kernel mode. As Steve
mentioned elsewhere, that leaves out any of the language modules, RTL
modules, and such. I'd think that that would also exclude STR$CONCAT
and such.
Well, you could call many of those functions assuming you use their "object"
brethren. (see: LINK/[NO]SYSSHR). However, I'm invoking STR$CONCAT at user
mode in the control utility for Attunity RMS CDC. While this does jump into
kernel mode to perform some interface tasks, it's NOT calling ST$CONCAT (or
any of the other RTLs of its ilk) when in kernel mode!
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
David Froble
2014-02-13 01:17:10 UTC
Permalink
Post by V***@SendSpamHere.ORG
{...snip...}
Post by V***@SendSpamHere.ORG
This particular piece of C has some inner mode code. I'm extra careful with
that using C; however, I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
After thinking about this for a while, I must confess to curiosity.
I'm assuming that by "inner mode" that you're talking about kernel mode.
If not, then ignore the rest of this.
Correct.
I've dabbled a bit at exec mode, mainly to allow some RTL code to use
I've *MORE* than dabbled in recent months/years. ;)
SYSLCK when the user didn't have that priv. But I've never had the need
to run anything in kernel made.
What would you be doing that would require running in kernel mode? I'm
assuming that you're working on some type of application, and not
modifying something in VMS.
Rather curious ....
Well, remember, you asked...
Yeah, even after many lessons about the dangers of doing so ..
Post by V***@SendSpamHere.ORG
http://www.attunity.com/products/attunity-cdc/rms-change-data-capture
http://www.attunity.com/products/attunity-cdc-ssis/rms-cdc-for-ssis
http://www.attunity.com/learning/video/attunity-rms-cdc-only-rms-solution-its-kind
http://www.enterpriseirregulars.com/25555/attunity-scores-a-win-with-rms-cdc-support/
http://www.attunity.com/news/attunity-announces-million-dollar-license-agreement-leading-communications-and-media-provider
I've been working with Hein van den Heuvel, who is now an Attunity employee,
since about 2009 when this project was conceived. There's not too much that
I don't know now about the inner workings of RMS as a result of this project.
It's been one of the most interesting and challenging VMS hacking projects I
have ever done.
That's some real interesting, and timely, information.

Timely, because of 2 possible tasks coming up.

1) Journaling or logging of all data updates, with the capability of
rebuilding the updates from a static backup and the journals.

2) In the event a port away from VMS must be done, a method to have
duplicate real time copies of the data, one in the current DAS data
files, and another in one of the free / open database products. This
would allow porting in small pieces while the applications continued to
be used, and updated.

Looks like others have faced similar problems.

But to get back on subject, while my RMS experience was years ago, and
it wasn't really deep into the internals, I'm wondering how you
intercept the updates? Are you talking data field granularity, data
record granularity, or other? For what I'm considering, I'm thinking to
modify the database access code. Don't know whether you're looking to
make modifications to RMS, or something else.
Post by V***@SendSpamHere.ORG
STR$CONCAT was used for a recent "new feature" request. The control utility
is written in C. Not my choice but... The rest of the code is pure OpenVMS
internals magic written in Macro32 with bits of Macro64 or Itanium Assembler.
My understanding, and it's vague, is that you'd never want to invoke any
code that might throw an error while running in kernel mode. As Steve
mentioned elsewhere, that leaves out any of the language modules, RTL
modules, and such. I'd think that that would also exclude STR$CONCAT
and such.
Well, you could call many of those functions assuming you use their "object"
brethren. (see: LINK/[NO]SYSSHR). However, I'm invoking STR$CONCAT at user
mode in the control utility for Attunity RMS CDC. While this does jump into
kernel mode to perform some interface tasks, it's NOT calling ST$CONCAT (or
any of the other RTLs of its ilk) when in kernel mode!
Stephen Hoffman
2014-02-13 19:38:53 UTC
Permalink
Post by David Froble
1) Journaling or logging of all data updates, with the capability of
rebuilding the updates from a static backup and the journals.
RMS Journaling on VMS would be one approach. That can be licensed for
and available to applications using the RMS record or RMS block I/O
calls. That's usually all based on RMS journaling with the DECdtm
transaction management.
Post by David Froble
2) In the event a port away from VMS must be done, a method to have
duplicate real time copies of the data, one in the current DAS data
files, and another in one of the free / open database products. This
would allow porting in small pieces while the applications continued to
be used, and updated.
That's conceptually simple, but tends to get gnarly around failure
scenarios. When one write goes through successfully but the parallel
write fails, you're skewed. Next step is to figure out what to do, and
either back out the error, fail out, or recover. This whether the
failing write was aimed at the primary or some secondary database, or
at the journal. Things get more interesting when a secondary error
arises in the recovery path.

If you're planning on running write I/O via both the existing VMS path
and the new database path in parallel, that makes the design much more
complex. (That may end up using something like ZeroMQ
<http://zeromq.org> across hosts, or database high availability or
replication features
<http://dev.mysql.com/doc/refman/5.7/en/replication.html>
<http://www.postgresql.org/docs/current/interactive/high-availability.html>.)


If you're rolling your own, there are various papers on database
reliability and recovery, too; tools and techniques and algorithms.

It's usually easier to use one of the existing databases than to write
one. Unfortunately, swapping out an existing database within a typical
large and accreted application environment is seldom a small and
isolated project; those database tendrils seem to get everywhere.
--
Pure Personal Opinion | HoffmanLabs LLC
David Froble
2014-02-13 20:45:38 UTC
Permalink
Post by Stephen Hoffman
Post by David Froble
1) Journaling or logging of all data updates, with the capability of
rebuilding the updates from a static backup and the journals.
RMS Journaling on VMS would be one approach. That can be licensed for
and available to applications using the RMS record or RMS block I/O
calls. That's usually all based on RMS journaling with the DECdtm
transaction management.
Well, we aren't using RMS, and trying to convert over to it might be a
large task.

I do have plans to learn a bit about DECdtm.
Post by Stephen Hoffman
Post by David Froble
2) In the event a port away from VMS must be done, a method to have
duplicate real time copies of the data, one in the current DAS data
files, and another in one of the free / open database products. This
would allow porting in small pieces while the applications continued
to be used, and updated.
That's conceptually simple, but tends to get gnarly around failure
scenarios. When one write goes through successfully but the parallel
write fails, you're skewed. Next step is to figure out what to do, and
either back out the error, fail out, or recover. This whether the
failing write was aimed at the primary or some secondary database, or at
the journal. Things get more interesting when a secondary error arises
in the recovery path.
If you're planning on running write I/O via both the existing VMS path
and the new database path in parallel, that makes the design much more
complex. (That may end up using something like ZeroMQ
<http://zeromq.org> across hosts, or database high availability or
replication features
<http://dev.mysql.com/doc/refman/5.7/en/replication.html>
<http://www.postgresql.org/docs/current/interactive/high-availability.html>.)
Gnarly doesn't begin to describe it. If it's to be usable from either
side, then any update would need to first lock the data on both systems.
Even with no problems, it would be "interesting", and there is the
question of performance impacts. But we all know that Murphy is alive
and well.
Post by Stephen Hoffman
If you're rolling your own, there are various papers on database
reliability and recovery, too; tools and techniques and algorithms.
It's usually easier to use one of the existing databases than to write
one. Unfortunately, swapping out an existing database within a typical
large and accreted application environment is seldom a small and
isolated project; those database tendrils seem to get everywhere.
Every time I think about this, my head hurts, and I run away and hide.
But they keep finding me and making me come back and think about it again.
Bob Koehler
2014-02-13 20:54:39 UTC
Permalink
Post by David Froble
Well, we aren't using RMS, and trying to convert over to it might be a
large task.
Which means either you are not using VMS (so why post here), or you
are doing file I/O with $QIO calls (painfull, rarley necessary).

All the HLL I/O packages use RMS.
Stephen Hoffman
2014-02-13 21:39:50 UTC
Permalink
Post by David Froble
Well, we aren't using RMS, and trying to convert over to it might be a
large task.
$qio virtual read and virtual write calls into a container file usually
map directly over to the $read and $write block I/O calls.
<http://h71000.www7.hp.com/doc/731final/4523/4523pro_032.html#read_service_routine>

<http://h71000.www7.hp.com/doc/731final/4523/4523pro_036.html#write_service_routine>

If you're using $qio logical or physical access or your own file
system, then all bets are off.
--
Pure Personal Opinion | HoffmanLabs LLC
JF Mezei
2014-02-13 23:24:39 UTC
Permalink
Post by Stephen Hoffman
If you're using $qio logical or physical access or your own file
system, then all bets are off.
Isn't that a job perfect for Mr VAXman ?

Have him don on his kernel mode suit and use his VAXmobile to dive into
the OS to intercept the $QIOs ?

(note that his kernel mode suit is thin and offers no protection for his
fragile/vital parts so an error in the wrong place could leave him in
severe pain in crouched position for a very long time before he can
recover :-)
Stephen Hoffman
2014-02-14 01:24:07 UTC
Permalink
Post by JF Mezei
Have him don on his kernel mode suit and use his VAXmobile to dive into
the OS to intercept the $QIOs ?
Intercepting a $qio system service is easy, either to a specific device
or just grabbing everything.
Using a logical or physical $qio "just" means the application can't
(easily) use RMS journaling.
--
Pure Personal Opinion | HoffmanLabs LLC
j***@gmail.com
2014-02-14 02:53:01 UTC
Permalink
Post by Stephen Hoffman
Intercepting a $qio system service is easy, either to a specific device
or just grabbing everything.
What technique(s) did you have in mind?

EJ
V***@SendSpamHere.ORG
2014-02-13 11:53:17 UTC
Permalink
Post by David Froble
Post by V***@SendSpamHere.ORG
{...snip...}
Post by V***@SendSpamHere.ORG
This particular piece of C has some inner mode code. I'm extra careful with
that using C; however, I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
After thinking about this for a while, I must confess to curiosity.
I'm assuming that by "inner mode" that you're talking about kernel mode.
If not, then ignore the rest of this.
Correct.
I've dabbled a bit at exec mode, mainly to allow some RTL code to use
I've *MORE* than dabbled in recent months/years. ;)
SYSLCK when the user didn't have that priv. But I've never had the need
to run anything in kernel made.
What would you be doing that would require running in kernel mode? I'm
assuming that you're working on some type of application, and not
modifying something in VMS.
Rather curious ....
Well, remember, you asked...
Yeah, even after many lessons about the dangers of doing so ..
Post by V***@SendSpamHere.ORG
http://www.attunity.com/products/attunity-cdc/rms-change-data-capture
http://www.attunity.com/products/attunity-cdc-ssis/rms-cdc-for-ssis
http://www.attunity.com/learning/video/attunity-rms-cdc-only-rms-solution-its-kind
http://www.enterpriseirregulars.com/25555/attunity-scores-a-win-with-rms-cdc-support/
http://www.attunity.com/news/attunity-announces-million-dollar-license-agreement-leading-communications-and-media-provider
I've been working with Hein van den Heuvel, who is now an Attunity employee,
since about 2009 when this project was conceived. There's not too much that
I don't know now about the inner workings of RMS as a result of this project.
It's been one of the most interesting and challenging VMS hacking projects I
have ever done.
That's some real interesting, and timely, information.
Timely, because of 2 possible tasks coming up.
1) Journaling or logging of all data updates, with the capability of
rebuilding the updates from a static backup and the journals.
2) In the event a port away from VMS must be done, a method to have
duplicate real time copies of the data, one in the current DAS data
files, and another in one of the free / open database products. This
would allow porting in small pieces while the applications continued to
be used, and updated.
Looks like others have faced similar problems.
But to get back on subject, while my RMS experience was years ago, and
it wasn't really deep into the internals, I'm wondering how you
intercept the updates? Are you talking data field granularity, data
record granularity, or other? For what I'm considering, I'm thinking to
modify the database access code. Don't know whether you're looking to
make modifications to RMS, or something else.
Any RMS service which has the potential of modifying data is intercepted.
Services such as $CREATE, $PUT, $DELETE, $UPDATE are of interest. THere's
no need to bother with things like $GET. What is captured is the data, the
entire record if you will, passed to the RMS service. In the case of the
$DELETE, the "before image" is captured; that's the content of the record
removed. Also, and it's optional and depends upon the application, $UPDATE
can also provide the "before image" prior to the new "updated" data. The
fun comes in with locking, synchronizing and obtaining the "before image"
data.

When initially scoped out, the idea was to simply intercept the RMS service
and copy the data from the FAB or RAB but that's not the *right* way to do
it. I won't go into detail here for a number of reasons. I did, however,
do a rather detailed expose' on the inner working at two OpenVMS Bootcamps.

Seriously, if you do see a use/need for this, contact Attunity. I'm sure
Hein would be happy to discuss the application of RMS CDC with you. I can
then answer specific questions for you if needed.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
David Froble
2014-02-13 16:20:26 UTC
Permalink
Post by V***@SendSpamHere.ORG
Post by David Froble
Post by V***@SendSpamHere.ORG
{...snip...}
Post by V***@SendSpamHere.ORG
This particular piece of C has some inner mode code. I'm extra careful with
that using C; however, I'm not so certain I'd want to be jumping into kernel
mode with BASIC.
After thinking about this for a while, I must confess to curiosity.
I'm assuming that by "inner mode" that you're talking about kernel mode.
If not, then ignore the rest of this.
Correct.
I've dabbled a bit at exec mode, mainly to allow some RTL code to use
I've *MORE* than dabbled in recent months/years. ;)
SYSLCK when the user didn't have that priv. But I've never had the need
to run anything in kernel made.
What would you be doing that would require running in kernel mode? I'm
assuming that you're working on some type of application, and not
modifying something in VMS.
Rather curious ....
Well, remember, you asked...
Yeah, even after many lessons about the dangers of doing so ..
Post by V***@SendSpamHere.ORG
http://www.attunity.com/products/attunity-cdc/rms-change-data-capture
http://www.attunity.com/products/attunity-cdc-ssis/rms-cdc-for-ssis
http://www.attunity.com/learning/video/attunity-rms-cdc-only-rms-solution-its-kind
http://www.enterpriseirregulars.com/25555/attunity-scores-a-win-with-rms-cdc-support/
http://www.attunity.com/news/attunity-announces-million-dollar-license-agreement-leading-communications-and-media-provider
I've been working with Hein van den Heuvel, who is now an Attunity employee,
since about 2009 when this project was conceived. There's not too much that
I don't know now about the inner workings of RMS as a result of this project.
It's been one of the most interesting and challenging VMS hacking projects I
have ever done.
That's some real interesting, and timely, information.
Timely, because of 2 possible tasks coming up.
1) Journaling or logging of all data updates, with the capability of
rebuilding the updates from a static backup and the journals.
2) In the event a port away from VMS must be done, a method to have
duplicate real time copies of the data, one in the current DAS data
files, and another in one of the free / open database products. This
would allow porting in small pieces while the applications continued to
be used, and updated.
Looks like others have faced similar problems.
But to get back on subject, while my RMS experience was years ago, and
it wasn't really deep into the internals, I'm wondering how you
intercept the updates? Are you talking data field granularity, data
record granularity, or other? For what I'm considering, I'm thinking to
modify the database access code. Don't know whether you're looking to
make modifications to RMS, or something else.
Any RMS service which has the potential of modifying data is intercepted.
Services such as $CREATE, $PUT, $DELETE, $UPDATE are of interest. THere's
no need to bother with things like $GET. What is captured is the data, the
entire record if you will, passed to the RMS service. In the case of the
$DELETE, the "before image" is captured; that's the content of the record
removed. Also, and it's optional and depends upon the application, $UPDATE
can also provide the "before image" prior to the new "updated" data. The
fun comes in with locking, synchronizing and obtaining the "before image"
data.
Yep! If you were able to know what updates were going to come along
before they did so, you'd probably own Atlantic City, Vegas, the NY
stock exchange, and such, at least until someone else discovered your
secret. I'm not greedy, I'd settle for one PowerBall win ....

:-)

My dim recollections are that there are 2 methods for obtaining RMS
record data, the "move mode" where data is moved to and from some static
buffer, such as a MAP in Basic, and then another method that I don't
believe I've ever used, and forget the terminology.

So, for the move mode, if you're intercepting the procedure before the
data record is moved back to the I/O buffer, then I'd think that you'd
have the "before image" still in the I/O buffer. It should still be
valid, since it would have a lock, else updating would not occur.

Then there is writing new data. And global buffers. My, you really
have gotten yourself into a quagmire.

:-)
Post by V***@SendSpamHere.ORG
When initially scoped out, the idea was to simply intercept the RMS service
and copy the data from the FAB or RAB but that's not the *right* way to do
it. I won't go into detail here for a number of reasons. I did, however,
do a rather detailed expose' on the inner working at two OpenVMS Bootcamps.
Seriously, if you do see a use/need for this, contact Attunity. I'm sure
Hein would be happy to discuss the application of RMS CDC with you. I can
then answer specific questions for you if needed.
I doubt they would have anything that would help me, as DAS has nothing
to do with RMS, well, once again I'm wrong, it uses the filename parser
in RMS, but nothing else.

Looking at it positively, it's all my code, and I can change it.
V***@SendSpamHere.ORG
2014-02-13 18:50:04 UTC
Permalink
{...snip...}
Yep! If you were able to know what updates were going to come along
before they did so, you'd probably own Atlantic City, Vegas, the NY
stock exchange, and such, at least until someone else discovered your
secret. I'm not greedy, I'd settle for one PowerBall win ....
:-)
My dim recollections are that there are 2 methods for obtaining RMS
record data, the "move mode" where data is moved to and from some static
buffer, such as a MAP in Basic, and then another method that I don't
believe I've ever used, and forget the terminology.
So, for the move mode, if you're intercepting the procedure before the
data record is moved back to the I/O buffer, then I'd think that you'd
have the "before image" still in the I/O buffer. It should still be
valid, since it would have a lock, else updating would not occur.
If you were to predicate this upon what the user passes in their FAB/RAB, to
use you AC and Vegas metaphor, you're going to wind up a sorry loser!

I'm not going to disclose here how I get the "before image" but I assure you
it's not stale data in the user's buffers. If you'd really want to know how
it's done, an NDA will need to be signed.
Then there is writing new data. And global buffers. My, you really
have gotten yourself into a quagmire.
Global buffers, believe it or not, are not treated any differently than the
local buffers.
Post by V***@SendSpamHere.ORG
When initially scoped out, the idea was to simply intercept the RMS service
and copy the data from the FAB or RAB but that's not the *right* way to do
it. I won't go into detail here for a number of reasons. I did, however,
do a rather detailed expose' on the inner working at two OpenVMS Bootcamps.
Seriously, if you do see a use/need for this, contact Attunity. I'm sure
Hein would be happy to discuss the application of RMS CDC with you. I can
then answer specific questions for you if needed.
I doubt they would have anything that would help me, as DAS has nothing
to do with RMS, well, once again I'm wrong, it uses the filename parser
in RMS, but nothing else.
DAS???
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
David Froble
2014-02-13 21:09:16 UTC
Permalink
Post by V***@SendSpamHere.ORG
{...snip...}
Yep! If you were able to know what updates were going to come along
before they did so, you'd probably own Atlantic City, Vegas, the NY
stock exchange, and such, at least until someone else discovered your
secret. I'm not greedy, I'd settle for one PowerBall win ....
:-)
My dim recollections are that there are 2 methods for obtaining RMS
record data, the "move mode" where data is moved to and from some static
buffer, such as a MAP in Basic, and then another method that I don't
believe I've ever used, and forget the terminology.
So, for the move mode, if you're intercepting the procedure before the
data record is moved back to the I/O buffer, then I'd think that you'd
have the "before image" still in the I/O buffer. It should still be
valid, since it would have a lock, else updating would not occur.
If you were to predicate this upon what the user passes in their FAB/RAB, to
use you AC and Vegas metaphor, you're going to wind up a sorry loser!
Not sure what you're saying about FAB and RAB.
Post by V***@SendSpamHere.ORG
I'm not going to disclose here how I get the "before image" but I assure you
it's not stale data in the user's buffers. If you'd really want to know how
it's done, an NDA will need to be signed.
What I meant was the data is read into an internal I/O buffer, and the
desired data record is then moved into a user's pre-defined record
buffer. In a write of the data record, RMS moves it back into the
internal I/O buffer, then writes the I/O buffer.

If the data in the I/O buffer is locked, then is should not be stale.

However, I think I've already mentioned that it's been years since I did
anything with RMS, and even then I wasn't deep into the internals, so
the above is old conjecture.

I wasn't asking how you got the "before image", and respect your
intellectual secrets.
Post by V***@SendSpamHere.ORG
Then there is writing new data. And global buffers. My, you really
have gotten yourself into a quagmire.
Global buffers, believe it or not, are not treated any differently than the
local buffers.
Yeah, after I wrote that, I began to suspect that they might be the
same, or even easier than private I/O buffers.
Post by V***@SendSpamHere.ORG
Post by V***@SendSpamHere.ORG
When initially scoped out, the idea was to simply intercept the RMS service
and copy the data from the FAB or RAB but that's not the *right* way to do
it. I won't go into detail here for a number of reasons. I did, however,
do a rather detailed expose' on the inner working at two OpenVMS Bootcamps.
This is what I fail to understand. As far as I know, neither the FAB
nor the RAB have any actual data in them. They surely have some
pointers that could be helpful, but no data.

Starting to wish I had been at those bootcamps ....
Post by V***@SendSpamHere.ORG
Post by V***@SendSpamHere.ORG
Seriously, if you do see a use/need for this, contact Attunity. I'm sure
Hein would be happy to discuss the application of RMS CDC with you. I can
then answer specific questions for you if needed.
I doubt they would have anything that would help me, as DAS has nothing
to do with RMS, well, once again I'm wrong, it uses the filename parser
in RMS, but nothing else.
DAS???
DAS is a Database Access System supporting indexed (ISAM) and relative
files. I implemented it in 1984, based on prior work at a previous job.
It consists of shared code for access, and some utilities for various
file maintenance. I/O is at the QIO level, and the DLM is used for locking.

It had been used by multiple customers, but now only by Consolidated
Data in Codis, the others having been assimilated by the Borg.

It was a good product in 1984. Having seen what's available in various
RDBMS systems, it really isn't a good product in 2014.
V***@SendSpamHere.ORG
2014-02-13 22:06:14 UTC
Permalink
{...snip...}
What I meant was the data is read into an internal I/O buffer, and the
desired data record is then moved into a user's pre-defined record
buffer. In a write of the data record, RMS moves it back into the
internal I/O buffer, then writes the I/O buffer.
If the data in the I/O buffer is locked, then is should not be stale.
OK. I reread. You were talking about the locate and move modes of the RMS
buffers. Locate mode is only valid using a $GET and it's unavailable when
the record crosses a block boundary, file access is set UPDATE, compressed
records (in the case of indexed files), global buffers have been specified
or multiple streams access the file.
However, I think I've already mentioned that it's been years since I did
anything with RMS, and even then I wasn't deep into the internals, so
the above is old conjecture.
I wasn't asking how you got the "before image", and respect your
intellectual secrets.
Post by V***@SendSpamHere.ORG
Post by David Froble
Then there is writing new data. And global buffers. My, you really
have gotten yourself into a quagmire.
Global buffers, believe it or not, are not treated any differently than the
local buffers.
Yeah, after I wrote that, I began to suspect that they might be the
same, or even easier than private I/O buffers.
Post by V***@SendSpamHere.ORG
Post by David Froble
Post by V***@SendSpamHere.ORG
When initially scoped out, the idea was to simply intercept the RMS service
and copy the data from the FAB or RAB but that's not the *right* way to do
it. I won't go into detail here for a number of reasons. I did, however,
do a rather detailed expose' on the inner working at two OpenVMS Bootcamps.
This is what I fail to understand. As far as I know, neither the FAB
nor the RAB have any actual data in them. They surely have some
pointers that could be helpful, but no data.
FAB/RAB maintain pointers to data which is what I meant when saying that you
can't trust the FAB and RAB.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
David Froble
2014-02-14 02:14:35 UTC
Permalink
Post by V***@SendSpamHere.ORG
OK. I reread. You were talking about the locate and move modes of the RMS
buffers.
Yep, that's it. It's been a long time, and I couldn't remember the name.

Never used it.
Johnny Billquist
2014-02-14 03:16:44 UTC
Permalink
Post by V***@SendSpamHere.ORG
{...snip...}
What I meant was the data is read into an internal I/O buffer, and the
desired data record is then moved into a user's pre-defined record
buffer. In a write of the data record, RMS moves it back into the
internal I/O buffer, then writes the I/O buffer.
If the data in the I/O buffer is locked, then is should not be stale.
OK. I reread. You were talking about the locate and move modes of the RMS
buffers. Locate mode is only valid using a $GET and it's unavailable when
the record crosses a block boundary, file access is set UPDATE, compressed
records (in the case of indexed files), global buffers have been specified
or multiple streams access the file.
Really? Are locate mode not available for writes in VMS. They are in
RSX. When you open the file, you tell what the maximum size you might
write is, and RMS will return a pointer to where you should be writing
your data. It might be a bounce buffer, but it might also be the actual
disk buffer directly.
And each $PUT will update the write pointer for the next write to be done.

Johnny
--
Johnny Billquist || "I'm on a bus
|| on a psychedelic trip
email: ***@softjar.se || Reading murder books
pdp is alive! || tryin' to stay hip" - B. Idol
JF Mezei
2014-02-13 23:15:28 UTC
Permalink
Post by V***@SendSpamHere.ORG
I'm not going to disclose here how I get the "before image" but I assure you
it's not stale data in the user's buffers.
I would be shocked if Mr VAXman dared lower himself to user mode to
access a user buffer. He is far more likely to wedge himself between the
XQP and RMS to capture those buffers :-)

If 2 processes access the same RMS indexed file at same time, is it RMS
that does the cache validatioN/updates when one process modifies
something that is also contained in the other process' cache ? Or is
that does at XQP level ?

What happens when the 2 processes are on different nodes of a cluster ?
Are are caches invalidated and at what level ?
Paul Sture
2014-02-14 08:27:56 UTC
Permalink
Post by David Froble
Post by V***@SendSpamHere.ORG
It would all have been in
Macro if it were up to me but the customer said they can only read C.
They lie! I submit that anyone can read BASIC, but I do recall some
almost successful instances of trying to make it unreadable.
A$ = B$ + C$ + D$ + E$ + F$ + G$ + H$ + I$ + J$ + K$ + L$ + ....
Basic, a language that knows how to work with strings ....
And no, I don't normally declare my variables ....
There are times when BASIC dynamic strings carry too much of an overhead
though. I distinctly recall someone here about a decade ago (Shane Smith?)
describing how he had got much improved performance by massaging some BASIC
to use static strings rather than dynamic ones.

--
Paul Sture
Stephen Hoffman
2014-02-10 15:02:10 UTC
Permalink
Post by hb
$ cc x
int bar (void) { return foo(1,2,3)+foo(1,2,3,4); }
........................^
%CC-E-TOOMANYARGS, In this statement, "foo" expects 2 arguments, but 3
are supplied.
at line number 2 in file DISK$USER:[USER]x.c;1
...
Post by hb
You can just #define the function to something totally different,
#undef it later and add the correct prototype...
Or (untested) suppress the error and move on:

#pragma message save
#pragma message disable (TOOMANYARGS)
#pragma message ("Suppressing argument mismatch error secondary to
str$routines.h definition error in " __FILE__)
str$concat( your, call, here, with, whatever );
#pragma message restore


Here's a similar diagnostic-suppression sequence I use to mask an error
in a header file that shows when I crank up the compiler diagnostics:

#pragma message save
#pragma message disable (level3,NESTEDCOMMENT)
#include <dvidef.h>
...
#include <stdbool.h>
#pragma message restore


ps: (and entirely unrelated to VAXman's issue with the header files)
for those folks reading this comp.os.vms newsgroup thread that might be
interested in a descriptor-like approach for a C project, have a look
at the <https://github.com/antirez/sds> library. This library is
entirely different from VMS string descriptors, but with a similar
general purpose and can be used where null-terminiated / ASCIZ strings
are deemed inappropriate. The library is also rather more portable.
--
Pure Personal Opinion | HoffmanLabs LLC
V***@SendSpamHere.ORG
2014-02-10 15:26:18 UTC
Permalink
Post by Stephen Hoffman
Post by hb
$ cc x
int bar (void) { return foo(1,2,3)+foo(1,2,3,4); }
........................^
%CC-E-TOOMANYARGS, In this statement, "foo" expects 2 arguments, but 3
are supplied.
at line number 2 in file DISK$USER:[USER]x.c;1
....
Post by hb
You can just #define the function to something totally different,
#undef it later and add the correct prototype...
#pragma message save
#pragma message disable (TOOMANYARGS)
#pragma message ("Suppressing argument mismatch error secondary to
str$routines.h definition error in " __FILE__)
str$concat( your, call, here, with, whatever );
#pragma message restore
%CC-E-TOOMANYARGS, (1) In this statement, "STR$CONCAT" expects 2 arguments, but 4 are supplied.
----^---- ERROR


$ HELP CC LANGUAGE_TOPICS PREPROCESSOR #PRAGMA

CC

Language_topics

Preprocessor

#pragma

The #pragma preprocessor directive performs compiler-specific tasks
as designated by each implementation of the C language.

All pragmas have a <pragma-name>_m version, which makes the pragma
subject to macro replacement. For example, #pragma assert is not
subject to macro expansion, but #pragma assert_m is.

All pragmas also have a <pragma-name>_nm version, which prevents
macro expansion. For example, #pragma inline is subject to macro
expansion, but #pragma inline_nm is not.

There is also a _Pragma operator (C99 Standard), which destringizes
its string literal argument, effectively allowing #pragma
directives to be produced by macro expansion. When specified using
this operator, the tokens of the pragma, which appear together
within a single string literal in this form, are not macro
expanded, even if they have an "_m" suffix. But macro expansion
can be accomplished if desired by using the stringization operator
(#) to form the string.

The _Pragma operator has the following syntax:

_Pragma ( string-literal )

HP C for OpenVMS Systems supports the following #pragma directives:

:
:

#pragma message[_m|_nm]

Controls the issuance of individual diagnostic messages or
groups of messages. Use of this pragma overrides any
command-line options that may affect the issuance of messages.

Syntax:

#pragma message option1 message-list
#pragma message option2
#pragma message (quoted-string)

where option1 is:

disable Suppresses the issuance of the indicated
messages.

====> Only messages of severity Warning (W) or
====> Information (I) can be disabled. If the
====> message has severity of Error (E) or
====> Fatal (F), it is issued regardless of
====> any attempt to disable it.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
Stephen Hoffman
2014-02-10 19:25:35 UTC
Permalink
Post by V***@SendSpamHere.ORG
====> Only messages of severity Warning (W) or
====> Information (I) can be disabled. If the
====> message has severity of Error (E) or
====> Fatal (F), it is issued regardless of
====> any attempt to disable it.
Ah, well. 'Tis a shame. Can't manually de-tune those errors down to
warning status via #pragma, either. Not sure why C won't allow these
blade guards to be disabled, but then any compiler changes and any
updates here are exceedingly unlikely at this point, and I'm not
inclined to patch the current compiler nor to port over a different
compiler, and you've already gotten a solution working. C'est la vie.
--
Pure Personal Opinion | HoffmanLabs LLC
V***@SendSpamHere.ORG
2014-02-10 20:11:33 UTC
Permalink
Post by Stephen Hoffman
Post by V***@SendSpamHere.ORG
====> Only messages of severity Warning (W) or
====> Information (I) can be disabled. If the
====> message has severity of Error (E) or
====> Fatal (F), it is issued regardless of
====> any attempt to disable it.
Ah, well. 'Tis a shame. Can't manually de-tune those errors down to
warning status via #pragma, either. Not sure why C won't allow these
blade guards to be disabled, but then any compiler changes and any
updates here are exceedingly unlikely at this point, and I'm not
inclined to patch the current compiler nor to port over a different
compiler, and you've already gotten a solution working. C'est la vie.
That's whay I asked here in the first place. I've suppressed warnings with
the "#pragma message" before, as you now know, errors can not be suppressed.
I was hoping there was some other "hidden from view" #pragma. The current
"hack", however, does get me out of the C swamps. Now, to only get out of
the NJ swamps.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG

Well I speak to machines with the voice of humanity.
Neil Rieck
2014-02-14 12:27:33 UTC
Permalink
Post by V***@SendSpamHere.ORG
I've encountered a VMS library call prototype that is incorrect. How can
I override/overwrite the prototype in my source to make it correct? I've
used other routines from this library without issue save for this one. Is
there a #pragma that allows for or provides this? I've read the on-line
help but don't see anything under #pragma.
--
VAXman- A Bored Certified VMS Kernel Mode Hacker VAXman(at)TMESIS(dot)ORG
Well I speak to machines with the voice of humanity.
Is this a VAX or Alpha problem? I am assuming it is not an Itanium problem because Itanium code generation tools (both C and C++ compilers) as well as the Linker were developed past Alpha. BTW, HP did not add Itanium features to Alpha (even though the new HP was supposed to be a merger of HP and Compaq, Alpha was treated like the proverbial red-headed step child)

On a related note, anyone doing code maintenance on C or C++ sources would be wise to insert this directive as close to the top as possible.

#define __NEW_STARLET 1 // enable new (strict) starlet for OpenVMS Alpha 7.0

for more information about this, please read:
http://h71000.www7.hp.com/doc/82final/5841/5841pro_059.html

The compile-time directive discussed in section 21.2 will allow you to pretest your code to see how broken it is before code renovation.

Neil Rieck
Kitchener / Waterloo / Cambridge,
Ontario, Canada.
http://www3.sympatico.ca/n.rieck/

Continue reading on narkive:
Loading...