www.digitalmars.com         C & C++   DMDScript  

D - Help requested...

reply larry cowan <larry_member pathlink.com> writes:
After writing a few small D programs to get the hang of D, I am trying to port a
C program I wrote to D as simply as possible.  The program is non-trivial.  I 
need help with the following 2 problems:

----------------------------------------
How can I use this style of struct in D?

typedef struct _leaf {
struct _leaf *next;
struct _leaf *prev;
int mydata;
} _LEAF;

(This will not compile)

struct LEAF {
LEAF *next;
LEAF *prev;
int mydata;
};

This would be a very common coding problem for those who use chained structs.

-----------------------------------------
I have the following type of #defines used by many functions (which accept a
pointer table of parsed control rec input) to provide meaningful readable code
and allow control rec definitions to change indeoendently.  How in D?

#define CMD *(ppdata+0)
..
#define M_FROM *(ppdata+1)
#define M_TO *(ppdata+2)
..
#define X_LN *(ppdata+1)
#define X_FROM *(ppdata+2)
#define X_TO *(ppdata+3)
#define X_MUL *(ppdata+4)
..
#define Y_OP *(ppdata+1)
#define Y_A *(ppdata+2)
#define Y_B *(ppdata+3)
#define Y_C *(ppdata+4)
#define Y_D *(ppdata+5)
..
void xfunct1 ( char bright;  char dim; char** ppdata )
{
int len = atoi(X_LN);
sprintf(globuf,"%c%.*s --> %c%.*s",dim,len,X_FROM,bright,len,X_TO);
}
..
int xfunct2 ( int line, char** ppdata )
{
int i, n = atoi(X_MUL);

for (i=0; i < n ;i++) {
xfunct1(ppdata);
printf("Line %3d: %s\n",line+i,globuf);
}
return (line+n);
}
..
---------------------------------------------
The example is made up, but the problem is real and extensive.  I am not
interested (yet) in a rewrite into object oriented style, I just want as quick
and simple a port as possible.
Feb 02 2004
next sibling parent "davepermen" <davepermen hotmail.com> writes:
 struct LEAF {
 LEAF *next;
 LEAF *prev;
 int mydata;
 };

 #define CMD *(ppdata+0)
 ..
 int xfunct2 ( int line, char** ppdata )
 {
 int i, n = atoi(X_MUL);

 for (i=0; i < n ;i++) {
 xfunct1(ppdata);
 printf("Line %3d: %s\n",line+i,globuf);
 }
 return (line+n);
 }
 ..

this is just ugly. rewrite it as soon as possible. eighter rewrite it like this: type CMD(char**data) { return *cast(type*)(data+0); } and replace CMD with CMD(ppdata) as well as the others, or bether rewrite it completely directly.
Feb 02 2004
prev sibling next sibling parent larry cowan <larry_member pathlink.com> writes:
HOLD THE PRESSES!  The first problem is not one.  I used:

struct _LEAF {
_LEAF *next;
_LEAF *prev;
int mydata;
}

Taking off the underscores corrected the problem.  It IS invalid according to
the manual (identifiers must begin with a letter).  My only complaint is the
error message:  on the second line, "identifier '_LEAF' not defined" is
misleading - maybe "identifier '_LEAF' invalid name" should be put out on the
first line when it is rejected?

-----------------------------------------------------

In article <bvll36$vmm$1 digitaldaemon.com>, larry cowan says...
After writing a few small D programs to get the hang of D, I am trying to port a
C program I wrote to D as simply as possible.  The program is non-trivial.  I 
need help with the following 2 problems:

----------------------------------------
How can I use this style of struct in D?

typedef struct _leaf {
struct _leaf *next;
struct _leaf *prev;
int mydata;
} _LEAF;

(This will not compile)

struct LEAF {
LEAF *next;
LEAF *prev;
int mydata;
};

This would be a very common coding problem for those who use chained structs.

-----------------------------------------
I have the following type of #defines used by many functions (which accept a
pointer table of parsed control rec input) to provide meaningful readable code
and allow control rec definitions to change indeoendently.  How in D?

#define CMD *(ppdata+0)
..
#define M_FROM *(ppdata+1)
#define M_TO *(ppdata+2)
..
#define X_LN *(ppdata+1)
#define X_FROM *(ppdata+2)
#define X_TO *(ppdata+3)
#define X_MUL *(ppdata+4)
..
#define Y_OP *(ppdata+1)
#define Y_A *(ppdata+2)
#define Y_B *(ppdata+3)
#define Y_C *(ppdata+4)
#define Y_D *(ppdata+5)
..
void xfunct1 ( char bright;  char dim; char** ppdata )
{
int len = atoi(X_LN);
sprintf(globuf,"%c%.*s --> %c%.*s",dim,len,X_FROM,bright,len,X_TO);
}
..
int xfunct2 ( int line, char** ppdata )
{
int i, n = atoi(X_MUL);

for (i=0; i < n ;i++) {
xfunct1(ppdata);
printf("Line %3d: %s\n",line+i,globuf);
}
return (line+n);
}
..
---------------------------------------------
The example is made up, but the problem is real and extensive.  I am not
interested (yet) in a rewrite into object oriented style, I just want as quick
and simple a port as possible.

Feb 02 2004
prev sibling parent reply "Ben Hinkle" <bhinkle4 juno.com> writes:
 I have the following type of #defines used by many functions (which accept

 pointer table of parsed control rec input) to provide meaningful readable

 and allow control rec definitions to change indeoendently.  How in D?

 #define CMD *(ppdata+0)
 ..
 #define M_FROM *(ppdata+1)
 #define M_TO *(ppdata+2)
 ..
 #define X_LN *(ppdata+1)
 #define X_FROM *(ppdata+2)
 #define X_TO *(ppdata+3)
 #define X_MUL *(ppdata+4)
 ..
 #define Y_OP *(ppdata+1)
 #define Y_A *(ppdata+2)
 #define Y_B *(ppdata+3)
 #define Y_C *(ppdata+4)
 #define Y_D *(ppdata+5)
 ..
 void xfunct1 ( char bright;  char dim; char** ppdata )
 {
 int len = atoi(X_LN);
 sprintf(globuf,"%c%.*s --> %c%.*s",dim,len,X_FROM,bright,len,X_TO);
 }
 ..
 int xfunct2 ( int line, char** ppdata )
 {
 int i, n = atoi(X_MUL);

 for (i=0; i < n ;i++) {
 xfunct1(ppdata);
 printf("Line %3d: %s\n",line+i,globuf);
 }
 return (line+n);
 }
 ..
 ---------------------------------------------
 The example is made up, but the problem is real and extensive.  I am not
 interested (yet) in a rewrite into object oriented style, I just want as

 and simple a port as possible.

If you want minimal effort just do a "search-replace" to expand the macros by hand. You lose readability but that might not be your goal here. If you just use the macros as rvalues then you can turn them into functions: char* CMD(char**ppdata) {return *(ppdata+0);} and make sure you pass in ppdata to the function when it is called. If you use the macros as lvalues then you'll have to write something more complex. -Ben
Feb 02 2004
parent reply larry cowan <larry_member pathlink.com> writes:
Damn, I hate entering into a text box, and tabbing - deleting everything!
-------------------------------------------------------------------------

Anyway, Thanks - that's probably what I was looking for, but 
making them functions, even trivial ones, kills the original
intent.  Better to just convert them back to *(ppdata+#) with
a comment to indicate the expected content.  I could throw out
more questions about precprocesser conversions, but attempting
to port a complex C program with sophisticated use of the preprocessor
seems a disaster.  It is a 5k line X12 HIPAA to XML or display
syntax checker, table driven to handle all HIPPA transaction
types.  I'll go back to learning D with small new programs. I'll
do a real rewrite later when I know D better - incidentally, I
never had a yen to convert it to C++, but D is more attractive.

-------------------------------------------------------------------------
In article <bvlon0$164g$1 digitaldaemon.com>, Ben Hinkle says...
 I have the following type of #defines used by many functions (which accept

 pointer table of parsed control rec input) to provide meaningful readable

 and allow control rec definitions to change indeoendently.  How in D?

 #define CMD *(ppdata+0)
 ..
 #define M_FROM *(ppdata+1)
 #define M_TO *(ppdata+2)
 ..
 #define X_LN *(ppdata+1)
 #define X_FROM *(ppdata+2)
 #define X_TO *(ppdata+3)
 #define X_MUL *(ppdata+4)
 ..
 #define Y_OP *(ppdata+1)
 #define Y_A *(ppdata+2)
 #define Y_B *(ppdata+3)
 #define Y_C *(ppdata+4)
 #define Y_D *(ppdata+5)
 ..
 void xfunct1 ( char bright;  char dim; char** ppdata )
 {
 int len = atoi(X_LN);
 sprintf(globuf,"%c%.*s --> %c%.*s",dim,len,X_FROM,bright,len,X_TO);
 }
 ..
 int xfunct2 ( int line, char** ppdata )
 {
 int i, n = atoi(X_MUL);

 for (i=0; i < n ;i++) {
 xfunct1(ppdata);
 printf("Line %3d: %s\n",line+i,globuf);
 }
 return (line+n);
 }
 ..
 ---------------------------------------------
 The example is made up, but the problem is real and extensive.  I am not
 interested (yet) in a rewrite into object oriented style, I just want as

 and simple a port as possible.

If you want minimal effort just do a "search-replace" to expand the macros by hand. You lose readability but that might not be your goal here. If you just use the macros as rvalues then you can turn them into functions: char* CMD(char**ppdata) {return *(ppdata+0);} and make sure you pass in ppdata to the function when it is called. If you use the macros as lvalues then you'll have to write something more complex. -Ben

Feb 02 2004
parent reply Ilya Minkov <minkov cs.tum.edu> writes:
larry cowan wrote:
 Damn, I hate entering into a text box, and tabbing - deleting everything!

Let Ctrl-Z be your friend.
 Anyway, Thanks - that's probably what I was looking for, but 
 making them functions, even trivial ones, kills the original
 intent.  Better to just convert them back to *(ppdata+#) with
 a comment to indicate the expected content.  I could throw out
 more questions about precprocesser conversions, but attempting
 to port a complex C program with sophisticated use of the preprocessor
 seems a disaster.  It is a 5k line X12 HIPAA to XML or display
 syntax checker, table driven to handle all HIPPA transaction
 types.  I'll go back to learning D with small new programs. I'll
 do a real rewrite later when I know D better - incidentally, I
 never had a yen to convert it to C++, but D is more attractive.

You can run a selective preprocessor over your original C program. D is clearly matching a slightly more high-level coding style. Why do you want this code converted if you can call it from D as it is? -eye
Feb 05 2004
parent larry cowan <larry_member pathlink.com> writes:
Thanks for the ^Z help - forgot about that.

Not sure what you mean about selective preprocessing, but I don't want all of
the .h-file based crap expanded, nor most of the others - the idea is to retain
the original code as much as possible, not to get rid of all #defines - many
convert quite nicely to const int XXX = ..., or const char[] YYY = "..., etc.
Some simple perl-based substitution did the job and continues.  It's too much
code, and the port is expected to be a throwaway, so I want to handle each
problem I uncover on a mass basis if possible.  That one [ the #defines of
*(ppdata+#) ] was going to be enough manual work I nearly quit the port.

Primarily because there may be some conflicting ownership noise about the C
code, but there would be none about a rewrite.

The port is just to 1) teach myself D a bit, especially D vs. C, 2)
refamiliarize myself with the C code, and 3) get design ideas as I go through it
on how best to do a rewrite. 

Enough. Thanks.

In article <bvtc79$2adm$1 digitaldaemon.com>, Ilya Minkov says...
larry cowan wrote:
 Damn, I hate entering into a text box, and tabbing - deleting everything!

Let Ctrl-Z be your friend.
 Anyway, Thanks - that's probably what I was looking for, but 
 making them functions, even trivial ones, kills the original
 intent.  Better to just convert them back to *(ppdata+#) with
 a comment to indicate the expected content.  I could throw out
 more questions about precprocesser conversions, but attempting
 to port a complex C program with sophisticated use of the preprocessor
 seems a disaster.  It is a 5k line X12 HIPAA to XML or display
 syntax checker, table driven to handle all HIPPA transaction
 types.  I'll go back to learning D with small new programs. I'll
 do a real rewrite later when I know D better - incidentally, I
 never had a yen to convert it to C++, but D is more attractive.

You can run a selective preprocessor over your original C program. D is clearly matching a slightly more high-level coding style. Why do you want this code converted if you can call it from D as it is? -eye

Feb 06 2004