g_over1=TRUE;for(i=0;i<blockquote_pos;i )

double f(double x); {double a=0; for (i=0;i&30;i+=10) a+=f((double)i); printf(&%5.0f\n&,a);}_百度知道
double f(double x); {double a=0; for (i=0;i&30;i+=10) a+=f((double)i); printf(&%5.0f\n&,a);}
完整的double f(double x); void main(){double a=0; for (i=0;i&30;i+=10) a+=f((double)i); printf(&%5.0f\n&,a);}double f(double x)(return x*x+1;)结果是503求给我讲明白怎么回事?谢谢~~
提问者采纳
函数f(x)返回x^2 + 1循环体内 a +=f((double)i) 等价于 a = a + f((double)i)
a的初始值为0, 所以循环体内的语句是累加f(i). 从for(i = 0; i & 30; i += 10)看出, i的初始值为0, 每次递增10,三次递增后达到30,不满足i&30,所以循环只有三次,i的值分别为0, 10, 20最终结果 a = f(0) + f(10) + f(20) = 1 + (10^2+1) + (20^2 + 1)
= 1 + 101 + 401 = 503把代码修改一下,printf中间数据,可以看得更清楚:#include &stdio.h&double f(double x);void main(){
double a=0;
for (i=0;i&30;i+=10) {
printf(&a=%f i=%d f(i)=%f\n&, a, i, f((double)i));
a+=f((double)i);
printf(&%5.0f\n&,a);}double f(double x){
return x*x+1;}运行输出:a=0.000000 i=0 f(i)=1.000000a=1.000000 i=10 f(i)=101.000000a=102.000000 i=20 f(i)=401.000000
提问者评价
其他类似问题
为您推荐:
printf的相关知识
其他1条回答
首先:i=0;进入for循环,执行a+=f((double)i),进入f()函数,return i*i+1;所以这个时候a=1;然后:i=10;进入for循环,执行a+=f((double)i),进入f()函数,return 10*10+1;a=10*10+1+1(a在上一次被赋值1).。所以a此时为102;最后:i=20;进入for循环,执行a+=f((double)i),进入f()函数,return 20*20+1;a=20*20+1+102(a在上一次被赋值102),所以此时a为503;然后i=30,不满足for循环条件,跳出循环,执行printf语句
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁求以下程序的运行结果main(){int i,n=0;for(i=1;i&20;i++)if(i%3==0&&i%5)n++;printf(:\n%d&,n)}_百度知道
求以下程序的运行结果main(){int i,n=0;for(i=1;i&20;i++)if(i%3==0&&i%5)n++;printf(:\n%d&,n)}
\for(i=1;20;i&lt,n=0main(){i++)if(i%3==0&&i%5)n++;n%d&,n);printf(
提问者采纳
5 因为if中的条件为能够整除3,且整除5结果为真(也就是整除5有余数,有余数结果就是true)时,n++
难道i%5不是i是5的倍数的意思吗,我以为是找3和5的公倍数
i%5==0,才是5的倍数i%5,这个表达式如果余数不是0,就是true
提问者评价
明白了~谢谢
来自团队:
其他类似问题
为您推荐:
其他3条回答
你这语法有问题,如果按程序的意思走应该是找15的倍数,n=1
求1~19能被3整除且不能被5整除的数的个数结果:5
n=5,i的分别为3,6,9,12,18时,n做自增。
printf的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁I recently created a protected user in chrome without really knowing anything about this feature.
Later I realised I couldn’t install add ons so wanted to upgrade the users permissions and keep all the cookies and settings for this new user.
There is no direct way to upgrade a user in the UI so you have to fiddle about with the filesystem,
Here’s how to do it.
This is for mac but should translate to other OS’s if you change the profile location.
1 Create a new user, give it a new name, this will be your upgraded users profile.
2 Close Chrome
3 Go to ~/Library/Application Support/Google/Chrome/ and work out which folder represents the old Supervised User, Copy all contents in here to the folder of the New user created in step 1*.
4 In the new user’s profile location open the file ‘Preferences’ in a text editor.
5 Find the key ‘profile’ and under here zero out the managed_user_id key so it reads –
“managed_user_id”: “”,
6 completely remove the key also under profile, this looks something like this..
&managed&: {
&custodian_email&: &&YOUR EMAIL&&,
&custodian_name&: &&YOUR NAME&&,
&shared_settings&: {
&&YOUR CODE&=&: {
&chrome-avatar-index&: {
&acknowledged&: true,
&value&: 13
7 Still in the new users profile folder, remove the file ‘Managed Mode Settings’
8 Restart Chrome, your user will now be a normal user with all the old supervised user’s settings
* To work out which folder belongs to which user open the ‘Preferences’ file in a folder and search for the ‘profile’ key.
Note the new user should be a folder called Profile X where X is an incremental number so you’d look at the highest.
Sometimes you may need a different colour scheme for every section / primary category in your site.
This can typically be a couple of hues of a colour per section, just to give a different personality to that corner of the site.
For example at
each main section has a dominant colour which is used in typgraphy and block headings within that section.
Here we took a basic approach of having CMS driven section variables which resolved to class names such as “bg-43;, you will see these peppered around the markup, mischievously binding presentation information to the markup.
Each page then has a dynamic &style& tag written out by the back end to marry things up.
Unfortunately this was built way before pre-processed CSS took off.
Nowadays we have tools such as LESS & SASS to make structuring site colour more elegantly.
With the use of mixins we can nominate which elements should inherit section colours all within our SCSS codebase.
Here’s how..
1st in your mixins location add this.
$primaryColors: (home #E73159)
(section2 #B0C038)
(section3 #FDAD00)
(anothersection #CB8840)
(keepaddingasmany #EAA3C5)
(sectionsasyouneed #8FBDCB);
@mixin section-color($properties:(background-color),$context:&body&){
$postContext:&&&;
@if ($context==&&&) {
$postContext:&&;
@each $i in $primaryColors {
#{$context}.#{nth($i,1)} #{$postContext} {
@each $property in $properties {
#{$property}:#{nth($i,2)};
$primaryColors is an array or ‘collection’ in sass language, fill this with all your sections’ colours.
I’m using the nth sass function to treat the collection as a multi dimensional array.
In SASS 3.3.0 there are ‘maps’ which will probably be a . To make this work you will need to ensure your CMS writes out the section name onto the body class.
You can now call…
@include section-color();
on each selector you wish to inherit a section colour.
By default it will apply the colour to the background, but you can easily override this by passing a different CSS property or collection of properties e.g.
@include section-color((color,border-color));
(note double bracketing needed for a collection).
The mixin iterates through all given properties and all possible sections and generates such CSS as…
body.home h1 {
color: #e73159;
border-color: #e73159;
body.section2 h1 {
color: #b0c038;
border-color: #b0c038;
body.section3 h1 {
color: #fdad00;
border-color: #fdad00;
body.anothersection h1 {
color: #cb8840;
border-color: #cb8840;
body.keepaddingasmany h1 {
color: #eaa3c5;
border-color: #eaa3c5;
body.sectionsasyouneed h1 {
border-color: #8
You may have noticed this bit of conditional logic at the top:
$postContext:&&&;
@if ($context==&&&) {
$postContext:&&;
This is to limit the trickery to a specific part of the site, for example the site nav.
Here you may wish to render all section colours, and more than likely have your cms output a section classname on each nav entity.
To switch into this mode there is a context parameter which by default is set to ‘body’.
When you override this to “&” the rule will no longer use the body class prefix and instead use the normal context of the rule that you are in.
So for example on your Nav elements you could call..
@include section-color($context:&&&);
Which compiles to
nav li.home {
background-color: #e73159;
nav li.section2 {
background-color: #b0c038;
nav li.section3 {
background-color: #fdad00;
nav li.anothersection {
background-color: #cb8840;
nav li.keepaddingasmany {
background-color: #eaa3c5;
nav li.sectionsasyouneed {
background-color: #8
Notice there is no longer a body prefix.
This all sounds a bit confusing so to help visualise what I’m talking about I’ve made a .
A recent Facebook post from , got people interested in Caracals, the wild cat I named my company after.
I am often ask to pronounce the name and explain what they are.
Hopefully this picture will help a little.
I’ve just uploaded a new jquery plugin to .
It’s a little plugin that allows you to bind a ‘domChanged’ event on any element.
Works cross browser by using ‘MutationObserver’ for modern browsers and a polling mechanism for older browsers (IE).
If you completely control the DOM on your page then this probably would be of no use.
It’s only really useful if you know a 3rd party script (an ad maybe) is going to change a part of your page but you have no means of knowing when it will have finished.
Why would you want to use PHPStorm’s file watcher when Grunt has a perfectly capable watching service?
If you work with many projects at any one time, I think it’s important to be able to quickly jump from one project to another without having to remember to fire a run command in a terminal screen.
With PHPStorm’s filewatchers I only have to worry about one app, my IDE – PHPStorm.
Of course it is possible to compile stylesheets & javascript with PHPStorm directly as described , but I prefer Grunt as it gives you a framework for defining production build patterns along side your dev building.
So to plug your Grunt workflow into PHPStorm, first define your Grunt task without using the grunt watcher like so.
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
compass: {
options: {
require: 'susy',
sassDir: '../sass/',
cssDir: '../web/css/src',
outputStyle: 'expanded'
options: {
require: 'susy',
sassDir: '../sass/',
cssDir: '../web/css',
outputStyle: 'compressed'
options: {
separator: ';'
src: ['../web/js/src/angular/*/*.js','../web/js/src/lib/*.js','../web/js/src/*.js'],
dest: '../js/min/concat.js'
'../web/js/min/scripts.min.js': ['&%= concat.prod.dest %&']
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-concat-css');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.registerTask('default', [ 'compass:dev']);
grunt.registerTask('prod', [ 'compass:prod','concat:prod','uglify:prod']);
Now running ‘grunt’ in my grunt directory will run the default task and I can use ‘grunt prod’ to build for production.
Make sure grunt alone works at this point.
Next I need to tell PHPStorm to run ‘grunt’ every time I edit an SCSS file.
First double check where grunt is.
$ which grunt
/usr/local/bin/grunt
Now enter this into a new file watcher form.
Make sure you set the working directory to where your grunt file is.
Now everytime you save an SCSS file your grunt task will execute.
Google Maps pretty much wins the map wars over Bing Maps hands down in my opinion, except for one killer Bing feature… Bird’s Eye!
Bird’s Eye really does come into its own when you’re looking at property to rent or buy, as it allows you to see a street from different angles for a unique perspective of the local topography. I made this bookmarklet to quickly switch between so whether you want street, satellite or bird’s eye view, you can switch quickly with this bookmarket.
Drag this link to your bookmark bar.
Locate a place of interest in Google Maps, click the bookmarklet to switch between Google Maps & Bing Bird’s eye.
So far tested this on Chrome and Firefox.
Note if you fire the bookmarklet when you’re not on Google Maps it will go to Google Maps.
Here is the code..
$j = jQuery.noConflict();
if(isGmaps()){
l=getLoc(&g&);
location.href=&/maps/default.aspx?sty=b&cp=& + l.lat + &~& + l.long +&&lvl=& + l.
}else if(isBing()){
l=getLoc(&b&);
location.href=&https://www.google.co.uk/maps/@& + l.lat+&,& + l.long+ &,& + l.zoom+ &z&;
location.href=&&
function isGmaps(){
return(location.host.search(/^maps.google/)==0||location.href.search(/^https?:\/\/www.google.co.*\/maps/)==0)
function isBing(){
return(location.href.search(/^https?:\/\/www.bing.co.*\/maps/)==0)
function getLoc(mode){
if (mode==&g&){
if($j(&.permalink-button&).length&0){
q=parseQuery($j(&.permalink-button&).attr(&href&));
ll = q[&ll&].split(&,&);
lat:ll[0],
long:ll[1],
zoom:q[&z&]
a1 = location.href.split(&@&).pop();
a2= a1.split(&,&);
lat:a2[0],
long:a2[1],
zoom:parseInt(a2[2])
q=parseQuery(VEShell.API.shareLink());
if (q[&cp&].indexOf(&~&)&0){
VEShell.API.setMapStyle(&r&);
q=parseQuery(VEShell.API.shareLink());
ll=q[&cp&].split(&~&);
lat:ll[0],
long:ll[1],
zoom:q[&lvl&]
function parseQuery(str){
if(typeof str != &string& || str.length == 0) return {};
var s = str.split(&&&);
var s_length = s.
var bit, query = {}, first,
for(var i = 0; i & s_ i++)
bit = s[i].split(&=&);
first = decodeURIComponent(bit[0]);
if(first.length == 0)
second = decodeURIComponent(bit[1]);
if(typeof query[first] == &undefined&) query[first] =
else if(query[first] instanceof Array) query[first].push(second);
else query[first] = [query[first], second];
It seems if you attach
a stylesheet with code like this…
$(&head&).append('&link type=&text/css& href=&/assets/css/tmp.css& rel=&stylesheet& /&');
You may not see all the styles in the right hand panel here. ↴
Although the browser will render any styles in tmp.css, IE developer tools will not be aware of that sheet in it’s style view.
So if you have a lot of CSS debugging to do in IE8 (you will) and you wish to attach a sheet dynamically with javascript, I suggest you just hard code the link tag in whilst you’re developing/fixing bugs, then revert to the JS appending when done.
There are a few ways to handle the displaying of retina images such as sending a
or a more .
Both are great, but in a recent project for , I was using a CMS –
and needed a different approach. .
Like most CMSs, Expression Engine generates a series of crops from one large ‘master’ file. So rather than one image and it’s double size retina counterpart, we have to think in terms of many file crops and the context of the image.
To do this, I wrote a JavaScript that, asks each image what size it wants to be and what pixel ratio the client is.
Using this information, and having knowledge of all the different crops available on the server, we should be able to identify the perfect crop to fetch.
The script became even more useful because womanshealth.co.uk
so images need to be of varying size depending on the user’s browser window. I eventually added some re-size detection, so even if a browser window started tiny, forcing a thumbnail image to download, you wouldn’t be stuck with a nasty pixelated stretched thumbnail when the window is maximised.
A typical URL from the Expression Engine image plugin we used would look like this…
/images/423/buccament_bay_resort_st_vincent_caribbean__small_4x3.jpg
There is some specific code in my script t you’ll have to amend this to match your CMS.
Also, a crop object is defined (crops) – make sure you change that to match the crops you’re using in your CMS.
To work the script runs at the bottom of the page just before .
There’s also an inline style in the head to temporarily prevent the natural image sizes loading, this will only kick in with js (using a modernizr selector), it is then removed when the script is done doing it’s stuff.
Note I’ve given all images I want to process a class of “c” for “content”.
UI images won’t be touched by this.
This is the inline style…
&style type=&text/css& id=&retina-hider&&
.js img.c {display:none}
Here’s the script with plenty of inline commentary…
(function(){
//this little generic function enables us to have a sort of 'after resize' event ie we don't want to fire
//loads of ret checks as we're resizing
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
function ret(firstRun){
//process retina images
var dpr = 1, crop,currentCrop,bestCrop,aS
if(window.devicePixelRatio !== undefined) dpr = window.devicePixelR
//define crop object
var crops = {thumb:152,small:320,medium:640,big:1112};
$(&img.c&).each(function(i){
var $img = $(this);
//calculate image crop from filename
//We're gonna be counting 2 _'s from the end of the filename to get the crop name, this bit is specific to our CMS
aSplits = $img.attr(&src&).split(&_&);
currentCrop =
aSplits[aSplits.length-2];
for(crop in crops){
(crops[crop]&=$img.width()*dpr ||
crop==&big&)
if(currentCrop==crop||(crops[currentCrop]&crops[crop] && !firstRun ) ){
//we already have the optimal crop or the crop we have is bigger anyhow, (no need to download a smaller version) so exit this images each loop
//if first run it's ok to get a smaller crop because we have nothing anyhoo.
//we've found a crop that's bigger or equal, (always scale down)
or if we've reached the end (largest) and it's different crop from current one.
aSplits[aSplits.length-2]=
$img.attr(&src&,aSplits.join(&_&));
ret(true);
$(&#retina-hider&).remove();
//bind resize
$(window).resize(function(){
delay(function(){
ret(false);
I love Jetbrains PHPStorm, it’s the best IDE out there in my opinion.
The latest version 6.0
included “File Watchers – for easy Sass, LESS, SCSS, CoffeeScript, TypeScript transpilation”.
The SCSS file watcher almost works with compass projects but when you start including like ‘@import “compass/reset”;’ you get errors because the compass/reset stylesheet isn’t actually in your project, it’s located centrally here /Library/Ruby/Gems/1.8/gems/compass-0.12.2/frameworks/compass.
So here’s how to get compass SASS files auto compiling.
Here is the xml config if you want to paste it into .idea/watcherTasks.xml
&?xml version=&1.0& encoding=&UTF-8&?&
&project version=&4&&
&component name=&ProjectTasksOptions&&
&TaskOptions isEnabled=&true&&
&option name=&arguments& value=&compile $FileParentDir$& /&
&option name=&checkSyntaxErrors& value=&true& /&
&option name=&description& value=&Compiles .scss files into .css files& /&
&option name=&exitCodeBehavior& value=&ERROR& /&
&option name=&fileExtension& value=&scss& /&
&option name=&immediateSync& value=&true& /&
&option name=&name& value=&Compass& /&
&option name=&output& value=&& /&
&option name=&outputFilters&&
&option name=&outputFromStdout& value=&false& /&
&option name=&passParentEnvs& value=&true& /&
&option name=&program& value=&/usr/bin/compass& /&
&option name=&scopeName& value=&Project Files& /&
&option name=&trackOnlyRoot& value=&true& /&
&option name=&workingDir& value=&$Projectpath$& /&
&/TaskOptions&
&/component&
&/project&
I’ve added the 3 following things to my Automatic Apache Virtual Host Applescript discussed (part one of this post ).
A vbscript for a VMware Fusion virtual machine
An index page of all virtual hosts
Root directory browsing of the webserver
First the vbscript which I’ve called updateHosts.vbs, for this I’ve used these .
The general idea is the ghost applescript will check is my virtual windows machine is running and if so run the vbscript inside of the virtual machine using the vmware vmrun command.
I also run the vbscript on windows vm login as well, just incase I last ran the applescript whilst the VM was off.
option Explicit
Dim hostip,root ,domain, clients, client, projects, project, projectSubFolders, projectSubFolder,oFSO
hostip=&172.16.214.1&
root = &W:\Projects&
Dim o_h : Set o_h = New std_host_file
Call o_h.Load( &C:\Windows\System32\drivers\etc\hosts& , False )
Call o_h.DeleteHostEntry( hostip )
set oFSO = CreateObject(&Scripting.FileSystemObject&)
ofso.getfolder(root)
for each client in ofso.getfolder(root).subfolders
For each project in client.SubFolders
If Left(project.Name,1) && &_& then
For Each projectSubFolder in project.SubFolders
projectSubFolder.Name = &web& then
Call o_h.AddHostEntry( hostip, project.name & &.& & client.name )
Call o_h.Save(&C:\Windows\System32\drivers\etc\hosts&)
Class std_host_file
Private Sub Class_Initialize()
Set m_lines = CreateObject(&Scripting.Dictionary&)
Set m_ip_map = CreateObject(&Scripting.Dictionary&)
Set m_alias_map = CreateObject(&Scripting.Dictionary&)
m_pareMode = vbTextCompare
Private sub Class_Terminate()
Set m_lines = Nothing
Set m_ip_map = Nothing
Set m_alias_map = Nothing
' Function returns the ip and data
Private Sub parse_line( ByVal line , ByRef comment , ByRef ip , ByRef aliases
Dim rx : Set rx = New RegExp
rx.Global = False
rx.IgnoreCase = True
rx.Pattern = &\s*(#.*)\s*&
' Parse Comment
If rx.Test( line ) Then
Set r = rx.Execute( line )
comment = r.Item(0).subMatches.Item(0)
line = rx.Replace( line , && )
rx.Pattern = &\s*((\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)|(\s*((([0-9A-F]{1,4}:){7}([0-9A-F]{1,4}|:))|(([0-9A-F]{1,4}:){6}(:[0-9A-F]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-F]{1,4}:){5}(((:[0-9A-F]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-F]{1,4}:){4}(((:[0-9A-F]{1,4}){1,3})|((:[0-9A-F]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){3}(((:[0-9A-F]{1,4}){1,4})|((:[0-9A-F]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){2}(((:[0-9A-F]{1,4}){1,5})|((:[0-9A-F]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){1}(((:[0-9A-F]{1,4}){1,6})|((:[0-9A-F]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-F]{1,4}){1,7})|((:[0-9A-F]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*))\s*&
' Parse IP
If rx.Test( line ) Then
Set r = rx.Execute( line )
ip = r.Item(0).subMatches.Item(0)
aliases = rx.Replace( line , && )
' Function returns the ip and data
Private Function getip( ByRef str , ByRef ip
getip = False
Dim rx_ip : Set rx_ip = New RegExp
rx_ip.Global = False
rx_ip.IgnoreCase = True
rx_ip.Pattern = &\s*((\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)|(\s*((([0-9A-F]{1,4}:){7}([0-9A-F]{1,4}|:))|(([0-9A-F]{1,4}:){6}(:[0-9A-F]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-F]{1,4}:){5}(((:[0-9A-F]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-F]{1,4}:){4}(((:[0-9A-F]{1,4}){1,3})|((:[0-9A-F]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){3}(((:[0-9A-F]{1,4}){1,4})|((:[0-9A-F]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){2}(((:[0-9A-F]{1,4}){1,5})|((:[0-9A-F]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){1}(((:[0-9A-F]{1,4}){1,6})|((:[0-9A-F]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-F]{1,4}){1,7})|((:[0-9A-F]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*))\s*&
If rx_ip.Test( str ) Then
Dim r : Set r = rx_ip.Execute( str )
ip = r.Item(0).subMatches.Item(0)
str = rx_ip.Replace( str , && )
getip = True
End Function
' Internal function used to validate IPV4 addresses
Private Function isipv4( ByVal ip )
Dim rx_ipv4 : Set rx_ipv4 = New RegExp
rx_ipv4.Global = false
rx_ipv4.IgnoreCase = True
rx_ipv4.Pattern = &^\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b$&
isipv4 = rx_ipv4.Test( ip )
End Function
' Internal function used to validate IPV6 addresses
Private Function isipv6( ip )
Dim rx_ipv6 : Set rx_ipv6 = New RegExp
rx_ipv6.Global = false
rx_ipv6.IgnoreCase = True
rx_ipv6.Pattern = &^\s*((([0-9A-F]{1,4}:){7}([0-9A-F]{1,4}|:))|(([0-9A-F]{1,4}:){6}(:[0-9A-F]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-F]{1,4}:){5}(((:[0-9A-F]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-F]{1,4}:){4}(((:[0-9A-F]{1,4}){1,3})|((:[0-9A-F]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){3}(((:[0-9A-F]{1,4}){1,4})|((:[0-9A-F]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){2}(((:[0-9A-F]{1,4}){1,5})|((:[0-9A-F]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-F]{1,4}:){1}(((:[0-9A-F]{1,4}){1,6})|((:[0-9A-F]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-F]{1,4}){1,7})|((:[0-9A-F]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$&
IsIPV6 = rx_ipv6.Test( ip )
End Function
' Internal function used to generate unique IDs
Private Function genguid()
Dim guidgen : Set guidgen = CreateObject(&Scriptlet.TypeLib&)
genguid = Mid(guidgen.Guid, 2, 36)
End Function
' Function returns true on success, otherwise false if the ip doesn't exist
Public Function GetHostEntryAliases( ByVal ip , ByRef aliases )
GetHostEntryAliases = False
aliases = Array
If m_ip_map.Exists( ip ) Then
aliases = m_lines.Item( m_ip_map.Item(ip) )(1).Keys
GetHostEntryAliases = True
End Function
' Function returns true on success, otherwise false if alias doesn't exist
Public Function GetHostEntryAliasAddresses( ByVal alias , ByRef ips )
GetHostEntryAliasAddresses = False
ips = Array
If m_alias_map.Exists( alias ) Then
ips = m_alias_map.Item( alias ).Keys
GetHostEntryAliasAddresses = True
End Function
' Removes a host entry by IPV4 or IPV6 address, return true
' on success, otherwise false if the IP is doesn't exist
Public Function DeleteHostEntry( ByVal ip )
DeleteHostEntry = False
If m_ip_map.Exists( ip ) Then
Dim uid : uid = m_ip_map.Item(ip)
' Remove the ip's from the associated aliases
For Each a In m_lines.Item(uid)(1).Keys
If m_alias_map.Item( a ).Exists( ip ) Then
m_alias_map.Item( a ).Remove( ip )
' If there are no more assoicated IPs remove the alias
If m_alias_map.Item(a).Count = 0 Then
m_alias_map.Remove( a )
' This *should* exist since we manage the entries and mappings
m_lines.Remove( uid )
m_ip_map.Remove( ip )
DeleteHostEntry = True
End Function
' Removes a host alias by IPV4 or IPV6 address
Public Function DeleteHostEntryAlias( ByVal ip , ByVal alias )
DeleteHostEntryAlias = False
' If the IP is valid
If m_ip_map.Exists( ip ) Then
Dim uid : uid = m_ip_map.Item(ip)
' If the alias exists remove the ip and if no more ip's are mapped to the alias remove the alias
If m_alias_map.Exists( alias ) Then
If m_alias_map.Item( alias ).Exists( ip ) Then
m_alias_map.Item( alias ).Remove( ip )
If m_alias_map.Item(alias).Count = 0 Then
m_alias_map.Remove( alias )
' If IP no longer has aliases associated with it remove it
Call delalias( uid , alias )
If m_lines.Item( uid )(1).Count = 0 Then
m_lines.Remove( uid )
m_ip_map.Remove( ip )
DeleteHostEntryAlias = True
End Function
' Adds a host entry by IPV4 or IPV6 address, alias should be
' the text alias for the address. Returns true on success
Public Function AddHostEntry( ByVal ip , ByVal alias )
AddHostEntry = False
Dim rx : Set rx = New RegExp
rx.Global = true
rx.IgnoreCase = True
rx.Pattern = &\s*&
alias = rx.Replace( alias , && )
ip = rx.Replace( ip , && )
' Validate IP
If isipv6( ip ) Or isipv4( ip ) Then
' Check for alias in the alias mapping
If Not m_alias_map.Exists( alias ) Then Call m_alias_map.Add( alias , CreateObject(&Scripting.Dictionary&) )
If Not m_alias_map.Item( alias ).Exists( ip ) Then Call m_alias_map.Item( alias ).Add( ip , && )
' Map IP -& alias
If m_ip_map.Exists( ip ) Then
' Lookup the index by ip then add aliases
Call addalias( m_ip_map.Item(ip) , alias )
' Store File Line
Dim uid : uid = genguid
Call m_lines.Add( uid , Array( ip , CreateObject(&Scripting.Dictionary&) , vbNullString ) )
Call addalias( uid , alias )
Call m_ip_map.Add( ip , uid )
AddHostEntry = True
End Function
' Should be used for debugging the data
Public Sub DumpData( )
Dim id, a, ip, a_map
' Debug dump host file out to text
WScript.Echo( &-------------------------------------------------------------------& )
For Each id In m_lines.Keys
If TypeName( m_lines.Item(id) )
= &String& Then
WScript.Echo m_lines.Item(id)
ElseIf TypeName( m_lines.Item(id) ) = &Variant()& Then
WScript.StdOut.Write lpad( m_lines.Item(id)(0) & && , & & , 16 )
& Space(8)
For Each a In m_lines.Item(id)(1).Keys
WScript.StdOut.Write a & & &
WScript.StdOut.Write m_lines.Item(id)(2) & vbCrLf
WScript.Echo( &-------------------------------------------------------------------& )
For Each ip In m_ip_map.Keys
For Each a In m_lines.Item( m_ip_map.Item(ip) )(1).Keys
WScript.Echo &IP [& & ip & &] ID Map {& & m_ip_map.Item(ip) & &} --& alias [& & a & &]&
If m_alias_map.Exists( a ) Then
For Each a_map In m_alias_map.Item( a ).Keys
WScript.Echo &alias Key [& & a & &] IP --& [& & a_map & &]&
' Internal formattig function for padding host data
Private Function lpad ( str , padch , padlen )
If padlen - Len(str) &= 0 Then
Lpad = String(padlen - Len(str),padch) & str
Lpad = str
End Function
' Returns all the IP addresses defined in the host file
' Returns true on success, otherwise false
Public Function GetAllHostEntryAddresses( ByRef ips )
GetAllHostEntryAddresses = False
ips = Array
If m_ip_map.Count & 0 Then
ips = m_ip_map.Keys
GetAllHostEntryAddresses = True
End Function
' Returns all the aliases defined in the host file
' Returns true on success, otherwise false
Public Function GetAllHostEntryAliases( ByRef aliases )
GetAllHostEntryAliases = False
aliases = Array
If m_alias_map.Count & 0 Then
aliases = m_alias_map.Keys
GetAllHostEntryAliases = True
End Function
' Write host file returns true if file could be opened for writing
Public Function Save( ByVal hostfile )
On Error Resume Next
Save = False
Dim objFSO : Set objFSO = CreateObject(&Scripting.FileSystemObject&)
Dim oFile : Set oFile = Nothing
Set oFile = objFSO.OpenTextFile( hostfile , 2 , True )
If Not oFile Is Nothing Then
For Each id In m_lines.Keys
If TypeName( m_lines.Item(id) ) = &String& Then
Call oFile.WriteLine( m_lines.Item(id) )
ElseIf TypeName( m_lines.Item(id) ) = &Variant()& Then
Call oFile.Write( lpad( m_lines.Item(id)(0) & && , & & , 16 )
& Space(8) )
For Each a In m_lines.Item(id)(1).Keys
Call oFile.Write( a & & & )
Call oFile.Write( m_lines.Item(id)(2) & vbCrLf )
Save = True
Set objFSO = Nothing
End Function
' Write host file returns true if file could be opened for reading
Public Function Load( ByVal hostfile , ByVal bmergecomments )
On Error Resume Next
Load = False
m_lines.RemoveAll()
m_ip_map.RemoveAll()
m_alias_map.RemoveAll()
Dim rx : Set rx = New RegExp
rx.Global = true
rx.IgnoreCase = True
rx.Pattern = &\s+&
Dim objFSO : Set objFSO = CreateObject(&Scripting.FileSystemObject&)
Dim oFile : Set oFile=Nothing
Set oFile = objFSO.OpenTextFile( hostfile , 1 )
If Not oFile Is Nothing Then
While Not oFile.AtEndOfStream
Dim pos : pos = 0
' Data will not be modified to preserve the file context
Dim data : data = Trim(oFile.ReadLine())
' Remove all the extra whitespace so we have a single spacing
' Line will be chopped up to see valid information exists
Dim line : line = Trim(rx.Replace(data, & &))
Dim ip : ip = vbNullString
Dim comment : comment = vbNullString
Dim aliases : aliases = vbNullString
' Check if the line is empty
If line && vbNullString Then
Call parse_line( line , comment , ip , aliases )
If isipv4( ip ) Or isipv6( ip ) Then
Dim a, uid
' Map alias -& IPs
For Each a In Split(aliases)
If Not m_alias_map.Exists( a ) Then
Call m_alias_map.Add( a , CreateObject(&Scripting.Dictionary&) )
If Not m_alias_map.Item( a ).Exists( ip ) Then Call m_alias_map.Item( a ).Add( ip , && )
' Map IP -& alias
If m_ip_map.Exists( ip ) Then
uid = m_ip_map.Item(ip)
' Lookup the index by ip then add aliases
For Each a In Split(aliases)
Call addalias( uid , a )
If bmergecomments Then
' Overkill (should be first # )
pos = InStr( 1, comment , &#& , vbTextCompare )
If pos && 0 Then
' Replace leading # from dual comment
comment = Mid( comment , pos + 1 )
' Merge comments
Call setcomment( uid , m_lines.Item( uid )(2) & &,& & comment )
' Store File Line
uid = genguid
Call m_lines.Add( uid , Array( ip , CreateObject(&Scripting.Dictionary&) , comment ) )
For Each a In Split(aliases)
Call addalias( uid , a )
Call m_ip_map.Add( ip , uid )
' Unknown IP format or malformed file
Call m_lines.Add(genguid,data)
Call m_lines.Add(genguid,data)
Set objFSO = Nothing
End Function
Private Function setip( uid , ip )
setip = False
If m_lines.Exists( uid ) Then
m_lines.Item(uid) = Array( ip , m_lines.Item(uid)(1) , m_lines.Item(uid)(2) )
setip = True
End Function
Private Function setcomment( uid , comment )
setcomment = False
If m_lines.Exists( uid ) Then
Dim a : a = m_lines.Item(uid)
m_lines.Item(uid) = Array( m_lines.Item(uid)(0) , m_lines.Item(uid)(1) , comment )
setcomment = True
End Function
Private Function addalias( uid , alias )
addalias = False
If m_lines.Exists( uid ) Then
If Not m_lines.Item(uid)(1).Exists( alias ) Then
Call m_lines.Item(uid)(1).Add( alias , && )
addalias = True
End Function
Private Function delalias( uid , alias )
delalias = False
If m_lines.Exists( uid ) Then
If m_lines.Item(uid)(1).Exists( alias ) Then
Call m_lines.Item(uid)(1).Remove( alias )
delalias = CBool( Not m_lines.Item(uid)(1).Exists( alias ) )
End Function
Private m_lines
Private m_ip_map
Private m_alias_map
Note the variables you may need to tweak here are hostip and root. I run my vm in NAT network mode which gives my windows machine access to my mac via the ip 172.16.214.1. The root variable is a shared vm folder here all my projects are stored.
The next addition is a handy little index page that returns all my virtual hosts. For this I’ve added the folder templates/index/web in order for me to get a domain of http://index.templates/. In here I’ve generated a hosts.txt which is an export of all the hosts generated by ghost using the following export command:
do shell script &ghost export & '& & unixRoot & &/templates/index/web/hosts.txt'& user name theUserName password thePassword with administrator privileges
I then parse this with the following index.php:
&!DOCTYPE HTML&
$masterList = array();
foreach (file(&hosts.txt&) as $name) {
//get rid of ip address part of line
$hosts = explode(& &,$name);
//Work out top level domain
$subs = explode(&.&,$hosts[0]);
$topLevel = $subs[count($subs)-1];
//construct array of top-level and full domain name
$masterList[] = array($topLevel,$hosts[0]);
//sort by top level
foreach ($masterList as $key =& $row) {
$tops[$key]
= $row[0];
array_multisort($tops, SORT_DESC, $masterList);
//output html links
$header = &&;
foreach ($masterList as
if ($header!=$row[0]){
$header= $row[0];
echo &&h2&&.$header.&&/h2&&;
echo &&a href='http://& .$row[1] . &'&&.$row[1]. '&/a&&br&';
I now have a handy http://index.templates/index page bookmarked on both my mac and virtual windows machine.
The final addition is not that notable really, it’s just getting the normal http://localhost to work in apache so I can browse around. My virtual hosts section of httpd.conf now looks like this:
&VirtualHost *&
VirtualDocumentRoot /Users/stu/Projects/%-1/%-2+/web
ServerName *
&/VirtualHost&
&VirtualHost *&
ServerName localhost
DocumentRoot /Users/stu/Projects
&/VirtualHost&
So here’s my final ghoster.scpt applescript
set root to &Macintosh HD:Users:stu:Projects&
set unixRoot to POSIX path of root
set domain to &&
--Get mac credentials from a keychain entry called MAMP
set theUserName to do shell script (&security
find-generic-password -gl MAMP | grep \&acct\& | cut -c 19-99 | sed 's/\&//g'&)
set thePassword to do shell script (&security 2&&1 &/dev/null find-generic-password -gl MAMP | cut -c 11-99 | sed 's/\&//g'&)
--get rid of current hosts entries in hosts, we're gonna create fresh ones
do shell script &ghost empty& user name theUserName password thePassword with administrator privileges
--add entries based of filesystem structure
tell application &Finder&
set clients to every folder of alias root
repeat with client in clients
set folderName to name of client
if first character of folderName is not &_& then
set projects to every folder of client
repeat with project in projects
set projectSubFolders to every folder of project
repeat with projectSubFolder in projectSubFolders
if name of projectSubFolder is &web& then
set domain to name of project & &.& & name of client
do shell script &ghost add & & domain user name theUserName password thePassword with administrator privileges
end repeat
end repeat
end repeat
--export what we've just made in a text file for the index.php to parse
do shell script &ghost export & '& & unixRoot & &/templates/index/web/hosts.txt'& user name theUserName password thePassword with administrator privileges
--get credentials for the windows VM
set winUserName to do shell script (&security
find-generic-password -gl win | grep \&acct\& | cut -c 19-99 | sed 's/\&//g'&)
set winPassword to do shell script (&security 2&&1 &/dev/null find-generic-password -gl win | cut -c 11-99 | sed 's/\&//g'&)
--get a list of running vmware machines
set test to do shell script &'/Applications/VMware Fusion.app/Contents/Library/vmrun' list&
--see if my windows dev machine is running
set search to offset of &win.vmx& in test
if search is greater than 0 then
--if it's running fire the vbscript inside the guest instance
do shell script &'/Applications/VMware Fusion.app/Contents/Library/vmrun' -T fusion -gu & & winUserName & & -gp & & winPassword & & runProgramInGuest '/pathtovmshere/win.vmx' -interactive 'c:\\windows\\system32\\cscript.exe' 'c:\updateHosts.vbs'&
Recent Posts

我要回帖

 

随机推荐