neutrofoton

Science, Technology and Life

Configure PHP and Virtual Host macOS High Sierra

| Comments

Apache is pre installed on macOS High Sierra. We just need to run its service with the following command to activate it.

1
$ sudo apachectl start

Then we just open http://localhost via browser. Apache will display a default HTML page come with it.

Activating PHP Module

High Sierra also comes with PHP 7. So we don’t need to install it manually. To activate PHP module

  1. Edit /etc/apache2/httpd.conf
  2. Uncomment / remove remark of #LoadModule php7_module libexec/apache2/libphp7.so
  3. Save it and restart apache using bash $ sudo apachectl restart

After applying the steps above, the php module should be activated and ready to use. In this post we will test it after configuring virtual host.

Configuring Virtual Host

The steps of configuring apache virtual host are :

  1. Enabling virtual host configuration in apache config by editing /etc/apache2/httpd.conf.

     $ sudo nano /etc/apache2/httpd.conf
    
  2. Uncomment the section Include /private/etc/apache2/extra/httpd-vhosts.conf, then save it.

  3. Create site directory. As an example in this post, let’s create a Site folder in home directory called /Users/USERNAME/Sites. Our website sample directory will be put in it, let’s create a directory called /Users/USERNAME/Sites/neutro.io and create an /Users/USERNAME/Sites/neutro.io/index.php with simple PHP syntax.

     <?php
     phpinfo();
     ?>
    
  4. Create virtual host configuration by editing the virtual host config

     $ sudo nano /etc/apache2/extra/httpd-vhosts.conf
    

    The following code is an example of virtual host with domain name neutro.io

     <VirtualHost *:80>
         ServerName neutro.io
         ServerAlias www.neutro.io
         DocumentRoot "/Users/neutro/Sites/neutro.io"
    
     <Directory /Users/neutro/Sites/neutro.io>
             Options Indexes FollowSymLinks
             #Options All Indexes FollowSymLinks
             AllowOverride None
             Require all granted
     </Directory>
    
    
         ErrorLog "/private/var/log/apache2/neutro.io-error_log"
         CustomLog "/private/var/log/apache2/neutro.io-access_log" common
         ServerAdmin web@neutro.io
     </VirtualHost>
    

    In this example, we create a neutro.io virtual host that refers to /Users/neutro/Sites/neutro.io as physical directory.

  5. Register domain for localhost

    Since we use neutro.io as domain for localhost, we need to add the domain and www alias to resolve to the localhost address by editing

        $ sudo nano /etc/hosts
    

    and add the following line

        127.0.0.1   neutro.io   www.neutro.io
    
  6. Restart apache

     $ sudo apachectl restart
    

When we open in browser http://neutro.io, we should get a page that display PHP info.

Losing Default Localhost

After configuring the virtual host, we may lose the previous default localhost that points to /Library/WebServer/Documents/ directory. We may get a 403 Forbidden Error when visiting http://localhost. To get around this, we need to add in a vhost for localhost and declare this vhost before any of the others. The following code is our new Virtual host after adding config for localhost.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<VirtualHost *:80>
    ServerName localhost
    DocumentRoot /Library/WebServer/Documents/
</VirtualHost>

<VirtualHost *:80>
    ServerName neutro.io
    ServerAlias www.neutro.io
    DocumentRoot "/Users/neutro/Sites/neutro.io"

   <Directory /Users/neutro/Sites/neutro.io>
        Options Indexes FollowSymLinks
        #Options All Indexes FollowSymLinks
        AllowOverride None
        Require all granted
   </Directory>


    ErrorLog "/private/var/log/apache2/neutro.io-error_log"
    CustomLog "/private/var/log/apache2/neutro.io-access_log" common
    ServerAdmin web@neutro.io
</VirtualHost>

Restart apache and open http://localhost in browser.

References

  1. https://websitebeaver.com/set-up-localhost-on-macos-high-sierra-apache-mysql-and-php-7-with-sslhttps
  2. https://coolestguidesontheplanet.com/set-up-virtual-hosts-in-apache-on-macos-high-sierra-10-13/

PPTP on macOS

| Comments

One day I need to connect my macOS to a network of client of the company I work for via Point-to-Point Tunneling Protocol (PPTP) VPN. Unfortunately Apple removed PPTP support on macOS Sierra, so I had to find an alternative for that. Some of them I found are third parties application that need a one time buying or annual subscription. In fact, Apple just remove the user interface option for PPTP VPN, meanwhile the libraries of it are still available on Sierre.

Since the libraries of PPTP are still available on Sierra, theoritically we should be able to call the libraries via terminal. Finally I found 3 blogs that write about PPTP protocol on macos and I put them in a reference section in this blog. Basically the three of them use the same technique that’s write a script contains configuration of PPTP that’s put in /etc/ppp/peers/ and call it via pppd command via terminal.

First of all create a file called /etc/ppp/peers/pptpvpn-client1

1
$ sudo /etc/ppp/peers/pptpvpn-client1

Fill the pptpvpn-client1 that contains configuration that pppd daemon will refer to connect.

/etc/ppp/peers/pptpvpn-client1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
plugin PPTP.ppp
noauth
# logfile /tmp/ppp.log
remoteaddress "xxx.xxx.xxx.xxx"
user "xxxxxx"
password "xxxxxxxx"
redialcount 1
redialtimer 5
idle 1800
# mru 1368
# mtu 1368
receive-all
novj 0:0
ipcp-accept-local
ipcp-accept-remote
# noauth
refuse-eap
refuse-pap
refuse-chap-md5
hide-password
mppe-stateless
mppe-128
# require-mppe-128
looplocal
nodetach
# ms-dns 8.8.8.8
usepeerdns
# ipparam gwvpn
defaultroute
debug

Then open terminal and call

1
$ sudo pppd call pptpvpn-client1

If you cannot connect with the configuration code I use, you can check the error messages displayed in terminal. May be some configuration items do not match with the vpn server setting you connect to.

If the you got no any error messages and connection established with your VPN network you can open a new tab on the terminal and try to ping to an ip address in the VPN local network.

References

  1. https://smallhacks.wordpress.com/2016/12/20/pptp-on-osx-sierra/
  2. https://malucelli.net/2017/05/16/pptp-vpn-on-macos-sierra/
  3. https://www.cts-llc.net/2017/02/21/pptp-on-osx-just-one-last-time.html

Create and Consume C++ Class DLL on Windows

| Comments

while visiting clients of the company I work on, sometime I still found some applications especially desktop application build on unmanaged code (such as Delphi, Visual Basic 6, C++, etc). Even though at the time of this blog post, many application build on .NET (managed code) on Windows platform. There are various reasons why they do not migrate to managed code which has some advantages over unmanaged code (such as the application still run well with the version of OS they use, rewrite app will need extra cost, etc). This means unmanaged code application is not dead at all for LOB app, even though the percentage is much lower than the managed one.

Maybe this topic seems out of date topic in the .NET era, but at least this post as a note for my self in case I need it on the other day.

While developing an application, usually we want to share some of our code with other application. Dynamic Link Library (DLL) is Microsoft’s implementation of the shared library concept in the Microsoft Windows. The term DLL in this post will refer to unmanaged code and only focus to the one build with Visual C++ compiler on Windows environment.

When we create a DLL, we also create a .lib file that contains information of exported class or functions. When we build an executable that calls the DLL, the linker uses the exported symbols in the .lib file to store this information for the loader. When the loader loads a DLL, the DLL is mapped into the memory space of the executable.

An executable file links to (or loads) a DLL in one of two ways, implicit or explicit linking. In this post will create simple sample both of them how C++ class exported in the two ways. The samples in this post created using IDE Microsoft Visual Studio 2013 Ultimate. To simplify the code, I just created a single solution contains a Win32 DLL project and a console application client. The DLL project contains classes for both sample implicit and explicit linking. Either the console application contains sample code for implicit and explicit linking caller. Here is the classes I use in this sample.

Implicit Linking

Implicit linking, where the operating system loads the DLL when the executable using it is loaded. The executable client calls the exported functions of the DLL just as if the functions were statically linked and contained within the executable. Implicit linking is sometimes referred to as static load or load-time dynamic linking[4]. Now let’s create a sample of DLL with implicit linking.

First of all, create an empty solution in Visual Studio by selecting File > New Project > scroll down on the left pane, expand Other Project Types > Visual Studio Solutions select Black Solution. Fill the solution name as VCppDLL.

Now we have an empty solution in Visual Studio. Right click the VCppDLL solution > Add > New Project. In the left pane of the New Project dialog box, expand Installed templates Visual C++, and then select Win32. Fill the project name as MathWin32DLL, then click OK.

On the Win32 Application Wizard dialog in the Application Settings part, select DLL and check Empty project, then click Finish

Now we have an empty C++ DLL project in the Visual Studio solution. As the class diagram picture above, let create a simple BaseMath class. Right click the MathWin32DLL project > Add > Class. On Visual C++ template on the left pane dialog, select C++ Class > click Add. On the Generic C++ Class Wizard, fill the Class name as BaseMath then click Finish. Edit the BaseMath.h with the following code.

BaseMath.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// If you are building the DLL project on the command line,
// use the /D compiler option to define the MATHDLLWIN32_EXPORTS symbol.

#pragma once

#ifdef MATHWIN32DLL_EXPORTS
#define Math_API __declspec(dllexport)
#else
#define Math_API __declspec(dllimport)
#endif // MATHWIN32DLL_EXPORTS

#include <string>

using namespace std;

namespace core
{
  class BaseMath
  {
  public:
      virtual void Destroy()
      {
          delete this;
      }

      virtual string Say(string& s) = 0;
      virtual double Calculate(const double a, const double b) = 0;
  };
}

We can delete BaseMath.cpp file since we will make the BaseMath as an abstract class.

In Visual Studio, by default the New Project template for a DLL adds PROJECTNAME_EXPORTS to the defined preprocessor symbols for the DLL project. We can see the preprocessor symbols definition in Property Pages of MathWin32DLL project in the Configuration Properties > C/C++ > Preposesor > Preposesor Definitions.

In the code of BaseMath.h, when MATHWIN32DLL_EXPORTS symbol is defined, the Math_API symbol is set to __declspec(dllexport) modifier otherwise it is set to __declspec(dllimport). The __declspec(dllexport) modifier can be applied to classes, functions, or variables that tells the compiler and linker to export them from the DLL so that it can be used by other applications.

Meanwhile when we include BaseMath.h in client project, Math_API is set to __declspec(dllimport). This modifier optimizes the import of the exported class in an application.

For the next, let’s create another class called AddOperationMath. Edit the AddOperationMath.h and AddOperationMath.cpp respectively as follow.

AddOperationMath.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include "BaseMath.h"

using namespace std;

namespace core
{
  // MS Visual C++ compiler emits C4275 warning about not exported base class.
  class Math_API AddOperationMath : public BaseMath
  {
  public:
      AddOperationMath();
      virtual ~AddOperationMath();


      string Say(string& s);
      double Calculate(const double a, const double b);

      static double Add(const double a, const double b);
  };
}
AddOperationMath.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "AddOperationMath.h"

namespace core
{
  AddOperationMath::AddOperationMath()
  {
  }

  AddOperationMath::~AddOperationMath()
  {
  }

  string AddOperationMath::Say(string& s)
  {
      string result =  s + " is calling add operation of class AddOperationMath";
      return result;
  }

  double AddOperationMath::Calculate(const double a, const double b)
  {
      return a + b;
  }

  double AddOperationMath::Add(const double a, const double b)
  {
      return a + b;
  }
}

The class AddOperationMath inherits from BaseMath. We also mark the AddOperationMath class with Math_API macro that’s defined in BaseMath.h which means we will expose the AddOperationMath class in the DLL to executable client application. When we compile the DLL project, we should get a warning

1
warning C4275: non dll-interface class 'core::BaseMath' used as base for dll-interface class 'core::AddOperationMath'

In this case, ideally we should export (mark with Math_API macro) both core::BaseMath and core::AddOperationMath to make the compiler does not fire the warning message.

To complete our sample, let’s create another project called MathWin32ClientConsole as we did the creation of MathWin32DLL project, except select Console Application instead of DLL in the Application Settings dialog.

In the MathWin32ClientConsole project, right click > Add > New Item. Select Visual C++ project template on the left pane, then select C++ File (.cpp). Fill the name with Main.cpp.

To make the MathWin32ClientConsole project has reference to MathWin32DLL project, right click MathWin32ClientConsole project > Properties. Scroll up the Property Pages dialog, expand Common Properties on the left pane > select References. Click Add New Reference button, select Projects and check the MathWin32DLL > OK. Now you should see MathWin32DLL added to the References pane as the following picture.

To make the AddOperationMath class is recognized in the MathWin32ClientConsole project, we have to include AddOperationMath.h. We can copy the AddOperationMath.h and BaseMath.h to the MathWin32ClientConsole project. But it is not a good way in our scenario, because if we make changes to one of them, we have to recopy it to the MathWin32ClientConsole project directory. To avoid this manual copy, we can include the MathWin32DLL project directory to the MathWin32ClientConsole so that we can include any header files of MathWin32DLL to MathWin32ClientConsole if needed. To do that open the Property pages of MathWin32ClientConsole, select Configuration Properties > C/C++ > General. Select the drop-down control next to the Additional Include Directories edit box, and then choose <Edit...>. Select the top pane of the Additional Include Directories dialog box to enable an edit control. In the edit control, fill $(SolutionDir)\MathWin32DLL which tells to Visual Studio to scan or search header files that we include in directory MathWin32DLL inside solution directory.

Now we can include header file defined in MathWin32DLL from MathWin32ClientConsole. Let create code that call class defined in the DLL.

Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <string>

#include "AddOperationMath.h"

using namespace std;


void CallDLLByImplicitLinking(double a, double b, string s);

int main()
{
  double a = 2;
  double b = 4;
  string s = "neutro";

  CallDLLByImplicitLinking(a, b, s);


  cout << "Press any key to exit ";
  cin.get();

  return 0;
}



void CallDLLByImplicitLinking(double a, double b, string s)
{
  cout << a << " + " << b << " = " << core::AddOperationMath::Add(a, b) << endl;

  core::AddOperationMath* math = new core::AddOperationMath();
  cout << math->Say(s) << endl;

  delete math;

  cout << endl << "===============================================================" << endl;
}
Output
1
2
3
4
2 + 4 = 6
neutro is calling add operation of class AddOperationMath

Press any key to exit

There is no need to explicitly specify a calling convention for exporting classes or their methods. By default, the C++ compiler uses the __thiscall calling convention for class methods. However, due to different naming decoration schemes that are used by different compilers, the exported C++ class can only be used by the same compiler and by the same version of the compiler. Only the MS Visual C++ compiler can use this DLL now. Both the DLL and the client code must be compiled with the same version of MS Visual C++ in order to ensure that the naming decoration scheme matches between the caller and the callee[5]

To use a DLL by implicit linking, an executable must include the header files that declare the data, functions or C++ classes exported by the DLL in each source file that contains calls to the exported data, functions, and classes. The classes, functions, and data exported by the DLL must all be marked __declspec(dllimport) in the header file. From a coding perspective, calls to the exported functions are just like any other function call.

To build the calling executable file, we must link with the import library (.lib). If we use an external makefile or build system, we need to specify the file name of the import library where we list other object (.obj) files or libraries that we link.

The operating system must be able to locate the DLL file when it loads the calling executable. This means that we must deploy or verify the existence of the DLL when our application is installed.

Explicit Linking

Explicit linking, where the operating system loads the DLL on demand at runtime. An executable that uses a DLL by explicit linking must make function calls to explicitly load and unload the DLL and to access the functions exported by the DLL. Unlike calls to functions in a statically linked library, the client executable must call the exported functions in a DLL through a function pointer. Explicit linking is sometimes referred to as dynamic load or run-time dynamic linking[4].

To use a DLL by explicit linking, applications must make a function call to explicitly load the DLL at run time. To explicitly link to a DLL, an application must [4]:

  1. Call LoadLibrary, LoadLibraryEx, or a similar function to load the DLL and obtain a module handle.

  2. Call GetProcAddress to obtain a function pointer to each exported function that the application calls. Because applications call the DLL functions through a pointer, the compiler does not generate external references, so there is no need to link with an import library. However, you must have a typedef or using statement that defines the call signature of the exported functions that you call.

  3. Call FreeLibrary when done with the DLL.

To create a sample for explicit linking, we will use an abstract interface (a class with pure virtual methods, and no data) and create a factory method for object instantiation.

On the MathWin32DLL create a new class called LogarithmicMath. Edit the header and implementation files as follow

LogarithmicMath.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma once

#include "BaseMath.h"

namespace core
{
  class LogarithmicMath : public BaseMath
  {
  public:
      LogarithmicMath();
      virtual ~LogarithmicMath();


      string Say(string& s);
      double Calculate(const double a, const double b);
  };
}
LogarithmicMath.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include "LogarithmicMath.h"
#include <math.h>

namespace core
{
  LogarithmicMath::LogarithmicMath()
  {
  }


  LogarithmicMath::~LogarithmicMath()
  {
  }

  string LogarithmicMath::Say(string& s)
  {
      string result = s + " is calling Logarithmic operation of class LogarithmicMath";
      return result;
  }

  double LogarithmicMath::Calculate(const double a, const double b)
  {
      return log10(b) / log10(a);
  }
}

Next, create a Factory class that encapsulates LogarithmicMath instantiation and will be called from client app.

Factory.h
1
2
3
4
5
#include "BaseMath.h"

using namespace std;

extern "C" Math_API core::BaseMath* __cdecl CreateLogarithmicMath();
Factory.cpp
1
2
3
4
5
6
7
8
9
#include "Factory.h"
#include "LogarithmicMath.h"

using namespace std;

core::BaseMath* CreateLogarithmicMath()
{
  return new core::LogarithmicMath();
}

We can see that the LogarithmicMath class look like a standard C++ class. Instead of directly export the LogarithmicMath class, we use Factory that handle the export technics.

In the Factory.h defined extern "C" which tells the C++ compiler that the linker should use the C calling convention. It is required in order to prevent the mangling of the function name. So, this function is exposed as a regular C function, and can be easily recognized by any C-compatible compiler. The name itself is exported from the DLL unmangled (CreateLogarithmicMath). The Math_API tells the linker to export the CreateLogarithmicMath method from the DLL. __cdecl is the default calling convention for C and C++ programs.

Now let create a sample code in the MathWin32ClientConsole by editing the Main.cpp as following.

Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <string>

#include <Windows.h>

#include "AddOperationMath.h"

using namespace std;

typedef core::BaseMath* (__cdecl *LogarithmicMathFactory)();

void CallDLLByImplicitLinking(double a, double b, string s);
void CallDLLByExplicitLinking(double a, double b, string s);

int main()
{
  double a = 2;
  double b = 4;
  string s = "neutro";

  CallDLLByImplicitLinking(a, b, s);
  CallDLLByExplicitLinking(a, b, s);


  cout << "Press any key to exit ";
  cin.get();

  return 0;
}



void CallDLLByImplicitLinking(double a, double b, string s)
{
  cout << a << " + " << b << " = " << core::AddOperationMath::Add(a, b) << endl;

  core::AddOperationMath* math = new core::AddOperationMath();
  cout << math->Say(s) << endl;

  delete math;

  cout << endl << "===============================================================" << endl;
}


void CallDLLByExplicitLinking(double a, double b, string s)
{
  HMODULE dll = LoadLibrary(L"MathWin32DLL.dll");
  if (!dll)
  {
      cout << "Fail load library" << endl;
      return;
  }

  LogarithmicMathFactory factory = reinterpret_cast<LogarithmicMathFactory>(GetProcAddress(dll, "CreateLogarithmicMath"));

  if (!factory)
  {
      cerr << "Unable to load CreateLogarithmicMath from DLL!\n";
      FreeLibrary(dll);
      return;
  }

  core::BaseMath* instance = factory();
  cout << a << " log (" << b << ") = " << instance->Calculate(a, b) << endl;
  cout << instance->Say(s) << endl;

  instance->Destroy();

  FreeLibrary(dll);

  cout << endl << "===============================================================" << endl;
}

Now build and run the MathWin32ClientConsole, we should get the following output.

output
1
2
3
4
5
6
7
8
9
2 + 4 = 6
neutro is calling add operation of class AddOperationMath

===============================================================
2 log (4) = 2
neutro is calling Logarithmic operation of class LogarithmicMath

===============================================================
Press any key to exit

In order to ensure proper resource release, an abstract interface provides an additional method for the disposal of an instance. In this case we provide Destroy method. Calling this method manually can be tedious and error prone. It’s recommend use smart pointer for auto resource release instead of manual release.

The code of this article can be found here

References

  1. https://docs.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp
  2. https://msdn.microsoft.com/en-us/library/1ez7dh12.aspx
  3. https://docs.microsoft.com/en-us/cpp/build/dlls-in-visual-cpp
  4. https://docs.microsoft.com/en-us/cpp/build/linking-an-executable-to-a-dll#determining-which-linking-method-to-use
  5. https://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL
  6. http://eli.thegreenplace.net/2011/09/16/exporting-c-classes-from-a-dll

WinMerge and DiffMerge as Git Diff Merge Tool

| Comments

On software development while working with source control, it’s inevitable sometime we get our code conflicts with other, since we work in a team. There are many diff and merge tools out there and some of them can be integrated with with Git. In this post I just want to note what I did in my development machine (Windows 7 and macOS Sierra)

DiffMerge on macOS

For my macOS development machine I use DiffMerge. Actually DiffMerge is not only available for macOS, but also for Windows and Linux. So we can use it as Git diff merge tool as well on Windows and Linux. To configure Git to use DiffMerge can be done by running the following command via terminal.

1
2
3
4
5
6
7
8
9
10
$ git config --global mergetool.prompt false
$ git config --global mergetool.keepBackup false
$ git config --global mergetool.keepTemporaries false

$ git config --global diff.tool diffmerge
$ git config --global difftool.diffmerge.cmd 'diffmerge "$LOCAL" "$REMOTE"'

$ git config --global merge.tool diffmerge
$ git config --global mergetool.diffmerge.cmd 'diffmerge --merge --result="$MERGED" "$LOCAL" "$(if test -f "$BASE"; then echo "$BASE"; else echo "$LOCAL"; fi)" "$REMOTE"'
$ git config --global mergetool.diffmerge.trustExitCode true

The command will add the following config code in global .gitconfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[mergetool]
  prompt = false
  keepBackup = false
  keepTemporaries = false

[diff]
  tool = diffmerge

[difftool "diffmerge"]
  cmd = diffmerge \"$LOCAL\" \"$REMOTE\"

[merge]
  tool = diffmerge

[mergetool "diffmerge"]
  cmd = "diffmerge --merge --result=\"$MERGED\" \"$LOCAL\" \"$(if test -f \"$BASE\"; then echo \"$BASE\"; else echo \"$LOCAL\"; fi)\" \"$REMOTE\""
  trustExitCode = true

We can also directly edit the .gitconfig and manually add the config code.

WinMerge 2.x on Windows

WinMerge is an open source differencing and merging tool for Windows. It can compare both folders and files, presenting differences in a visual text format that is easy to understand and handle. At the time of writing this blog post, WinMerge 3 is still in progress of development and no release yet. WinMerge 3 will be modern compare/synchronization tool. It will be based on Qt library and cross-platform. You can use the same tool in Windows and in Linux. So for now and so on in this blog post, WinMerge term means WinMerge 2.x.

After installing WinMerge, to configure it as diff and merge tool of Git is by adding /editing the following config setting to C:\Users\{UserName}\.gitconfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[mergetool]
  prompt = false
  keepBackup = false
  keepTemporaries = false

[merge]
  tool = winmerge

[mergetool "winmerge"]
  name = WinMerge
  trustExitCode = true
  cmd = "/c/Program\\ Files\\ \\(x86\\)/WinMerge/WinMergeU.exe" -u -e -dl \"Local\" -dr \"Remote\" $LOCAL $REMOTE $MERGED

[diff]
  tool = winmerge

[difftool "winmerge"]
  name = WinMerge
  trustExitCode = true
  cmd = "/c/Program\\ Files\\ \\(x86\\)/WinMerge/WinMergeU.exe" -u -e $LOCAL $REMOTE

The config above also can be configured by Git bash shell with –global parameter instead of manual edit via text editor.

Now, whenever you want it to launch diffs just use difftool[1]:

1
2
3
4
5
6
7
8
# diff the local file.m against the checked-in version
$ git difftool file.m

# diff the local file.m against the version in some-feature-branch
$ git difftool some-feature-branch file.m

# diff the file.m from the Build-54 tag to the Build-55 tag
$ git difftool Build-54..Build-55 file.m

To resolve merge conflicts

1
$ git mergetool

References

  1. http://twobitlabs.com/2011/08/install-diffmerge-git-mac-os-x/
  2. http://winmerge.org/

Arduino and NEO-6M GPS Module

| Comments

Couple days ayo, I met a friend of mine when I was at university. He plays extensively with Arduino, Raspberry Pi, Orange Pi and other IoT stuff. He showed me how interesting IoT is, include wiring modules, and surely its programming. I remember that a few months ago, I got Arduino kit with GPS module from another friend of mine. The items were idle since I have other things to do in my work. Yesterday, I just have a free time to play with the Arduino kit. And I never play or explore Arduino before.

On the first time exploring Arduino, the hardware I use are :

  1. Arduino Uno
  2. GPS Module NEO-6M-0-001

To get working Arduino with GPS module, I use TinyGPS library. TinyGPS is designed to provide most of the NMEA GPS functionality. The detail description about TinyGPS can found here. TinyGPS is additional library for Arduino. So we need to install it before include it to our project. The steps of installation additional Arduino libraries can be found here

The table below shows wiring between Arduino and NEO-6M-0-001 GPS module

NEO-6M-0-001 GPS Arduino Uno Cable
Vcc Power 3.3 Volt Black
GND GND White
TXD RX pin 4 Gray
RXD TX pin 3 Magenta

To simplify our testing, I grab sample source code provided by TinyGPS. On This sample, I Set the data rate in bits per second (baud) for serial data transmission to 9600.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <SoftwareSerial.h>

#include <TinyGPS.h>

/ This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
/

TinyGPS gps;
SoftwareSerial ss(4, 3);

static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char str, int len);

void setup()
{
  //Serial.begin(115200);
  Serial.begin(9600);

  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.println("Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum");
  Serial.println("          (deg)     (deg)      Age                      Age  (m)    — from GPS —-  —- to London  —-  RX    RX        Fail");
  Serial.println("————————————————————————————————————————————-");

  //ss.begin(4800);
  ss.begin(9600);
  delay(1000);
}

void loop()
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  gps.f_get_position(&flat, &flon, &age);
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  print_date(gps);
  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2);
  print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
  print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? " " : TinyGPS::cardinal(gps.f_course()), 6);
  print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
  print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? " " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

  gps.stats(&chars, &sentences, &failed);
  print_int(chars, 0xFFFFFFFF, 6);
  print_int(sentences, 0xFFFFFFFF, 10);
  print_int(failed, 0xFFFFFFFF, 9);
  Serial.println();

  smartdelay(1000);
}

static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void print_float(float val, float invalid, int len, int prec)
{
  if (val == invalid)
  {
    while (len > 1)
      Serial.print('');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(' ');
  }
  smartdelay(0);
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, "");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0)
    sz[len-1] = ' ';
  Serial.print(sz);
  smartdelay(0);
}

static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print(" **** ");
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
        month, day, year, hour, minute, second);
    Serial.print(sz);
  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  smartdelay(0);
}

static void print_str(const char str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  smartdelay(0);
}

The output of this testing on Serial monitor showed as follow.

If you do not get similar output as above (get * on table output) it means your arduino fails get data from GPS module. Please ensure your GPS led is blinking which indicate it receives data from the GPS satellites.

The other thing that you should ensure is you have the right wiring. RX of the Arduino (pin 4, according to the SoftwareSerial statement) goes to the TX of the GPS. Arduino pin 3 (ss TX) goes to the GPS RX.

To validate the accuracy of GPS output (Latitude, Longitude) showed on Arduino Serial Monitor you can check it on google map.

References

Import Existing Git Repository to Another

| Comments

While working with git, we may need to import source code from an existing git repository to our working copy. Merging it and pushing to origin master. The scenario that I had was :


  • I have a project template that I store on a git repository. Let say the url is http://server/git/template.git
  • I have another git repository with url http://server/git/project1.git

What I need from the two repositories are importing all contents (libraries, sources, etc) from template repository into my project1 working copy. Since I don’t want to coding from zero. To get into what I need, here are the steps.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# git clone project1
$ git clone http://server/git/project1.git
$ cd project1

# add remote url named REMOTE.TEMPLATE
$ git remote add REMOTE.TEMPLATE http://server/git/template.git

# fetch from REMOTE.TEMPLATE remote url
$ git fetch REMOTE.TEMPLATE

# checkout REMOTE.TEMPLATE/master and create a new branch called TEMPLATE
$ git checkout -b TEMPLATE REMOTE.TEMPLATE/master

#switch back to master branch
$ git checkout master

# merge TEMPLATE brach to master branch
$ git merge TEMPLATE

# commit changes
$ git commit

The next step is checking the merge result on our working copy of master branch. If what we have been imported already there, now we can remove the remote URL of REMOTE.TEMPLATE and TEMPLATE branch to get rid of the extra branch before pushing.

1
2
3
4
5
6
7
8
# remove REMOTE.TEMPLATE remote address
$ git remote rm REMOTE.TEMPLATE

# remove template branch. It is useful to get rid of the extra branch before pushing
$ git branch -d TEMPLATE

# push to remote origin/master
$ git push

References

  1. http://stackoverflow.com/questions/1683531/how-to-import-existing-git-repository-into-another

Working With Multiple Github Account on a Computer

| Comments

Source control is one of a basic need for software development, especially when we work on a team. Git is one of popular distributed source control. Working with multiple github account on the same computer need a few tricky way. Let’s assume we have cloned the repository from github to local computer. The following ways are the simple ways I got on internet.

Change Remote URL to HTTPS

This way is by changing the remote URL to HTTPS with the following format.

1
$ git remote set-url origin https://USERNAME@github.com/USERNAME/PROJECTNAME.git

Then do normal git operation such as commit, push etc. To ensure that the commits appear as performed by USERNAME, we can configure the username and email on our working directory.

1
2
$ git config user.name USERNAME
$ git config user.email USERNAME@example.com

Multiple SSH Key

The other way is by using multiple SSH key. Here is the complete tutorial by Jeffrey Way

References

  1. http://stackoverflow.com/questions/3860112/multiple-github-accounts-on-the-same-computer
  2. https://code.tutsplus.com/tutorials/quick-tip-how-to-work-with-github-and-multiple-accounts--net-22574

C++ Set With Custom Comparator

| Comments

std::set is a C++ STL container that store unique elements following a specific order. It is defined in the set header file.

Benefits and Features of std::set[3]:

  1. It’s doesn’t allow duplicate elements i.e. it only contains unique elements
  2. std::set can contain element of any specified type in template argument
  3. std::set internally store elements in balanced binary tree
  4. By default std::set uses the operator < for comparing two elements and but if user passes the external sorting criteria i.e. comparator then it uses it instead of default operator < .
  5. std::set will keep the inserted elements in sorted order based on the assigned sorting criteria i.e. either by default criteria operator < or by passed comparator (if passed).
  6. In this post the samples only limited to std::set that use custom comparator and store complex object instead of basic data type. The complex object that we will use is reusing class Person on previous post.

    Let’s create custom class that handles comparation process

    CustomCompare
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    #ifndef CustomCompare_h
    #define CustomCompare_h
    
    #include "Person.hpp"
    
    struct CustomCompare
    {
        bool operator()(const int& lhs, const int& rhs)
        {
            return lhs < rhs;
        }
    
        bool operator()(const Person& lhs, const Person& rhs)
        {
            return lhs.getAge() < rhs.getAge();
        }
    };
    
    #endif / CustomCompare_h /
    

    The following code is an example how to use the comparator class in std:set

    sample how to use
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    void SampleSetWithCustomCompare()
    {
        set<Person,CustomCompare> setOfPersons;
    
        setOfPersons.insert(Person("Person 1", 25));
        setOfPersons.insert(Person("Person 2", 16));
        setOfPersons.insert(Person("Person 3", 28));
        setOfPersons.insert(Person("Person 4", 9));
    
        for(set<Person,CustomCompare>::iterator it = setOfPersons.begin(); it!=setOfPersons.end(); ++it)
        {
            cout << it->getName() << " , age : " << it->getAge()<< endl;
        }
    
    }
    

    References

    1. http://www.cplusplus.com/reference/set/set/
    2. http://www.wrox.com/WileyCDA/WroxTitle/Professional-C-2nd-Edition.productCd-0470932449.html
    3. http://thispointer.com/stdset-tutorial-part-1-set-usage-details-with-default-sorting-criteria/

C++ Priority Queue With Comparator

| Comments

priority_queue is categorized as a STL container adaptor. It is like a queue that keeps its element in sorted order. Instead of a strict FIFO ordering, the element at the head of the queue at any given time is the one with the highest priority.

The template class definition of priority_queue is as follow

template definition
1
2
3
4
5
template <
   class Type,
   class Container=vector<Type>,
   class Compare=less<typename Container::value_type> >
class priority_queue

A user-provided compare can be supplied to change the ordering, e.g. using std::greater would cause the smallest element to appear as the top(). We also can create custom comparator for our need.

Many samples available on net about priority_queue with default compare parameter. In this article let’s create samples by specifying the compare parameter template.

priority_queue with std::greater
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//helper function displays sorted data
template<class T>
void printQueue(T& q)
{
    while (!q.empty())
    {
        cout << q.top() << endl;
        q.pop();
    }
}

void SamplePriorityQueue()
{
    std::priority_queue<int, std::vector<int>, std::greater<int> > q;

    for(int n : {1,8,5,6,3,4,0,9,7,2})
        q.push(n);

    printQueue(q);
}

The code above uses std::greater as a compare parameter template.

output
1
2
3
4
5
6
7
8
9
10
0
1
2
3
4
5
6
7
8
9

Beside the std::less or std::greater, we can create our custom comparator with lamda or custom class or struct.

lamda as compare parameter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void SamplePriorityQueueWithLamda()
{
    // using lambda to compare elements.
    auto compare = [](int lhs, int rhs)
                {
                    return lhs < rhs;
                };

    std::priority_queue<int, std::vector<int>, decltype(compare)> q(compare);

    for(int n : {1,8,5,6,3,4,0,9,7,2})
        q.push(n);


    printQueue(q);
}

To use the custom comparator, we just need to pass it as the third parameter of priority_queue template

custom comparator
1
2
3
4
5
6
7
struct CustomCompare
{
    bool operator()(const int& lhs, const int& rhs)
    {
        return lhs < rhs;
    }
};
sample with custom comparator
1
2
3
4
5
6
7
8
9
10
11
void SamplePriorityQueueWithCustomComparator()
{
    priority_queue<int,vector<int>, CustomCompare > pq;

    pq.push(3);
    pq.push(5);
    pq.push(1);
    pq.push(8);

    printQueue(pq);
}

The data stored in priority_queue is not limited to basic data type. We can store object in it. Let’s create a sample of it. Let’s say we have a Person class.

Person.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef Person_hpp
#define Person_hpp

#include <stdio.h>
#include <string>

using namespace std;

class Person
{
public:
    Person();
    Person(string name, int age);
    virtual ~Person();

    string getName() const;
    int getAge() const;

    friend bool operator < (const Person& lhs, const Person& rhs);
    friend bool operator > (const Person& lhs, const Person& rhs);

private:
    string name;
    int age;
};

#endif /* Person_hpp */
Person.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include "Person.hpp"

bool operator < (const Person& lhs, const Person& rhs)
{
    return lhs.getAge() < rhs.getAge();
}

bool operator > (const Person& lhs, const Person& rhs)
{
    return lhs.getAge() > rhs.getAge();
}

Person::Person()
{
}

Person::Person(string name, int age):name(name), age(age)
{
}

Person::~Person()
{
}

string Person::getName() const
{
    return name;
}

int Person::getAge() const
{
    return age;
}

On the Person class, we have friend overloading methods, right angle bracket and left angle bracket. The methods act as comparation operator. The operator overloading is needed if we want to use std::less or std::greater.

sample priority_queue stores object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
void SamplePriorityQueueStoreObject()
{
    vector<Person> personVector =
    {
        Person("Person 1", 25),
        Person("Person 2", 17),
        Person("Person 3", 35),
        Person("Person 4", 7),
        Person("Person 5", 50)
    };

    cout << "======== Less Priority Queue ======= " << endl;

    priority_queue<Person, vector<Person>, less<vector<Person>::value_type>> pqueue_less;

    //fill pqueue_less
    for (auto it = personVector.cbegin(); it!=personVector.cend(); it++)
    {
        pqueue_less.push(*it);
    }

    //iterate,display and pop
    while (!pqueue_less.empty())
    {
        Person value = pqueue_less.top();
        cout << value.getName() << " : " << value.getAge() << endl;

        pqueue_less.pop();
    }


    cout << endl << endl;

    cout << "======== Greater Priority Queue ======= " << endl;

    priority_queue<Person, vector<Person>, greater<vector<Person>::value_type>> pqueue_greater;
    //fill pqueue_greater
    for (auto it = personVector.cbegin(); it!=personVector.cend(); it++)
    {
        pqueue_greater.push(*it);
    }

    //iterate,display and pop
    while (!pqueue_greater.empty())
    {
        Person value = pqueue_greater.top();
        cout << value.getName() << " : " << value.getAge() << endl;

        pqueue_greater.pop();
    }
}

References

  1. http://en.cppreference.com/w/cpp/container/priority_queue
  2. https://support.microsoft.com/en-us/kb/837697
  3. http://www.wrox.com/WileyCDA/WroxTitle/Professional-C-2nd-Edition.productCd-0470932449.html

Reset Git Credential on OS X Keychain

| Comments

This post basically just a note for my self. In case I got the same condition in the next, it can help me to remember what I did in the past.

I got a condition which I have just changed my git password. Surely I cannot pull or push since my local credential was not valid anymore. When I run git config –list, I believe my git password stored on OS X Keychain. The simple way I do was running a command via terminal :

1
$ git config credential.helper osxkeychain

I was then prompted to input my username and password. By inputing my username and new password everything back to normal.

If you want it to apply globally just append parameter –global to the command.

1
$ git config --global credential.helper osxkeychain

References

  1. http://stackoverflow.com/questions/20195304/how-to-update-password-for-git