How to resolve warning 'excess arguments to builtin `define' ignored' with m4 - preprocessor

I'm using m4 define to create a macro.
I tried using include(file) to read the content of the file as below.
define(`TEST', include(file1))
TEST
file1:
test -abc -LDFLAGS "-Wl,-rpath,/home/user -lmsg"
When I run the code, it gives a warning and doesn't print anything beyond -Wl
m4:r1:1: Warning: excess arguments to builtin `define' ignored
test -abc -LDFLAGS "-Wl
I tried using single quotes, but it didn't work.
Can someone please help me resolve this?

If there are commas in the file, those will be interpreted as argument separators. The include replacement is inserted before determining the arguments to define.
Using single quotes is correct -- then the include will be processed in the output instead. For example:
define(`TEST', `include(file1)')
TEST
does work on my machine. (note that an even better solution is to add quotes around file1 as well).

Related

Clang libtooling: how to print compiler macro definitions

I have a LibTooling based utility and I would like to output a list of macro definitions for debug purposes. One can print compiler macro definitions with clang/gcc -dM -E -, but it does not seem to work if I pass -dM -E or -dD to ClangTool. Is it possible to do so with LibTooling API or CLI options in any way? It does not matter if it will include macros defined in a parsed source code or not.
I've looked at other similar questions, and as far as I can tell they all are about macros expanded in a parsed source code. That's not exactly what I need.
The answer is blindingly obvious—in retrospect. clang::Preprocessor::getPredefines() returns just that—a list of compiler predefines. The preprocessor object can be obtained e.g. from clang::CompilerInstance, as an argument in clang::DiagnosticConsumer::BeginSourceFile(), etc.
Just for the sake of completeness, this functionality is not available via libclang API, but I could do that using the fact that all predefines are present in the beginning of a translation unit. So after parsing I just listed all top-level cursors of CursorKind.MACRO_DEFINITION that are not in any real location (location.file is None using python bindings notation)

AST of a project by Clang

I use the Clang python binding to extract the AST of c/c++ files. It works perfectly for a simple program I wrote. The problem is when I want to employ it for a big project like openssl. I can run clang for any single file of the project, but clang seems to miss some headers of the project, and just gives me the AST of a few functions of the file, not all of the functions. I set the include folder by -I, but still getting part of the functions.
This is my code:
import clang.cindex as cl
cl.Config.set_library_path(clang_lib_dir)
index = cl.Index.create()
lib = 'Path to include folder'
args = ['-I{}'.format(lib)]
translation_unit = index.parse(source_file, args=args)
my_get_info(translation_unit.cursor)
I receive too many header files not found errors.
UPDATE
I used Make to compile openssl by clang? I can pass -emit-ast option to clang to dump the ast of each file, but I cannot read it now by the clang python binding.
Any clues how I can save the the serialized representation of the translation units so that I will be able to read it by index.read()?
Thank you!
You would "simply" need to provide the right args. But be aware of two possible issues.
Different files may require different arguments for parsing. The easiest solution is to obtain compilation database and then extract compile commands from it. If you go this way be aware that you would need to filter out the arguments a bit and remove things like -c FooBar.cpp (potentially some others), otherwise you may get something like ASTReadError.
Another issue is that the include paths (-I ...) may be relative to the source directory. I.e., if a file main.cpp compiled from a directory /opt/project/ with -I include/path argument, then before calling index.parse(source_file, args=args) you need to step in (chdir) into the /opt/project, and when you are done you will probably need to go back to the original working directory. So the code may look like this (pseudocode):
cwd = getcwd()
chdir('/opt/project')
translation_unit = index.parse(source_file, args=args)
chdir(cwd)
I hope it helps.

Is there a way to show custom warnings when building a project in XCode?

Let's say I want to detect something in my code which I cannot check by tests.
e.g.:
- Go over my entire code base to detect there I have a space between brackets and curly brackets (using a regex).
- Go over my entire code base and detect style smells.
etc...
If one of these checks fails, I'd like to show a custom warning I define myself.
Is there anything like this in XCode?
Thanks.
I wrote a run script for Xcode that does exactly what you requested. It searches by regex for predefined "code smells" or "style smells" and warns you at compile time
Read the blog post, but the final script is here
#test if git exists.
command -v git > /dev/null 2>$1 || {exit 0}
#separate code smells with | i.e. (code_smell_1|code_smell_2)
KEYWORDS="(didDeselectRowAtIndexPath)"
git diff --name-only HEAD | grep "\.m" | xargs egrep -s --with-filename --line-number --only-matching "$KEYWORDS.*[^\/]*$" | perl -p -e "s/($KEYWORDS)/ warning: Are you sure you want to use \$1?\nTo remove this warning, append a comment at the end of this line \$1/"
This particular script searches for appearances of didDeselectRowAtIndexPath in the code, but you can change that to any string
You would need to create a project target that runs a script, which searches through your source files and does your checks (this is not trivial) and returns non-zero to indicate error.
Then make your app target dependent on this "check target" and the build will fail if the check fails.
If you want some indication of how you write this "check script" then I would be inclined to employ the clang static analyzer. However, unfortunately, scan-build is not installed as part of the Xcode Command Line tools, so you would need to use the LLVM-binaries in some way, or perhaps the macports version contains it.
For trivial checks, relating to spaces and other stylistic issues rather than real, live, code problems, then you will have to employ some other mechanism, and I have no idea how to start with that, sorry.

How to import lua file to execute it?

I'm using Lua Mac 5.1.4 Compiler.
I'm trying to import lua file and run it.
I tried using this code:
% lua hello.lua
But I'm getting this error: stdin:1: unexpected symbol near '%'
Am I doing something wrong? This is my first day using lua so be easy on me.
Thank you.
The problem is probably that you saw this verbatim text in a tutorial:
% lua hello.lua
The '%' at the beginning of the line is not something you are supposed to type into your terminal, but is rather a generic prompt indicator. Sometimes you might see it written as '$' instead:
$ lua hello.lua
In either case, the first character is not something you type, but rather is a typographical convention to suggest that what follows is to be typed at a prompt. Your actual prompt might look something like this:
mo#macbook$
So you would type lua hello.lua but your screen would look like this:
mo#macbook$ lua hello.lua
So, try just entering lua hello.lua and see what happens.
Note that the error message you got regarding stdin:1 is likely from your shell (e.g. bash), and not from Lua (which never even started running due to the malformed command in the shell).
The error stdin:1: unexpected symbol near '%' suggests that you typed in % lua hello.lua while in an interactive lua session (or you executed a script containing it). Now that's something that you should type in in the commandline window.
Instead try something like print'Hello World!'
Lua provides two ways to call a file. One is the loadfile() and the other is the dofile() commands. Try using dofile("hello.lua").That should work.If it doesn't type the absolute path...:)

Why won't applications in Program Files run using os.execute in lua?

I'm trying to run an executable using Lua's os.execute() function. If I do something like the following it does not work:
os.execute("C:\\\Program Files\\\Movie Maker\\\moviemk.exe")
However, if I put my lua file in the same path that moviemk.exe is in then it can call it.
Any ideas why this may be?
P.S. I'm using Windows XP SP3
This is a classic problem with the command shell. It isn't really a Windows specific problem, except that on *nix, people never really got into the habit of putting spaces in file names, and Windows puts spaces in several default system places such as C:\Program Files.
What is happening is that os.execute(str) is implemented in terms of the ANSI C function system(str), which on Windows tries to duplicate the effect of typing "cmd /C "..str to the command prompt. (On *nix, it uses /bin/sh -c instead of cmd /C.)
The classic problem is that this has to split the complete command string at whitespace to decide what program to run, and what its arguments are.
Your original example: os.execute("C:\\Program Files\\Movie Maker\\moviemk.exe") effectively became cmd /c c:\program files\movie maker\moviemk.exe, which after splitting it up on whitespace, CMD tried to find a program named c:\program to execute with arguments named files\movie and maker\moviemk.exe. This isn't what you intended.
The solution is to be much more defensive about quoting.
I would write this as:
os.execute [["C:\Program Files\Movie Maker\Moviemk.exe"]]
If there were additional command line arguments to be supplied, I would use double-quotes around each, and a single space between arguments. Using the long string syntax [[...]] has the advantage that backslash isn't a special character, so you don't need extra leaning toothpicks making it harder to read the string literal.
Using double quotes around each argument should work on both Windows and *nix, although it is harder to find commands that are the same on both platforms, of course.
One other detail to be aware of is that \Programs Files might not be on C:. There might not even be a disk named C:. (My work PC boots from E: and I find more buggy programs that way.) The easiest way to learn the correct pathname is to just use the environment variable ProgramFiles. There are many other ways.
Try:
os.execute("C:\\Program Files\\Movie Maker\\moviemk.exe")
or:
os.execute("C:/Program Files/Movie Maker/moviemk.exe")
The '\' character is used for escape characters in Lua.

Resources