Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Union cases not included in generated C header #4

Open
pvaibhav opened this issue Jan 30, 2018 · 0 comments
Open

Union cases not included in generated C header #4

pvaibhav opened this issue Jan 30, 2018 · 0 comments

Comments

@pvaibhav
Copy link

pvaibhav commented Jan 30, 2018

Setup

In my upload.idl I have this:

union progress switch(int type) {
  case Starting:;
  case Uploading: double progressPercent;
  case Finished:;
  case Error:;
};

Running camlidl -header upload.idl generates this in the .mli (looks fine though I'd prefer avoiding "union_2" alias):

type union_2 =
  | Starting
  | Uploading of float
  | Finished
  | Error
and progress = union_2

HOWEVER the following definition is generated in the C header (no mention of case labels):

struct progress {
  int type; // <------------ ???
  union {
    double progressPercent;
  } u;
};

Problem

The definition for the various cases of the discriminant are not included in the header and are effectively lost on the C side. The upload_stubs.c file still makes use of the case labels as if they were defined like an enum:

value camlidl_c2ml_upload_struct_progress(struct progress * _c1, camlidl_ctx _ctx)
{
  value _v2;
  value _v3;
  switch ((*_c1).type) {
  case Starting: // <--------------- undefined!
    _v2 = Val_int(0);
    break;
  case Uploading: // <------------- undefined!
    _v3 = copy_double((*_c1).u.progressPercent);
...
...
...

This would cause the stubs to fail to compile, and users of the header to not have any idea what values are supported for the discriminant field.

Solution attempts

I tried separately defining the union's cases as a separate enum progress_type { Starting, ... in the idl file, then using [switch_is(type)] union progress { .. } inside en enclosing struct with a field enum progress_type type;. But this causes the generated .mli file to duplicate the definitions first as a Ocaml enumerated type, then again as a sum type. So the C stubs are now complete but the .mli has compile errors.

Question ..

How to actually use unions?

Ideal solution

The generated header should include an enum of the case labels like so:

struct progress {
  enum {
    Starting,
    Uploading,
    Finished,
    Error
  } type;
  union {
    double progressPercent;
  } u;
};

Or perhaps an enum progress_type { ... } outside the struct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant