iOS Objective-C XCode: Logging Breakpoints and "magic" variables - ios

I am trying to use breakpoints for logging instead of NSLog, but I am having trouble accessing the "magic" compiler variables like __FUNCTION__, __FILE__, etc.
Neither Debugger Command nor Log Message breakpoints seem to evaluate the variables in the same way as NSLog.
NSLog(#"%s", __FILE__) results in correct debug output of /Users/nbirkholz/Documents/project_name/folder_name/file_name.m
When I set a Debugger Command breakpoint of po __FILE__ I receive debug output of "Parse" { 'P' 'a' 'r' 's' 'e' <nil>}
When I use p __FILE__ I receive debug output of (const char [6]) $1 = "Parse"
Similar results ensue from p/po __func__/__PRETTY_FUNCTION__/__FUNCTION__/__LINE__
po [NSString stringWithFormat:#"file is: %s", __FILE__] results in
error: too many arguments to method call, expected 1, have 2
po (void)NSLog(#"the file is: %s", __FILE__) returns <timestamp> <module> the file is: Parse
expr/expression (void)NSLog(#"the file is: %s", __FILE__) gives the same results.
Similarly, adding a Log Message breakpoint either fails to evaluate the expression at all or produces similar results, I can't seem to find an expression syntax that works encased in # #
For example a Log Message of the file is #__FILE__# begets the file is "Parse"
Is there a way to get this to work without adding an NSLog() to the code directly and get it to properly evaluate the variable?

These "Magic variables" are actually macros whose value is derived during compilation at the point they are referenced. They will not have the same value at debug time as they have at compile time. In fact, at debug time, you are most likely getting the variable's value as compiled into the debugger. I.E., not the file name of that code from MySpecialProgram, but the file name of the code executing in the debugger, likely the command parser.
Either put the logging in the code, as in:
NSLog(#"this is %s line %d function %s", __FILE__, __LINE__, __FUNCTION__);
or assign the vars to something you can access:
char[] foo = __FILE__;

I'm not sure here but afaik these are preprocessor macros, I think you can't get these to work in runtime.

Related

In Bazel, is it possible to use a function output as input to a load statement?

In Bazel, is it possible to use simple functions and variables as input to a load statement?
For example:
my_workspace = "a" + "b"
load(my_workspace, "foo")
load(my_workspace, "bar")
WARNING: Target pattern parsing failed.
ERROR: error loading package 'loadtest/simple': malformed load statements
The exact error message might have changed with version, I'd see:
syntax error at 'my_workspace': expected string literal
but no, you cannot use anything but string literal as per docs:
Use the load statement to import a symbol from an extension.
...
Arguments must be string literals (no variable)...

Service __len__ not found Unexpected error, recovered safely

python3.8
My code:
from googleads import adwords
def execute_request():
adwords_client = adwords.AdWordsClient.LoadFromStorage(path="google_general/googleads.yaml")
campaign_service = adwords_client.GetService('CampaignService', version='v201809')
pass
context["dict_list"] = execute_request()
Traceback:
Traceback (most recent call last):
File "/home/michael/pycharm-community-2019.3.2/plugins/python-ce/helpers/pydev/_pydevd_bundle/pydevd_xml.py", line 282, in frame_vars_to_xml
xml += var_to_xml(v, str(k), evaluate_full_value=eval_full_val)
File "/home/michael/pycharm-community-2019.3.2/plugins/python-ce/helpers/pydev/_pydevd_bundle/pydevd_xml.py", line 369, in var_to_xml
elif hasattr(v, "__len__") and not is_string(v):
File "/home/michael/PycharmProjects/ads3/venv/lib/python3.8/site-packages/googleads/common.py", line 694, in __getattr__
raise googleads.errors.GoogleAdsValueError('Service %s not found' % attr)
googleads.errors.GoogleAdsValueError: Service __len__ not found
Unexpected error, recovered safely.
googleads.yaml about logging
logging:
version: 1
disable_existing_loggers: False
formatters:
default_fmt:
format: ext://googleads.util.LOGGER_FORMAT
handlers:
default_handler:
class: logging.StreamHandler
formatter: default_fmt
level: DEBUG
loggers:
# Configure root logger
"":
handlers: [default_handler]
level: DEBUG
I've just started studying the API.
Namely, I'm trying to execute my first request (https://developers.google.com/adwords/api/docs/guides/first-api-call#make_your_first_api_call)
Could you help me with this problem? At least how to localize it more precisely.
This seems to be a problem which results from the way the PyCharm debugger inspects live objects during debugging.
Specifically, it checks if a given object has the __len__ attribute/method in the code of var_to_xml, most likely to determine an appropriate representation of the object for the debugger interface (which seems to require constructing an XML representation).
googleads service objects such as your campaign_service, however, use some magic to be able to call the defined SOAP methods on them without requiring to hard-code all of them. The code looks like this:
def __getattr__(self, attr):
"""Support service.method() syntax."""
if self._WsdlHasMethod(attr):
if attr not in self._method_proxies:
self._method_proxies[attr] = self._CreateMethod(attr)
return self._method_proxies[attr]
else:
raise googleads.errors.GoogleAdsValueError('Service %s not found' % attr)
This means that the debugger's check for a potential __len__ attribute is intercepted, and because the CampaignService does not have a SOAP operation called __len__, an exception is raised.
You can validate this by running your snippet in the regular way (i.e. not debugging it) and checking if that works.
An actual fix would seem to either require that PyCharm's debugger changes the way it inspects objects (not calling hasattr(v, "__len__")) or that googleads modifies the way it implements __getattr__, for example by actually implementing a __len__ method that just raises AttributeError.

How to open file for writing?

I'm trying to open and write to a file using Dart's IO library.
I have this code:
File file = File("text.txt");
RandomAccessFile raf = file.openSync();
raf.writeStringSync("A string!");
Now when doing this I get the following error in the console:
(OS Error: Access is denied., errno = 5)
So file is not opened for writing, and I'm looking here: open method, and can't figure out how to use open or openSync to get RandomAccessFile I can write to.
It says I need to use write constant to do that but just can't figure out how?
If I try to create FileMode and add it to open method as an argument I get an error saying:
Error: Too many positional arguments: 0 allowed, but 1 found.
So open and openSync methods can't take any arguments, how would one use FileMode, and open method to open a file that is ready for writing? So I need to get RandomAccessFile that is in writing mode? And by default its only in read mode? I'm not trying to use writeString or writeStringSync, I know those methods exist, but I'm interested in how is this done using open and openSync methods that return RandomAccessFile!
Update:
You are getting this error:
Error: Too many positional arguments: 0 allowed, but 1 found.
because the openSync method has no positional arguments, but just one named parameter (mode).
So to fix your code you must add it:
RandomAccessFile raf = file.openSync(mode: FileMode.append); //Or whatever mode you'd to apply
Having said that, there are several other ways to write to a file, most of them listed in the docs:
writeString or writeStringSync, I'd suggest these if what you need is just to write once to a file.
openWrite, which returns a Stream that can be written in order to write to the file.
(All of these methods have a FileMode mode named parameter)

Lua Compiling Error 'do' expected near '['

I have a Lua file that I decompiled using unluac. When I try to recompile the files without any changes I get the following error:
lua: main.lua:647: 'do' expected near '['
I really do not know the problem here, as the while do statement follows the correct format.
The error is on line 647 as stated above.
Source is here:
Full Pastebin Source
Expressions like while {}[1] do and if {}[1].parentFolderName then are invalid because of {}[1] reference. It needs to be ({})[1]. It's probably a result of some sort of automated processing, but you should be able to fix it manually.

<eof> expected near 'end'

I'm using these files in my gaming server, and every time I add a new player model, I get
[ERROR] lua/autorun/server/fastdlskins.lua:938: '<eof>' expected near 'end'
1. unknown - lua/autorun/server/fastdlskins.lua:0
I also get a similar error when I add an add-on to a different file
[ERROR] lua/autorun/server/workshopitems.lua:55: '<eof>' expected near 'end'
1. unknown - lua/autorun/server/workshopitems.lua:0
I usually just have to put an 'end' after the code, but I don't see what else I'm required to do. I don't have any loops running (I think), so I'm not closing any of those out. Not sure what to do.
As Egor said, remove the extra end at the end of the files.
end is only used to close blocks for functions and loops, like } in C-like languages. The end at the file is not closing anything, and is thus invalid syntax.

Resources