Posts mit dem Label code werden angezeigt. Alle Posts anzeigen
Posts mit dem Label code werden angezeigt. Alle Posts anzeigen

Dienstag, 15. Oktober 2013

Build specific targets of a sub-makefile (inspired by Gruntjs)

I recently had a great idea:
When I was using gruntjs a couple of months ago, I was introduced to the possibility of sub-targets there. Those were specified using colons (":") to seperate parent target and subtarget. Since I am using dedicated sub-makefiles for single modules in my project, I just had the brilliant idea: realize something similar to access goals from those. This saves me the trouble of specifying the file used and to define necessary environment variables by hand.

So what I came up with initially and what worked out quite well, was this:
# idea from http://blog.jgc.org/2007/06/escaping-comma-and-space-in-gnu-make.html 
# I put this in my dedicated defs.mk file for general usage
 ,             := ,
 space         :=
 space         +=
 $(space)      := 
 $(space)      +=
   
 $(PROJECT)\:%:  
      $(eval SUBGOALS := $(subst $(,),$( ),$*))  
      $(PRINT) making $(PROJECT) with goal\(s\) $(SUBGOALS)...  
      $(MAKE) -f "$(abspath $(ROOTDIR)/Make/$(PROJECT).mk)" $(SUBGOALS)  
      $(PRINT) done making $(PROJECT) with goal\(s\) $(SUBGOALS)  

Here is an example, of what the benefit of this is:

$: make modulexy:libxy,binxy
making modulexy with goal(s) libxy binxy...

There is one problem, though: While you CAN run makefile goals in any recursion level
(e.g. $: make goal1:goal2:goal3: ...)
only the first level allows you to pass the goals together to a single instance of make. Things like
"$: make goal1:goal2:goal3.1,goal3.2"
will be executed as
"make -f goal1file goal2:goal3.1 goal3.2"
That means, the command tries to run goal3.2 in goal1file (the file belonging to goal1).
The workaround would be
"make goal1:goal2:goal3.1,goal2:goal3.2"
which is then causing two instances of make being run on the makefile belonging to goal2: One for goal3.1 and one for goal 3.2.

So far, I did not feel the need to improve this (by adding a way to evaluate brackets, for example. Imagine "$: make goal1:goal2:(goal3.1,goal3.2)"). But if you are in a desperate need of this, it will be hard to achieve with make-internal tools only. sed will probably be your friend, here.
Contact me, if you come to a solution, so I can add it here.

See you soon!

Donnerstag, 10. Oktober 2013

GNU Make as templating engine (???)

Hello visitors!

So this is already my second post about GNU Make I am writing within two weeks! My intention this time is to describe how you can get all the power of the Makefile-parser into any usual, build-related file.

To give you a better image of what I wanted to achieve originally and why, let me give you this scenario:
Imagine you are starting to work on yet another c/c++ program for GNU and you are trying to use as much basic project stuff as possible from your previous project. You are copying over makefiles, licenses, other textfiles and launching scripts. After that, you alter the name of the last project everywhere to match your new one's - which is pretty inconvenient if done by hand. You know: These project specific strings occuring in standard files all over the place should be kept at only one place, namely your build system's configuration file.

In my last article I was calling this build system configuration file for make "defs.mk". Now the question is: How will we get the definitions from there into our text files?

With the help of the standard *nix tools "cat", "sed" and "printf" I managed to write a small copy-over routine for make which performs make's variable expansion on the text files we want to reuse in the future. Here is the code:

 DOCFILES        = $(DOCSRCDIR)/LICENSE.txt $(DOCSRCDIR)/README.txt  
 DOCDESTS    = $(subst $(DOCSRCDIR),$(DISTDIR),$(DOCFILES))  
 .PHONY    = all  
 all: $(DOCDESTS)  
 $(DISTDIR)/%: $(DOCSRCDIR)/%  
 # Get the file's contents into "DOCCONTENT". Don't forget to escape "#"  
 # by using sed -e 's/\#/\\&/g' and also get rid of troublesome newlines  
 # (replaced with \n which is re-translated by printf later)  
 # http://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n  
     @$(eval DOCCONTENT := $(shell cat $^ | sed -e ':a;N;$$!ba;{s/\#/\\&/g;s/\n/\\n/g}'))  
     @printf "$(DOCCONTENT)" > $@  

By reading the document into the makefile variable "DOCCONTENT" all currently set variables are being expanded (replaced) in the script before we write it back to its destination. DISTDIR is hereby our distributiable package folder.

Inside the document we are also able to use make's inbuilt functions, such as $(wildcard and even $(shell. This is a bit risky though, since almost everything can be done this way. At least noone will complain about lacking features, though :)

I hope this can be helpful for you!
Regards

Dienstag, 22. Mai 2012

Show a preview of your latest blogspot post on your external domain homepage

Hello readers!


During my internship I was given the task to find out on how to realize a small preview of the newest post from a blog here on blogspot. The problem was, that the previews should be integrated into a website owned by our client which was hosted by a different provider on a different domain, and that they should always keep up to date without any modifications. Additionally, my boss preferred to have the preview generated on client side, because it means less traffic and probably less trouble when integrating it into the rest of the framework-based project. In plain words, I was supposed to use Javascript.

So I searched the internet for multiple keyword combinations but did not find any solutions of someone who did that before. So I had to come up with a solution myself.

I believe there are three possible approaches for that:
The worst should be to go via the blog homepage, because then the desired information would either be mixed up with all sort of additional markup or completely hidden in other js-scripts.

The second approach is probably the most elegant one, but not completely simple to realize: If I tried to receive the data by pulling it from the blog's atom/rss feed I would have my information in a relatively good structure and Google would probably not set a limit to the number of accesses per day. Unfortunately though, plain javascript does not provide tools to parse the xml-alike feed output and I did not want to mess with an external library or parse the feed myself, which is probably still relatively easy with regular expression matches.

But I went the third way, which is probably the first one that came to your mind: Via the blogger api.
The api is currently under construction (heading for version 2) and the registration process takes some time to complete. You have to register/create a new api-Project on https://code.google.com/apis/console/ and apply for the permission to use the blogger api in it. The response e-mail took about twelve hours during the two times I tried it, which is the reason why I even think that there is only one Google employee who manually admits the usage of the api for your project.

Afterwards you simply do what the blogger-team wrote in their answer and you get access to the API-key, which is used by Google to keep track of your usage. I believe, the standard daily quota is about 1000 and I hope, it is counted by IPs and not by API-calls. Otherwise the permitted accesses would be exhausted quite rapidly.

Here is the code of my blogger.js file that generates the preview:
 /**  
  * Version: 2012/05/23 rev.1  
  *   
  * This script obtains information from the first post of a blogger-blog   
  * (in particular title + first image) and injects it into a specific  
  * place in the webpage.  
  *   
  * Currently, the information is written into an element (<div>) with the  
  * ID "blogger_output"  
  *   
  * To be able to style the information via css, the following classes are given to it:  
  * post title (p-tag): blogger_title  
  * post image (img-tag): blogger_image  
  */  
   
 function Blogger() {  
    Blogger.init();  
 }  
   
 Blogger.htmlOut = "blogger_output"; //The html-element, in which the blog-preview is to be written  
 Blogger.gAPI_URL = "https://www.googleapis.com/blogger/v2/blogs/"; //the blogger api base-url  
 Blogger.blogID = "9034413279324519603"; //The id of the blog whose latest post we want to generate a preview from  
 Blogger.apiKey = "AIzaSyCYuAlcd4NzcvTB2Igp7b2Tuuak_mLfcfk"; //The api-key to access the blogger-api  
   
 /**  
  * Writes a new line of (html-) text into the output element specified above  
  * @param text Some text to be written into the htmlOut element  
  */  
 Blogger.echo = function(text, writeInID) {  
    document.getElementById(writeInID).innerHTML += text;  
 };  
   
 /**  
  * Dynamically injects a script to the end of the body of the page  
  * @param jsname the url or name of the script to be injected  
  */  
 Blogger.injectScript = function (jsname) {  
    var scr = document.createElement('script');  
    scr.setAttribute('type','text/javascript');  
    scr.setAttribute('src',jsname);  
      
    var body = document.getElementsByTagName('body')[0];  
    body.appendChild(scr);  
 };  
   
 /**  
  * This is the callback method of the first blogger api call. Currently it does all  
  * the work (get title, image(s), preview text...), but at a later point we hope  
  * the blogger REST-api will support at least images as an additional resource type.   
  * In this case it is easy to add a second callback method correponding to the image[s]  
  * of the first post only.  
  * @param response The response of the google server after our api call  
  */  
 Blogger.handleBlog = function(response) {  
    //extract image url  
    var imgTag = response.items[0].content.match('(\\u003cimg.*?(/\\u003e))')[0];  
    var imgUrl = imgTag.match('http:.*?(?=\")');  
      
    //output  
    var aName = "blogger_link";  
    this.echo('<a id="' + aName + '" class="' + aName + '" href="' + response.items[0].url + '"></a>', this.htmlOut);  
    this.echo('<p class="blogger_title">' + response.items[0].title + '</p>', aName);  
      
    //Maybe a post has no image  
    //TODO: In this case, other information from the post could be shown  
    if(imgUrl != null) {  
       this.echo('<img class="blogger_image" alt="" src="' + imgUrl + '"/>', aName);  
    }  
    this.echo('</a>');  
 };  
   
 /**  
  * The first method of the script.  
  */  
 Blogger.init = function() {  
    //Inject script to obtain blog-data from google/blogger  
    var callback = 'Blogger.handleBlog';  
    var jsname = this.gAPI_URL + this.blogID + '/posts?callback=' + callback + '&key=' + this.apiKey;  
    this.injectScript(jsname);  
    return;  
 };  
   
   
 Blogger();  

Of course, you have to replace the values of the variablesapiKey and blogID with your personal data.

There are two techniques used here that may require explanation for beginners:
First, the data is received in JSON format via JSON with Padding (JSONP). You will easily find guides on this by using the internet.
And secondly there is the dynamic javascript injection in injectScript, which I borrowed from http://javascript.about.com/library/bladdjs.htm.

Additionally, there are a few things that I wanted to comment on here:
First thing is: please don't forget that I am an intern and this is actually my first try in anything javascript related. This is my first attempt of a pure js version.

You can also find a version of this script as a jquery-plugin under http://dl.dropbox.com/u/19826318/Blogger/bloggerJQP.js
In this case, only jquery has to be loaded, followed by the script call.

Secondly, you might have seen some passages in the code which refer to the current status of the blogger api. I really hope, there will be some improvement there as far as resource types are concerned. At least, the developer in charge has already received and approved a feature request upon this.

The code is well documented I hope, and there are classes/IDs given to the output later on which allow easy CSS-styling.

Used in a website, the html might look like the following:
1:  <html>  
2:   <head>  
3:    <title>JavaScript-Test</title>  
4:   </head>  
5:   <body>  
6:    <div id='blogger_output'><p>Neues aus meinem Blog:</p></div>  
7:    <script src="blogger.js" type="text/javascript"></script>  
8:   </body>  
9:  </html>  
...where the <div>-tag's id "blogger_output" is required for the script to be able to write the content into.

Result: 
Title and image of the post, all linking to the original post-url
Title and image of the post, all linking to the original post-url

I hope, this might be useful for some web-developer or intern out there. Please leave a comment if you liked it or if you have suggestions on how to improve this:)

See you soon,
suluke







Helpful links:
Getting started of the blogger JSON api 2.0
Code formatter for blogger

Mittwoch, 8. Februar 2012

Fibonacci in batch

Here a simple programm showing some of the power of batch, just so you get an impression why I think it is a good start to learn how to program:
Fibonacci.bat
1 :: This script prints out all Fibonacci-numbers up
2 :: to a position defined by the user
3 :: Version 1.0
4 :: Date: 2012/01/26
5 :: Author: Lukas Boehm
6 @echo off
7
8 :: Section that asks the user to enter a VALID
9 :: position in the fibonacci-sequence
10 setlocal
11 :input
12 set /p POS=Bitte geben Sie die gewuenschte Stelle in der Folge ein
13 set /a NUM=%POS% + 0
14 echo.
15 if %NUM% neq %POS% (
16 echo Fehler: keine gueltige Zahl!
17 goto input
18 )
19 endlocal & set POS=%POS%
20
21 :: Section that calculates and prints out
22 :: the fibonacci numbers
23 setlocal EnableDelayedExpansion
24 set LAST=0
25 set CURRENT=1
26
27 FOR /L %%N IN (1, 1, %POS%) DO (
28 set SWAP=!CURRENT!
29 set /A CURRENT +=!LAST!
30 echo !LAST!
31 set LAST=!SWAP!
32 )
33 endlocal
34
35 :EOF
36 PAUSE