SAS Proc Format Executing Without All Datetime Directives - format

I have defined a datetime format with %h %0M %0S , but when it executes within my macro, the hour part is left out. Below is the (unedited) log from a stripped down macro using option mprint to demonstrate the issue.
Notice at the top of the log, where my macro is reprinted, the format my_fmt includes a "%h" ... but then below in the log when my_fmt is referenced, it is printed without "%h" in it, and then outputs a string with the hour part missing. I've tried with several different format names (including a random string) as well to make sure it's not conflicting with a pre-existing format. (using SAS 9.4 in case that matters).
18486 %macro myMacro(mydt);
18487
18488 %put &mydt;
18489 proc format; picture my_fmt low-high = "%0d-%b-%Y %h:%0M:%0S" (datatype=datetime); quit;
18490
18491 %*Comment;
18492 %let startDT_fmtd = %sysfunc(putn(&mydt, my_fmt.));
18493 %put &startDT_fmtd;
18494 %mend;
18495
18496 %*Useage example;
18497 %myMacro(1738144208.3);
1738144208.3
MPRINT(MYMACRO): proc format;
WARNING: Apparent invocation of macro B not resolved.
WARNING: Apparent invocation of macro Y not resolved.
MPRINT(MYMACRO): picture my_fmt low-high = "%0d-%b-%Y %0M:%0S" (datatype=datetime);
NOTE: Format MY_FMT has been output.
MPRINT(MYMACRO): quit;
NOTE: PROCEDURE FORMAT used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
29-JAN-2015 50:08

After some brute-force debugging, I realized the %h in your code is not being treated as a macro call. It is being treated as a %label statement (for %goto), because there is a colon after it. This explains why it does not trigger a warning in your log and is not part of the generated code.
Here is a simplified example:
127 %macro test(dummy);
128 %put "%y %h:";
129 %mend;
130 %test()
WARNING: Apparent invocation of macro Y not resolved.
"%y "
If you remove the colon, it works as expected:
131 %macro test(dummy);
132 %put "%y %h";
133 %mend;
134 %test()
WARNING: Apparent invocation of macro Y not resolved.
WARNING: Apparent invocation of macro H not resolved.
"%y %h"
This shows the %h: label works for %goto:
167 %macro test(dummy);
168 %goto h;
169 %put I am skipped by goto;
170 %put "%y %h:";
171 %mend;
172 %test()
WARNING: Apparent invocation of macro Y not resolved.
"%y "
Surprisingly (to me) I think that last example shows that a %GOTO label in the middle of a macro statement not only "works", it is the same as a %GOTO label at the beginning of the statement.
This also explains why the code works in open code (outside of a macro definition). Outside of a macro, %h: cannot be interpreted as a %GOTO label, so the %h is interpreted as a macro invocation, and the colon is just text:
209 %put "%y %h:";
WARNING: Apparent invocation of macro Y not resolved.
WARNING: Apparent invocation of macro H not resolved.
"%y %h:"
That said, #Reeza's solution of using single quotes is correct, as this prevents the %h: from being interpreted as a macro label.

The log indicates that SAS is trying to treat %h, %m as macros. You can avoid this by using single quotes in your proc format.

Related

Why some varaiables need %% and others don't in Windows batch files?

For example, this:
ffmpeg -i %1 -c:v libx264 -preset medium -crf 30 -c:a aac "%~n1_OUT.mp4"
Does not need %%1 and %%~n1 respectively.
But this:
FOR /f %%f in ('dir /b .') DO somecommand %%f
Needs %%, otherwise it's not working.
Can somebody explain any logical reason for this chaotic design?
The percent-sign % is used by cmd.exe and also its predecessor command.com to mark expansion1 of environment variables (like %VAR%), for-loop meta-variables (like %I/%%I), and argument references in batch files (like %1).
There are two distinct parsing modes, which behave differently when it comes to %-expansion:
Command line mode:
There are no command line arguments, hence no argument references are supported.
Empty (undefined) variables are not expanded, meaning that %VAR% is kept as is when an environment variable VAR is not set.
There is no escaping of %-signs supported, so %%VAR%% results in % + value of VAR + %.
Batch file mode:
Batch files may have arguments, which are expanded by argument references like %1.
Empty (undefined) variables are expanded to a blank string.
Escaping of the %-sign is supported in that %% represents a literal %.
Of course I cannot tell why the developers decided the parser to behave that way, but I believe there are several factors contributing:
The command line mode existed before batch file mode, the latter of which required introduction of support for arguments, which in turn led to the demand to let the parser distinguish between variable or argument references.
When the for command was introduced2, the developers decided to use the %-sign too to mark loop meta-variables, leading to conflicts in command line mode, particularly because empty variables remain: For instance, an expression like %foo%bar results in the value of foo + bar when variable foo is set, but otherwise to value of %f + oo + value of %b + ar when loop variables %f and %b exist, and so on. This is particularly because for parses the command line a second time after the initial potential expansion of environment variables.
Introduction of batch file mode and the conflicts coming from the for parser probably led to the decision of improved handling of %-expansion in that undefined variables are treated differently by expanding such to empty strings. In order to still be able to yield literal %-symbols, escaping like %% was introduced: For example, a text like 10% plus 20% could not be returned without escaping since a variable named SPACE + plus 20 is most likely undefined; however, specifying 10%% plus 20%% results in the literal string 10% plus 20%.
Anyway, the %-escaping in batch file mode is the intrinsic reason for why for meta-variables need to be specified like %%I (in contrast to %I in command line mode) in order for them to survive the escaping, resulting in %I, which is then recognised by the for command parser that comes into play after %-expansion.
For detailed information about what exactly happens, refer to: How does the Windows Command Interpreter (CMD.EXE) parse scripts?
1) The term expansion means to replace an expression (like %VAR%) by the string value it refers to (like the one stored in the respective environment variable named VAR) while parsing.
2) Although I do not know whether the for command was introduced before or after implementation of the batch file mode.
Command started from console window use single percent sign in for loop varible, but script files uses doubled percent sign. Its by design, well documented. Nothing chaotic..
https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/for

format specifiers with no newline and multiple writes in fortran

I want to write a header for an output file that's aligned with several variables, something like:
var1 var2 ................. varX
value value value
So I'd rather avoid manually padding every variable name.
From reading the docs, a format specifier when calling write() is the preferred method.
write(1, "(a23)") "var1", "var2", !etc.
But this inserts a newline after every variable.
write(1, "(a23)", advance="no") does NOT fix this, it only suppresses the newline after the final variable is written. write(1, *) DOES print a newline only after the final variable, but then I lose the spacing.
Tested in GNU Fortran 10.2 with -std=f2003.
Ideas?
"(a23)" is the format for a single character variable. When the format finishes, but there are still items to be written in the input list, the format is interpreted from the beginning, but a new line character (end of record) is added.
You have to use a format for multiple items: "(3a23)", "(3(a23))", "(9999(a23))" or even "(*(a23))"
See also https://stackoverflow.com/a/9881337/721644
Note that you can also use the t or tr or x descriptor to insert padding.

Shell in emacs displays names of variables by preceding them \200\230

When i run a compile instruction from the shell/eshell/term in emacs , the names of the variables appear weird in the shell .
Here is a sample code (with some random error) and the output when I compile :
#include iostream
#include cstdlib
int main (void)
{
cscdsd ;//some random error
return ;
}
//shell o/p:
g++ new.cc
new.cc: In function â\200\230int main()â\200\231:
new.cc:7: error: â\200\230cscdsdâ\200\231 was not declared in this scope
new.cc:8: error: return-statement with no value, in function returning â\200\230intâ\200\231
~/codes $
What i have figured out is that \200\230 and \200\231 mean the start and end of a variable or function name .
Any ideas what this happens or how to get rid of it ?
\200 is an octal escape sequence. In hex, â\200\230 is E2 80 98, which is how U+2018 (LEFT SINGLE QUOTATION MARK) is encoded in UTF-8. Likewise, â\200\231 is U+2019 (RIGHT SINGLE QUOTATION MARK). This is what happens when g++ emits UTF-8 and Emacs interprets it as ISO-8859-1.
You probably need to set default-process-coding-system to a different value. Try (in your ~/.emacs):
(setq default-process-coding-system '(utf-8-unix . utf-8-unix))
There are other ways to tell Emacs what coding system to expect. Read the documentation for the variables default-process-coding-system & process-coding-system-alist and the functions universal-coding-system-argument & set-buffer-process-coding-system.
Text encoding should be part of LANG environment variable.
export LANG=en_US.UTF-8 should fix.
On Ubuntu systems, change it in /etc/default/locale.

Compiling Ruby Inline C code - resolving errors

I am trying to get this Ruby inline C code http://pastie.org/2825882 to work. The code works in vanilla C, but here I get errors and warnings. What causes this error?
./backtrack_inline.rb:67: error: lvalue required as unary '&' operand
Also, why do I get the following error?
./backtrack_inline.rb:73: error: too few arguments to function 'backtrack'
Inspecting the resulting C code ( http://pastie.org/2826036) I fail to see anything wrong with the arguments. But I do also get the following warnings:
./backtrack_inline.rb:73: warning: passing argument 1 of 'backtrack' makes integer from pointer without a cast
./backtrack_inline.rb:73: warning: passing argument 2 of 'backtrack' makes integer from pointer without a cast
./backtrack_inline.rb:73: warning: passing argument 3 of 'backtrack' makes integer from pointer without a cast
Starting with this:
./backtrack_inline.rb:73: error: too few arguments to function 'backtrack'
If you look at your generated code, the backtrack function is defined on line 29:
static VALUE backtrack(VALUE self, VALUE _ss, VALUE _s, VALUE _p, VALUE _mm, VALUE _ins, VALUE _del) { ... }
It has seven arguments, the original six, plus VALUE self as it has been converted into a method on the Scan class.
The call to this function, on line 67 looks like this:
end = backtrack(ss, s, p, mm, ins, del);
It has only six arguments. RubyInline doesn't convert this to a call to a method on the object, it simply copies it verbatim. This is also where the warnings about makes integer from pointer without a cast come from: the function definition has been converted to take VALUEs, but you're calling with the original types.
The error message says that the error is from line 73 in backtrack_inline.rb because of the directive on line 54 of the generated code:
# line 61 "./backtrack_inline.rb"
which basically tells the compiler to "reset" its line and file values for errors, and treat the next line (55) as being line 61 in the file ./backtrack_inline.rb. The actual line is 67, 12 ahead of 55, but the compiler reports it as being 73, 12 ahead of 61 (the value it was reset to) and from a differnt file. This technique doesn't really work in this case as it doesn't take into account the extra lines added by RubyInline. The actual line in the source is 69.
A simple fix for this is to change the definition of the backtrack function to be just a C function rather than add it as a method on the object. Change builder.c to builder.prefix (on line 38 of your Ruby file). This won't work if you want to have backtrack available as a method on the object in Ruby. If that's the case you might need create another function to be the method, which then wraps the "real" backtrack function.
Next, looking at
./backtrack_inline.rb:67: error: lvalue required as unary '&' operand
This actually refers to line 61 of the generated code, which looks like:
char* s = StringValuePtr(rb_iv_get(self, "#seq"));
StringValuePtr is a macro which is defined as:
#define StringValue(v) rb_string_value(&(v))
This is where the & in lvalue required as unary '&' operand comes from. You need to add a local variable to be the lvalue:
VALUE seq = rb_iv_get(self, "#seq");
char* s = StringValuePtr(seq);
In my case (Mac OS X Snow Leopard, Ruby 1.9.3-p0, RubyInline 3.11.0) these two changes made the script run without errors, but gave the warning:
backtrack_inline.rb:47: warning: implicit conversion shortens 64-bit value into a 32-bit value
This actually refers to line 46 of the ruby file:
return (s - ss) - 1;
s and ss are char *, i.e. 64 bit pointers (on this machine), and the return type of the function is int - 32 bits. Adding an explicit cast fixed this:
return (int)((s - ss) - 1);
It now runs cleanly:
ruby-inline $ ruby backtrack_inline.rb
14
ruby-inline $
(I hope 14 is the correct answer!)
Here's a version of the script with these changes.
OK, the question was also answered at Ruby Forum:
http://www.ruby-forum.com/topic/2959614
Ok... thought a bit more about this.
you are calling a variable end. While this isn't a reserved word in C - and ruby shouldn't be looking at it... perhaps ruby is getting confused?
I'd suggest you have a go at renaming it just in case. Worthwhile trying even just to rule it out.

How to cast a function name to an address and add offset in LLDB?

Say, I have two adjacent functions subfunc() and main() in the Mach-O executable and want to disassemble all instructions from subfunc() to main()+0x10.
I know I can cast functions to addresses using `(void(*)())subfunc` - isn't there an easier way?
My attempt is as follows, but I get the error message below:
dis -s `(void(*)())subfunc` -e `(void(*)())main+0x10`
error: error: arithmetic on a pointer to the function type 'void ()'
How can I fix this?
This appears to be the correct syntax:
dis --start-address `(void(*)())main` --end-address `(void(*)())main`+0x10
The very small difference between this syntax and the variant you tried is that the +0x10 offset goes outside the backtick characters, i.e. the offset goes after the closing backtick.
FWIW this variant also appears to work correctly:
dis --start-address `(void(*)())main` --end-address 0x10+`(void(*)())main`
Discovery process:
I was unfamiliar with the "backtick" + function cast that you described in your original question so that was a very helpful starting point.
In my case I was trying to set a breakpoint at a function offset inside a shared library and got about as far as this before my search landed me on your question:
breakpoint set --shlib libexample.dylib --address `((void*)some_function)+81`
error: error: function 'some_function' with unknown type must be given a function type
error: 1 errors parsing expression
The use of your function cast hint met the "function type" requirement stated in the error message so I was next able to get to:
print (void(*)())some_function
(void (*)()) $38 = 0x00000001230094d0 (libexample.dylib`some_function)
I then tried the backtick variant which appeared to work but I wanted the value to be displayed in hexadecimal:
print `(void(*)())some_function`
(long) $2 = 4882207952
But when I tried to use the -f hex format option with print I got an error:
print -f hex `(void(*)())some_function`
error: use of undeclared identifier 'f'
error: 1 errors parsing expression
Eventually I noticed the comment 'print' is an abbreviation for 'expression --' at the bottom of the help print output and realised that means it's (apparently?) not possible to use an alternative display format with print because it gets converted into expression -- -f hex ... which is not valid syntax.
Eventually I figured out the required placement & combination of command name, display format and "--" to make it display as desired:
expression -f hex -- `(void(*)())some_function`
(long) $7 = 0x00000001230094d0
For no particular reason (that I can remember) it was at this point I tried placing the offset outside the backticks and it worked!
expression -f hex -- `(void(*)())some_function`+81
(long) $12 = 0x0000000123009521
And it still worked when I tried it with a breakpoint:
breakpoint set --shlib libexample.dylib --address `(void(*)())some_function`+81
Breakpoint 6: where = libexample.dylib`some_function + 81, address = 0x0000000123009521
Then I verified that it also worked with the dis command from your original question:
dis --start-address `(void(*)())some_function` --end-address `(void(*)())some_function`+81
And confirmed that the bare function name was not sufficient:
dis --start-address some_function --end-address `(void(*)())some_function`+81
error: address expression "some_function" evaluation failed
I also re-confirmed that the offset being between the backticks did not work:
dis --start-address `(void(*)())some_function` --end-address `(void(*)())some_function+1`
error: error: arithmetic on a pointer to the function type 'void ()'
error: 1 errors parsing expression
It was at this point that I realised I was able to parse the error message (as it was presumably intended):
[arithmetic on a pointer] [to the function type] ['void ()']
The underlying issue being "arithmetic on a pointer"...
Which further research shows is both "undefined on pointers to function types" and available as a gcc extension:
https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html
Why is it not allowed to perform arithmetic operations on function pointers?
Should clang and gcc produce a diagnostic message when a program does pointer arithmetic on a function pointer?
Incrementing function pointers
Function pointer arithmetic
How to print the address of a function?
https://github.com/llvm/llvm-project/blob/f804bd586ee58199db4cfb2da8e9ef067425900b/clang/test/Sema/pointer-addition.c
https://reviews.llvm.org/D37042
Which brings us back to the comments by #JasonMolenda & #JimIngham and how the function pointer arithmetic parsing is special-cased.
To my mind the "error: arithmetic on a pointer to the function type..." message you received is at best poor UX & at worst a bug--given that lldb itself essentially displays address references in that manner:
0x1230094f9: jle 0x123009cc2 ; some_function + 2034
I feel similarly about libexample.dylib`some_function + 81 being displayed but AFAICT not being parsed.
In conclusion, this form works:
`(void(*)())some_function`+0x10
Now I just need to figure out why some_function isn't doing what I think it should... :)

Resources