I’ve been using z/OS in some for over 40 years and I do not see many major problems with it (some other people may – but it cannot be very many). It is the same with MQ on z/OS – but since I left IBM, and did not use MQ on z/OS for a year or so, and I am now coming to it as a customer, I do see a few things that could be improved. When these products were developed, people were grateful for any solution which worked, rather than an elegant solution which did not work. In general people do not like to be told their baby is ugly.
I have been programming in Python, and gone back to C to extract certificate information from RACF, and C looks really ugly in comparison. It may be lack of vision from the people who managed the C language, or lack of vision from the people who set standards, but the result is ugly.
My little problem (well, one of them)
I have decoded a string returned from RACF and it is in an ugly structure which uses
typedef struct _attribute {
oid identifier;
buffer * pValue ;
int lName
} x509_rdn_attribute;
typedef enum {
unknown = 0,
name = 1,
surname = 2,
givenName = 3,
initials = 4,
commonName = 6
....
} oid ;
My problem is that I have an oid identifier of 6 – how to I get map this to the string “commonName”.
I could use a big switch statement, but it means I have to preprocess the list, or type it all in. I then need to keep an eye on the provided definitions, and update my file if it changes. The product could provide a function to do the work for me. A good start – but perhaps the wrong answer.
If I ruled the world…
As well as “Every day would be the first day of Spring” I would have the C language provide a function for each enum so mune_oid(2) returns “surname”;
I wrote some code to interpret distributed MQ trace, and I had to do this reverse mapping for many field types. In the end, I wrote some Python script which took the CMQC.h header file and transformed each enum into a function which did the switch, and return the symbolic name from the number.
I came up with the idea of using definitions like colin.h with clever macros,
TYPEDEF_ENUM (_attribute)
ENUM(unknown,0,descriptive comment);
ENUM(name,1,persons name);
...
END_TYPEDEF_ENUM(OID)
For normal usage I would define macros
#if ndef TYPEDEF_ENUM
#define TYPEDEF_ENUM (a) typedef struct a {
#define ENUM(a,b,c) a=b,/* c*/
#define END_TYPEDEF_ENUM(a) } a;
#endif
#include <colin.h>
For the lookup processing the macros could be
#define TYPEDEF_ENUM (a) char * lookup_a(int in);switch(in){
#define ENUM(a,b,c) case b return #a; /* c */
#define END_TYPEDEF_ENUM(a) } return "Unknown";
#include <colin.h>
but this solution means I have to include colin.h more than once, which may cause duplicate definitions.
My solution looks uglier than the problem, so I think I’ll just stick to my Python solution and creating a mune… function.