m4-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: m4 newbie q: ifelse not operating based on the value of sysval


From: Eric Blake
Subject: Re: m4 newbie q: ifelse not operating based on the value of sysval
Date: Tue, 6 Dec 2022 15:15:40 -0600
User-agent: NeoMutt/20220429

On Mon, Dec 05, 2022 at 02:33:12PM -0500, deference@null.net wrote:
> The new command is:
> 
> for i in *.mkv; do  echo 'define(`mkv'\'', `ogg'\'')ifelse(`1'\'',
> syscmd(`test -f '\''defn(`f'\''))sysval, `-i'\'' f `-map 1'\'')dnl' | m4
> -D f="$i" -; done
> 
> I get the following output:
> sh: 1: test: MY-FILE: unexpected operator
> ...
> 
> I'm not really sure what's going on. The filenames do need to be quoted,
> but if I replace the test command with the echo command I get the
> expected string output.
> -f MY-FILE 01.ogg
> -f MY-FILE 02.ogg
> ...

So, to make sure I get this right, your file name is "MY-FILE 01.ogg",
including the space.  You are asking syscmd() to execute the
equivalent of:

"test" "-f" "MY-FILE" "01.ogg"

which is a syntax error in shell.  It looks like you want to ask the
shell to execute the equivalent of:

"test" "-f" "MY-FILE 01.ogg"

If so, make sure you include that quoting in your m4 command:

for i in *.mkv; do  echo 'define(`mkv'\'', `ogg'\'')ifelse(`1'\'', syscmd(`test 
-f "'\''defn(`f'\'')")sysval, `-i'\'' "defn(`f'\'')" `-map 1'\'')dnl' | m4 -D 
f="$i" -; done

Also, consider using changequote; it makes life easier for writing m4
code on the command line:

echo 'changequote([,])define([mkv], [ogg])ifelse(1, syscmd([test -f 
"]defn([f])["])sysval, [-i "]defn([f])[" -map 1])dnl'

> 
> > plus the extra quoting needed to write ' in shell.
> >
> 
> I think I got that, see above.
> 
> > > 
> > > As a bit of a bonus question, can I somehow tack a period onto the
> > > front of the mkv macro expansion? That way, instead of matching
> > > "mkv", it would match ".mkv".  
> > 
> > If you are asking "can m4 treat '.mkv' as a macro name", the answer is
> > no for m4 1.4 unless it was built with --enable-changeword (which
> > penalizes speed performance).  But if you are asking if you can write
> > an m4 macro that inspects whether its argument includes the substring
> > '.mkv' and if so does something, then yes.
> > 
> 
> I'd like to have a "macro that inspects whether its argument includes the
> substring '.mkv' and if so does something."

Using the changequote tip above,

define([macro], [ifelse(index([$1], [.mkv]), 1, [do stuff for mkv],
  [do stuff for non-mkv])])dnl
macro(defn([f]))

You can also get fancier such as using substr() and len() to only
check for .mkv as the last four bytes of the input.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org




reply via email to

[Prev in Thread] Current Thread [Next in Thread]