Storing folder's paths - c

Where can I store folder's paths, which can be accessed from every function/variable in a C program?
Ex. I have an executable called do_input.exe in the path c:\tests\myprog\bin\do_input.exe,
another one in C:\tools\degreesToDms.exe, etc. how and where should I store these?
I stored them as strings in an header file which I included in every project's file but someone discouraged from doing this. Are they right?

I stored them as strings in an header file which I included in every project's file but someone discouraged from doing this. Are they right?
Yes, they are absolutely right: "baking in" installation-specific strings with paths in a file system into a compiled code is not a good decision, because you must recompile simply to change locations of some key files. This limits the flexibility of other members of your team to run your tests, and may prevent your tests from being ran automatically in an automated testing environment.
A better solution would use a plain text configuration file with the locations of the key directories, and functions that read that file and produce correct locations at run-time.
Alternatively, you could provide locations of key directories as command-line parameters to your program. This way, users who run your program would be able to set correct locations without recompiling.

If they stay the same, then I don't see any problem defining these paths in a ".h" header file included in all the various .c files that reference the paths. But every computer this thing will be running on may have different paths ("Tests" instead of "test"), so this is super risky programming and probably only safe if you're running it on a single machine or a set of machines that you control directly.
If the paths will change, then you need to create a storage place for these paths (e.g. static character array, etc.) and then have methods to allow these to be fetched and possibly reset dynamically (e.g. instead of writing output files to "results", maybe the user wants to change things to write files to "/tmp"). Totally depends on what you are doing in your code and what the tools you're writing will be doing.

Related

Why use separate source files?

I'm learning C, coming from scripted languages background it is highly intriguing and rather confusing.
A brief story of how I got to this question:
At first I was confused why I can't include a source (.c) file in another source file, then I found out that function declarations repeat. Then I found out about header files (.h) and was confused, why I have to declare a function in one file then define in another, then if something changes I have to go edit 2 files, so I started defining functions in header files. Then I found out that #ifndef doesn't work across separate source files, so here's the question I can't yet find the answer to:
Why do I even have to use separate source files? Why can't I just have 1 source file and put all of my other code/function definitions in header files, this way I'm going to have things defined once and included once in the final build?
Now don't get me wrong, I'm not thinking I'll start a revolution, I'm just looking for answers as to why this is not how it works.
If you think beyond small learning programs, there are several benefits to splitting code into multiple source files.
Code Organization
Large programming projects can have millions of lines of code. You don't want to have files that big! Editors will probably have trouble handling it. Human beings will have trouble understanding it. Multiple developers would have conflicts all touching the same file. If you separate the code by purpose, it will be much easier to handle.
Build Times
Many code changes are small, while compilation time can be expensive. Compilers typically work on a file at a time, not parts of files. So if you make a tiny change and then have to rebuild the entire project, that can be very time consuming. If your code is separated into multiple source files, making a change in one of them means you only have to recompile that file.
Reusability
Frequently, code can be reused for more than one program. If you have all your code in one source file, you'll have to go and copy that code into another file to reuse it. Of course, now if it has a bug you have two places to fix it. Not good.
Let's say, for example, you have code that uses a linked list. If you put the linked list code into its own source file, you can then simply link that into another program. If there's a bug, you can fix it in one place, recompile, and then re-link the programs that use it.
You can use a single source file for some (small) projects.
For many projects though, it makes sense to divide the source in different source files according to their function.
Let's say your making a game.
Have all the user interface code in its source file.
Have all the computer move algorithms in its source file.
...
Have the main() function which ties it all together in its source file.
Then, to compile for PC you do gcc game.c algo.c ui-pc.c, to compile to android you do gcc game.c algo.c ui-android.c ..., to compile a brand new algorithm you though up and don't know if it's good gcc game.c algo-test.c ui-pc.c
Header files help keep everything in sync. And they're a good place for documentation.

What goes in an "inc" includes folder in a project?

I'm putting my Simplicity Studio project into TortoiseSVN. I've been told to create an inc (includes) folder and use it. What is it? Why would I use it?
It's just a convention, not something that is required. For large projects it is often used to hold any file that is included from another file, i.e.:
#include "headerFile.h"
You might ask the person who "told" you to do that - it is not a language or tool-chain requirement.
The preprocessor does not care where the include files are so long is you tell it (either in the #include directive itself, by command line options or environment variables). Putting all headers in a folder separate to the associated .c files is a common practice but often a habit rather than for any good reason. It is useful when the headers relate to some static, shared library, or DLL where the headers are to be distributed with the compiled object code.
In other cases it is arguably simpler and more useful to keep the headers and the associated .c files in the same directory as each other. That allows for example "localised" headers to be included using double-quotes without needing to explicitly tell the preprocessor which paths to search.

shake build: how to deal with case where the needed file are discovered later

I use shake to build a website (with pandoc). When files are converted to pandoc, other files (css, bibliography, templates, etc.) may be needed, but shake does not know it, because it is internal to the pandoc calling function and the information is in the files used and only gradually visible.
I have the impression from reading the docs, that asking the function called by shake to return a list of the files used and, after the function called in shake, to use the returned list of files to call need. Is it correct that the order in which need is called, matters?
Alternatively,
(1) I can build functions to only find which other files are needed (doing the work nearly twice) and call them first. Or,
(2), to break the process into steps, each resulting in a file and then start a new rule to go forward from this file (and the additional files) and add needs there. The second solution builds intermediate files and breaks the logical flow of the transformation from pandoc to html.
What is better?
The answer depends on the details of the files that are depended upon (e.g. the css, bibliography):
If they are source files, you can add the dependency after they are used, using needed.
If they are generated by Shake itself, you can't use needed without first ensuring they are present. If you can statically predict a superset of which files are the dependencies consulted, you can use orderOnly to ensure all the files that the rule might depend on have been built, then use needed after to declare which are actually required.
Finally, if you can't predict which files are dependencies, and you might be generating them, then the easiest is to run part of the computation twice.

Replace include directive with a different file name using make

I have a header file, sample_A.h, which has an include statement of the form #include "sample_B.h". I also have another header file sample_C.h. I would like header file sample_A.h to include sample_C.h instead of sample_B.h, but under no circumstances can I edit anything outside of the Makefile used to build the project. What would be the best way to "redirect" sample_A.h to include sample_C.h instead of sample_B.h by solely editing the Makefile? Assume that both sample_C.h and sample_B.h will allow sample_A.h to compile.
EDIT: I am working on a project which has a vast build structure. Some files are outdated, but due to upper management orders, these files should not be messed with until future meetings take place. In the meantime, I am trying to figure out a way to circumvent these outdated files (and their outdated include directives) without touching the files themselves. I am using the gcc compiler.
I would like header file sample_A.h to include sample_C.h instead of sample_B.h, but under no circumstances can I edit anything outside of the Makefile used to build the project.
In principle, the compiler is at leisure to choose how to interpret the file identifier presented in an #include directive (i.e. "sample_B.h"), but in practice, every compiler you're likely ever to meet interprets it as a file name or path. Thus, if you have a file whose (only) simple name is sample_C.h, and you have no allowable way to provide another name for it (by copying it or creating a symlink to it, for example) then it is unlikely that there is any way that file will ever be chosen to satisfy an #include "sample_B.h" directive.
If, however, the two headers have the same simple name but reside in different directories, e.g. src/sample_B.h and custom/sample_B.h, then it is normally possible to influence which is selected via compiler options that affect the search path for include files. The traditional option of that kind for Unix C compilers is -I.

Cross-platform way of storing setting/cache

I'm currently writing a program in C that needs to store configuration files, and various cache files on disk, as well as some static data files that never change, and that can safely be shared for all users.
I want to store these files in the appropriate location of the OS, in a portable way if possible…
For example, on GNU/Linux :
$XDG_CONFIG_HOME/<program_rame>/ -- for configuration files
$XDG_CACHE_HOME/<program_name>/ -- for cache files
$XDG_DATA_DIRS/<program_name>/ -- for static files
And, if these are unset, I can use the recommended default values ("~/.config", "~/.cache" and "/usr/share"). GNU/Linux is the easy one.
However, on Windows, I have no idea how to find the equivalent of these. I think it's going to be somewhere in AppData, but where ? And, most importantly, how do I get this programatically ? And what about other OSes (especially Mac OS, since most other UNIXes could use the "GNU/Linux" method as well) ?
I'm open to all solutions, whether it requires a library or not. Thanks in advance for your help !
Windows has so called known folder IDs, formerly (before Vista) known as special item IDs, or CSIDL. For instance in the folder referenced by FOLDERID_LocalAppData (that is %USERPROFILE%\AppData\Local) might be what you're looking for. I'm not on Windows and thus I don't know which C-API these values provide. However, chances are that these folders are also available as environment variables (e.g. %LOCALAPPDATA%).

Resources