APPELEZ-NOUS
819-345-3497

How to parse C/C++ declarations

This was somewhere lying around in one my old HDD backups, and I always wanted to put it somewhere convenient for me to be able to reference it on demand.

It’s a post from comp.lang.c++ from when I was doing a lot of C++ development (most of which I’ve forgotten now that I use C# and .NET for EPLAN API development), but I think it’s just too good to let go to waste.

For those who might be interested in such things, enjoy:

Re: int (*t(int))(int *); // what does this mean?

Author: jim.hyslop
Email: jim.hyslop@leitch.com
Date: 1998/09/17
Forums: comp.lang.c++.moderated, comp.lang.c++
————————————————————————

In article <6tok7l$3ook$1@newssvr04-int.news.prodigy.com>,
« JER » wrote:
> Please give me the meaning of the declaration:
> int ( * t (int) )( int * );

The rules for parsing are:
Start at the identifier. Process to the right until you hit the end of the declaration or a closing parenthesis. Process to the left until you
hit an opening parenthesis or the beginning of the declaration. Repeat until the declaration is fully parsed.

So, the declaration is read as:
int ( * t (int) )( int * ) ;
10 6 5 1 2 3 4 7 8 9 11

1 – t
2 – is a function
3 – which accepts an int parameter
4 – [closing parenthesis – parse backwards now]
5 – and returns a pointer
6 – [opening parenthesis – parse forwards now]
7 – to a function
8 – which accepts an int *
9 – [closing parenthesis – parse backwards now]
10- and returns an int [beginning of dec – parse forwards now]
11- end of declaration – you’re done.

So: « t is a function which accepts an int parameter and returns a
pointer to a
function which accepts an int * and returns an integer ». The following
code
will work with your declaration:

#include 
using std::cout;
using std::endl;

int x(int *val)
{
  cout << "In x, passed value of " << *val << endl;
  return *val;
}

int y(int *val)
{
  cout << "In y, passed value of " << *val << endl;
  return *val;
}

int z(int *val)
{
  cout << "In z, passed value of " << *val << endl;
  return *val;
}

int ( * t (int v) )( int *) // Your original declaration
{
   // Exercise to the reader - how do you parse arr:
   // Hint: "=" is the end-of-declaration
   static int (*arr[])(int *) = {x, y, z};

   if (v < 0 || v >= sizeof(arr) / sizeof(arr[0])) {
      return NULL;
   }
   return arr[v];
}

int main(void)
{
  // and how do you parse:
  int(*p) (int *);

  int count=0;
  p=t(count);
  while(p) {
     cout << "p(&count) returned " << p(&count) << endl;
     p=t(++count);
  }
}

(English) Creating pull lists reports

Désolé, cet article est seulement disponible en English.

(English) Fun with wire numbering

Automated wire numbering in EPLAN Electric P8 is certainly a great time saver. I’ve worked with 500+ page projects, and I wouldn’t want to go back to use AutoCAD.

While EPLAN is certainly flexible when it comes to wire numbering, sometimes a specific customer requirement leaves me pensive, and sometimes it becomes a challenge I have to accept.

In this example, the customer wanted all connections to motors to be numbered like this:

where the format is <Page number><Non-digit part of motor connection point designation><Counter per motor per page>

The picture above shows a proof of concept with two motors on page 2, and their corresponding desired wire numbers. The more motor on a page, the higher the last digit(s) of the connection designation. I’ve tested my solution with 12 motors on a page with the correct result.

Connection numbering scheme

The idea is to create a connection numbering scheme that defines a format group based on specific devices, in our case the motors, or devices with « MTR » as their DT identifier (note that in some cases the DT identifier for motors might be only « M », so this would have to be tweaked):

I placed that group at the top of the list so that those connections in that group are considered first when numbering. Once a connection is handled by a format group, it is not handled by groups further down the list, so you have to go from specific to general (top to bottom in the list of format groups).

This is how the group is defined:

The selected format elements are:

  • The Page name of the target component.
  • A block property defined on the connection currently being numbered (described in details below).
  • Then finally a subcounter defined over the signal/state of the connection (in our example, the same number on each side of terminals).

Here are screenshots of their specific settings:

Block property format for connections

Block property formats can be defined at the individual connections, but it’s better to define them globally in the project.

Under Project > Properties…, you can select the Formats from the Category drop-down in the Properties tab. This will limit the number of properties displayed in the grid.

Add those two properties to the grid:

Block property: Replacement text [1]:

○│??_??@^.*MTR[0-9]{1,2}:U[0-9]{0,1}$;│??_??@U;║○│??_??@^.*MTR[0-9]{1,2}:V[0-9]{0,1}$;│??_??@V;║○│??_??@^.*MTR[0-9]{1,2}:W[0-9]{0,1}$;│??_??@W;

Block property: Format (connection) [10]:

[20025,1,1&lt;20048,1,0,0,0,0,0,0,0,en_US,0,0,0,0,0,1&gt;]

The replacement text table is defined like this:

It’s important to note the Operator is set to Regular expression on all 3 rows. Then the Source text is the actual Regular expression to evaluate, and the Output text is what we want to replace the match from the RexEx with.

The RegEx is used to detect which pin of the motor we are connected to, and then use « U », « V » or « W » accordingly.

The block property format is defined as follows:

Last function via connection point and target number (PLC), Connection point 1, Target 1: Name of target connection point (Full),

and then the Replacement text is set on the block property format:

Explanation

By defining a block property format for connections at the project level, we implicitly assign it to all connections of the project.

The block property format « pulls » the Name of target connection point (full), meaning that it will return something such as:

MTR21:U

And then using the replacement table and its regular expression, we convert that to simply « U ».

In the connection numbering scheme we have defined the Page, the Block Property, and a subcounter.

All together, those pieces of data form the connection designation as wanted by the customer.

Conclusion

I try to stay as active as I can on the official EPLAN forum in english at:

http://forum.eplan.info/en/

Registration is required, but free. If you have questions about this, or any related topics (or unrelated), don’t hesitate to ask there.

Cheers

 

Problem when using UNC notation for master data directories

On a recent project I had to work with a remote team of designer.

The company provided me with the VPN client configuration and read/write access to a shared folder on one of their servers.

Everything went fine until I started assigning the master data directories within Eplan P8. I kept getting error messages saying that I didn’t have access to those folders. We checked with the IT team, and they assured me the rights were properly set.

It turns out that for some reason, if you use UNC notation, ie \\server\path\to\folder, then Eplan seems to want to have access rights to each folder within the path, which was not the case here. I only had access rights to the deepest directory.

The problem can be easily solved by using a mapped letter drive in Windows that is mapped to the deepest directory, and then use that drive letter in Eplan.

Enjoy.

(English) Stopping PLC Tracking at terminal

Désolé, cet article est seulement disponible en English.

(English) Defeating the « Design Mode » annoyance

Désolé, cet article est seulement disponible en English.

(English) Refreshing the GED after changing project setting

Désolé, cet article est seulement disponible en English.

(English) From AutoCAD to Eplan P8

Désolé, cet article est seulement disponible en English.

(English) API to set arrow at graphical line’s end

Désolé, cet article est seulement disponible en English.

(English) Some issue with accessory parts in EPlan P8

Désolé, cet article est seulement disponible en English.

NOUVELLES

How to parse C/C++ declarations


This was somewhere lying around in one my old HDD backups, and I always wanted [...]

SUIVEZ-NOUS

CERTIFIÉEXPERT