AC_ARG_ENABLE in an m4_foreach_w loop: no help string - autoconf

I wish to generate a lot of --enable-*/--disable-* options by something like:
COMPONENTS([a b c], [yes])
where the second argument is the default value of the automatic enable_* variable. My first attempt was to write an AC_ARG_ENABLE(...) within an m4_foreach_w, but so far, I'm only getting the first component to appear in the ./configure --help output.
If I add hand-written AC_ARG_ENABLEs, they work as usual.
Regardless, the --enable-*/--disable-* options work as they should, just the help text is missing.
Here's the full code to reproduce the problem:
AC_INIT([foo], 1.0)
AM_INIT_AUTOMAKE([foreign])
AC_DEFUN([COMPONENTS],
[
m4_foreach_w([component], [$1], [
AS_ECHO(["Processing [component] component with default enable=$2"])
AC_ARG_ENABLE([component],
[AS_HELP_STRING([--enable-[]component], [component] component)],
,
[enable_[]AS_TR_SH([component])=$2]
)
])
AC_ARG_ENABLE([x],
[AS_HELP_STRING([--enable-[]x], [component x])],
,
[enable_[]AS_TR_SH([x])=$2]
)
AC_ARG_ENABLE([y],
[AS_HELP_STRING([--enable-[]y], [component y])],
,
[enable_[]AS_TR_SH([y])=$2]
)
])
COMPONENTS([a b c], [yes])
for var in a b c x y; do
echo -n "\$enable_$var="
eval echo "\$enable_$var"
done
AC_CONFIG_FILES(Makefile)
AC_OUTPUT
And an empty Makefile.am. To verify that the options work:
$ ./configure --disable-a --disable-b --disable-d --disable-x
configure: WARNING: unrecognized options: --disable-d
...
Processing component a with default enable=yes
Processing component b with default enable=yes
Processing component c with default enable=yes
$enable_a=no
$enable_b=no
$enable_c=yes
$enable_x=no
$enable_y=yes

After I poked around in autoconf sources, I figured out this has to do with the m4_divert_once call in the implementation of AC_ARG_ENABLE:
# AC_ARG_ENABLE(FEATURE, HELP-STRING, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
# ------------------------------------------------------------------------
AC_DEFUN([AC_ARG_ENABLE],
[AC_PROVIDE_IFELSE([AC_PRESERVE_HELP_ORDER],
[],
[m4_divert_once([HELP_ENABLE], [[
Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]]])])dnl
m4_divert_once([HELP_ENABLE], [$2])dnl
_AC_ENABLE_IF([enable], [$1], [$3], [$4])dnl
])# AC_ARG_ENABLE
# m4_divert_once(DIVERSION-NAME, CONTENT)
# ---------------------------------------
# Output CONTENT into DIVERSION-NAME once, if not already there.
# An end of line is appended for free to CONTENT.
m4_define([m4_divert_once],
[m4_expand_once([m4_divert_text([$1], [$2])])])
I'm guessing that the HELP-STRING argument is remembered in it's unexpanded form, so it is added just once for all components. Manually expanding the AC_HELP_STRING does what I want:
AC_DEFUN([COMPONENTS],
[
m4_foreach_w([comp], [$1], [
AS_ECHO(["Processing component 'comp' with default enable=$2"])
AC_ARG_ENABLE([comp],
m4_expand([AS_HELP_STRING([--enable-comp], enable component comp)]),
,
[enable_[]AS_TR_SH([comp])=$2]
)
])
])
COMPONENTS([a b c x y], [yes])
I couldn't find a way to properly quote components so that it appears as a string, after being used as the loop variable in m4_foreach_w, so I just renamed it to spare me the trouble.

Related

How to use warm starts in Minizinc?

I'm trying to use the warm start anotation in Minizinc to give a known suboptimal solution to a model.
I started by trying to execute this warm start example from the Minizinc documentation (the only one they provide):
array[1..3] of var 0..10: x;
array[1..3] of var 0.0..10.5: xf;
var bool: b;
array[1..3] of var set of 5..9: xs;
constraint b+sum(x)==1;
constraint b+sum(xf)==2.4;
constraint 5==sum( [ card(xs[i]) | i in index_set(xs) ] );
solve
:: warm_start_array( [ %%% Can be on the upper level
warm_start( x, [<>,8,4] ), %%% Use <> for missing values
warm_start( xf, array1d(-5..-3, [5.6,<>,4.7] ) ),
warm_start( xs, array1d( -3..-2, [ 6..8, 5..7 ] ) )
] )
:: seq_search( [
warm_start_array( [ %%% Now included in seq_search to keep order
warm_start( x, [<>,5,2] ), %%% Repeated warm_starts allowed but not specified
warm_start( xf, array1d(-5..-3, [5.6,<>,4.7] ) ),
warm_start( xs, array1d( -3..-2, [ 6..8, 5..7 ] ) )
] ),
warm_start( [b], [true] ),
int_search(x, first_fail, indomain_min)
] )
minimize x[1] + b + xf[2] + card( xs[1] intersect xs[3] );
The example runs, and it gets the optimal solution. However, the output displays warnings stating all the warm start anotations were ignored.
Warning, ignored search annotation: warm_start_array([warm_start([[xi(1), xi(2)], [i(5), i(2)]]), warm_start([[xf(0), xf(2)], [f(5.6), f(4.7)]]), warm_start([[xs(0), xs(1), xs(2)], [s(), s()]])])
Warning, ignored search annotation: warm_start([[xb(0)], [b(true)]])
Warning, ignored search annotation: warm_start_array([warm_start([[xi(1), xi(2)], [i(8), i(4)]]), warm_start([[xf(0), xf(2)], [f(5.6), f(4.7)]]), warm_start([[xs(0), xs(1), xs(2)], [s(), s()]])])
I didnt modified anything in the example, just copy-pasted it and ran it in the Minizinc IDE with the Geocode default solver. In case it is relevant, I'm using Windows. I have ran other models and used other search anotations without problems.
In the example there is two blocks of warm stars (one after solve and one inside seq_search). I'm not sure if both are necessary. I tried removing one, then the other, but the warnings still happen for all the remaining warm start anotations. Also I dont get why 'b' isnt refered in the fisrt block.
There is a similar example in git https://github.com/google/or-tools/issues/539 but it also produces the warnings.
If someone could point me out to a working example of warm_start it would be great.
Your usage of the warm_start annotations are correct, but warm start annotations are currently not supported in most solvers. At the time of writing I believe the warm start annotations are only supported by the Mixed Integer Programming interfaces (CoinBC, Gurobi, CPlex, XPress, and SCIP). Although we've been working on adding support for the annotation in Gecode and Chuffed, support for this annotation has not been included in any of the released versions.

Snakemake refuses to unpack input function when rule A is a dependency of rule B, but accepts it when rule A is the final rule

I have a snakemake workflow for a metagenomics project. At a point in the workflow, I map DNA sequencing reads (either single or paired-end) to metagenome assemblies made by the same workflow. I made an input function conform the Snakemake manual to map both single end and paired end reads with one rule. like so
import os.path
def get_binning_reads(wildcards):
pathpe=("data/sequencing_binning_signals/" + wildcards.binningsignal + ".trimmed_paired.R1.fastq.gz")
pathse=("data/sequencing_binning_signals/" + wildcards.binningsignal + ".trimmed.fastq.gz")
if os.path.isfile(pathpe) == True :
return {'reads' : expand("data/sequencing_binning_signals/{binningsignal}.trimmed_paired.R{PE}.fastq.gz", PE=[1,2],binningsignal=wildcards.binningsignal) }
elif os.path.isfile(pathse) == True :
return {'reads' : expand("data/sequencing_binning_signals/{binningsignal}.trimmed.fastq.gz", binningsignal=wildcards.binningsignal) }
rule backmap_bwa_mem:
input:
unpack(get_binning_reads),
index=expand("data/assembly_{{assemblytype}}/{{hostcode}}/scaffolds_bwa_index/scaffolds.{ext}",ext=['bwt','pac','ann','sa','amb'])
params:
lambda w: expand("data/assembly_{assemblytype}/{hostcode}/scaffolds_bwa_index/scaffolds",assemblytype=w.assemblytype,hostcode=w.hostcode)
output:
"data/assembly_{assemblytype}_binningsignals/{hostcode}/{binningsignal}.bam"
threads: 100
log:
stdout="logs/bwa_backmap_samtools_{assemblytype}_{hostcode}.stdout",
samstderr="logs/bwa_backmap_samtools_{assemblytype}_{hostcode}.stdout",
stderr="logs/bwa_backmap_{assemblytype}_{hostcode}.stderr"
shell:
"bwa mem -t {threads} {params} {input.reads} 2> {log.stderr} | samtools view -# 12 -b -o {output} 2> {log.samstderr} > {log.stdout}"
When I make an arbitrary 'all-rule' like this, the workflow runs successfully.
rule allbackmapped:
input:
expand("data/assembly_{assemblytype}_binningsignals/{hostcode}/{binningsignal}.bam", binningsignal=BINNINGSIGNALS,assemblytype=ASSEMBLYTYPES,hostcode=HOSTCODES)
However, when the files created by this rule are required for subsequent rules like so:
rule backmap_samtools_sort:
input:
"data/assembly_{assemblytype}_binningsignals/{hostcode}/{binningsignal}.bam"
output:
"data/assembly_{assemblytype}_binningsignals/{hostcode}/{binningsignal}.sorted.bam"
threads: 6
resources:
mem_mb=5000
shell:
"samtools sort -# {threads} -m {mem_mb}M -o {output} {input}"
rule allsorted:
input:
expand("data/assembly_{assemblytype}_binningsignals/{hostcode}/{binningsignal}.sorted.bam",binningsignal=BINNINGSIGNALS,assemblytype=ASSEMBLYTYPES,hostcode=HOSTCODES)
The workflow closes with this error
WorkflowError in line 416 of
/stor/azolla_metagenome/Azolla_genus_metagenome/Snakefile: Can only
use unpack() on list and dict
To me, this error suggests the input function for the former rule is faulty. This however, seems not to be the case for it ran successfully when no subsequent processing was queued.
The entire project is hosted on github. The entire Snakefile and a github issue.

Minimal self-compiling to .pdf Rmarkdown file

I need to compose a simple rmarkdown file, with text, code and the results of executed code included in a resulting PDF file. I would prefer if the source file is executable and self sifficient, voiding the need for a makefile.
This is the best I have been able to achieve, and it is far from good:
#!/usr/bin/env Rscript
library(knitr)
pandoc('hw_ch4.rmd', format='latex')
# TODO: how to NOT print the above commands to the resulting .pdf?
# TODO: how to avoid putting everyting from here on in ""s?
# TODO: how to avoid mentioning the file name above?
# TODO: how to render special symbols, such as tilde, miu, sigma?
# Unicode character (U+3BC) not set up for use with LaTeX.
# See the inputenc package documentation for explanation.
# nano hw_ch4.rmd && ./hw_ch4.rmd && evince hw_ch4.pdf
"
4E1. In the model definition below, which line is the likelihood?
A: y_i is the likelihood, based on the expectation and deviation.
4M1. For the model definition below, simulate observed heights from the prior (not the posterior).
A:
```{r}
points <- 10
rnorm(points, mean=rnorm(points, 0, 10), sd=runif(points, 0, 10))
```
4M3. Translate the map model formula below into a mathematical model definition.
A:
```{r}
flist <- alist(
y tilda dnorm( mu , sigma ),
miu tilda dnorm( 0 , 10 ),
sigma tilda dunif( 0 , 10 )
)
```
"
Result:
What I eventually came to use is the following header. At first it sounded neat, but later I realized
+ is indeed easy to compile in one step
- this is code duplication
- mixing executable script and presentation data in one file is a security risk.
Code:
#!/usr/bin/env Rscript
#<!---
library(rmarkdown)
argv <- commandArgs(trailingOnly=FALSE)
fname <- sub("--file=", "", argv[grep("--file=", argv)])
render(fname, output_format="pdf_document")
quit(status=0)
#-->
---
title:
author:
date: "compiled on: `r Sys.time()`"
---
The quit() line is supposed to guarantee that the rest of the file is treated as data. The <!--- and --> comments are to render the executable code as comments in the data interpretation. They are, in turn, hidden by the #s from the shell.

RBParser message nodes and targeting the receiver and the argument?

Trying to get some of my old code up and running in Pharo. Some method names are different but after some hardship I managed to find equivalents that work.
I am parsing my code and I'd like to check if the receiver or any of the arguments is aSymbol in an effort to match them to supported alternatives. I've managed to do this to selectors, by analysing RBMessageNode s
aNode selector == aSymbol ifTrue: [ aNode selector: replacementSymbol ].
How can this be done to arguments and receivers? Is there a comprehensive guide on RBParser somewhere?
By direct manipulation
Assuming that you are looking for cases like this:
aSymbol message: aSymbol message: aSymbol
For receiver you should do:
(aNode isMessage and: [
aNode receiver isVariable and: [
aNode receiver name = 'aSymbol' ]]) ifTrue: [
"do your job here" ]
Here is another example on how to replace #aSymbol arguments with #newSymbol:
messageNode arguments: (messageNode arguments collect: [ :arg |
(arg isLiteralNode and: [ arg value = #aSymbol ])
ifFalse: [ arg ]
ifTrue: [ | newNode |
newNode := #aNewSymbol asLiteralNode.
arg replaceSourceWith: newNode.
newNode ] ]).
methodClass compile: ast newSource
The replaceSourceWith: makes sure that just a source will be replaced, but for newSource to actually return a new source you also need to swap the nodes themselves, that's why I'm doing a collect on arguments and return the new ones where needed.
You can view help about RBParser in Word Menu > Help > Help Browser > Refactoring Framework.
You can also play around by inspecting
RBParser parseExpression: 'aSymbol message: aSymbol message: aSymbol'
and looking at its contents
By Parse Tree Transformation
You can use pattern code to match and replace certain code. For example to change the symbol argument of a perform: message you can do this:
ast := yourMethod parseTree.
rewriter := RBParseTreeRewriter new
replace: '`receiver perform: #aSymbol'
with: '`receiver perform: #newSelector'.
(rewriter executeTree: ast) ifTrue: [
yourMethod class compile: ast newSource ]
You can learn more about the pattern matching syntax in the help topic Word Menu > Help > Help Browser > Refactoring Framework > Refactoring Engine > RBPatternParser …. I thing that MatchTool from pharo catalog can greatly help you in testing the match expressions (it also has a dedicated help topic about the matching syntax) while RewriteTool can help you to preview how your code will be transformed.

Perl Module Error - defined(%hash) is deprecated

Background:
I am working to migrate a Linux server to a newer one from Ubuntu 10.04 to 12.04
This server is responsible for executing several a number of Perl modules via crontabs.
These Perl Modules rely heavily on 30-40 perl extensions.
I have installed all Perl extensions and the crontabs are able to process successfully except for several Syntax errors caused by the newer versions of these Perl extensions.
I need some help with modifying the syntax to get the Perl script to process as intended.
Errors:
defined(%hash) is deprecated at pm/Alerts/Alerts.pm line 943.
(Maybe you should just omit the defined()?)
defined(%hash) is deprecated at pm/Alerts/Alerts.pm line 944.
(Maybe you should just omit the defined()?)
Code:
###
# Iterate the arrays deleting identical counts from each.
# If we found a mismatch then die.
# If either array is not empty when we are done then die
$logger->info('Comparing ' . (scalar keys %cms_rows) . ' CMS symbols to ' . (scalar keys %stats_rows) . ' STATS symbols');
foreach my $symbol ( keys %cms_rows ) {
my %cms_row = delete $cms_rows{$symbol};
my %stats_row = delete $stats_rows{$symbol};
##LINE 943## die("Error: NULL CMS counts for symbol '$symbol'") unless defined %cms_row;
##LINE 944## die("Error: NULL Stats counts for symbol '$symbol'") unless defined %stats_row;
my $cms_json = encode_json(\%cms_row);
my $stats_json = encode_json(\%stats_row);
$logger->debug("Comparing counts for '$symbol': CMS($cms_json), Stats($stats_json)");
die("Error: Up Counts Don't match for symbol '$symbol': CMS($cms_json), Stats($stats_json)") unless (!defined $cms_row{1} && !defined $stats_row{1}) || $cms_row{1} == $stats_row{1};
die("Error: Down Counts Don't match for symbol '$symbol': CMS($cms_json), Stats($stats_json)") unless (!defined $cms_row{-1} && !defined $stats_row{-1}) || $cms_row{-1} == $stats_row{-1};
}
###
Hopefully someone can help with this, any help is appreciated.
You must have upgraded from a seriously old version of Perl. The Perl 5.6.1 release notes say:
defined(%hash) is deprecated
(D) defined() is not usually useful on hashes because it checks for an
undefined scalar value. If you want to see if the hash is empty, just
use if (%hash) { # not empty } for example.
It was always a pretty stupid thing to do and Perl now warns you that you're doing something stupid. The warning is pretty clear about what you should do to fix this:
Maybe you should just omit the defined()?
So your lines would become:
die("Error: NULL CMS counts for symbol '$symbol'") unless %cms_row;
die("Error: NULL Stats counts for symbol '$symbol'") unless %stats_row;

Resources