I have the following code in my project:
class RangeConverter {
private:
struct Converter {
double MinimumInput;
double MaximumInput;
double MinimumOutput;
double MaximumOutput;
template <typename RangeType>
RangeType Convert ( RangeType invalue ) const {
double v = static_cast<double> ( invalue );
if ( v < MinimumInput ) {
v = MinimumInput;
} else if ( v > MaximumInput ) {
v = MaximumInput;
}
double interpolationfactor = ( v - MinimumInput ) / ( MaximumInput - MinimumInput );
return static_cast<RangeType> ( ( interpolationfactor * ( MaximumOutput - MinimumOutput ) ) + MinimumOutput );
}
};
.....
After formatting that code with AStyle I get the following:
class RangeConverter {
private:
struct Converter {
ngeConverter {
private:
struct Converter {
double MinimumInput;
double MaximumInput;
double MinimumOutput;
double MaximumOutput;
template <typename RangeType>
RangeType Convert ( RangeType invalue ) const {
double v = static_cast<double> ( invalue );
if ( v < MinimumInput ) {
v = MinimumInput;
} else if ( v > MaximumInput ) {
v = MaximumInput;
}
double interpolationfactor = ( v - MinimumInput ) / ( MaximumInput - MinimumInput );
return static_cast<RangeType> ( ( interpolationfactor * ( MaximumOutput - MinimumOutput ) ) + MinimumOutput );
}
};
.....
The astyle command:
astyle
\ --style=java
\ --indent=force-tab=2
\ --indent-classes
\ --indent-switches
\ --indent-labels
\ --indent-preprocessor
\ --indent-col1-comments
\ --pad-oper
\ --pad-paren
\ --delete-empty-lines
\ --add-brackets
\ --align-pointer=type
\ --align-reference=type
Is that a bug of astyle, or I forget any options?
If it is a bug, what could you suggest to format C++ code with VIM?
Sure, it's a bug. AStyle is not supported well these days. There are lots of bugs that were sitting there forever and never got resolved. You shouldn't expect the situation to improve in the nearest future. I highly recommend switching to Uncrustify. Certainly, it has some issues too, but they are not so nasty and do not break your code like AStyle does. It has hundreds of configuration options - much more flexible than AStyle - so be patient you'll have to spend quite some time to tweak it to your tastes and conventions.
When you are done and if you'd like to integrate it with Vim properly, here you go the code you could add into your .vimrc:
" Restore cursor position, window position, and last search after running a
" command.
function! Preserve(command)
" Save the last search.
let search = #/
" Save the current cursor position.
let cursor_position = getpos('.')
" Save the current window position.
normal! H
let window_position = getpos('.')
call setpos('.', cursor_position)
" Execute the command.
execute a:command
" Restore the last search.
let #/ = search
" Restore the previous window position.
call setpos('.', window_position)
normal! zt
" Restore the previous cursor position.
call setpos('.', cursor_position)
endfunction
" Specify path to your Uncrustify configuration file.
let g:uncrustify_cfg_file_path =
\ shellescape(fnamemodify('~/.uncrustify.cfg', ':p'))
" Don't forget to add Uncrustify executable to $PATH (on Unix) or
" %PATH% (on Windows) for this command to work.
function! Uncrustify(language)
call Preserve(':silent %!uncrustify'
\ . ' -q '
\ . ' -l ' . a:language
\ . ' -c ' . g:uncrustify_cfg_file_path)
endfunction
Now you can either map this function (Uncrustify) to a combination of keys or you could do the convenient trick that I use. Create a file ~/.vim/after/ftplugin/cpp.vim where you can override any Vim settings particularly for C++ and add the following line there:
autocmd BufWritePre <buffer> :call Uncrustify('cpp')
This basically adds a pre-save hook. Now when you save the file with C++ code it will be automatically formatted by Uncrustify utilizing the configuration file you supplied earlier.
NOTE: Everything presented here is well-tested and used every day by me.
Related
I can't get the Perl script below to write to the file output.html.
I doesn't need to be a CGI script yet, but that is the ultimate intention.
Can anyone tell me why it isn't writing any text to output.html?
#!/usr/bin/perl
#-----------------------------------------------------------------------
# This script should work as a CGI script, if I get it correctly.
# Most CGI scripts for Perl begin with the same line and must be
# stored in your servers cgi-bin directory. (I think this is set by
# your web server.
#
# This scripts will scrape news sites for stories about topics input
# by the users.
#
# Lara Landis
# Sinister Porpoise Computing
# 1/4/2018
# Personal Perl Project
#-----------------------------------------------------------------------
#global_sites = ();
print( "Starting program.\n" );
if ( !( -e "sitedata.txt" ) ) {
enter_site_info( #global_sites );
}
if ( !( -e "scrpdata.txt" ) ) {
print( "scrpdata.txt does not exist. Creating file now.\n" );
print( "Enter the search words you wish to search for below. Press Ctrl-D to finish.\n" );
open( SCRAPEFILE, ">scrpdata.txt" );
while ( $line = <STDIN> ) {
chop( $line );
print SCRAPEFILE ( "$line\n" );
}
close( SCRAPEFILE );
}
print( "Finished getting site data..." );
scrape_sites( #global_sites );
#----------------------------------------------------------------------
# This routine gets information from the user after the file has been
# created. It also has some basic checking to make sure that the lines
# fed to it are legimate domains. This is not an exhaustive list of
# all domains in existence.
#----------------------------------------------------------------------
sub enter_site_info {
my ( #sisites ) = #_;
$x = 1;
open( DATAFILE, ">sitedata.txt" ) || die( "Could not open datafile.\n" );
print( "Enter websites below. Press Crtl-D to finish.\n" );
while ( $x <= #sisites ) {
$sisites[$x] = <STDIN>;
print( "$sisites[$x] added.\n" );
print DATAFILE ( "$sisites[$x]\n" );
$x++;
}
close( DATAFILE );
return #sisites;
}
#----------------------------------------------------------------------
# If the file exists, just get the information from it. Read info in
# from the sites. Remember to create a global array for the sites
# data.
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# Get the text to find in the sites that are being scraped. This requires
# nested loops. It starts by going through the loops for the text to be
# scraped, and then it goes through each of the websites listend in the
# sitedata.txt file.
#-----------------------------------------------------------------------
sub scrape_sites {
my ( #ss_info ) = #_;
#gsi_info = ();
#toscrape = ();
$y = 1;
#---------------------------
# Working code to be altered
#---------------------------
print( "Getting site info..." );
$x = 1;
open( DATAFILE, "sitedata.txt" ) || die( "Can't open sitedata.txt.txt\n" );
while ( $gsi_info[$x] = <DATAFILE> ) {
chop( $gsi_info[$x] );
print( "$gsi_info[$x]\n" );
$x++;
}
close( DATAFILE );
open( SCRAPEFILE, "scrpdata.txt" ) || die( "Can't open scrpdata.txt\n" );
print( "Getting scrape data.\n" );
$y = 1;
while ( $toscrape[$y] = <SCRAPEFILE> ) {
chop( $toscrape[$y] );
$y++;
}
close( SCRAPEFILE );
print( "Now opening the output file.\n" );
$z = 1;
open( OUTPUT, ">output.html" );
print( "Now scraping sites.\n" );
while ( $z <= #gsi_info ) { #This loop contains SITES
system( "rm -f index.html.*" );
system( "wget $gsi_info[$z]" );
$z1 = 1;
print( "Searching site $gsi_info[$z] for $toscrape[$z1]\n" );
open( TEMPFILE, "$gsi_info[$z]" );
$comptext = <TEMPFILE>;
while ( $comptext =~ /$toscrape[z1]/ig ) { # This loop fetches data from the search terms
print( "Now scraping $gsi_info[$z] for $toscrape[$z1]\n" );
print OUTPUT ( "$toscrape[$z1]\n" );
$z1++;
}
close( TEMPFILE );
$z++;
}
close( OUTPUT );
return ( #gsi_info );
}
You're making assumptions about the current work directory that are often incorrect. You seem to assume the current work directory is the directory in which the script resides, but that's never guaranteed, and it's often / for CGI scripts.
"sitedata.txt"
should be
use FindBin qw( $RealBin );
"$RealBin/sitedata.txt"
There could also be a permission error. You should include the error cause ($!) in your error message when open fails so you know what is causing the problem!
While you're checking some, you're not checking all of your open or system calls. If they fail, the program will keep going without an error message telling you why.
You can add checks to all of these, but it's easy to forget. Instead, use autodie to do the checks for you.
You'll also want to use strict to ensure you haven't made any variable typos, and use warnings to warn you about small mistakes. See this answer for more.
Also #global_sites is empty so enter_site_info() isn't going to do anything. And scrape_sites() does nothing with its argument, #ss_info.
All of these things are helpful. Thank you. I found the problem. I was opening the wrong file. It was putting the error-checking in on the file that let me spot the error. It should have been
open (TEMPFILE, "index.html") || die ("Cannot open index.html\n");
I have taken as many of the suggestions as I remembered and included them in the code. I still need to implement the directory advice, but it should not be difficult.
How to make sublime text 3's SublimeOnSaveBuild package not compile the file named beginning with _ prefix?
For Example. I want a.scss or a_b.scss files can be complied when I saving this files. But not include the files such as named _a.scss.
I saw the guide in github is to set the filename_filter configuring.
So I create a SublimeOnSaveBuild.sublime-settings.Contents:
{
"filename_filter": "/^([^_])\\w*.(sass|less|scss)$/"
}
I used two \ , because it seems would saved as a .sublime-settings file which format likes JSON.
But it doesn't work.I use JavaScript to test it, it works well !
let reg = /^[^\_]\w*.(sass|less|scss)$/,
arr = [
'a.scss',
'_a.scss',
'a_b.scss'
];
arr.forEach(function( filename ) {
console.log( filename + '\t' + reg.test(filename) );
});
// a.scss true
// _a.scss false
// a_b.scss true
Thanks!
I found a solution in joshuawinn. But I can't understand why my codes can't work...
{
"filename_filter": "(/|\\\\|^)(?!_)(\\w+)\\.(css|js|sass|less|scss)$",
"build_on_save": 1
}
Sorry for my poor English !
let reg = /^(_|)\w*.(sass|less|scss)$/,
arr = [
'a.scss',
'_a.scss',
'a_b.scss'
];
arr.forEach(function( filename ) {
console.log( filename + '\t' + reg.test(filename) );
});
I have a perl script that I use to extract data from a raw data/log file. I need help on making the script dynamic. First, let me show you the part of the perl script and raw data file.
Perl script:
if ( /Catalyst tester (\S+)\S+/ )
{
$DETAILS{tester_name} = $1;
}
if ( /(CATALYST_TH\s*1)/ )
{
$FOUND_CAT = 1;
$DETAILS{test_head} = $1;
$TEST_HEAD = $1;
}
if ($FOUND_CAT)
{
if ( /(BACKPLANE\s*A)/ )
{
$FRAME = $TEST_HEAD .' '. $1;
$FOUND_BACKPLANE_A = 1;
}
if ( /(BACKPLANE\s*B)/ )
{
$FRAME = $TEST_HEAD . ' ' . $1;
$FOUND_BACKPLANE_B = 1;
}
}
if ( /END/ )
{
$FOUND_CAT = 0;
$FOUND_BACKPLANE_A = 0;
$FOUND_BACKPLANE_B = 0;
$FOUND_PRECISION_1 = 0;
$FOUND_PRECISION_2 = 0;
$FOUND_UB_SPS = 0;
$FOUND_HSD100_1 = 0;
$FOUND_HSD100_2 = 0;
$FOUND_HSD100_3 = 0;
$FOUND_TSY = 0;
$FOUND_TIME_SUB = 0;
}
if ($FOUND_BACKPLANE_A)
{
if ( /(\d+)\s+(\S+)\s+(\w+)\s+\w+\s+\d*\s+\#\s+\S+\s+(?:\d+\s+){2}((?!.*EMPTY\b).+)$/ )
{
push #{$DETAILS{frame}}, $FRAME;
push #{$DETAILS{slot}}, $1;
push #{$DETAILS{part_no}}, $2;
push #{$DETAILS{serial_no}}, $3;
push #{$DETAILS{board_name}}, $4;
}
}
if ($FOUND_BACKPLANE_B)
{
if ( /(\d+)\s+(\S+)\s+(\w+)\s+\w+\s+\d*\s+\#\s+\S+\s+((?!.*EMPTY\b).+)$/ )
{
push #{$DETAILS{frame}}, $FRAME;
push #{$DETAILS{slot}}, $1;
push #{$DETAILS{part_no}}, $2;
push #{$DETAILS{serial_no}}, $3;
push #{$DETAILS{board_name}}, $4;
}
}
if( /(PRECISION\_AC\s*1)/ )
{
$FOUND_PRECISION_1 = 1;
$FRAME = $1;
}
if ($FOUND_PRECISION_1)
{
if ( /(\d+)\s+(\S+)\s+(\w+)\s+\w+\s+\d*\s+\#\s+\S+\s+((?!.*EMPTY\b).+)/ )
{
push #{$DETAILS{frame}}, $FRAME;
push #{$DETAILS{slot}}, $1;
push #{$DETAILS{part_no}}, $2;
push #{$DETAILS{serial_no}}, $3;
push #{$DETAILS{board_name}}, $4;
}
}
## And the rest of the script follows the same format
In my perl script, my logic is if the line/word/header(as I prefer to call it) is found, assign a variable with a true or 1. Then in another if statement if the variable is 1, search for the data needed using regex and store it in a hash.
Now my main problem is that it is not dynamic. If you noticed I did an if statement for every header and the variable that is used to store a 1 is different for every header; if it's Catalyst tester then the variable would be $FOUND_CAT = 1;.
Somethings to take note of: for the header specifically CATALYST_TH 1, there will always be BACKPLANE A or it could be BACKPLANE B. If there is a BACKPLANE B I would have to write another if statement and push everything into the hash again. It's tedious because other log files may have even up to C or D which I do not know of yet, therefore making my script hard to maintain.
Other headers only need one line like PRECISION_AC 1. Only CATALYST_TH 1 will always have a backplane. This is just to take note in case it affects any answers.
So any help on this? Is there anyway to reduce the number of variables? Or even the number or if statements? I've tried but that way it wouldn't push other data into the hash if it's not true. Suggestions would greatly be appreciated.
P.S. Ignore the comments with one '#' symbol, those are part of the log file. The ones with two '#' symbols, like '##' are the comments I have added in.
Since your parsing has lots of state in it depending on what your program has already seen I would switch from regex to Parse-RecDescent, which can easily handle all that state nicely.
It's a steep learning curve at first though. There's a tutorial on it here, and an older, simpler tutorial here.
I'm trying to reproduce an R example based in R help.
This is an example for cxxfunction from inline package.
require(Rcpp)
require(inline)
# Rcpp plugin
if( require( Rcpp ) ){
fx <- cxxfunction( signature(x = "integer", y = "numeric" ) , '
return wrap( as<int>(x) * as<double>(y) ) ;
', plugin = "Rcpp" )
fx( 2L, 5 )
## equivalent shorter form using rcpp()
fx <- rcpp(signature(x = "integer", y = "numeric"),
' return wrap( as<int>(x) * as<double>(y) ) ; ')
}
I got this message:
Error in compileCode(f, code, language = language, verbose = verbose) :
Compilation ERROR, function(s)/method(s) not created! Warning message:
running command 'make -f "C:/PROGRA~1/R/R-30~1.3/etc/i386/Makeconf" -f "C:/PROGRA~1/R/R-30~1.3/share/make/winshlib.mk" ....
And in addition:
Warning message:
running command 'C:/PROGRA~1/R/R-30~1.3/bin/i386/R CMD SHLIB file3a86e316ef8.cpp ...
I'm using:
platform i386-w64-mingw32 and R-3.0.3
As Kevin said, its easier to use attributes. The attribute // [[Rcpp::export]] does all the work for you.
With the current versions on R and Rcpp installed create a file called test.cpp to put this code:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double fx(int x, double y){
return x*y;
}
/*** R
fx(2L,5)
fx(2L,5.1)
*/
Then in a R session run: Rcpp::sourceCpp('test.cpp')
That should work, if you have followed the instructions for installing R, R-tools and set PATH variables (if on windows) correctly.
I've been looking and playing with RegEx for a while now and am trying to find this solution that I can apply to both AS3 and to HTML5.
I've got a custom user entry section, 256 chars that they can customize.
What I would like is for them to use my predefined table of codes 00 - 99 and they can insert them into the box to automatically generate a response that can go through a few hundred examples.
Here is a simple example:
Please call: 04
And ask for help for product ID:
03
I'd be able to take this and say, okay i got the following into an array:
[Please call: ]
[04]
[/n]
[And ask for help for product ID: ]
[/n]
[03]
and possibly apply a flag to say whether this is a database entry or not
[Please call: ][false]
[04][true]
[/n][false]
[And ask for help for product ID: ][false]
[/n][false]
[03][true]
this would be something that my program could read. Where I know that for the ## matches, to find a database entry and insert, though for anything else, use the strings.
I have been playing around on
http://gskinner.com/RegExr/
to try and brute force an answer to no avail so far.
Any help would be greatly appreciated.
The best I've come up with so far for matches is the following. Though this is my first time playing with the regex functions and would need to find out how to push these entries into my ordered array.
\d\d
\D+
And would need some way to combine them to pull an array... or I'll be stuck with a crappy loop:
//AS3 example
database_line_item:int = 127;
previous_value_was_int:boolean = false;
_display_text:string = "";
for(var i:int = 0; i < string.length; i++){
if(string.charAt(i) is int){
if(previous_value_was_in){
previous_value_was_int = true;
}else{
_display_text += getDatabaseValue(string.charAt(i-1)+string.charAt(i), database_line_item);
previous_value_was_int = false;
}
}else{
//Hopefully this handles carriage returns, if not, will have to add that in.
_display_text += string.charAt(i);
}
}
// >>>>>>>>> HTML5 Example <<<<<<<<<<<<<
...
and I would cycle through the database_line_item, though for maybe 400 line items, this will be a taxing, to go through that string. Splitting it into smaller arrays would be easier to handle.
Here is the magic reg : /([^0-9\n\r]+)|(\d+)|(\r\n?|\n)/gi
Exemple output :
[Please call: ][false]
[4][true]
[/n][false]
[And ask for help for product ID:][false]
[/n][false]
[3][true]
Exemple code that do the job and put the data into an array :
package
{
import flash.display.Sprite;
public class TestReg extends Sprite
{
public function TestReg()
{
super();
var data : Array = parse("Please call: 04\n"+
"And ask for help for product ID:\n"+
"03");
// Output
for(var i : uint = 0; i < data.length; i += 2)
trace("[" + data[ i ] + "][" + data[ i + 1 ] + "]");
}
private var _search : RegExp = /([^0-9\n\r]+)|(\d+)|(\r\n?|\n)/gi;
public function parse(str : String) : Array
{
var result : Array = [];
var data : Array = str.match( _search );
for each(var item : * in data)
{
// Replace new line by /n
if(item.charAt( 0 ) == "\n" || item.charAt( 0 ) == "\r")
item = "/n";
// Convert to int if is a number
if( ! isNaN( parseFloat( item.charAt( 0 ) ) ) )
item = parseInt( item );
result.push( item );
result.push( !( item is String ));
}
return result;
}
}
}