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

struct member expansion #137

Closed
saivert opened this issue Jun 3, 2017 · 6 comments
Closed

struct member expansion #137

saivert opened this issue Jun 3, 2017 · 6 comments

Comments

@saivert
Copy link

saivert commented Jun 3, 2017

I have a struct:

// FILE object wrapper for vfs access
typedef struct {
    struct DB_vfs_s *vfs;
} DB_FILE;

dstep now looks up struct DB_vfs_s and expands this inside the parent struct while eating all comments before the definition of struct DB_vfs_s. Leading to something like:

// FILE object wrapper for vfs access
struct DB_FILE
{
    // md5 calc control structure (see md5/md5.h)

    // bps must be 32 if this is true

    // lots more comments

    struct DB_vfs_s
    {
        DB_plugin_t plugin;

        // capabilities
        const(char*)* function () get_schemes; // NULL-terminated list of supported schemes, e.g. {"http://", "ftp://", NULL}; can be NULL

and so on...

This is a workaround (C code):

typedef struct DB_vfs_s DB_vfs_t;
// FILE object wrapper for vfs access
typedef struct DB_FILE_s {
    DB_vfs_t *vfs;
} DB_FILE;

but seems like dstep should cope with using struct notation without expanding it inline.

@jacob-carlborg
Copy link
Owner

Running the following file through DStep master:

// FILE object wrapper for vfs access
typedef struct {
    struct DB_vfs_s *vfs;
} DB_FIL

Givens the following result:

// FILE object wrapper for vfs access

extern (C):

struct DB_FILE
{
    struct DB_vfs_s;
    DB_vfs_s* vfs;
}

That looks correct to me. Are you using a pre-compiled release? Because those are quite old and o lot has happened since then.

@saivert
Copy link
Author

saivert commented Jun 3, 2017

I'm running v0.2.2-164-g4e574fe

@jacob-carlborg
Copy link
Owner

Hmm, seems like you have the latest.

@jacob-carlborg
Copy link
Owner

Does your header file contain some more code that perhaps causes this problem?

@saivert
Copy link
Author

saivert commented Jun 3, 2017

Full source is here: https://github.com/Alexey-Yakovenko/deadbeef/blob/b669ceb346fa895cc5f873e52f2a1b26f8ec2789/deadbeef.h
Specifically you need the declaration of struct DB_vfs_s which is later in the code.

I have pasted the minimal excerpt from the above file which still exhibits the problem:

#include <stdint.h>
#include <time.h>
#include <stdio.h>
#include <dirent.h>
#include <stdarg.h>

// FILE object wrapper for vfs access
typedef struct {
    struct DB_vfs_s *vfs;
} DB_FILE;

typedef int (*DB_plugin_action_callback_t) (struct DB_plugin_action_s *action, void *userdata);
#if (DDB_API_LEVEL >= 5)
typedef int (*DB_plugin_action_callback2_t) (struct DB_plugin_action_s *action, int ctx);
#endif

// playlist item
// these are "public" fields, available to plugins
typedef struct DB_playItem_s {
    int32_t startsample32; // start sample of track, or -1 for auto
    int32_t endsample32; // end sample of track, or -1 for auto
    int32_t shufflerating; // sort order for shuffle mode
} ddb_playItem_t;

typedef ddb_playItem_t DB_playItem_t;

typedef struct DB_plugin_action_s {
    const char *title;
    const char *name;
    uint32_t flags;
    // the use of "callback" is deprecated,
    // only use it if the code must be compatible with API 1.4
    // otherwise switch to callback2
    DB_plugin_action_callback_t callback;
    struct DB_plugin_action_s *next;
#if (DDB_API_LEVEL >= 5)
    DB_plugin_action_callback2_t callback2;
#endif
} DB_plugin_action_t;

// base plugin interface
typedef struct DB_plugin_s {
    // type must be one of DB_PLUGIN_ types
    int32_t type;
    // api version
    int16_t api_vmajor;
    int16_t api_vminor;
    // plugin version
    int16_t version_major;
    int16_t version_minor;

    uint32_t flags; // DDB_PLUGIN_FLAG_*
    uint32_t reserved1;
    uint32_t reserved2;
    uint32_t reserved3;

    // any of those can be left NULL
    // though it's much better to fill them with something useful
    const char *id; // id used for serialization and runtime binding
    const char *name; // short name
    const char *descr; // short description (what the plugin is doing)
    const char *copyright; // copyright notice(s), list of developers, links to original works, etc
    const char *website; // plugin website

    // plugin-specific command interface; can be NULL
    int (*command) (int cmd, ...);

    // start is called to start plugin; can be NULL
    int (*start) (void);

    // stop is called to deinit plugin; can be NULL
    int (*stop) (void);

    // connect is called to setup connections between different plugins
    // it is called after all plugin's start method was executed
    // can be NULL
    // NOTE for GUI plugin developers: don't initialize your widgets/windows in
    // the connect method. look for up-to-date information on wiki:
    // http://github.com/Alexey-Yakovenko/deadbeef/wiki/Porting-GUI-plugins-to-deadbeef-from-0.5.x-to-0.6.0
    int (*connect) (void);

    // opposite of connect, will be called before stop, while all plugins are still
    // in "started" state
    int (*disconnect) (void);

    // exec_cmdline may be called at any moment when user sends commandline to player
    // can be NULL if plugin doesn't support commandline processing
    // cmdline is 0-separated list of strings, guaranteed to have 0 at the end
    // cmdline_size is number of bytes pointed by cmdline
    int (*exec_cmdline) (const char *cmdline, int cmdline_size);

    // @returns linked list of actions for the specified track
    // when it is NULL -- the plugin must return list of all actions
    DB_plugin_action_t* (*get_actions) (DB_playItem_t *it);

    // mainloop will call this function for every plugin
    // so that plugins may handle all events;
    // can be NULL
    int (*message) (uint32_t id, uintptr_t ctx, uint32_t p1, uint32_t p2);

    // plugin configuration dialog is constructed from this data
    // can be NULL
    const char *configdialog;
} DB_plugin_t;

// vfs plugin
// provides means for reading, seeking, etc
// api is based on stdio
typedef struct DB_vfs_s {
    DB_plugin_t plugin;

// capabilities
    const char **(*get_schemes) (void); // NULL-terminated list of supported schemes, e.g. {"http://", "ftp://", NULL}; can be NULL

    int (*is_streaming) (void); // return 1 if the plugin streaming data over slow connection, e.g. http; plugins will avoid scanning entire files if this is the case

    int (*is_container) (const char *fname); // should return 1 if this plugin can parse specified file

// this allows interruption of hanging network streams
    void (*abort) (DB_FILE *stream);

// file access, follows stdio API with few extension
    DB_FILE* (*open) (const char *fname);
    void (*close) (DB_FILE *f);
    size_t (*read) (void *ptr, size_t size, size_t nmemb, DB_FILE *stream);
    int (*seek) (DB_FILE *stream, int64_t offset, int whence);
    int64_t (*tell) (DB_FILE *stream);
    void (*rewind) (DB_FILE *stream);
    int64_t (*getlength) (DB_FILE *stream);

    // should return mime-type of a stream, if known; can be NULL
    const char * (*get_content_type) (DB_FILE *stream);

    // associates stream with a track, to allow dynamic metadata updating, like
    // in icy protocol
    void (*set_track) (DB_FILE *f, DB_playItem_t *it);

    // folder access, follows dirent API, and uses dirent data structures
    int (*scandir) (const char *dir, struct dirent ***namelist, int (*selector) (const struct dirent *), int (*cmp) (const struct dirent **, const struct dirent **));

#if (DDB_API_LEVEL >= 6)
    // returns URI scheme for a given file name, e.g. "zip://"
    // can be NULL
    // can return NULL
    const char *(*get_scheme_for_name) (const char *fname);
#endif
} DB_vfs_t;

@jacob-carlborg
Copy link
Owner

Hmm, ok. This occurs if the struct used in a field is declared after the struct it's used in.

ciechowoj added a commit to ciechowoj/dstep that referenced this issue Jun 4, 2017
jacob-carlborg added a commit that referenced this issue Jun 4, 2017
Fix #137: struct member expansion.
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

2 participants