How do I mix functions and plain text for setting the fish greeting? - fish

The function solution here works fine.
Suppress or Customize Intro Message in Fish Shell
However I can't seem to insert text as well. Essentially I want to display the fish_logo from OMF, then beneath it my own message.
I thought perhaps to enclose the text in ', or " but I get an error. I tried without any enclosures and got an error.
This is what I thought would work.
function fish_greeting
fish_logo
'Hello Phil. What magic shall we create today?'
end

To output text, use echo thetext.
So
function fish_greeting
fish_logo
echo 'Hello Phil. What magic shall we create today?'
end

Obviously the other user's response is a valid answer to your problem, but I figured I may as well offer you another solution. First off, to explain the root of your problem in detail: You were just putting a quoted string in the function without actually invoking a function, command, or builtin to actually write your desired text to the terminal. Simple enough. The other user suggested you use echo "STRING" which is a completely acceptable response.
However, I would suggest alternatively that you use printf. When writing your scripts it requires a quite different approach to implement printf than it does to use echo, but I know many individuals who would argue that getting familiar with printf is the better option. It may cost being a little trickier to use properly, but it is much more versatile and reliable than echo. I won't bore you even more by documenting every possible manner of using printf as there is PLENTY of documentation, guides, and information out there on the subject.
In your specific case, to achieve the same results as the previous response:
function fish_greeting
fish_logo
printf "%s" "Hello Phil. What magic shall we create today?"
end
This will also, like the echo use case, result in the logo being printed to the terminal via the fish_logo function that fish_greeting invoked followed by your string via printf. A brief explanation of what printf is doing there:
The first quoted value is acting as the format and the following as the argument. Luckily, printf supports a variety of format specifiers for different scenarios. In this case the %s indicates a string, and the argument was passed into that format and written to the terminal output. It's a mouthful... but if you learned anything here then it's totally worth it! And, I personally find it much more rewarding to dig deep in order to garner more experience and knowledge, which will no doubt benefit you in the future.
I'll end this by just showing you a list of printf's format specifiers to give you a glimpse into how much more useful it is than echo:
%d: Argument will be used as decimal integer. (signed or unsigned)
%i: Argument will be used as a signed integer.
%o: An octal unsigned integer.
%u: An unsigned decimal integer.
%x or %X: An unsigned hexadecimal integer.
%f, %g or %G: A floating-point number.
%e or %E: A floating-point number in scientific notation.
%s: A string.
%b: A string that interprets backslash escapes.
%% signifies a literal %.
Besides all of those printf also functions with a large number of recognized backslash escapes, and is just a far superior method of printing than echo! To wrap this up for sure this time: visit the Fish Shell Documentation, and specifically the section for printf to learn more.
Fish Shell Docs
Printf Page

Related

perl format : how to avoid truncation when i try to print out strings of unfixed length

I'm trying to do debug port and muxing verification in the ASIC,
the signal hierarchy name can be fairly long, for example
top.eagleTop.ahb_top.btu.u_ble_core.u_ble_txrx_ctlr.rx_dmem_be_3
Right now I'm using pad character for left justification to print out the string
#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
but it makes my code looks messy. Is there any better way to print a variable length string other than this
Perl's format construct isn't used very much any more so you are unlikely to get good advice, but have you read the documentation for format?
It looks to me like you want the ^* placeholder, documented here. It says it is "for Variable-Width One-line-at-a-time Text".

Unicode String Issue

I am storing some unicode characters "лфи" in a char array.
When I view(x/30s ) the values in gdb it show me something like:
0x80ac47c: "?\004>\004 "
0x80ac482: "A\0048\004;\004L\004D\004>\004=\004:\0045\004/"
Why it is happening so and what are these \004 representing?
You should read gdb's character set documentation, since it seems gdb is escaping these characters instead of letting the terminal display them.
See Gdb Unicode Printing. If you overload the dbg_dump function in your code, by invoking print dbg_dump("лфи") inside gdb it will hopefully invoke your overloaded function, resulting in proper UTF-8 representation. Remember, in your custon dbg_dump you may need to explicitly express that you want to display Unicode characters.

Why would Perl's printf output the format specifier rather than the formatted number?

I'm trying to debug a problem on a remote user's site. We've narrowed it down to a problem with formatted output in Perl. The user swears up and down that
perl -e 'printf "Number: %lG\n", 0.1'
prints
Number: %lG
not
Number: 0.1
The user reports that their Perl is version 5.8. The oldest version I have around is 5.8.1, and it seems to behave correctly.
Any guesses? Misconfiguration? Module conflicts?
Quoting from the sprintf documentation:
Returns a string formatted by the usual printf conventions of the C library
function sprintf. See below for more details and see sprintf(3) or
printf(3) on your system for an explanation of the general principles.
IOW, like with many built-ins, Perl just thinly wraps a function, and it's
platform dependent.
Perl's sprintf permits the following universally-known conversions:
%l is not part of it. My guess is that the remote user is not using GNU. He can find out exactly what is supported by his unwashed Unix by typing man 3 sprintf or man 3 printf.
It should only do that if it doesn't recognise the format specifier. For example:
pax> perl -e 'printf "Number: %q\n", 0.1'
Number: %q
I think you're going to have to go on site to figure this one out although you may want to first get them to cut and paste the text and a screen dump from, for example, HyperSnap demo, into an email so you can check it carefully. I only suggest that one since we use it internally and it has a free trial. You can use any decent screen capture program you like.
I originally thought that they may be typing in 1G (wun jee) instead of lG (ell jee) but the former still works.
I do notice the IG (eye jee) will print out the text rather than the number but, unless they're using a particularly bad font, that should be a recognisable difference.
BTW, I only have 5.10 to work with so it may be a version problem. It's hard to imagine, however, that there'd be a major difference between 5.8 and 5.8.1.
It looks like it was a Perl build configuration issue. The Perl build supports a `d_longdbl` option, which indicates whether long doubles are allowed or not. You can test whether it is set on your machine with:
perl -V:d_longdbl
More info at perldoc sprintf.
Thanks for your input everybody.
Edit:
Nope, that wasn't it either. Close inspection of the sprintf documentation revealed that the modifiers for a long double are q, ll, and L, NOT l. l is a valid modifer for integer types. D'oh.
It looks like most installations of perl will silently ignore the l, and parse the rest of the modifier correctly. Except on our user's site. ☹ Anyway, the problem was fixed by using a valid modifier for a long double.
FYI, I played with the same format specifiers in the C printf.
printf("The number is %lG\n", 0.001);
printf("The number is %LG\n", 0.001);
The first call “worked”, printing out 0.001, but the second call printed out a garbage value until I properly specified the type of the numeric literal:
printf("The number is %LG\n", 0.001L);
Apparently the C printf is silently ignoring the improper l modifier. This makes me suspect that most Perl installations ignore it too.

Japanese COBOL Code: rules for G literals and identifiers?

We are processing IBMEnterprise Japanese COBOL source code.
The rules that describe exactly what is allowed in G type literals,
and what are allowed for identifiers are unclear.
The IBM manual indicates that a G'....' literal
must have a SHIFT-OUT as the first character inside the quotes,
and a SHIFT-IN as the last character before the closing quote.
Our COBOL lexer "knows" this, but objects to G literals
found in real code. Conclusion: the IBM manual is wrong,
or we are misreading it. The customer won't let us see the code,
so it is pretty difficult to diagnose the problem.
EDIT: Revised/extended below text for clarity:
Does anyone know the exact rules of G literal formation,
and how they (don't) match what the IBM reference manuals say?
The ideal answer would a be regular expression for the G literal.
This is what we are using now (coded by another author, sigh):
#token non_numeric_literal_quote_g [STRING]
"<G><squote><ShiftOut> (
(<NotLineOrParagraphSeparatorNorShiftInNorShiftOut>|<squote><squote>|<ShiftOut>)
(<NotLineOrParagraphSeparator>|<squote><squote>)
| <ShiftIn> ( <NotLineOrParagraphSeparatorNorApostropheNorShiftInNorShiftOut>|
<ShiftIn>|<ShiftOut>)
| <squote><squote>
)* <ShiftIn><squote>"
where <name> is a macro that is another regular expression. Presumably they
are named well enough so you can guess what they contain.
Here is the IBM Enterprise COBOL Reference.
Chapter 3 "Character Strings", subheading "DBCS literals" page 32 is relevant reading.
I'm hoping that by providing the exact reference, an experienced IBMer can tell us how we misread it :-{ I'm particularly unclear on what the phrase "DBCS-characters" means
when it says "one or more characters in the range X'00...X'FF for either byte"
How can DBCS-characters be anything but pairs of 8-bit character codes?
The existing RE matches 3 types of pairs of characters if you examine it.
One answer below suggests that the <squote><squote> pairing is wrong.
OK, I might believe that, but that means the RE would only reject
literal strings containing single <squote>s. I don't believe that's
the problem we are having as we seem to trip over every instance of a G literal.
Similarly, COBOL identifiers can apparantly be composed
with DBCS characters. What is allowed for an identifier, exactly?
Again a regular expression would be ideal.
EDIT2: I'm beginning to think the problem might not be the RE.
We are reading Shift-JIS encoded text. Our reader converts that
text to Unicode as it goes. But DBCS characters are really
not Shift-JIS; rather, they are binary-coded data. Likely
what is happening is the that DBCS data is getting translated
as if it were Shift-JIS, and that would muck up the ability
to recognize "two bytes" as a DBCS element. For instance,
if a DBCS character pair were :81 :1F, a ShiftJIS reader
would convert this pair into a single Unicode character,
and its two-byte nature is then lost. If you can't count pairs,
you can't find the end quote. If you can't find the end quote,
you can't recognize the literal. So the problem would appear
to be that we need to switch input-encoding modes in the middle
of the lexing process. Yuk.
Try to add a single quote in your rule to see if it passes by making this change,
<squote><squote> => <squote>{1,2}
If I remember it correctly, one difference between N and G literals is that G allows single quote. Your regular expression doesn't allow that.
EDIT: I thought you got all other DBCS literals working and just having issues with G-string so I just pointed out the difference between N and G. Now I took a closer look at your RE. It has problems. In the Cobol I used, you can mix ASCII with Japanese, for example,
G"ABC<ヲァィ>" <> are Shift-out/shift-in
You RE assumes the DBCS only. I would loose this restriction and try again.
I don't think it's possible to handle G literals entirely in regular expression. There is no way to keep track of matching quotes and SO/SI with a finite state machine alone. Your RE is so complicated because it's trying to do the impossible. I would just simplify it and take care of mismatching tokens manually.
You could also face encoding issues. The code could be in EBCDIC (Katakana) or UTF-16, treating it as ASCII will not work. SO/SI sometimes are converted to 0x1E/0x1F on Windows.
I am just trying to help you shoot in the dark without seeing the actual code :)
Does <NotLineOrParagraphSeparatorNorApostropheNorShiftInNorShiftOut> also include single and double quotation marks, or just apostrophes? That would be a problem, as it would consume the literal closing character sequence >' ...
I would check the definition of all other macros to make sure. The only obvious problem that I can see is the <squote><squote> that you already seem to be aware of.

How should I handle digits from different sets of UNICODE digits in the same string?

I am writing a function that transliterates UNICODE digits into ASCII digits, and I am a bit stumped on what to do if the string contains digits from different sets of UNICODE digits. So for example, if I have the string "\x{2463}\x{24F6}" ("④⓶"). Should my function
return 42?
croak that the string contains mixed sets?
carp that the string contains mixed sets and return 42?
give the user an additional argument to specify one of the three above behaviours?
do something else?
Your current function appears to do #1.
I suggest that you should also write another function to do #4, but only when the requirement appears, and not before .
I'm sure Joel wrote about "premature implementation" in a blog article sometime recently, but I can't find it.
I'm not sure I see a problem.
You support numeric conversion from a range of scripts, which is to say, you are aware of the Unicode codepoints for their numeric characters.
If you find an unknown codepoint in your input data, it is an error.
It is up to you what you do in the event of an error; you may insert a space or underscore, or you may abort conversion. What you would do will depend on the environment in which your function executes; it is not something we can tell you.
My initial thought was #4; strictly based on the fact that I like options. However, I changed my mind, when I viewed your function.
The purpose of the function seems to be, simply, to get the resulting digits 0..9. Users may find it useful to send in mixed sets (a feature :) . I'll use it.
If you ever have to handle input in bases greater than 10, you may end up having to treat many variants on the first 6 letters of the Latin alphabet ('ABCDEF') as digits in all their forms.