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

Include several files with the same name #107

Closed
C-far opened this issue Jul 4, 2016 · 16 comments
Closed

Include several files with the same name #107

C-far opened this issue Jul 4, 2016 · 16 comments

Comments

@C-far
Copy link

C-far commented Jul 4, 2016

Like Y_less said it :
"If you have two files with the same name - REGARDLESS OF FOLDER - only the first one will be included. "

But I think it's possible to fix this bug in the compiler...
What do you think ?

@oscar-broman
Copy link
Contributor

That is only true of you use compatibility mode. If you wish to include a file multiple times in compat mode, simply undefine _inc_filename.

#include "test"
#undef _inc_test
#include "test"

@C-far
Copy link
Author

C-far commented Jul 4, 2016

What I mean, it's this :

#include "Lootcrate\index.pwn"
//-----------------------------
#include "Hardpoint\index.pwn"
//-----------------------------
#include "TDM\index.pwn"
//-----------------------------
#include "ZoneWar\index.pwn"
//-----------------------------
#include "FFA\index.pwn"
//-----------------------------
#include "SniperWar\index.pwn"
//-----------------------------
#include "RocketWar\index.pwn"
//-----------------------------
#include "BassHunt\index.pwn"

@Y-Less
Copy link
Member

Y-Less commented Jul 5, 2016

It is slightly more complicated than that. If you look at YSI, that has many files with the same name all behaving fine, It is to do with directory separators and what the compiler thinks is a filename:

#include "dir1/file1" // Includes file 1 inside directory 1
#include "dir2\file2" // Includes file 2 inside directory 2
#include "dir3\dir4\file3" // Includes file 3 inside two directories
#include "dir5\dir6/file5" // Includes file "dir6/file5" inside directory "dir5"

The final example demonstrates the effect that YSI takes advantage of. Because of the mix of directory separators, the compiler gets slightly confused and defines an inclusion symbol of "_inc_dir6/file5" instead of "_inc_file5", so the next time you try to include a file called "file5", it looks for "_inc_file5", doesn't find it, and includes your new file. Note that because the internally declared symbol name has a slash in it, there is no way to undefine it: #undef _inc_dir6/file5 is a syntax error.

@Y-Less
Copy link
Member

Y-Less commented Jul 5, 2016

Even more confusingly, it works with multiple layers of includes:

file1:

#include "dir2\file2"

file2:

#include "dir3/file3"

The compiler concatenates the directories, deliniated by the first directory separator type found, so this will include "dir2\dir3/file3", which is correct, but has the "inc" bug described above.

It gets even worse:

file3:

#include "dir4/file4"

What file will that include? The obvious (and probably should be correct) answer is "dir2\dir3/dir4/file4"; however, this actually includes "dir2\dir4/file4". The reason being that because the compiler previously thought that it was in file "dir3/file3", it still thought it was in directory "dir2", not "dir3", so a new relative include resulted in the new path being appended to the directory the compiler incorrectly thought it was in. Note that consistent use of "" negates all of this, the problem stems from mixing directory separators on one OS. This is all the reason why YSI MUST be included via #include <YSI\y_whatever> and why #include <YSI/y_whatever> gives cryptic errors (or at least used to, I've improved file inclusion for better compatability with the updated compiler, I don't know what effect that has any more).

@C-far
Copy link
Author

C-far commented Jul 5, 2016

So, modifications of the compiler could solve this or it is complicated ?

@oscar-broman
Copy link
Contributor

Did you not read what we wrote?

Also, if you don't compile with compatibility mode, you can include files multiple times without any problems.

@Y-Less
Copy link
Member

Y-Less commented Jul 5, 2016

The simplest way to include two files with the same name is:

#include <dir1\file>
#undef _inc_file
#include <dir2\file>

If you do this, make sure you have custom include guards (a-la a-samp.inc) to avoid the same file getting included multiple times. You could even put the #undef in the file itself (this is what I do a lot):

dir1\file:

#if defined _inc_file // The new compiler doesn't generate this symbol.
    #undef _inc_file
#endif
#if defined _INC_dir1_file
    #endinput
#endif
#define _INC_dir1_file

dir2\file:

#if defined _inc_file // The new compiler doesn't generate this symbol.
    #undef _inc_file
#endif
#if defined _INC_dir2_file
    #endinput
#endif
#define _INC_dir2_file

Then this will work fine:

#include <dir1\file>
#include <dir2\file>

The new compiler (without -Z as Slice says) will already allow you to include multiple files with the same name. But since the old compiler won't, and the new compiler will require your own include guards, it forces you to be quite defensive with code like that above.

@Y-Less
Copy link
Member

Y-Less commented Jul 5, 2016

Thinking about it, it might be nice if the new compiler did still generate the _inc_file defines on inclusion, but just didn't use them. Then they can still be queried and unset without additional boilerplate.

@Y-Less
Copy link
Member

Y-Less commented Jul 5, 2016

Or it might not be nice, I don't know.

In answer to your question about whether it can be solved: it already has been.

@C-far
Copy link
Author

C-far commented Jul 6, 2016

Mhm, I don't understand very well the method...

My folders (Lootcrate, Hardpoint...) are in the gamemodes folder, and I don't see how I can use your method in this case.

The files must be .inc or .pwn ?

I don't have custom include guards.

@C-far
Copy link
Author

C-far commented Jul 6, 2016

Any solution Alex ?

gamemodes\MODS\include_mods :

#tryinclude "Lootcrate\index.pwn"
//-----------------------------
#tryinclude "Hardpoint\index.pwn"

gamemodes\MODS\Loocrate\index.pwn :

#if defined _inc_index
    #undef _inc_index
#endif
#if defined _INC_Lootcrate_index
    #endinput
#endif
#define _INC_Lootcrate_index

#warning test

gamemodes\MODS\Hardpoint\index.pwn :

#if defined _inc_index
    #undef _inc_index
#endif
#if defined _INC_Hardpoint_index
    #endinput
#endif
#define _INC_Hardpoint_index

#warning test

@Y-Less
Copy link
Member

Y-Less commented Jul 6, 2016

No clue if/how it works with .pwn files, I only know for certain that it works with the default include extensions (.p, .pawn, and .inc).

@C-far
Copy link
Author

C-far commented Jul 6, 2016

I tried with .inc and it works. Weird.
Zeex could fix this bug, no ?

Edit : .p doesn't work

@Y-Less
Copy link
Member

Y-Less commented Jul 6, 2016

It is fixed, clearly you are just doing it wrong.

@C-far
Copy link
Author

C-far commented Jul 6, 2016

I meant for the .pwn, he could fix it ?

@Y-Less
Copy link
Member

Y-Less commented Jul 6, 2016

It really does depend. "It doesn't do what I think it should" isn't always the same as "it's a bug". We have given you several ways of doing this.

@C-far C-far closed this as completed Jul 8, 2016
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

3 participants