tag:blogger.com,1999:blog-16478147524460972802024-03-13T02:12:57.482+00:00Cide by CideNotes and musings from my latest adventure: Return to Software Development. And the weird name? A good name gets you halfway there. That's a lesson I should remember next time.Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.comBlogger82125tag:blogger.com,1999:blog-1647814752446097280.post-49437946156609857182016-04-22T13:27:00.000+01:002016-04-22T13:27:16.177+01:00Design - avoiding the obvious<div style="text-align: justify;">
Suppose you have a process that combs a database and generates monthly reports. The rule is simple, you run at the beginning of the month, and your universe is defined by the first and last days of the previous month.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
See? Simple. You've got a begin date and an end date, and just grab everything that falls within that time period.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Since this date arrangement is a recurring requirement, I've decided it was time to abstract it into a s<i>cript-lib</i>, i.e., something other processes can call on the command line, and that can also be included as a library/module by other scripts.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And so I went about defining the interface, based on this use case - OK, we'll need a function that returns the begin date, and a function that returns the end date, and a rule for calculating the required interval. In my defense, I did kill the "and we could include formatting" thought as soon as it appeared.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Why all these functions? Well, SRP, and composability and all that jazz.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
After a few attempts, I scrapped the idea. I wasn't happy with the interface, and I had no alternative design. I went on to do something else, and as I was looking at another problem, the solution hit me: The key is the first day of the <i>current</i> month. Everything else should flow from there.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This solution is in ruby (Ruby 1.8.7, no <i>ActiveSupport</i>), and it goes something like this:</div>
<div style="text-align: justify;">
<br /></div>
<code style="font-size: 14px;"> def get_first_day_of_month(ref_date)<br />
day = ref_date.day()<br />
<br />
if day > 1<br />
ref_date -= day - 1<br />
end<br />
<br />
return ref_date<br />
end</code><br />
<br />
<span style="text-align: justify;">Now, with this, it's trivial to get the begin and end dates I actually need:</span><br />
<code style="font-size: 14px;"><br />
first_day = get_first_day_of_month(Date.today())</code><br />
<code style="font-size: 14px;"><br />
begin_date = first_day << 1 # subtract 1 month</code><br />
<code style="font-size: 14px;"><br />
</code> <code style="font-size: 14px;"> end_date = first_day - 1 # subtract 1 day</code><br />
<br />
<div style="text-align: justify;">
Going back to my script-lib, I can now create an interface that can both return an array/hash with the two dates (usable as a module by other Ruby scripts), and output the dates to file/stdout, separated by a delimiter specified by the caller (usable by any script). Yes, it's a modest lib, but we all gotta start somewhere.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
One thing I don't understand is the lack of modifier operators on date/time frameworks (see Java's <i>Calendar</i> class and Free Pascal's <i>dateutils Recode*</i> functions for two examples on how to do this right). It would've been a lot simpler to do something like this:</div>
<div style="text-align: justify;">
<span style="font-family: monospace; font-size: 14px;"><br />
</span></div>
<code style="font-size: 14px;"> first_day = Date.today().day!(1)<br />
</code><br />
<div style="text-align: justify;">
Yes, I know, Ruby has open classes, I can add it myself. But just because I can, doesn't mean I should.</div>
<div style="text-align: justify;">
<br /></div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-64930970769579758202016-02-18T12:25:00.000+00:002016-02-18T12:25:24.532+00:00Explicit template instantiation - Exhibit 1<div style="text-align: justify;">
As I promised last time, let's put our design to work on some code.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Back in 2013, I wrote a couple of template functions as a quick solution to a very specific problem - outputting non-ASCII characters on a Windows console in a program compiled with Mingw. Here's the <a href="https://github.com/PauloCaetano/bluesy/blob/master/src/ms_windows/win_console_out.h" target="_blank">header</a>, and here's the <a href="https://github.com/PauloCaetano/bluesy/blob/master/src/ms_windows/win_console_out.cpp" target="_blank">source</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I've now applied the idea from the last post, and changed the code from full inclusion to explicit instantiation. There are other changes to be made, but those will wait.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If you go back in the header's history, you'll see that the previous version used full inclusion. As such, this was included in every translation unit (TU) that used this code:<br />
<br /></div>
<div style="text-align: justify;">
<div>
<code style="font-size: 14px;">#include "boost/locale.hpp"</code></div>
<div>
<code style="font-size: 14px;">#include "windows.h"</code></div>
<div>
<code style="font-size: 14px;">#include <cassert></code></div>
<div>
<code style="font-size: 14px;">#include <locale></code></div>
<div>
<code style="font-size: 14px;">#include <sstream></code></div>
<div>
<code style="font-size: 14px;">#include <string></code></div>
<div>
<code style="font-size: 14px;"><br />
</code></div>
</div>
<div style="text-align: justify;">
Not necessarily outrageous. However, all of this was included because of a couple of functions. Not only that, but because the implementation was in the header, some helper functions had to be declared in the header, too, thus leaking implementation details.<br />
<br />
Now, applying our new-fangled design, here's what we get.<br />
<br />
<h4>
Header (win_console_out.h)</h4>
Contains just the declaration for the functions.<br />
<code style="font-size: 14px;"><br />
template <typename CharT><br />
std::string ConvertOutput(CharT const* s);<br />
<br />
template <typename CharT><br />
std::string ConvertOutput(std::basic_string<CharT> const& s);<br />
<br />
template <typename CharT = DefaultCharT, typename T = void><br />
std::string ConvertOutput(T const& t);<br />
</code><br />
Because the only <code style="font-size: 14px;">#include</code> we need is <code style="font-size: 14px;"><string></code>, everything else has been removed from the header.<br />
<br />
<div>
<h4>
Source (win_console_out.cpp)</h4>
Just as before, contains the non-template helper functions. These are not part of the interface, and were removed from the header.<br />
<br /></div>
<div>
<h4>
Implementation (win_console_out.ipp)</h4>
<div>
Most of the previous content of the header ended up here - all the <code style="font-size: 14px;">#includes</code>, the declarations for the helper functions, and the template functions definitions.<br />
<br /></div>
</div>
<div>
<h4>
Explicit instantiation</h4>
Finally, each user of this code will supply its own explicit instantiation. In this case, you can see <a href="https://github.com/PauloCaetano/bluesy/blob/master/examples/win_console_out_inst.cpp" target="_blank">here</a> what we're defining:<br />
<code style="font-size: 14px;"><br />
template std::string ConvertOutput(char const* s);<br />
template std::string ConvertOutput(</code><br />
<code style="font-size: 14px;"> std::basic_string<char> const& s);<br />
template std::string ConvertOutput(wchar_t const* s);<br />
template std::string ConvertOutput(</code><br />
<code style="font-size: 14px;"> std::basic_string<wchar_t> const& s);<br />
</code><br />
And that's it. I'll use my extensive (hah!) body of published code as a test for this design. If it works, I plan to keep using it, in order to reveal its ugly warts.</div>
<div>
<br />
I've also created the mechanism for reverting to full inclusion via <code style="font-size: 14px;">#define</code>d variables, either globally or on a header-by-header basis. As I usually say, I believe users should have the right to choose, and I strive to keep to that principle.</div>
<br /></div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-14372941412764164962016-02-14T00:06:00.000+00:002016-02-14T00:08:45.892+00:00Explicit template instantiation as an organization tool<div style="text-align: justify;">
When you create a class template, the easiest way to organize your source code is to splat everything in a header file and be done with it. Users of your class just <code style="font-size: 14;">#include</code> your header, and Bob's an annoying (in an endearing way) relative you get to see once a year.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Of course, the easiest way has a couple of drawbacks.<br />
<ol>
<li>Your header's code will get compiled for each translation unit (TU) that <code style="font-size: 14px;">#include</code>s it, even for similar types, i.e., if it has already been compiled before. During linking, all those equal copies (instantiations for the same types) will be discarded.</li>
<li>Since your header contains the implementation, it's chock-full of... implementation details. Among other things, this means it probably <code style="font-size: 14px;">#include</code>s other headers. See #1.</li>
</ol>
This means your compilation time for class templates will put on some weight. Wouldn't it be nice if we could put it on a diet?<br />
<br />
I've been taking a shot a this issue for the last few days, with the following goals:<br />
<ul>
<li>The header should contain only declarations.</li>
<li>The implementation should go on a separate file.</li>
<li>The class template user should have as little work, and as many options available, as possible.</li>
</ul>
So, we'll begin with the header file. This file contains the class template declaration, and this is the file that will be <code style="font-size: 14px;">#include</code>d by all the code that uses our class template.<br />
<br />
<b>Note:</b> I'm leaving out the include guards, but they're necessary, same as in any other header.<br />
<br />
<code style="font-size: 14px;"><b><i>listener.h</i></b><br />
template <typename T><br />
class Listener<br />
{<br />
public:<br />
Listener();<br />
~Listener();<br />
private:<br />
T i;<br />
};</code><br />
<br />
We place the implementation in another file.<br />
<br />
<code style="font-size: 14px;"> <b><i> listener.ipp</i></b><br />
#include "listener.h"<br />
#include <iostream></code><br />
<code style="font-size: 14px;"><span style="font-size: 14px;">#include <string></span></code><br />
<code style="font-size: 14px;"><span style="font-size: 14px;"><br />
</span></code> <span style="font-family: monospace;"><span style="font-size: 14px;">void print(std::string s)</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;">{</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;"> std::cout << s << '\n';</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;">}</span></span><br />
<div>
<br /></div>
<code style="font-size: 14px;"><span style="font-size: 14px;"> template <typename T></span><br />
<span style="font-size: 14px;"> Listener<T>::Listener()</span><br />
<span style="font-size: 14px;"> {</span><br />
<span style="font-size: 14px;"> print("Listener:ctor");</span><br />
<span style="font-size: 14px;"> }</span><br />
<br />
<span style="font-size: 14px;"> template <typename T></span><br />
<span style="font-size: 14px;"> Listener<T>::~Listener()</span><br />
<span style="font-size: 14px;"> {</span><br />
<span style="font-size: 14px;"> print("Listener:dtor");</span><br />
<span style="font-size: 14px;"> }</span></code><br />
<br />
Note we don't have to <span style="font-family: monospace; font-size: 14px;">#include <iostream></span> or <span style="font-family: monospace; font-size: 14px;"><string></span> in the header.<br />
<br />
However, if we tried to build our program like this, it would fail, because the TU containing the header would not see the implementation. Which means we'll get missing symbols at link-time.<br />
<br />
So, here we get to the first task for the class template user - creating an artificial TU to generate the code he needs.<br />
<code style="font-size: 14px;"><br />
<b><i> listener_session.cpp</i></b><br />
#include "listener.ipp"<br />
#include "session.h"<br />
<br />
template class Listener<Session>;</code><br />
<br />
This explicit instantiation of the class template will generate all the template's members, which will allow the linker to find them and resolve the undefined references to those symbols.<br />
<br />
Simple, heh?<br />
<br />
Well, keeping the template declaration and definition in separate files is all fine and dandy, but if it were that simple, everyone would be doing it. There is a trade-off, and, as is usually the case, 80% of the time it’s probably not necessary; in fact, I suspect the old 80/20 rule may even be more skewed in this case.<br />
<br />
Which begs the question – why am I spending time with this? Because that’s how I learn.<br />
<br />
So, what’s the trade-off here? In order for this to work you must create explicit instantiations for all the types you will be using. So, instead of just <code style="font-size: 14px;">#include</code>-ing the header and defining your <code style="font-size: 14px;">Listener<Whatever></code> variables, your project must have one or more TUs that <code style="font-size: 14px;">#include</code> both the header and the implementation and then contain explicit instantiations for the types you’ll be using, just as shown with <i>listener_session.cpp</i>, above.<br />
<br />
And this means the projects that stand to benefit more from this practice are the ones where it requires the most work, namely, large projects.<br />
<br />
The class template author can’t predict all the types that will parametrize the template, so he can’t supply the explicit instantiations (although sometimes he does, more about that in a minute). So, this means it’s up to the class template user to create the TUs with the required explicit instantiations. I happen to think the trade-off is worth it, but I’ve never been involved in a huge C++ project, so I could be wrong.<br />
<br />
Has it been a minute, already? OK, let’s go to the case where the class template author organizes his code like this and supplies the explicit instantiations – when he wants to limit the types available to instantiate the template. By doing this, and withholding the source code, the class author guarantees that users of his template can’t instantiate it with any type other than those supplied.<br />
<div>
<br /></div>
So, we get the first two goals, but so far the third goal doesn't look good. There's not much we can do, within the language, to reduce the work required from our user. But we can give him more options.<br />
<br />
Suppose our user doesn't actually care about all this. Maybe he's just developing a <i>hello_template_world</i>, or he loves coffee, and doesn't mind a 10 min. coffee-break every 30 mins.<br />
<br />
In that case, we have several options.<br />
<br />
<b>Just include the .ipp file.</b><br />
That's it, nothing more needs to be done.<br />
<br />
<b>Create a header the includes the .ipp file.</b><br />
This allows the author some liberty with the naming of the .ipp file, if necessary. Other than that, it's just the same as including the .ipp file.<br />
<br />
Quite simple, heh?<br />
<br />
Yes, indeed. And quite wrong, too. We won't have much problem with the class template members, but that <span style="font-family: monospace; font-size: 14px;">void print(std::string s)</span> will send us straight into duplicate-symbol-land (BTW, this is actually the only reason why it exists).<br />
<br />
So, how can we go about it? There's a simple solution (really), and it doesn't require that much extra work.<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: justify; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
</div>
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin: 0px; orphans: auto; text-align: justify; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<code style="font-size: 14px;"><b><i>listener.h</i></b><br />
template <typename T><br />
class Listener<br />
{<br />
public:<br />
Listener();<br />
~Listener();<br />
private:<br />
T i;<br />
};</code></div>
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin: 0px; orphans: auto; text-align: justify; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<code style="font-size: 14px;"><br />
</code></div>
<span style="font-family: monospace;"><span style="font-size: 14px;">#if defined(LISTENER_FULL_HEADER) || defined(ALL_FULL_HEADER)</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;">#define LISTENER_INLINE inline</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;">#include "listener.ipp"</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;">#else</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;">#define LISTENER_INLINE</span></span><br />
<span style="font-size: 14px;"><code style="font-size: 14px;"></code></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;">#endif</span></span><br />
<br />
We give our users two options, they can either <span style="font-family: monospace; font-size: 14px;">#define</span> <span style="font-family: monospace; font-size: 14px;">LISTENER_FULL_HEADER</span>, which will only apply full inclusion to this class template; or they can <span style="font-family: monospace; font-size: 14px;">#define</span> <span style="font-family: monospace; font-size: 14px;">ALL_FULL_HEADER</span>, which will apply full inclusion to every class template.<br />
<br />
And our implementation becomes this:<br />
<br />
<code style="font-size: 14px;"><b><i>listener.ipp</i></b><br />
#include "listener.h"<br />
#include <iostream></code><br />
<code style="font-size: 14px;"><span style="font-size: 14px;">#include <string></span></code><br />
<code style="font-size: 14px;"><span style="font-size: 14px;"><br />
</span></code> <code style="font-size: 14px;">LISTENER_INLINE</code><br />
<span style="font-family: monospace;"><span style="font-size: 14px;">void print(std::string s)</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;">{</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;"> std::cout << s << '\n';</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;">}</span></span><br />
<div>
<br /></div>
<code style="font-size: 14px;"><span style="font-size: 14px;">template <typename T></span></code><br />
<code style="font-size: 14px;"><span style="font-size: 14px;">LISTENER_INLINE</span><br />
<span style="font-size: 14px;">Listener<T>::Listener()</span><br />
<span style="font-size: 14px;">{</span><br />
<span style="font-size: 14px;"> print("Listener:ctor");</span><br />
<span style="font-size: 14px;">}</span><br />
<br />
<span style="font-size: 14px;">template <typename T></span></code><br />
<code style="font-size: 14px;"><span style="font-size: 14px;">LISTENER_INLINE</span><br />
<span style="font-size: 14px;">Listener<T>::~Listener()</span><br />
<span style="font-size: 14px;">{</span><br />
<span style="font-size: 14px;"> print("Listener:dtor");</span><br />
<span style="font-size: 14px;">}</span></code><br />
<code style="font-size: 14px;"><span style="font-size: 14px;"><br />
</span></code> <code style="font-size: 14px;"><span style="font-size: 14px;">#undef LISTENER_INLINE</span></code><br />
<div>
<code style="font-size: 14px;"><span style="font-size: 14px;"><br />
</span></code></div>
The <span style="font-family: monospace; font-size: 14px;">#undef</span> at the end is just for preprocessor hygiene.<br />
<br />
How do we know this actually works as advertised? Here’s what we get when we build the program with each option. The code was built with VS 2015, and we used <code style="font-size: 14px;">dumpbin /symbols</code> on the resulting .obj files.<br />
<br />
The results are edited, to fit on a single line.<br />
<div>
<br />
Full inclusion gives us this:<br />
<br />
<i>ear.obj</i><br />
<code style="font-size: 14px;">1B0 SECT65 notype External Listener?3?5dtor?6?$AA@<br />
1B4 SECT66 notype External Listener?3?5ctor?6?$AA@</code><br />
<i><br />
</i> <i>main.obj</i><br />
<code style="font-size: 14px;">1C9 SECT6B notype External Listener?3?5dtor?6?$AA@<br />
1CD SECT6C notype External Listener?3?5ctor?6?$AA@</code><br />
<br />
The symbols are defined on the two object files, one of these will be dropped when linking.<br />
<br />
Separate implementation gives us this:<br />
<br />
<i>ear.obj</i><br />
<code style="font-size: 12px;">020 UNDEF notype () External Listener<Session>::Listener<Session>(void))<br />
021 UNDEF notype () External Listener<Session>::~Listener<Session>(void))</code><br />
<i><br /></i>
<i>main.obj</i><br />
<code style="font-size: 12px;">075 UNDEF notype () External Listener<Session>::Listener<Session>(void))<br />
076 UNDEF notype () External Listener<Session>::~Listener<Session>(void))</code><br />
<i><br /></i>
<i>listener_instant.obj</i><br />
<code style="font-size: 14px;">199 SECT60 notype External Listener?3?5dtor?6?$AA@<br />
19D SECT61 notype External Listener?3?5ctor?6?$AA@</code><br />
<br />
We get the undefined symbols on ear.obj and main.obj, which will be resolved during linking.<br />
<br />
So far, so good. Now, time to move this out of Proof-of-Concept-Land.<br />
<br /></div>
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-71835367923732141132016-02-08T12:30:00.000+00:002016-02-08T12:30:09.032+00:00This behavior is by design<div style="text-align: justify;">
Visual customization (or personalization, or whatever else you want to call the ability to configure software to suit your specific needs) is a big thing for me. Especially for software that I use for long periods of time. And, for this kind of software, there's nothing more important than changing the color scheme. Sure, changing the font can be nice, changing the font size is definitely important, but changing the color scheme is, as far as I'm concerned, essential.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For me, there's nothing worse than staring at a glaring white background for hours. I've got nothing against all you <i>0xFFFFFF</i> lovers out there, it's just not my thing.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
These last few days, I've been comparing several visual customization alternatives, from the user's point of view. Why from the user's point of view? Because I consider that to be the most important point of view, we create software for users.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Also, when selecting the criteria for classification, there was one aspect that out-weighted the others by several orders of magnitude: Time. It's not just about changing the look of software, but doing it quickly.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As a final note, when I talk about visual customization, I mean the ability to change just about every visual aspect of the interface. There is a name for software that has a "customization" option that only allows you to change the color of the title bar or the toolbar, but I won't say it here, there may be children reading this (I hear it's great for insomnia).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So, here's the final result, from best to worst:</div>
<div style="text-align: justify;">
<br /></div>
<h4 style="text-align: justify;">
1. The software provides official alternatives to the default look</h4>
<div style="text-align: justify;">
"Official" here means "created or curated by the software developer", and easily accessible/installable via some sort of manager that takes care of download/installation. To qualify, these alternatives must be diverse (not just variations on glaring white) and must actually work (e.g., no blue text on a black background - yes, Linux shell, I'm looking at you).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Oh, and "curated" means someone actually looked at the whole thing and confirmed that we're not getting the blue-on-black stroke of genius. Being free of bugs/exploits/nasty surprises is a must, but it's not enough.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For software that makes this grade, I don't really care that much about how difficult it may be to change individual aspects of the provided looks/themes/whatever, because we have a coherent whole that works.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Out of the software I use, the winners are Visual Studio and Qt Creator. Congratulations to these teams, top quality work. Android Studio follows right behind, and the only reason it's not up there with those two is because does have some hard-to-read combinations, where the text and background colors are very similar.</div>
<div style="text-align: justify;">
<br /></div>
<h4 style="text-align: justify;">
2. The software is easy to configure</h4>
<div style="text-align: justify;">
Since we're not guaranteed to have a coherent alternative here, it must be easy to either change the whole look (e.g., via theming) or individual aspects of it.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So, here we may have software that has a "wealth of community-provided looks/themes/whatever", where trying out a theme is trivial, but changing each individual aspect is not - e.g., Chrome/Firefox extensions.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And we also have software that may or may not have all that wealth, but has a trivial way of either changing the whole look or individual aspects of it - e.g., Notepad++ or gedit.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Changing individual aspects may not give the user a complete coherent workspace, but it will provide a good starting point and, since it's easy to configure, it will allow the user to quickly solve problems as they appear. Again, a very time-efficient solution. Not as good as #1, but a positive experience, all things considered.</div>
<div style="text-align: justify;">
<br /></div>
<h4 style="text-align: justify;">
3. The software is not easy to configure</h4>
<div style="text-align: justify;">
Here, it's irrelevant if we're talking about the whole look or individual aspects of it.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This is the software that expects the user to manually download some sort of file (usually, an archive file), copy it to some directory and expand it; or to copy some existing files from a system-protected directory to a user directory and then edit those, looking for some more-or-less cryptic configuration key and changing some usually-even-more-or-less cryptic value; and then, maybe, having to restart the software. Bonus (negative) points if it's a system-wide configuration, where "restart" actually means "reboot".</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Most Linux desktops I've tried fall in this category. In order to change a simple visual aspect, if you can't find a recipe for changing the exact item you want, you're in for a good reading of Gtk, or Qt, or some-other-widget-toolkit docs (assuming what you want is properly documented), followed by some file copying, key-searching, and value tweaking. And, since what you'll get will usually be a good starting point, you'll have the enormous pleasure of repeating the process as further problems appear.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Oh, and if you do find the recipe you're looking for, check its date, and make sure the toolkit/software version match yours.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Here, I usually do just enough work to splash a dark background on the software I use the most and ignore everything else. I definitely don't want to waste more time than absolutely necessary.</div>
<div style="text-align: justify;">
<br /></div>
<h4 style="text-align: justify;">
4. The abomination</h4>
<div style="text-align: justify;">
This is a special category. You may have already got that impression from the heading, but it's also special in that it has only one entry: Windows Aero.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let's make this clear - I often look at design options and think "This is incredibly stupid, but maybe there is some logic that I'm missing here". As the man sang, "I'm not the sharpest tool in the shed", so there's definitely room for error on my part. However, when we get to Windows Aero, I can't get past the comma in that sentence. I've considered it several times, and I can see no logic here.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let's look at the symptoms:</div>
<div style="text-align: justify;">
</div>
<ul>
<li style="text-align: justify;">Countless posts asking what should be a very simple question, "How do I change the background color for Windows Explorer?", and getting one of two answers: Either "Switch from Aero to Basic/Classic/Anything-Else-That's-Not-Aero" or "Why would you want to do that, there's plenty of people that use white and love it". Both these answers actually mean "You can't".</li>
</ul>
<br />
<div style="text-align: justify;">
</div>
<ul>
<li style="text-align: justify;">Of course, that's not entirely true. You can. You just have to reverse-engineer the binary format that stores the color configuration (basically it's a DLL containing resources). Or pay for a utility created by someone who went through that effort; then, you'll still have to create your "visual style", and you'll still have to patch Windows to allow you to use your non-signed "visual style".</li>
</ul>
<br />
<div style="text-align: justify;">
</div>
<ul>
<li style="text-align: justify;">Yes, you read that correctly. Binary format? Check! DLL? Check! Patch Windows? Check! Options such as the background color for applications are stored (although "buried", "concealed", or even "encrypted" would be more suited here) in an undocumented binary format, in a DLL, stored in a protected system folder.</li>
</ul>
<br />
<div style="text-align: justify;">
This is the only example I've found where your best option is to actually pay for a third-party application to do something as simple as changing a background color. BTW, this is also why you find successful commercial alternatives to Windows Explorer. It's not just the extra functionality these alternatives have (and they do add value to their offerings), it's also this brain-dead design by the Aero team, that means that something as simple as "the ability to change the background color" is a value point.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Here, I don't even waste my time. I'm just grateful that whoever designed Windows Aero didn't get to unleash its remarkable genius anywhere near Visual Studio.</div>
<div style="text-align: justify;">
<br /></div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-41858628325966323722016-01-06T18:39:00.001+00:002016-01-06T18:39:24.653+00:00Logging Abstraction Layer - Take 2<div style="text-align: justify;">
As I did on the previous post, I'll begin by saying I won't go into another "My, how long it has been" post. I do, however, hope I'm not too late to express my Best Wishes for 2016.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now, then...</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I'm having another iteration on my idea for an abstraction layer for logging libraries, which is basically fancy-speak for “<a href="https://github.com/PauloCaetano/SimpleSampleTuts/tree/master/MacroLogger" target="_blank">a collection of (hopefully, organized) macros</a>” that will allow me to replace logging libraries with minimal effort.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I've been going back and forth between Boost Log and Poco Logger. I like both, even though I tend to prefer Poco Logger, because I haven't yet found a satisfactory solution for the issue with Boost Log's preference for truncating an existing log file when the application is restarted.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div>
I've hit some maintenance problems with my “collection of macros”, so I decided to give Boost Preprocessor another go. Back when I began working on this idea, I looked into Boost PP, but got caught in a blind spot, probably a faulty reaction to all the metaprogramming examples. I had the feeling I could use it, but I wasn't able to make it work.</div>
<div>
<br /></div>
<div>
<div>
So, I rolled my own and have since been banging my head against several walls, thus gaining the required experience to make a number of questions I didn't even know were there. Which gave me a different perspective when I approached Boost Preprocessor again, and things went much better this time.</div>
</div>
<div>
<br /></div>
<div>
<div>
I quickly set up a PoC, and then I hit the issue I'm looking at now – How to format the log record. This is only somewhat important for readability, but it's crucial for automation. Without a structured format, we'll have a hard time creating tools to operate on the logs.</div>
</div>
<div>
<br /></div>
</div>
<div style="text-align: justify;">
My initial design, which I haven't changed, treats the logging statement as a sequence of values to output. E.g.,</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<code style="background: #ffffff; color: black; font-size: 14px;">SOMEPREFIX_DEBUG(object_id, discount_id, “Getting object price”);</code></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
But a structured format requires other artifacts – at a minimum, we need delimiters. And an obvious requirement for some sort of intelligent automatism is that the nature of the values must be identified, i.e., we need to know if an element logged as an <i>integer</i> is, say, a <i>total</i> or an <i>ID</i>; so, we need to decorate values with names.<br />
<br />
Boost Log gives us attributes, values which are added to the log record without the need to output them explicitly on the logging statements. Furthermore, attributes can be used in filtering and formatting, and can be scoped. I suppose there may be even performance benefits in the use of attributes, but that's something I'd have to measure.<br />
<br />
At first, I thought this could be the way to go. Define attributes, create formatters or override the output operator, and control the way the record is written to file.<br />
<br />
However…<br />
<br />
Poco Logger does not have this concept. And while I'm not considering any other logging library at the moment, that may change in the future. And, as I said above, my main goal is to “replace logging libraries with minimal effort”. So, if this is my main goal, it is important enough to warrant an under-utilization of the library.<br />
<br />
Naturally, if I don't use the library's capabilities to output this data, I'll need to output it on the logging statements. This means that formatting will also have to happen there. And since I'm already using the preprocessor as an abstraction mechanism, I'll just… use it some more.<br />
<br />
So, I already have something like this:<br />
<div>
<br /></div>
</div>
<div style="text-align: justify;">
<span style="background-color: white; font-family: monospace; font-size: 14px;">SOMEPREFIX_DEBUG(object_id, discount_id, “Getting object price”);</span><br />
<br />
What I need is something along these lines (simplified):<br />
<br />
<span style="font-family: monospace;"><span style="font-size: 14px;">SOMEPREFIX_DEBUG</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;">(</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;"> SOMEPREFIX_FORMAT(“ObjectID”, object_id),</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;"> SOMEPREFIX_FORMAT(“DiscountID”, discount_id), </span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;"> “Getting object price”</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;">);</span></span><br />
<br />
Which could, then, output something like this (line breaks for readability):<br />
<br />
<span style="font-family: monospace;"><span style="font-size: 14px;">2016-01-01 00:00:00 <DEBUG> </span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;"> { "ObjectID": "42", “DiscountID”: “24” } Getting object price</span></span><br />
<br />
Then, one day, if we decided life had become too easy, we could switch formats to something like this, <b>without changing the logging statements</b>:<br />
<br />
<span style="font-family: monospace;"><span style="font-size: 14px;">2016-01-01 00:00:00 [DEBUG]</span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;"> <LogRecord><ObjectID>42</ObjectID></span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;"> <DiscountID>24</DiscountID></LogRecord></span></span><br />
<span style="font-family: monospace;"><span style="font-size: 14px;"> Getting object price</span></span><br />
<br />
So, the next step will be identifying the required formatting elements, and how to incorporate them in the logging statements. The goal here is to keep the logging statements as simple as possible.<br />
<br />
On this iteration, I will leave out any sort of container/compound data type. Not only will these make the design a lot more complex, but I'm prepared to do without them – in my experience, I have found very few scenarios requiring the logging of these types, and it has always been possible to find a workaround somewhere between acceptable and undesirable.<br />
<div>
<br /></div>
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-88038996947568225302015-10-13T22:53:00.000+01:002015-10-13T22:53:54.575+01:00Visual Studio 2015, ICU, and error LNK2005<div style="text-align: justify;">
I'll begin by saying that I'm just going to ignore the fact that I haven't written anything in nearly nine months.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So...</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
While building ICU 56.1 with VS 2015, I was greeted with thousands of errors like this (also described <a href="http://sourceforge.net/p/icu/mailman/message/34306942/" target="_blank">here</a> by someone who came across the same problem):</div>
<div style="text-align: justify;">
<br /></div>
<blockquote class="tr_bq">
<div style="text-align: justify;">
error LNK2005: "public: static bool const</div>
<div style="text-align: justify;">
std::numeric_limits<unsigned short>::is_signed"</div>
<div style="text-align: justify;">
(?is_signed@?$numeric_limits@...@std@@2_NB) already defined in</div>
<div style="text-align: justify;">
ParagraphLayout.obj</div>
</blockquote>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This is defined in <code style="background: #ffffff; color: black; font-size: 14px;"><limits></code>, in a statement like this:</div>
<div style="text-align: justify;">
<br /></div>
<blockquote class="tr_bq" style="text-align: justify;">
_STCONS(bool, is_signed, false);</blockquote>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Looking at the pre-processor output, we can see its actual definition:</div>
<div style="text-align: justify;">
<br /></div>
<blockquote class="tr_bq" style="text-align: justify;">
static constexpr bool is_signed = (bool)(false);</blockquote>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If I understood the Standard correctly, this should be OK, and there should be no duplicate symbols during linking. So, I was still missing a logical cause for this.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The usual internet search for «<i>ICU LNK2005</i>» didn't bring anything useful, except for the link above.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Then, as I concentrated my search on LNK2005, I came across <a href="http://stackoverflow.com/questions/31808256/multi-file-iostream-error-lnk2005-in-vs2015-with-za" target="_blank">this post</a>. The same mysterious behaviour, but now there was a plausible explanation, in a comment by MS's Stephan T. Lavavej, in a <a href="http://blogs.msdn.com/b/vcblog/archive/2015/07/14/stl-fixes-in-vs-2015-part-2.aspx" target="_blank">quoted post</a> from an MSDN blog:</div>
<div style="text-align: justify;">
<br /></div>
<blockquote class="tr_bq" style="text-align: justify;">
We recommend against using /Za, which is best thought of as "enable extra conformance and extra compiler bugs", because it activates rarely-used and rarely-tested codepaths. I stopped testing the STL with /Za years ago, when it broke perfectly conformant code like vector<unique_ptr<T>>. </blockquote>
<blockquote class="tr_bq" style="text-align: justify;">
That compiler bug was later fixed, but I haven't found the time to go re-enable that /Za test coverage. Implementing missing features and fixing bugs affecting all users has been higher priority than supporting this discouraged and rarely-used compiler option.</blockquote>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So, after removing /Za from all projects in ICU's <i>allinone</i> VS Solution (Project Properties -> Configuration Properties -> C/C++ -> Language -> Disable Language Exceptions -> No), I was able to build it with no errors, on all configurations (x86/x64, debug/release).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Apparently, it's one of those rare cases where the error is actually in the compiler, not in the code.</div>
<div style="text-align: justify;">
<br /></div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com4tag:blogger.com,1999:blog-1647814752446097280.post-71754742430261361402015-01-31T19:02:00.001+00:002015-01-31T19:02:18.629+00:00CA Certificates - The tale of the invisible certificate<div style="text-align: justify;">
I've been through a memory upgrade on my 5-year old PC. My goal is to set up a few VMs running simultaneously, because I need to widen my scope for experimentation. I found out my BIOS has an incompatibility with the memory DIMMs currently available, but fortunately a friend lent me 8GB, so I can start working now, while I try to sort out this mess.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As I set up each VM, I'm importing my bookmarks, so that I have my net environment available "everywhere". And I've come across a curious situation, regarding certificates.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
One of the URLs I have on my bookmarks is https://www.ddo.com/forums. The first time I accessed it on Firefox, I got an error message:</div>
<blockquote class="tr_bq" style="text-align: justify;">
Peer's certificate has an invalid signature. (Error code: sec_error_bad_signature)</blockquote>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Using <code style="background: #ffffff; color: black; font-size: 14px;">openssl s_client</code>, I checked that ddo.com sends only its own certificate, not the chain, so I looked up the chain in IE, and checked the intermediate CA on Firefox's certificate store. It was there, but it was a different certificate - different signature, different validity (both valid, because the validities on both certificates overlapped), different issuer, only the subject was the same.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I exported that CA certificate from IE, and ran <code style="background: #ffffff; color: black; font-size: 14px;">openssl verify</code> using each CA certificate; using the one from Firefox certificate store, I got an error; using the site's CA certificate, the validation succeeded.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So, I imported the site's CA certificate to Firefox, accessed the site, and all was well again.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Then, I checked Firefox's certificate store. And I only found the exact same certificate that was there already, and which wasn't previously validating ddo.com's certificate. Except that now it was.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And much scratching of head ensued.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Until yesterday, when discussing this at lunch with a friend, he told me the obvious: "Well, if you imported it, and the site's certificate is now correctly validated, then it must be there, even if you can't see it". And that gave me a memory jolt, to an issue I had a little more a year ago, with Sun One's web server certificate store, where we had two certificates for the same CA, but only one was visible on the web console. In order to correctly see both, I had to use <code style="background: #ffffff; color: black; font-size: 14px;">certutil</code> on the command line.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And in this case, the solutions was the same:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<code style="background: #ffffff; color: black; font-size: 14px;">certutil -L -d sql:<i>path to Firefox profile directory</i> -n <i>certificate subject</i></code></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Which promptly listed the two certificates.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And another Mystery of the Universe was solved during a meal.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I don't understand why the GUI shows just one certificate. I'm not going to say it's stupid because it may be a reasonable decision, based on knowledge I don't have. But to completely hide the fact that a CA has two simultaneously valid certificates on the store is terribly misleading, it's definitely not what I'd call a good solution.</div>
<div style="text-align: justify;">
<br />
In the end, it was command line to the rescue... as usual.</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-42471510928028908512015-01-10T12:44:00.001+00:002015-01-10T12:44:12.572+00:00Visual Studio - Getting to your debugging symbols<div style="text-align: justify;">
I've recently been reformulating my lib environment. Basically, it consists of:</div>
<div style="text-align: justify;">
</div>
<ul>
<li style="text-align: justify;">A loading zone, where I install the library sources, and run the build process. It has a folder for each lib, with each version in its own sub-folder.</li>
<li style="text-align: justify;">A library root folder, with sub-roots for mingw and MSVC, where I store the files resulting from the builds. Again, each lib folder has a sub-folder for each installed version.</li>
</ul>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
There's a bit more to it, but it's not important for today's post.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This reformulation has gone through several iterations, and it's still a work in progress. This time, I had the following goals:</div>
<div style="text-align: justify;">
</div>
<ul>
<li style="text-align: justify;"><b>G1</b> Getting some further progress on automating the process of building libraries from source, both release and debug versions. Actually, it was this requirement for debug versions of all the libs that led to my patch to OpenSSL with a <a href="http://cidebycide.blogspot.pt/2015/01/openssl-debug-build-configuration-for.html" target="_blank">debug configuration for mingw32</a>.</li>
<li style="text-align: justify;"><b>G2</b> Correcting some bad decisions regarding the lib folders' names, especially when it comes to version numbers. The goal is to use the same number format each lib uses for its own files, where applicable.</li>
<li style="text-align: justify;"><b>G3</b> Clearing the landing zone after building the libs. Now, when I finish building, I run <code style="background: #ffffff; color: black; font-size: 14px;">make</code> (actually, <code style="background: #ffffff; color: black; font-size: 14px;">mingw32-make</code> or <code style="background: #ffffff; color: black; font-size: 14px;">nmake</code>) <code style="background: #ffffff; color: black; font-size: 14px;">clean</code>.</li>
</ul>
<div style="text-align: justify;">
<br />
Point G3 led me on another learning experience.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The most common debug option when using MSVC seems to be <code style="background: #ffffff; color: black; font-size: 14px;">/Zi</code>, which stores the debug symbols in PDB files. As such, I haven't looked into the other options, which store debugging information in the object files themselves; I won't discuss them in this post, but if I had to hazard a guess, I'd say the behaviour is the same as the one described below.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
During a debug build, the compiler/linker stores the absolute path to the PDB file on the executable files (EXE or DLL). When you fire up the debugger, as it loads these executable files, it looks up the PDB using this path, to load the symbols. If it can't find the PDB, it then goes through <a href="http://msdn.microsoft.com/en-us/library/ms241613.aspx" target="_blank">other steps</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
On the open-source projects I've seen, I've come across two default behaviours - either the PDB files are not copied to the library folder at all (e.g., Boost); or they're copied to the folder containing the static libraries/import libraries, but not the DLLs themselves (e.g., ICU). I call these <i>default behaviours</i>, because there may be options for gettting a different behaviour; I've looked for these, but found none.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This, combined with point G3 above, is not-so-good news, because <code style="background: #ffffff; color: black; font-size: 14px;">make clean</code> deletes the PDB files. So, when we fire up the debugger, it cannot find the symbols for these DLLs. It never happened before because my procedure has always been:<br />
<ul>
<li>build release.</li>
<li>clean up.</li>
<li>build debug.</li>
<li>don't clean up.</li>
</ul>
</div>
<div style="text-align: justify;">
<br />
So, the PDBs were always available at the landing zone, i.e., the path stored on the executables. And even though some libs copied them to the lib folders, these weren't actually used when the DLLs were loaded by the debugger.<br />
<br />
There are several options for dealing with this, including these three:<br />
<ul>
<li><b>O1</b> Setting up a local symbol server, which, as I understand it, is more of a local cache to store symbol files.</li>
<li><b>O2</b> Adding each individual folder where PDB files are installed to the _NT_SYMBOL_PATH env variable, which MS debuggers use to locate symbol files.</li>
<li><b>O3</b> Manually copying the PDB files to the DLLs folders.</li>
</ul>
<br />
I believe option O1 is the best, but I'll leave it for another iteration. For now, I'll go with option O3. Like I said, this is a work in progress, and I don't feel a particular pressure to go for the optimal solution (which I'll have to test before I adopt it), I prefer getting to a working solution faster, in order to keep my self-imposed deadline (which will end this weekend).<br />
<br />
Of course, once you have all this worked out, you still need your debugger to load the correct DLLs. You may have other versions of those DLLs on your path; with popular libraries, like OpenSSL, this is more common than you may think.<br />
<br />
On Qt Creator, assuring that you load the correct DLLs is very simple. On <i>Projects </i>mode (Ctrl + 5), you switch to the <i>Run</i> configuration and edit the PATH on the <i>Run Environment</i>. Since I don't have these libraries on the PATH, I always need to do this; if you usually have your debug libraries on the PATH, you don't need to edit anything.<br />
<br />
Visual Studio is a different sort of creature. A <b>larger</b> sort of creature, where everything usually takes a bit more work to find.<br />
<br />
I knew it was on <i>Project Properties</i> (Alt + F7). At first, I thought it was on <i>Configuration Properties -> VC++ Directories -> Executable Directories</i>. When I hit help, it took me <a href="http://msdn.microsoft.com/en-us/library/Ee855621(v=vs.120).aspx" target="_blank">here</a>, where we can read: "Directories in which to search for executable files. <b>Corresponds to the PATH environment variable</b>". Fine, that's just what we need. Somewhat later, and after a moderate amount of gnashing of the dental (not mental, mind you) persuasion, I noticed that the description on the project Property Pages was a wee-bit more complete, namely "Directories in which to search for executable files <b>while building a VC++ project</b>". Ah... right... building the project... as in, "not <b>running the executable</b>".<br />
<br />
Then, I turned to the next obvious choice, <i>Configuration Properties -> Debugging -> Environment</i>. This time, I read the description before going for the help button. It is quite helpful, it says "Specifies the environment for the debugee, or variables to merge with existing environment". After reading this, I knew exactly what to do. Which was hitting the help button, and hoping the <a href="http://msdn.microsoft.com/query/dev12.query?appId=Dev12IDEF1&l=EN-US&k=k(VC.Project.IVCLocalDebugPageObject.Environment)&rd=true" target="_blank">help page</a> for this option was more useful.<br />
<br />
Fortunately, it was. We control the PATH here, using something like this: <code style="background: #ffffff; color: black; font-size: 14px;">PATH=E:\Dev\lib\msvc\openssl\openssl1_0_1j\debug\bin;E:\Dev\lib\msvc\icu\icu54_1\debug\bin;%PATH%</code>.<br />
<br />
And, finally, after some gnashing of the <b>mental</b> persuasion, I can say that Visual Studio's debugger and me are finally getting along just fine.<br />
<br />
As they say, until next time... when I turn this into reusable project configurations, instead of having to specify these manually on every project.<br />
<br /></div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-70459249328375228152015-01-08T23:04:00.000+00:002015-01-08T23:04:07.067+00:00OpenSSL - Debug build configuration for mingw32<div style="text-align: justify;">
I've just submitted a patch to OpenSSL, to include a debug build configuration for mingw32, as it currently lacks one.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Not only have I done the obvious - removed optimizations and add the <code style="background: #ffffff; color: black; font-size: 14px;">-g</code> compiler option, but I've also used <code style="background: #ffffff; color: black; font-size: 14px;">debug-Cygwin</code> as a starting point to include a set of debug <code style="background: #ffffff; color: black; font-size: 14px;">#define</code>s for OpenSSL. You can find the patch <a href="https://github.com/PauloCaetano/patches" target="_blank">here</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
At first, I sent it to the openssl-dev mailing list. Later, I find out there was already an issue open for this on <a href="http://rt.openssl.org/Ticket/Display.html?id=2330&user=guest&pass=guest" target="_blank">OpenSSL's RT</a>.<br />
<br />
Anyway, the patch makes the changes below.<br />
<br />
<h4>
config</h4>
This is the script called from the command line for configuration, which will generate the makefile.<br />
<br />
The patch adds <code style="background: #ffffff; color: black; font-size: 14px;">MSYS*</code> to the script's platform guessing mechanism, allowing us to build on MSYS2. It wasn't really necessary for the debug configuration, but I like to have the ability to build on MSYS2.<br />
<div>
<br />
<h4>
Configure</h4>
<code style="background: #ffffff; color: black; font-size: 14px;">Configure</code> is a perl script that is called by <code style="background: #ffffff; color: black; font-size: 14px;">config</code>.<br />
<br />
The patch adds the mingw32 debug configuration (<code style="background: #ffffff; color: black; font-size: 14px;">debug-mingw</code>), and changes the part of the script that defines the executable extension, to look for <code style="background: #ffffff; color: black; font-size: 14px;">/mingw/</code> instead of <code style="background: #ffffff; color: black; font-size: 14px;">/^mingw/</code>, which then makes it work correctly with both mingw configurations.<br />
<br />
As a side note, I think it would have been better to name the debug configurations as <<i>platform-debug</i>>, rather than <<i>debug-platform</i>>, but I don't know the reasons behind this, so I might be wrong.<br />
<div>
<br />
<h4>
Makefile.org</h4>
This file is a base for the final makefile.<br />
<br />
The patch changes platform checks from <code style="background: #ffffff; color: black; font-size: 14px;">mingw</code> and <code style="background: #ffffff; color: black; font-size: 14px;">mingw*</code> to <code style="background: #ffffff; color: black; font-size: 14px;">.*mingw</code> and <code style="background: #ffffff; color: black; font-size: 14px;">*mingw*</code>. Curious, now that I'm writing this, it's the first time I've noticed the incoherence. I'll probably go back to the testing board and change that to <code style="background: #ffffff; color: black; font-size: 14px;">*ming*</code> on both.<br />
<br />
<h4>
Makefile.shared</h4>
This file is used when we're building shared libraries (DLLs on mingw).<br />
<br />
This is where I was more bold with the changes. The original file was always passing <code style="background: #ffffff; color: black; font-size: 14px;">-Wl,-s</code> to the linker, meaning it would clear the symbols from the object files. However, on a debug build we want to keep the symbols, that's the main reason for wanting a debug build in the first place.<br />
<br />
So, the patch not only adds a check for <code style="background: #ffffff; color: black; font-size: 14px;">.*mingw</code> instead of <code style="background: #ffffff; color: black; font-size: 14px;">mingw</code>, it also changes the linker arguments for the debug configuration, excluding the <code style="background: #ffffff; color: black; font-size: 14px;">-s</code>.<br />
<div>
<br /></div>
And that's it. Not that much work, but a lot of experimenting. And, since shell script and <i>make </i>are not the most user-friendly debugging experiences, it has required a lot of creative experimenting.<br />
<br />
Hope someone finds it useful.<br />
<div>
<br /></div>
</div>
</div>
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-89964296369856926952014-12-27T13:10:00.001+00:002014-12-27T13:10:51.228+00:00'Tis the Season...<div abp="236" style="text-align: justify;">
... to be jolly, and grateful, and hopeful.</div>
<div abp="237" style="text-align: justify;">
</div>
<h4 abp="238" style="text-align: justify;">
On the personal front...</h4>
<div abp="239" style="text-align: justify;">
...this year has been very positive, the only clouds on the horizon being some health issues. If I had to choose the most important points of 2014, I'd go with these:<div abp="240">
</div>
<ul abp="241">
<li abp="242"><div abp="243" style="text-align: justify;">
The level of complicity and understanding between me and my wife has increased tremendously. I believe we achieved this by undergoing a similar change, which takes us right to the next point...</div>
</li>
<li abp="244">We both began going at life with a more relaxed attitude. It's a daily exercise to keep from slipping, but it's quite worth it. Obviously, it occasionally slips, but not only have we gotten better at identifying these slips, both on ourselves and on each other, we are also quicker to defuse these situations, often by sharing a good laugh at ourselves.</li>
</ul>
<div abp="245">
The kids are working their way through college, on what are the first steps of their own journey, their own adventure. It's time they take full control of the pen and start writing their story; that's their part. Our part is hoping everything they've taken in through the years will serve them well in getting their bearings as they set out. More than hopeful, we're confident it will.</div>
<div abp="246">
</div>
<div abp="247">
I'm a somewhat spiritual guy, although I don't often stop to think about it. However, looking at 2014, I feel blessed; I already knew I'd found someone more understanding of my failings than I ever deserved, but this year took it to a new height. If I have so much to write about in the following point is because I was fortunate enough to find someone as understanding as my wife.</div>
<div abp="248">
</div>
<div abp="249">
If you don't care much for mildly technical stuff, you can jump straight to the end of the post.</div>
<div abp="249">
</div>
<h4 abp="249">
On the professional front...</h4>
<div abp="252" style="text-align: justify;">
...this has been a year where I continued a trend that began in mid-2013, namely, generalization.</div>
<div abp="253" style="text-align: justify;">
</div>
<div abp="254" style="text-align: justify;">
When it all began in 2011, I had picked up C#. Then, because I felt I wasn't learning anything other than the language, I've added C++. Actually, my plan was <em abp="255">adding</em> C++, but I ended up <em abp="256">switching to</em> C++, and C# was left behind. The learning experience was a lot more intense, not just about the language, but also about the whole system - processor, OS, environment, external libs, debugging, assembly, and a whole lot of etc.</div>
<div abp="254" style="text-align: justify;">
<br abp="257" />Then, I've accidentally set out on a task for which I found little help on the web. So, for much of what I was doing, I was on my own. While I did manage to get a working result (which is still a top-hitter on <a abp="259" href="https://www.google.com/?gws_rd=ssl#q=libssh2+boost+asio" target="_blank">google.com</a> and <a abp="322" href="http://www.bing.com/search?q=libssh2+boost+asio&go=Submit+Query&qs=ds&form=QBLH" target="_blank">bing.com</a>), I wasn't totally happy with it, and I suspected I'd have been even less happy if my knowledge about what I was doing wasn't so lacking. So, I've stepped back and went back to basics. And I've quickly learned that, indeed, the potential for "improvement" (i.e., correction) in what I'd done was much bigger than I had anticipated.</div>
<div abp="254" style="text-align: justify;">
</div>
<div abp="254" style="text-align: justify;">
Then, as I began taking on more technical tasks at work, the generalization began - certificates, network, DNS, managing Linux, setting up environments according to specific constraints, managing web servers, managing Weblogic server, picking up new languages (e.g., Ruby), revisiting familiar languages (e.g., Java).</div>
<div abp="254" style="text-align: justify;">
</div>
<div abp="254" style="text-align: justify;">
At the same time, I've taken the learning experience provided by C++ deeper - assembly debugging, system traces, building gcc from source and installing it without touching the system gcc, doing the same with perl. And I've also began getting my feet wet with Javascript (bootstrap and query.js) and Android development.</div>
<div abp="254" style="text-align: justify;">
</div>
<div abp="254" style="text-align: justify;">
And before I noticed, I had not only changed my course, but I was quite satisfied with that change. This is where I see myself going, becoming a generalist. I love solving problems, and you need a widespread knowledge to do it; you don't always find the cause of a problem at the same level, and I don't like getting stuck for lack of knowledge. I also don't like getting stuck for lack of system access, but that's the way things are when you work in a large-ish corporation.</div>
<div abp="254" style="text-align: justify;">
</div>
<div abp="254" style="text-align: justify;">
So, here are my New Years resolutions, a.k.a., goals for 2015:</div>
<ul abp="340">
<li abp="341"><div abp="342" style="text-align: justify;">
Redesign my libssh2 + asio components, incorporating what I've learned in the meantime. And hoping that two years from now I may look at what I've done, say "What I was thinking??!!", and repeat this goal again, as I keep learning more.</div>
</li>
<li abp="343">Pick up a functional language, probably Haskell or Erlang. It's about time I get my feet wet on functional programming. I love what I've learned about generic programming in C++ (actually, <em abp="344">what I'm still learning</em>), but it's time to add something more to the mix.</li>
<li abp="345">Continue my exposure to Javascript and Android.</li>
<li abp="346">Deepen my knowledge of systems/network administration.</li>
<li abp="347">Increase my knowledge of low-level tracing/debugging. It's time to begin some serious experiments with loading up core dumps and getting my bearings, and getting more mileage out of stuff like Windows Performance Analyzer.</li>
</ul>
<div abp="348">
Too ambitious, you say? Yes, I know. I won't manage to do all of this? Probably not. Which is a good thing, otherwise 2016 would be a very boring year.</div>
<div abp="349">
</div>
<h4 abp="350">
At the end of the day...</h4>
<div abp="435" class="separator" style="clear: both; text-align: center;">
</div>
<div abp="435" class="separator" style="clear: both; text-align: center;">
<a abp="436" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXe80rBiAAP4RYF4rbMCYiQHQa8M94EUMa3mA9Q4rLgGLnyinIdB71M0rB6mpxywFwA2Xx6raGeiKnIGD_OLD0djvw2OdacyGB-zopm2LuTU6UlNmStTtSnAoZqZuHyr8gGNO95t_mxgU/s1600/bright.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img abp="437" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXe80rBiAAP4RYF4rbMCYiQHQa8M94EUMa3mA9Q4rLgGLnyinIdB71M0rB6mpxywFwA2Xx6raGeiKnIGD_OLD0djvw2OdacyGB-zopm2LuTU6UlNmStTtSnAoZqZuHyr8gGNO95t_mxgU/s1600/bright.png" height="264" width="320" /></a></div>
<div abp="351">
</div>
<div abp="354">
...our family wishes you and your loved ones a Merry Christmas and a Happy 2015, filled with love, joy, and peace.</div>
<div abp="355">
</div>
<div abp="264" style="text-align: justify;">
</div>
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-26219509915335474492014-12-07T16:30:00.001+00:002014-12-07T16:30:15.351+00:00A simple class to read files<div abp="202" style="text-align: justify;">
Yes, I'm <em abp="203">olde</em> enough to know "simple" is a misnomer.</div>
<div abp="204" style="text-align: justify;">
</div>
<div abp="205" style="text-align: justify;">
I have a new addition to my <a abp="207" href="https://github.com/PauloCaetano/bluesy">bluesy github repo</a>.</div>
<div abp="209" style="text-align: justify;">
</div>
<div abp="210" style="text-align: justify;">
Part of what I do at work involves reading through user-un-friendly log files. How user-un-friendly? Just to give a small example, the cases where a "log record" is on a single line are the exception (I wish it was just the <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">Exception</code>s), and there's usually no easy way to correlate the beginning/end of operations with a single <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">grep</code>. This means I spend a lot of time creating scripts/small programs to process those log files.</div>
<div abp="210" style="text-align: justify;">
</div>
<div abp="210" style="text-align: justify;">
I'm not an enthusiast of shell scripting. Oh, I can persuade it to do some complex stuff, yes, but it always seems to obey me reluctantly, and I'm left with the nagging feeling that, somehow, it's laughing behind my back. Not to mention that the resulting scripts are very... spaghetti-like. I find it hard to think modularly when writing shell scripts. I had a similar issue with Perl. It's still there with Ruby, but being modular with Ruby is a lot easier for me.<br />
</div>
<div abp="210" style="text-align: justify;">
However, I don't have this difficulty with C++. Or Java, or C#, or Delphi/Lazarus, for that matter. It must be some sort of mental block, because while I couldn't create a modular design in shell scripting to save my life, that comes as second nature when I'm working in C++.<br />
</div>
<div abp="210" style="text-align: justify;">
So, when I have to create some kind of custom tool to process these files, most of the time I turn to C++. Thanks to C++1y/Boost, I don't take much longer to write it than I would with any other tool/language, and I definitely appreciate that when I need to change something a few weeks/months later, I can find my bearings much more quickly.<br />
</div>
<div abp="210" style="text-align: justify;">
And, after creating a few very similar programs, all driven by a file-reading loop, I've figured I had enough use-cases to create...<br />
</div>
<h4 abp="210" style="text-align: justify;">
FileLineReader</h4>
<div abp="210" style="text-align: justify;">
A class... actually, a class template, that reads lines from a file. Surprising, heh?</div>
<div abp="210" style="text-align: justify;">
</div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">template</span><span style="color: silver;"> </span><span style="color: black;"><</span><span style="color: olive;">typename</span><span style="color: silver;"> </span><span style="color: purple;">LineMatcher</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: purple;">SimpleLineMatcher</span><span style="color: black;">,</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">typename</span><span style="color: silver;"> </span><span style="color: purple;">LineCounter</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: purple;">SimpleLineCounter</span><span style="color: black;"><</span><span style="color: olive;">unsigned</span><span style="color: silver;"> </span><span style="color: olive;">long</span><span style="color: black;">>></span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">class</span><span style="color: silver;"> </span><span style="color: purple;">FileLineReader</span><span style="color: silver;"> </span><span style="color: black;">:</span><span style="color: silver;"> </span><span style="color: olive;">private</span><span style="color: silver;"> </span><span style="color: purple;">LineMatcher</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: olive;">private</span><span style="color: silver;"> </span><span style="color: purple;">LineCounter</span></pre>
<div abp="210" style="text-align: justify;">
</div>
<div abp="211" style="text-align: justify;">
The concept is simple - read a line, which becomes the current line, and give the caller a way to get it (or copy it). Then, we add some nuggets of convenience:<br />
<ul>
<li>Keep a counter of read lines. Implemented by <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">LineCounter</code>.</li>
<li>Supply matching operations, that not only perform matching on the current line, but also allow skipping lines based on matching/non-matching. The matching is implemented by <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">LineMatcher</code>; which is then used by <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">FileLineReader</code> to implement the skipping.</li>
</ul>
<br />
Why inheritance, instead of composition? Because there will be cases where <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">LineMatcher</code> and <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">LineCounter</code> have no state, and a data member is a bit of waste (yes, a <em>tiny little bit</em> of a waste). Can this be abused? Absolutely, but you know - protect against Murphy, not Machavelli.<br />
<div>
</div>
</div>
<h4 abp="212" style="text-align: justify;">
Skipping lines </h4>
<div abp="212" style="text-align: justify;">
The first line skipping functions I introduced were <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">SkipMatchingLines()</code>, which skips lines while there's a match, and <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">SkipLinesUntilMatch()</code>, which skips lines until it finds a match.</div>
<div abp="212" style="text-align: justify;">
</div>
<div abp="212" style="text-align: justify;">
These functions share a similar trait - their stop condition is met after reading the line that triggers the stopping condition. Suppose we have this file:</div>
<div abp="212" style="text-align: justify;">
<br />
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">[</span><span style="color: navy;">2014</span><span style="color: black;">-</span><span style="color: navy;">01</span><span style="color: black;">-</span><span style="color: navy;">01</span><span style="color: silver;"> </span><span style="color: navy;">00</span><span style="color: black;">:</span><span style="color: navy;">00</span><span style="color: black;">:</span><span style="color: navy;">00.000</span><span style="color: black;">]</span><span style="color: silver;"> </span>match<span style="color: black;">-</span><span style="color: navy;">1</span><span style="color: silver;"> </span>This<span style="color: silver;"> </span>is<span style="color: silver;"> </span>line<span style="color: silver;"> </span><span style="color: navy;">0</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">[</span><span style="color: navy;">2014</span><span style="color: black;">-</span><span style="color: navy;">01</span><span style="color: black;">-</span><span style="color: navy;">01</span><span style="color: silver;"> </span><span style="color: navy;">00</span><span style="color: black;">:</span><span style="color: navy;">00</span><span style="color: black;">:</span><span style="color: navy;">00.100</span><span style="color: black;">]</span><span style="color: silver;"> </span>match<span style="color: black;">-</span><span style="color: navy;">1</span><span style="color: silver;"> </span>This<span style="color: silver;"> </span>is<span style="color: silver;"> </span>line<span style="color: silver;"> </span><span style="color: navy;">1</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">[</span><span style="color: navy;">2014</span><span style="color: black;">-</span><span style="color: navy;">01</span><span style="color: black;">-</span><span style="color: navy;">01</span><span style="color: silver;"> </span><span style="color: navy;">00</span><span style="color: black;">:</span><span style="color: navy;">00</span><span style="color: black;">:</span><span style="color: navy;">00.200</span><span style="color: black;">]</span><span style="color: silver;"> </span>match<span style="color: black;">-</span><span style="color: navy;">1</span><span style="color: silver;"> </span>This<span style="color: silver;"> </span>is<span style="color: silver;"> </span>line<span style="color: silver;"> </span><span style="color: navy;">2</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">[</span><span style="color: navy;">2014</span><span style="color: black;">-</span><span style="color: navy;">01</span><span style="color: black;">-</span><span style="color: navy;">01</span><span style="color: silver;"> </span><span style="color: navy;">00</span><span style="color: black;">:</span><span style="color: navy;">00</span><span style="color: black;">:</span><span style="color: navy;">00.300</span><span style="color: black;">]</span><span style="color: silver;"> </span>match<span style="color: black;">-</span><span style="color: navy;">2</span><span style="color: silver;"> </span>This<span style="color: silver;"> </span>is<span style="color: silver;"> </span>line<span style="color: silver;"> </span><span style="color: navy;">3</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">[</span><span style="color: navy;">2014</span><span style="color: black;">-</span><span style="color: navy;">01</span><span style="color: black;">-</span><span style="color: navy;">01</span><span style="color: silver;"> </span><span style="color: navy;">00</span><span style="color: black;">:</span><span style="color: navy;">00</span><span style="color: black;">:</span><span style="color: navy;">00.400</span><span style="color: black;">]</span><span style="color: silver;"> </span>match<span style="color: black;">-</span><span style="color: navy;">2</span><span style="color: silver;"> </span>This<span style="color: silver;"> </span>is<span style="color: silver;"> </span>line<span style="color: silver;"> </span><span style="color: navy;">4</span></pre>
</div>
<div abp="212" style="text-align: justify;">
Something like this<br />
<br />
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: purple;">FileLineReader</span><span style="color: black;"><></span><span style="color: silver;"> </span>flr<span style="color: black;">{</span>kFileName<span style="color: black;">};</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">flr<span style="color: black;">.</span>SkipMatchingLines<span style="color: black;">(</span><span style="color: green;">"match-1"</span><span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: green;">//</span><span style="color: silver;"> </span><span style="color: green;">Process</span><span style="color: silver;"> </span><span style="color: green;">lines</span></pre>
</div>
<div abp="212" style="text-align: justify;">
can only stop when the line "<em>... line 3</em>" is read, because there's no way we can perform a match against a line that hasn't been read yet. This means that when we reach "<code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">// Process lines</code>", the current line will be the first line to process, so we should "process-then-read" (<em>do-while</em>), rather than the more intuitive "read-then-process" (<em>while</em>).</div>
<div abp="212" style="text-align: justify;">
<br /></div>
<div abp="212" style="text-align: justify;">
I've entertained the notion of using <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">tellg()</code>/<code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">seekg()</code> to rewind the file (IOW, <em>un-read</em> the line), but I didn't even get started, after reading about how it behaves in text mode. So, I'll stick with "process-then-read", for now.</div>
<div abp="212" style="text-align: justify;">
<br /></div>
<div abp="212" style="text-align: justify;">
Another common scenario I encounter is skipping a certain number of lines, usually a header. So, I've added this:</div>
<div abp="212" style="text-align: justify;">
<span style="color: silver;"> </span></div>
<div abp="212" style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">void</span><span style="color: silver;"> </span><span style="color: black;">SkipNumberLines</span><span style="color: black;">(</span><span style="color: olive;">unsigned</span><span style="color: silver;"> </span><span style="color: olive;">int</span><span style="color: silver;"> </span>number_lines<span style="color: black;">);</span></pre>
</div>
<div abp="212" style="text-align: justify;">
<br /></div>
<div abp="212" style="text-align: justify;">
Because we're skipping lines independently of any matching, it didn't make sense to implement this in <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">LineMatcher</code>; so, I've implemented it straight in <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">FileLineReader</code>. I'm not completely happy with this solution, but I figured it's better than no solution.</div>
<div abp="212" style="text-align: justify;">
</div>
<h4 abp="212" style="text-align: justify;">
Skipping dilemmas</h4>
<div abp="212" style="text-align: justify;">
I also thought it would make sense to keep semantic coherence between all the line-skipping functions. So, <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">SkipNumberLines()</code> should stop on the first line to process, not on the last line skipped (even though it could, because we're skipping a known number of lines), just like the other functions.</div>
<div abp="212" style="text-align: justify;">
</div>
<div abp="212" style="text-align: justify;">
No biggie, we just perform an extra read - so, for <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">SkipNumberLines(3)</code>, we actually read 4 lines. Lovely, everything's coherent, little ponies are happy, and fairies are spreading pixie dust and sneezes throughout the realm.</div>
<div abp="212" style="text-align: justify;">
</div>
<div abp="212" style="text-align: justify;">
The thing is... nobody expects the Spanish Inquisition... their chief weapon is surprise and <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">SkipNumberLines(0)</code>... their two chief weapons are surprise, an almost fanatical devotion to the Pope, and <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">SkipNumberLines(0)</code>... OK, among their weaponry we can find elements as diverse as... blah, blah, blah, and <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">SkipNumberLines(0)</code>.<br />
<br />
Yep, <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">SkipNumberLines(0)</code>.<br />
<br />
Let's say you have a function that calculates how many lines to skip, based on, e.g., an input argument - it could be the type of file being processed, or the phase of the moon; then, you could use it like this:</div>
<div abp="212" style="text-align: justify;">
<br />
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">flr<span style="color: black;">.</span>SkipNumberLines<span style="color: black;">(</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;"> </span><span style="color: black;">CalculateNumberLinesToSkip</span><span style="color: black;">(</span>some_relevant_argument<span style="color: black;">));</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-indent: 0px;"> </pre>
</div>
<div abp="213" style="text-align: justify;">
You're aware <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">CalculateNumberLinesToSkip()</code> could return 0 (you could, say, be processing a file without a header). And I'd venture a guess that you would probably expect that <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">SkipNumberLines(0)</code> would skip, you know, a number of lines kinda equal to... zero. As in, more than -1, but definitely less than 1.<br />
<br />
Which left me with <strong>two</strong> alternatives:<br />
<ol>
<li>Treat 0 as a special case. Which would force upon the caller the "specialness" of this case.</li>
<li>Indulge in a fanatical devotion to coherence - read one line on <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">SkipNumberLines(0)</code>, and consequences be damned.</li>
<li>Forget coherence, and accept that even though they're all line-skipping functions, they can have different semantics/post-conditions.</li>
</ol>
<br />
OK, enough Spanish Inquisition jokes.<br />
<div>
</div>
I've settled for alternative 3. I'm not entirely sure it's the best option, and as I get more use out of this class, I expect to find new scenarios and patterns, which will provide me with more data to revisit this design later. But, for now, it seems to be the safest choice.<br />
<br />
And there you have it. Quite modest, yes, but it has been saving me some boilerplate code in these last few weeks.<br />
<br />
I don't know yet how it will evolve. I can feel an itch with regards to a text mode rewind, but I'll have to dive into streams and buffers much more deeply than I feel like, at the moment.<br />
<br />
And right now I have other challenges awaiting... impatiently, I might add. A crash course in some obscure aspects of Weblogic administration to better diagnose socket problems without resorting to <em>strace</em>.<br />
<br />
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-6730779062859748422014-09-14T23:51:00.003+01:002014-09-14T23:51:20.341+01:00Performance puzzle(d)<div style="text-align: justify;">
So, back to programming.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Every now and then, I pick up a programming puzzle. The goal is not only to solve the puzzle, but also the learn more about the performance of my solutions.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
A few days ago, I've decided to take a shot at making a Cracker Barrel solver. Simple stuff, just brute-force your way through solving the puzzle. First, I've started with a standard 15-hole board. Then, I've moved on to a configurable board (but never smaller than 15 holes). Then, I've implemented getting the board setup (including the list of all possible moves) just from the number of holes. Then, I've decided that this list would be kept in an <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">std::array</code>, which meant getting this information at compile-time, which gave an excuse for a little bit of basic recursive template meta-programming <em>lite</em>.</div>
<div style="text-align: justify;">
<br />
Yes, I've forced feature-creep on myself. Ah, and no design optimization - e.g, I didn't use STL's <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">bitset<N></code> (or even C bit-twiddling) for the board, and I've created a good-ole <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">struct</code> for the moves, with three integers.<br />
<br />
I've built it with GCC (mingw32/Qt Creator) and MSVC 2013. For a board with 15 holes, both were immediate. As I've moved to 21 holes, the GCC exe took a few seconds, but MSVC took almost... 1 minute?! With 28 holes, Qt Creator takes forever, and so does MSVC.<br />
<br />
The fact that this takes forever doesn't surprise me. As I said, I've made no optimizations. However, the difference between GCC and MSVC puzzled me. So, I turned to Windows Performance Analyzer (WPA) to figure out what was going on.<br />
<br />
Now, I had a good guess about what was going on - I was sure that, compiler optimizations notwithstanding, there was probably a lot of copying going on. There certainly is a lot of vectors getting constructed, and I was expecting to find my main culprit along those lines.<br />
<br />
So, I fired up WPA, loaded the trace file, selected the CPU Usage (Sampled) graph, changed it to <em>Display table only</em>, opened the View Editor and set the Stack (call stack) to Visible.<br />
<br />
And this was flagged as the most time-consuming operation of all:<br />
<br />
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">std::_Equal_range<GameMove const *,GameMove,int,</span><br />
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> bool (__cdecl*)(GameMove const &,GameMove const &)</span><br />
<br />
Sometimes, life proves more interesting than anticipated. However, this time it was just me not paying attention.<br />
<br />
When I say I've made no optimizations, I didn't even go for the most important optimization of all - an intelligent algorithm. This means that when I calculate all the valid moves after each move, I go through the entire board, including spots for which no move is possible. And I'm using sorted vectors/arrays and <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">equal_range()</code> to perform this search.<br />
<br />
So, while it the result was surprising, it shouldn't really have been.<br />
<br />
Next step - find a more intelligent way to get the list of valid moves.<br />
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-71512684739400815532014-08-30T16:58:00.000+01:002014-08-30T16:58:00.778+01:00Extremely destructive<div abp="402" style="text-align: justify;">
Off-topic, today. Quite so, actually. If you came here to read about programming, you may want to give this one a miss.</div>
<div abp="403" style="text-align: justify;">
</div>
<div abp="404" style="text-align: justify;">
There's this light comedy French film called <a abp="405" href="http://www.imdb.com/title/tt0243493/">"Le Placard"</a> ("The Closet" in English, "Sai do Armário" in Portuguese). Quite enjoyable, BTW, recommended.</div>
<div abp="406" style="text-align: justify;">
</div>
<div abp="407" style="text-align: justify;">
The IMDB summary says it all:</div>
<div abp="408" style="text-align: justify;">
<blockquote abp="409" class="tr_bq">
A man spreads the rumor of his fake homosexuality with the aid of his neighbor, to prevent his imminent firing at his work.</blockquote>
<div abp="410" style="text-align: justify;">
The man's elderly neighbour is actually gay, and at some point mentions the irony of him being fired for being gay back in the day, when he was young, and how these days what happens is the exact opposite, because of anti-discrimination laws/fear of lawsuits/whatever. Yes, I know it's an over-simplification, but it's a light comedy, not a documentary.</div>
<div abp="410" style="text-align: justify;">
</div>
<div abp="410" style="text-align: justify;">
However, it's no secret that, if we go back a few decades, being gay could land you in trouble at the workplace (and land you <em abp="416">out of</em> the workplace). It was a totally unfair practice, where your professional performance would be ignored and you'd be judged exclusively on (selected parts of) your personal profile. And you have any doubt on how unfair and tragic this was, just read <a abp="496" href="http://en.wikipedia.org/wiki/Alan_Turing">Alan Turing's bio</a>, and think on how many "anonymous" people suffered similar fates.</div>
<div abp="410" style="text-align: justify;">
</div>
<div abp="410" style="text-align: justify;">
Fast-forward to the 21st century, and things are looking a lot better... or so I thought. Until I witnessed the whole Brendan Eich's debacle.</div>
<div abp="419" style="text-align: justify;">
</div>
<div abp="420" style="text-align: justify;">
Speaking solely for myself, the only thing it has achieved was to make me more cautious in providing my support to a cause I've always considered worthwhile (and still do) - equal rights for everyone. That's the way I've always voted, and that's the way I've always seen myself voting. But now that I've witnessed how the previously-persecuted can do the exact same thing to others with such abandon and glee, I'm left wondering - if I'm ever called to vote on any subject-related matter, what will I do? As the guy sang, "<a abp="421" href="https://www.youtube.com/watch?feature=player_detailpage&v=rMdDjJLQz00#t=163">I don't know the answer</a>".<br abp="422" /><br abp="423" />You see, the thing is... I don't like mobs, and I'm not particularly amenable to the argument "We're a mob, but it's for a good cause, a just cause". There is no "good cause" in mob mentality, only rabid persecution.</div>
<div abp="420" style="text-align: justify;">
</div>
<div abp="420" style="text-align: justify;">
However, this incident was months ago, why write about it now? Well, because now we have "the mobs" up in arms again, this time in the "gaming industry".</div>
<div abp="426" style="text-align: justify;">
</div>
<div abp="427" style="text-align: justify;">
I'm an on/off gamer. I'm a Steam customer, and a very good GOG customer (if there's one thing I've learned is to vote with my wallet and reward those that actually care about their customers). These days, I sometimes go for months without playing a game. Before I got back into programming, I could spend all my free time playing games. Now, gaming is relegated to 3rd place, behind programming and guitar-playing (I'm excluding Real Life, which means family, friends and work, obviously).</div>
<div abp="427" style="text-align: justify;">
</div>
<div abp="427" style="text-align: justify;">
I've never had any problem in calling myself a gamer, even as it stopped being part of what I did. And then, slowly but surely, the word "gamer" began to take on very specific meanings, all of them negative. It didn't bothered me much. It's like reading "All Portuguese are lazy bastards, living off everyone else's money", this says more about the speaker than about the Portuguese people.</div>
<div abp="430" style="text-align: justify;">
</div>
<div abp="431" style="text-align: justify;">
Anyway, now it all came to a climax with this last brouhaha. I'm sure you can find the... "relevant information" (for lack of more appropriate words) and links. I'll just link to the <a abp="432" href="https://twitter.com/shamusyoung/statuses/504625131621462016">best summation</a> I've seen of this whole deal:</div>
<blockquote abp="433" class="tr_bq">
So many interesting conversations and things to challenge. But you can't have a discussion during a riot. It's a shame.</blockquote>
<div abp="434" style="text-align: justify;">
Indeed. What you have here is <strong abp="435">a)</strong> a few people who should be detained for online harassment/threats; <strong abp="436">b)</strong> some people <strong abp="437">on both sides</strong> who have nothing to say except indulge in some feces-throwing (<a abp="439" href="http://www.markshuttleworth.com/archives/439">tribalism</a> at its best); <strong abp="498">c)</strong> some people (fortunately, more numerous), again <strong abp="499">on both sides</strong>, who are raising up important issues that should be discussed (but, as Shamus put it, not "during a riot"); and <strong abp="500">d)</strong>, (going out on a limb here) I'm willing to bet you have an even grater number of people who are just looking at this whole thing from the sideline, thinking "God, what a waste".</div>
<div abp="434" style="text-align: justify;">
</div>
<div abp="434" style="text-align: justify;">
Like the "Eich incident", this has just contributed to make me more skeptical towards a cause I would definitely lend my unconditional support to - namely, equal treatment, be it of gender or any other differentiating aspect.</div>
<div abp="434" style="text-align: justify;">
</div>
<div abp="434" style="text-align: justify;">
Because, once again, I don't care what is moving a persecuting mob. At the end of the day, it's still a persecuting mob.</div>
<div abp="434" style="text-align: justify;">
</div>
<div abp="434" style="text-align: justify;">
Actually, I'm just about to finish, so I believe it's a good time to let Godwin in to make an argumentum ad Nazium (Nauziem, maybe?) - I see <strong abp="501">absolutely no difference</strong> between a mob that's going to indiscriminately shoot Jews, calling them all sub-humans, and a mob that's going to indiscriminately shoot Germans, calling them all Nazis. I, for one, am glad we had the "Nuremberg trials", not the "Nuremberg massacres".</div>
<div abp="434" style="text-align: justify;">
</div>
<div abp="434" style="text-align: justify;">
So, if all you want is to stoop down to the lowest level of what you have elected as your "opposing tribe", I'll just stand by the sideline, watching, and taking notes. Those are notes I'll reread and evaluate the next time I'm called to vote, either with my ballot or my wallet.</div>
<div abp="434" style="text-align: justify;">
</div>
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-86251862462550579922014-08-24T16:54:00.001+01:002014-08-24T16:54:10.748+01:00Productivity - Cakes and lies<div abp="344" style="text-align: justify;">
<div abp="1598">
On my "<a abp="345" href="http://cidebycide.blogspot.pt/2014/07/c-and-ruby-side-by-side.html">C++ and Ruby - Side by side</a>" post, I mentioned having a natural affinity towards a programming language. Today, I'll elaborate on that, using something I've worked on recently to illustrate.</div>
</div>
<div abp="346">
<div abp="1601">
</div>
</div>
<div abp="347" style="text-align: justify;">
<div abp="1603">
<strong abp="348">Important note:</strong> Nothing I write below is an indictment/endorsement for this or that language. What I'm going for is the exact opposite - whenever you read a book/article about a language (any language) that promises greater productivity just by switching to that language, you should be suspicious.</div>
<div abp="1603">
</div>
</div>
<h4 abp="350">
The problem</h4>
<div abp="351" style="text-align: justify;">
<div abp="1607">
I've never liked the way IDEs (in my case, Visual Studio/Qt Creator) define their project structures, and I've been trying to setup my own structure, with the goal of supporting multiple tools.</div>
</div>
<div abp="352">
<div abp="1609">
</div>
</div>
<div abp="353" style="text-align: justify;">
<div abp="1611">
Unfortunately, the tools prefer their own particular structure arrangements, and aren't very cooperative to anything that strays from their comfort zone.</div>
</div>
<div abp="354">
<div abp="1613">
</div>
</div>
<div abp="355" style="text-align: justify;">
<div abp="1615">
So, in the end, I've settled for a two-step procedure - I create the projects using the IDEs and then I run a process I created to move the project to my structure. The moving part is easy, and I could do it manually. The tinkering with the project settings files is more tricky, and is what ended up giving me the final push to look at automating the whole thing.</div>
</div>
<div abp="356">
<div abp="1617">
</div>
</div>
<div abp="357" style="text-align: justify;">
<div abp="1619">
I've had three attempts at creating this process.</div>
<div abp="1619">
</div>
</div>
<h4 abp="359">
Perl</h4>
<div abp="360" style="text-align: justify;">
<div abp="1622">
The first version of this process was a Perl script. Why Perl? Well, because... scripting language... well-suited to small hacks... higher productivity... y'know?</div>
</div>
<div abp="361">
<div abp="1624">
</div>
</div>
<div abp="362" style="text-align: justify;">
<div abp="1626">
It was easy to create a linear script. However, a few weeks later, when I wanted to introduce some changes, it was also easy to get lost navigating around said script, trying to get a grasp of what I had done.</div>
</div>
<div abp="363">
<div abp="1628">
</div>
</div>
<div abp="364" style="text-align: justify;">
<div abp="1630">
So, I went through several redesign/refactor iterations, trying to move from a linear script to something a bit more structured.</div>
</div>
<div abp="365">
<div abp="1632">
</div>
</div>
<div abp="366" style="text-align: justify;">
<div abp="1634">
I finally settled on a version that lasted several months, with <em abp="367">Modern::Perl</em> and <em abp="368">Moose</em> as foundations. As I used this script, I became aware of several weaknesses in my original design. So, a few weeks ago, I decided to review my design, and proceeded to change the script. And, again, I was lost. Even more so than in the linear script, in fact.</div>
</div>
<div abp="369">
<div abp="1638">
</div>
</div>
<div abp="370" style="text-align: justify;">
<div abp="1640">
I've had to review all the scripts/modules I created in order to understand again what I had done at that time (docs? Come on, it's a simple script to create some directories, copy a few files, edit a couple of those, and <em abp="371">init git</em>). And, since I had to do that, I've decided to have another go at it, but this time in...</div>
<div abp="1640">
</div>
</div>
<h4 abp="373">
Ruby</h4>
<div abp="374" style="text-align: justify;">
<div abp="1644">
Why Ruby? Well, because... scripting language... well-suited to small hacks... higher productivity... y'know?</div>
</div>
<div abp="375">
<div abp="1646">
</div>
</div>
<div abp="376" style="text-align: justify;">
<div abp="1648">
It began well. I removed some syntactic quirks, especially where OO-ness was concerned. Strange as it may seem, a clean language presents a greater potential for a clear design. Maybe it's just me, maybe I'm easily distracted by these syntactic quirks, which I admit should not be quite so important.</div>
</div>
<div abp="377">
<div abp="1650">
</div>
</div>
<div abp="378" style="text-align: justify;">
<div abp="1652">
Long story short, it began well, but... I've started having growing difficulties to implement my design. I've finally decided to try...</div>
<div abp="1652">
</div>
</div>
<h4 abp="380">
C++</h4>
<div abp="381" style="text-align: justify;">
<div abp="1655">
Yes, predictable, I know...</div>
</div>
<div abp="382">
<div abp="1657">
</div>
</div>
<div abp="383" style="text-align: justify;">
<div abp="1659">
Why? Because I've decided that maybe "lower productivity" was worth a shot.</div>
</div>
<div abp="384">
<div abp="1661">
</div>
</div>
<div abp="385" style="text-align: justify;">
<div abp="1663">
And it went smoothly. Not "easily", not "simply"; but definitely smoothly. I've actually finished the process with the design I wanted. I can actually navigate around the code, easily finding what I'm looking for.</div>
</div>
<div abp="386">
<div abp="1665">
</div>
</div>
<div abp="387" style="text-align: justify;">
<div abp="1667">
What was I aiming at? Here, look at my "<em abp="388">main()</em>":</div>
<div abp="1667">
</div>
</div>
<div abp="390">
</div>
<pre abp="391" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="392" style="color: olive;">void</span><span abp="393" style="color: silver;"> </span><span abp="394" style="color: black;">Run</span><span abp="395" style="color: black;">(</span><span abp="396" style="color: olive;">int</span><span abp="397" style="color: silver;"> </span><span abp="398" style="color: black;">argc</span><span abp="399" style="color: black;">,</span><span abp="400" style="color: silver;"> </span><span abp="401" style="color: olive;">char</span><span abp="402" style="color: silver;"> </span><span abp="403" style="color: black;">*</span><span abp="404" style="color: black;">argv</span><span abp="405" style="color: black;">[])</span></pre>
<pre abp="406" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="407" style="color: black;">{</span></pre>
<pre abp="408" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="409" style="color: silver;"> </span><span abp="410" style="color: purple;">AppOptions</span><span abp="411" style="color: black;"><</span><span abp="412" style="color: purple;">ConfigProjectOptions</span><span abp="413" style="color: black;">></span></pre>
<pre abp="408" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="409" style="color: silver;"> </span><span abp="415" style="color: black;">ao</span><span abp="416" style="color: black;">{</span><span abp="417" style="color: black;">argc</span><span abp="418" style="color: black;">,</span><span abp="419" style="color: silver;"> </span><span abp="420" style="color: black;">argv</span><span abp="421" style="color: black;">,</span><span abp="422" style="color: silver;"> </span><span abp="423" style="color: green;">"Opções</span><span abp="424" style="color: silver;"> </span><span abp="425" style="color: green;">ProjectConfig"</span><span abp="426" style="color: black;">};</span></pre>
<div abp="408" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
</div>
<div abp="428">
</div>
<pre abp="429" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="430" style="color: silver;"> </span><span abp="431" style="color: olive;">if</span><span abp="432" style="color: silver;"> </span><span abp="433" style="color: black;">(</span><span abp="434" style="color: black;">ao</span><span abp="435" style="color: black;">.</span><span abp="436" style="color: black;">HaveShownHelp</span><span abp="437" style="color: black;">())</span></pre>
<pre abp="438" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="439" style="color: silver;"> </span><span abp="440" style="color: black;">{</span></pre>
<pre abp="441" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="442" style="color: silver;"> </span><span abp="443" style="color: olive;">return</span><span abp="444" style="color: black;">;</span></pre>
<pre abp="445" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="446" style="color: silver;"> </span><span abp="447" style="color: black;">}</span></pre>
<div abp="445" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
</div>
<div abp="449">
</div>
<pre abp="450" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="451" style="color: silver;"> </span><span abp="452" style="color: purple;">ConfigProjectOptions</span><span abp="453" style="color: silver;"> </span><span abp="454" style="color: olive;">const</span><span abp="455" style="color: black;">&</span><span abp="456" style="color: silver;"> </span><span abp="457" style="color: black;">opt</span><span abp="458" style="color: silver;"> </span><span abp="459" style="color: black;">=</span><span abp="460" style="color: silver;"> </span><span abp="461" style="color: black;">ao</span><span abp="462" style="color: black;">.</span><span abp="463" style="color: black;">GetOptions</span><span abp="464" style="color: black;">();</span></pre>
<pre abp="465" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="466" style="color: silver;"> </span><span abp="467" style="color: purple;">string</span><span abp="468" style="color: silver;"> </span><span abp="469" style="color: black;">project_name</span><span abp="470" style="color: silver;"> </span><span abp="471" style="color: black;">=</span><span abp="472" style="color: silver;"> </span><span abp="473" style="color: black;">opt</span><span abp="474" style="color: black;">.</span><span abp="475" style="color: black;">GetProjectName</span><span abp="476" style="color: black;">();</span></pre>
<div abp="465" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
</div>
<div abp="478">
</div>
<pre abp="479" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="480" style="color: silver;"> </span><span abp="481" style="color: green;">//</span><span abp="482" style="color: silver;"> </span><span abp="483" style="color: green;">All</span><span abp="484" style="color: silver;"> </span><span abp="485" style="color: green;">objects</span><span abp="486" style="color: silver;"> </span><span abp="487" style="color: green;">are</span><span abp="488" style="color: silver;"> </span><span abp="489" style="color: green;">validated</span><span abp="490" style="color: silver;"> </span><span abp="491" style="color: green;">on</span><span abp="492" style="color: silver;"> </span><span abp="493" style="color: green;">construction.</span></pre>
<pre abp="494" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="495" style="color: silver;"> </span><span abp="496" style="color: purple;">ProjectDirectory</span><span abp="497" style="color: silver;"> </span><span abp="498" style="color: black;">prj_dir</span><span abp="499" style="color: black;">(</span>PROJ_PRJ<span abp="500" style="color: black;">,</span><span abp="501" style="color: silver;"> </span><span abp="502" style="color: black;">project_name</span><span abp="503" style="color: black;">,</span><span abp="504" style="color: silver;"> </span></pre>
<pre abp="505" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="506" style="color: silver;"> </span>STRUCT_PRJ<span abp="507" style="color: black;">,</span><span abp="508" style="color: silver;"> </span>SHOULD_NOT_EXIST<span abp="509" style="color: black;">);</span></pre>
<pre abp="510" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="511" style="color: silver;"> </span><span abp="512" style="color: purple;">ProjectDirectory</span><span abp="513" style="color: silver;"> </span><span abp="514" style="color: black;">bld_dir</span><span abp="515" style="color: black;">(</span>PROJ_BLD<span abp="516" style="color: black;">,</span><span abp="517" style="color: silver;"> </span><span abp="518" style="color: black;">project_name</span><span abp="519" style="color: black;">,</span><span abp="520" style="color: silver;"> </span></pre>
<pre abp="521" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="522" style="color: silver;"> </span>STRUCT_BLD<span abp="523" style="color: black;">,</span><span abp="524" style="color: silver;"> </span>SHOULD_NOT_EXIST<span abp="525" style="color: black;">);</span></pre>
<pre abp="526" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="527" style="color: silver;"> </span><span abp="528" style="color: purple;">ProjectDirectory</span><span abp="529" style="color: silver;"> </span><span abp="530" style="color: black;">stg_dir</span><span abp="531" style="color: black;">(</span>PROJ_STG<span abp="532" style="color: black;">,</span><span abp="533" style="color: silver;"> </span><span abp="534" style="color: black;">project_name</span><span abp="535" style="color: black;">,</span><span abp="536" style="color: silver;"> </span></pre>
<pre abp="537" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="538" style="color: silver;"> </span>STRUCT_STG<span abp="539" style="color: black;">,</span><span abp="540" style="color: silver;"> </span>SHOULD_EXIST<span abp="541" style="color: black;">);</span></pre>
<div abp="537" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
</div>
<div abp="543">
</div>
<pre abp="544" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="545" style="color: silver;"> </span><span abp="546" style="color: purple;">Project</span><span abp="547" style="color: black;"><</span><span abp="548" style="color: purple;">QtcStgValidator</span><span abp="549" style="color: black;">,</span><span abp="550" style="color: silver;"> </span><span abp="551" style="color: purple;">QtcCopier</span><span abp="552" style="color: black;">,</span><span abp="553" style="color: silver;"> </span><span abp="554" style="color: purple;">QtcProjectConfigUpdater</span><span abp="555" style="color: black;">></span></pre>
<pre abp="556" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="557" style="color: silver;"> </span><span abp="558" style="color: black;">qtc_project</span><span abp="559" style="color: black;">{</span><span abp="560" style="color: black;">project_name</span><span abp="561" style="color: black;">,</span><span abp="562" style="color: silver;"> </span><span abp="563" style="color: black;">prj_dir</span><span abp="564" style="color: black;">,</span><span abp="565" style="color: silver;"> </span><span abp="566" style="color: black;">bld_dir</span><span abp="567" style="color: black;">,</span><span abp="568" style="color: silver;"> </span><span abp="569" style="color: black;">stg_dir</span><span abp="570" style="color: black;">};</span></pre>
<pre abp="571" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="572" style="color: silver;"> </span><span abp="573" style="color: purple;">Project</span><span abp="574" style="color: black;"><</span><span abp="575" style="color: purple;">MsvcStgValidator</span><span abp="576" style="color: black;">,</span><span abp="577" style="color: silver;"> </span><span abp="578" style="color: purple;">MsvcCopier</span><span abp="579" style="color: black;">,</span><span abp="580" style="color: silver;"> </span><span abp="581" style="color: purple;">MsvcProjectConfigUpdater</span><span abp="582" style="color: black;">></span></pre>
<pre abp="583" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="584" style="color: silver;"> </span><span abp="585" style="color: black;">msvc_project</span><span abp="586" style="color: black;">(</span><span abp="587" style="color: black;">project_name</span><span abp="588" style="color: black;">,</span><span abp="589" style="color: silver;"> </span><span abp="590" style="color: black;">prj_dir</span><span abp="591" style="color: black;">,</span><span abp="592" style="color: silver;"> </span><span abp="593" style="color: black;">bld_dir</span><span abp="594" style="color: black;">,</span><span abp="595" style="color: silver;"> </span><span abp="596" style="color: black;">stg_dir</span><span abp="597" style="color: black;">);</span></pre>
<div abp="583" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
</div>
<div abp="599">
</div>
<pre abp="600" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="601" style="color: silver;"> </span><span abp="602" style="color: green;">//</span><span abp="603" style="color: silver;"> </span><span abp="604" style="color: green;">Everything</span><span abp="605" style="color: silver;"> </span><span abp="606" style="color: green;">is</span><span abp="607" style="color: silver;"> </span><span abp="608" style="color: green;">valid,</span><span abp="609" style="color: silver;"> </span><span abp="610" style="color: green;">get</span><span abp="611" style="color: silver;"> </span><span abp="612" style="color: green;">user</span><span abp="613" style="color: silver;"> </span><span abp="614" style="color: green;">confirmation.</span></pre>
<pre abp="615" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="616" style="color: silver;"> </span><span abp="617" style="color: olive;">if</span><span abp="618" style="color: silver;"> </span><span abp="619" style="color: black;">(!</span><span abp="620" style="color: black;">UserConfirms</span><span abp="621" style="color: black;">(</span><span abp="622" style="color: black;">project_name</span><span abp="623" style="color: black;">))</span></pre>
<pre abp="624" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="625" style="color: silver;"> </span><span abp="626" style="color: black;">{</span></pre>
<pre abp="627" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="628" style="color: silver;"> </span><span abp="629" style="color: olive;">return</span><span abp="630" style="color: black;">;</span></pre>
<pre abp="631" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="632" style="color: silver;"> </span><span abp="633" style="color: black;">}</span></pre>
<div abp="631" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
</div>
<div abp="635">
</div>
<pre abp="636" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="637" style="color: silver;"> </span><span abp="638" style="color: black;">prj_dir</span><span abp="639" style="color: black;">.</span><span abp="640" style="color: black;">CreateStructure</span><span abp="641" style="color: black;">();</span></pre>
<pre abp="642" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="643" style="color: silver;"> </span><span abp="644" style="color: black;">bld_dir</span><span abp="645" style="color: black;">.</span><span abp="646" style="color: black;">CreateStructure</span><span abp="647" style="color: black;">();</span></pre>
<div abp="642" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
</div>
<div abp="649">
</div>
<pre abp="650" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="651" style="color: silver;"> </span><span abp="652" style="color: olive;">if</span><span abp="653" style="color: silver;"> </span><span abp="654" style="color: black;">(</span><span abp="655" style="color: black;">opt</span><span abp="656" style="color: black;">.</span><span abp="657" style="color: black;">WantGit</span><span abp="658" style="color: black;">())</span></pre>
<pre abp="659" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="660" style="color: silver;"> </span><span abp="661" style="color: black;">{</span></pre>
<pre abp="662" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="663" style="color: silver;"> </span><span abp="664" style="color: black;">ConfigureGit</span><span abp="665" style="color: black;">(</span><span abp="666" style="color: black;">prj_dir</span><span abp="667" style="color: black;">.</span><span abp="668" style="color: black;">GetProjectHomeDir</span><span abp="669" style="color: black;">());</span></pre>
<pre abp="670" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="671" style="color: silver;"> </span><span abp="672" style="color: black;">}</span></pre>
<div abp="670" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
</div>
<div abp="674">
</div>
<pre abp="675" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="676" style="color: silver;"> </span><span abp="677" style="color: olive;">if</span><span abp="678" style="color: silver;"> </span><span abp="679" style="color: black;">(</span><span abp="680" style="color: black;">opt</span><span abp="681" style="color: black;">.</span><span abp="682" style="color: black;">IsQtcProject</span><span abp="683" style="color: black;">())</span></pre>
<pre abp="684" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="685" style="color: silver;"> </span><span abp="686" style="color: black;">{</span></pre>
<pre abp="687" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="688" style="color: silver;"> </span><span abp="689" style="color: black;">qtc_project</span><span abp="690" style="color: black;">.</span><span abp="691" style="color: black;">Copy</span><span abp="692" style="color: black;">();</span></pre>
<pre abp="693" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="694" style="color: silver;"> </span><span abp="695" style="color: black;">}</span></pre>
<div abp="693" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
</div>
<div abp="697">
</div>
<pre abp="698" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="699" style="color: silver;"> </span><span abp="700" style="color: olive;">if</span><span abp="701" style="color: silver;"> </span><span abp="702" style="color: black;">(</span><span abp="703" style="color: black;">opt</span><span abp="704" style="color: black;">.</span><span abp="705" style="color: black;">IsMsvcProject</span><span abp="706" style="color: black;">())</span></pre>
<pre abp="707" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="708" style="color: silver;"> </span><span abp="709" style="color: black;">{</span></pre>
<pre abp="710" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="711" style="color: silver;"> </span><span abp="712" style="color: black;">msvc_project</span><span abp="713" style="color: black;">.</span><span abp="714" style="color: black;">Copy</span><span abp="715" style="color: black;">();</span></pre>
<pre abp="716" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="717" style="color: silver;"> </span><span abp="718" style="color: black;">}</span></pre>
<pre abp="719" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="720" style="color: black;">}</span></pre>
<div abp="721">
<div abp="1992">
<br /></div>
</div>
<div abp="723" style="text-align: justify;">
<div abp="1994">
This is what I was after all along, but was unable to achieve either with Perl or Ruby. It's as clean as it gets, with the main classes clearly identified, based on the operations that I need to do, and with support classes implementing policies that actually take care of the different ways things are done.</div>
</div>
<div abp="724">
<div abp="1996">
</div>
</div>
<div abp="725" style="text-align: justify;">
<div abp="1998">
The code itself is quite simple (this is a trivial program, after all), and you can find it <a abp="2000" href="https://github.com/PauloCaetano/SimpleSampleTuts/tree/master/ProjectConfig">here</a>.</div>
</div>
<div abp="726">
<div abp="2003">
</div>
</div>
<div abp="727" style="text-align: justify;">
<div abp="2005">
I probably could have achieved the same with Ruby, but this is what I'm talking about when I say "natural affinity". With C++, this code structure flowed naturally; with Ruby, not so much. </div>
<div abp="2005">
</div>
</div>
<h4 abp="729">
What's all this about, then?</h4>
<div abp="730" style="text-align: justify;">
<div abp="2008">
I'm repeating myself, but I'll say it anyway.</div>
</div>
<div abp="731">
<div abp="2010">
</div>
</div>
<div abp="732" style="text-align: justify;">
<div abp="2012">
Don't trust productivity promises at face value, especially for quick hacks/trivial programs, where everyone says shell/scripting languages are the best choice. Sometimes, <a abp="734" href="http://knowyourmeme.com/memes/the-cake-is-a-lie">the cake is actually a lie</a>.</div>
</div>
<div abp="736">
<div abp="2015">
</div>
</div>
<div abp="737" style="text-align: justify;">
<div abp="2017">
If all you want is to get a count of particular string/regex on a log file, <em abp="2018">grep</em> is the way to go. But say you need to do some manipulation on the results - e.g., the customer finds out he doesn't need a simple total count, but rather a list of totals for each key (e.g., customer ID). Suddenly, you're reading man pages/docs and searching the web, finding <em abp="2019">awk</em>/<em abp="2020">perl</em>/whatever "solutions" that don't quite give you what you want; so, you fiddle with those solutions and read some more man pages/docs.</div>
</div>
<div abp="737">
<div abp="2022">
</div>
</div>
<div abp="738" style="text-align: justify;">
<div abp="2024">
And, then, you look at the clock, see how much time has passed and say - if I had fired up MS Access, I'd probably have written a little VBA, finished this and moved on (yes, "MS Access" and "VBA" are just examples, not endorsements).</div>
</div>
<div abp="738">
<div abp="2026">
</div>
</div>
<div abp="739" style="text-align: justify;">
<div abp="2028">
At the end of the day, just because it's the best option for someone else, doesn't mean it's the best option for you.</div>
<div abp="2029">
</div>
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-76803023380484388972014-08-16T18:40:00.001+01:002014-08-16T18:40:59.626+01:00Still here, still going<div abp="200" style="text-align: justify;">
<div abp="201">
I'm back, after another long absence.</div>
</div>
<div abp="202" style="text-align: justify;">
<div abp="203">
</div>
</div>
<div abp="204" style="text-align: justify;">
<div abp="205">
I went on vacation, which meant the weeks before were spent on the pre-vacation rush, where you work like crazy to leave things in a state that can then be managed by the rest of the team.</div>
</div>
<div abp="206" style="text-align: justify;">
<div abp="207">
</div>
</div>
<div abp="208" style="text-align: justify;">
<div abp="209">
After a few days winding off, I've started coding again, mainly tackling off code puzzles in C++. I've also been refactoring (and redesigning) the small program I was going to use for the "next post" I promised on my last post (no, it's not forgotten). And what else?</div>
<div abp="210">
</div>
</div>
<h4 abp="211" style="text-align: justify;">
Building GCC</h4>
<div abp="212" style="text-align: justify;">
<div abp="213">
I'll kick this off by saying: <strong abp="214">Hats off to the folks behind GCC! Well done!</strong> I've built it a couple of times, with different configurations, on a CentOS VM, and it was totally effortless, just fire-and-forget. This time, instead of downloading and building each prerequisite by itself, I've decided to use every automatism available. So, I've reread the docs more carefully, and found <a abp="216" href="http://gcc.gnu.org/wiki/InstallingGCC">this</a> (which I had missed the first time around):</div>
</div>
<blockquote abp="218" class="tr_bq">
<div abp="219">
Alternatively, after extracting the GCC source archive, simply run the ./contrib/download_prerequisites script in the GCC source directory. That will download the support libraries and create symlinks, causing them to be built automatically as part of the GCC build process. Set GRAPHITE_LOOP_OPT=yes in the script if you want to build GCC with the Graphite loop optimizations.</div>
</blockquote>
<div abp="220">
<br /></div>
<div abp="221" style="text-align: justify;">
<div abp="222">
<code abp="223" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">GRAPHITE_LOOP_OPT=yes</code> is the default, but it doesn't hurt to check it before running the script.</div>
</div>
<div abp="224" style="text-align: justify;">
<div abp="225">
</div>
</div>
<div abp="226" style="text-align: justify;">
<div abp="227">
I've also noted that it is now possible for all prerequisites to be built together with GCC. A few months back, when I first did it, this was possible only for GMP, MPFR, and MPC (or so the docs said, at the time).</div>
<div abp="227">
</div>
</div>
<h4 abp="228" style="text-align: justify;">
Linux distros</h4>
<div abp="229" style="text-align: justify;">
<div abp="230">
After playing around with a CentOS VM, I've decided I needed something else.</div>
</div>
<div abp="231" style="text-align: justify;">
<div abp="232">
</div>
</div>
<div abp="233" style="text-align: justify;">
<div abp="234">
What did I need?</div>
</div>
<div abp="235" style="text-align: justify;">
<div abp="236">
</div>
</div>
<div abp="237" style="text-align: justify;">
<div abp="238">
Something more "bleeding edge", that gave me <em>simple</em> access to more up-to-date software. <em>Simple</em> as in "no need to set up every repo known to man" and, at the same time, as in "no need to manually configure every damn piece of software on the system". After some research, I chose Fedora 20.</div>
</div>
<div abp="239" style="text-align: justify;">
<div abp="240">
</div>
</div>
<div abp="241" style="text-align: justify;">
<div abp="242">
Why did I need it?</div>
</div>
<div abp="243" style="text-align: justify;">
<div abp="244">
</div>
</div>
<div abp="245" style="text-align: justify;">
<div abp="246">
I'm going to start taking a closer look at some open-source software and, while I've become quite comfortable with building OSS on Windows, I'd rather just install it from a repository.</div>
</div>
<div abp="247" style="text-align: justify;">
<div abp="248">
</div>
</div>
<div abp="249" style="text-align: justify;">
<div abp="250">
Couldn't I get by with CentOS?</div>
</div>
<div abp="251" style="text-align: justify;">
<div abp="252">
</div>
</div>
<div abp="253" style="text-align: justify;">
<div abp="254">
Not really. I've decided to use FileZilla as a pilot for this, and build it. Even after adding some non-official repositories on CentOS (e.g., EPEL), it was still a pain to get all the necessary packages in the required versions. On Fedora? I was running <em abp="255">make</em> in a matter of minutes.</div>
</div>
<div abp="256" style="text-align: justify;">
<div abp="257">
</div>
</div>
<div abp="258" style="text-align: justify;">
<div abp="259">
I may have to go for a memory upgrade, since I didn't design my system specs with virtualization in mind. But, for now, I'll make do without it.</div>
</div>
<div abp="260" style="text-align: justify;">
<div abp="261">
</div>
</div>
<div abp="262" style="text-align: justify;">
<div abp="263">
I did have to install a different desktop. Not only did I find GNOME Shell (Fedora's default) non-intuitive, but it was also resource-consuming. Fedora responded a lot slower than CentOS, and both VMs had the same characteristics. I switched to MATE, and it's much more responsive.</div>
</div>
<div abp="264" style="text-align: justify;">
<div abp="265">
</div>
</div>
<div abp="266" style="text-align: justify;">
<div abp="267">
I understand the need for a unified desktop experience across all devices, and I accept it brings an advantage both to the (average) user and the developer. However, not only am I perfectly capable of dealing with different paradigms on different devices, I actually prefer it that way. AFAIC, it makes sense that different devices require different experiences. On a desktop, GNOME Shell doesn't make sense for me; just like Unity, on Ubuntu, didn't; same for Windows 8 (although, to its credit, MS is making corrections). But with Linux we can, at least, switch desktops.</div>
</div>
<div abp="268" style="text-align: justify;">
<div abp="269">
</div>
<div abp="270">
Anyway...</div>
<div abp="271">
</div>
<div abp="272">
I expect to be absent again for a few weeks, since I'm going to enter the post-vacation rush, where you work like crazy to pick up everything that was left behind while on vacation.</div>
</div>
<div abp="273">
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-9435217250542844262014-07-06T14:07:00.001+01:002014-07-06T14:07:04.232+01:00C++ and Ruby - Side by side<div style="text-align: justify;">
Yes, I know, choosing this blog's name wasn't my finest moment.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
A couple of weeks ago I had to create a process to cross-validate files. Each line in those files is identified by a key (which can be repeated), and we have to sum all the values for each key in each file and compare those sums.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
So, I whipped up a Ruby script in a couple of hours, and it took me a few more hours to refine it. As a side note, the "Refinement To Do" list has been growing, but my priorities lie elsewhere, so this will stay at "good enough" for now.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Then, when I got home, I've decided to replicate that Ruby script in C++. I didn't go for changing/improving the design (although I did end up changing one detail), just replicating it.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
And I was pleasantly surprised.</div>
<div style="text-align: justify;">
<ul>
<li>It also took me a couple of hours.</li>
<li>The C++ code was not noticeably "larger" than its Ruby counterpart.</li>
</ul>
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Yes, you read it right. Not only was my "C++ productivity" on par with my "Ruby productivity", but also the resulting code was very similar, both in size and in complexity.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Let's take a look at it, shall we?</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<strong>Important:</strong> The Ruby code, as presented in this post, may not be legal Ruby code, i.e., if copy/pasted on a script, may cause errors. My concern here was readability, not correctness.</div>
<div style="text-align: justify;">
</div>
<h4 style="text-align: justify;">
Paperwork, please</h4>
<div style="text-align: justify;">
While the Ruby script needed no "paperwork", the C++ program needed some.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This was the only non-standard header I included:</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-indent: 0px;"> </pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: navy;">#include</span><span style="color: silver;"> </span><span style="color: green;"><boost/algorithm/string.hpp></span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">using</span><span style="color: silver;"> </span><span style="color: purple;">boost</span><span style="color: black;">::</span>split<span style="color: black;">;</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">using</span><span style="color: silver;"> </span><span style="color: purple;">boost</span><span style="color: black;">::</span>is_any_of<span style="color: black;">;</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">using</span><span style="color: silver;"> </span><span style="color: purple;">boost</span><span style="color: black;">::</span>replace_first_copy<span style="color: black;">;</span></pre>
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br />
And these were the definitions I had in C++:</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">using</span><span style="color: silver;"> </span><span style="color: purple;">Total</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: olive;">double</span><span style="color: black;">;</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: purple;">Total</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: silver;"> </span>VALUE_DIFF<span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: navy;">0.0009</span><span style="color: black;">;</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: purple;">Total</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: silver;"> </span>ZERO_DIFF<span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: navy;">0.0001</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"> </pre>
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">using</span><span style="color: silver;"> </span><span style="color: purple;">CardEntries</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span>map<span style="color: black;"><</span><span style="color: olive;">int</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: purple;">Total</span><span style="color: black;">>;</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">using</span><span style="color: silver;"> </span><span style="color: purple;">CardEntry</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span>pair<span style="color: black;"><</span><span style="color: olive;">int</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: purple;">Total</span><span style="color: black;">>;</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">using</span><span style="color: silver;"> </span><span style="color: purple;">SplitContainer</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span>vector<span style="color: black;"><</span><span style="color: purple;">string</span><span style="color: black;">>;</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"> </pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: navy;">#define</span><span style="color: silver;"> </span><span style="color: navy;">NOOP</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: navy;"></span> </pre>
</div>
<span style="font-size: xx-small;"></span><h4 style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
Support structures</h4>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
We created a structure to gather the data necessary to process the files. Here it is in Ruby.<br />
</div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">class TrafficFile<br />
attr_reader(:description, :filename, </span></div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> :key_position, :value_position, :calc_value)<br />
<br />
def initialize(description, filename, key_position, </span></div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> value_position = 0, &calc_value</span></div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> )<br />
@description = description<br />
@filename = filename<br />
@key_position = key_position<br />
@value_position = value_position<br />
@calc_value = calc_value<br />
end<br />
end</span></div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
<br />
The <em>key position</em> is the field number on the file containing the key. The <em>value position</em> is the field number on the file containing the value to add. Why do we also have a code block to calculate the value? Because it turned out that one of the validations had to be performed by adding three fields, instead of just one, so I decided to add the code block.</div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
</div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
It would've been easier to turn <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">value_position</code> into an array, but I wanted to experiment with code blocks. So, I've done what I usually do in these situations - I set myself a deadline (in this case, 30 minutes); if I don't have something ready when the time comes, I switch to my alternative - usually, simpler - design.<br />
</div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
And here is its counterpart in C++. I've eliminated de <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">value_position</code>/<code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">calc_value</code> dichotomy, and decided to use lambdas for every case.</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-indent: 0px;"> </pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">template</span><span style="color: silver;"> </span><span style="color: black;"><</span><span style="color: olive;">typename</span><span style="color: silver;"> </span><span style="color: purple;">T</span><span style="color: black;">></span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">struct</span><span style="color: silver;"> </span><span style="color: purple;">TrafficFile</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">TrafficFile</span><span style="color: black;">(</span><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: black;">desc</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: black;">fn</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: olive;">short</span><span style="color: silver;"> </span><span style="color: black;">kp</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: purple;">T</span><span style="color: silver;"> </span><span style="color: black;">cv</span><span style="color: black;">)</span><span style="color: silver;"> </span><span style="color: black;">:</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: maroon;">description</span><span style="color: black;">{</span><span style="color: black;">desc</span><span style="color: black;">},</span><span style="color: silver;"> </span><span style="color: maroon;">filename</span><span style="color: black;">{</span><span style="color: black;">fn</span><span style="color: black;">},</span><span style="color: silver;"> </span><span style="color: maroon;">key_position</span><span style="color: black;">{</span><span style="color: black;">kp</span><span style="color: black;">},</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: maroon;">calc_value</span><span style="color: black;">{</span><span style="color: black;">cv</span><span style="color: black;">}</span><span style="color: silver;"> </span><span style="color: black;">{}</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;"></span> </pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: maroon;">description</span><span style="color: black;">;</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: maroon;">filename</span><span style="color: black;">;</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">short</span><span style="color: silver;"> </span><span style="color: maroon;">key_position</span><span style="color: black;">;</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">T</span><span style="color: silver;"> </span><span style="color: maroon;">calc_value</span><span style="color: black;">;</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">};</span> </pre>
</div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
</div>
<div style="text-align: justify;">
<strong>Note:</strong> Yes, I'm passing objects by value (e.g., the strings above). Whenever I don't foresee an actual benefit in passing by reference, I'll stick to pass-by-value.</div>
<div style="text-align: justify;">
</div>
<h4 style="text-align: justify;">
Little Helpers</h4>
<div style="text-align: justify;">
The filenames have a date, in the format <em>MMYYYY</em>. We extract this from the name of one particular file, which serves as an index to all the other files.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Here's the Ruby method.<br /> </div>
<div style="text-align: justify;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">def get_file_date(filename)<br /> return filename.split('_')[8].split('.')[0]<br />end</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
And here's the equivalent in C++, which is pretty much... well, equivalent. It's not a one-liner, but other than that, it's exactly the same - two splits.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: black;">GetFileDate</span><span style="color: black;">(</span><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: black;">filename</span><span style="color: black;">)</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">SplitContainer</span><span style="color: silver;"> </span><span style="color: black;">c</span><span style="color: black;">;</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>split<span style="color: black;">(</span><span style="color: black;">c</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">filename</span><span style="color: black;">,</span><span style="color: silver;"> </span>is_any_of<span style="color: black;">(</span><span style="color: green;">"_"</span><span style="color: black;">));</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>split<span style="color: black;">(</span><span style="color: black;">c</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">c</span><span style="color: black;">[</span><span style="color: navy;">8</span><span style="color: black;">],</span><span style="color: silver;"> </span>is_any_of<span style="color: black;">(</span><span style="color: green;">"."</span><span style="color: black;">));</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span><span style="color: black;">c</span><span style="color: black;">[</span><span style="color: navy;">0</span><span style="color: black;">];</span></pre>
</div>
<div style="text-align: justify;">
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;"></span> </pre>
</div>
<h4 style="text-align: justify;">
Main </h4>
<div style="text-align: justify;">
Now, the entry point. This is where we have the most number of differences between Ruby and C++, because we're always passing a lambda to calculate the total in the C++ version. Other than that, it's similar.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
We're creating an object that contains all the data to describe each file being validated and to gather the data for that validation.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Here it is in Ruby.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">file_date = get_file_date(ARGV[0])</span></div>
<div style="text-align: left;">
<span style="font-family: Courier New; font-size: x-small;"></span> </div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">tel_resumo = </span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> TrafficFile.new("Telemóvel (resumo)", </span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> "#{file_date}_tlm.csv", 3, 15)<br />resumo = </span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> TrafficFile.new("Resumo", "#{file_date}_rsm.csv", 8, 13)</span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">compare(tel_resumo, resumo)</span></div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">detalhe = </span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> TrafficFile.new("Detalhe", "#{file_date}_det.csv", 4, 22)<br />tel_detalhe = </span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> TrafficFile.new("Telemóvel (detalhe)", </span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> "#{file_date}_tlm.csv", 3)</span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> do |fields|</span></div>
<div style="text-align: left;">
<span style="font-family: Courier New; font-size: x-small;"> fields[4].gsub(',', '.').to_f() + </span></div>
<div style="text-align: left;">
<span style="font-family: Courier New; font-size: x-small;"> fields[8].gsub(',', '.').to_f() + </span></div>
<div style="text-align: left;">
<span style="font-family: Courier New; font-size: x-small;"> fields[31].gsub(',', '.').to_f()<br /> end</span></div>
<span style="font-family: Courier New; font-size: x-small;"><div style="text-align: left;">
<br />compare(detalhe, tel_detalhe)</div>
<div style="text-align: left;">
<br /> </div>
</span><div style="text-align: justify;">
And here it is in C++.</div>
<div style="text-align: justify;">
</div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">int</span><span style="color: silver;"> </span><span style="color: black;">main</span><span style="color: black;">(</span><span style="color: olive;">int</span><span style="color: silver;"> </span><span style="color: black;">argc</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: silver;"> </span><span style="color: black;">*</span><span style="color: black;">argv</span><span style="color: black;">[])</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: black;">file_date</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: black;">GetFileDate</span><span style="color: black;">(</span><span style="color: purple;">string</span><span style="color: black;">{</span><span style="color: black;">argv</span><span style="color: black;">[</span><span style="color: navy;">1</span><span style="color: black;">]});</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;"></span> </pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">auto</span><span style="color: silver;"> </span><span style="color: black;">cv_tr</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: black;">[]</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: purple;">SplitContainer</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">&</span><span style="color: silver;"> </span>c<span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span><span style="color: olive;">return</span><span style="color: silver;"> </span>stod<span style="color: black;">(</span>replace_first_copy<span style="color: black;">(</span>c<span style="color: black;">[</span><span style="color: navy;">15</span><span style="color: black;">],</span><span style="color: silver;"> </span><span style="color: green;">","</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: green;">"."</span><span style="color: black;">));};</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">TrafficFile</span><span style="color: black;"><</span><span style="color: olive;">decltype</span><span style="color: black;">(</span><span style="color: black;">cv_tr</span><span style="color: black;">)></span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">tel_resumo</span><span style="color: black;">{</span><span style="color: green;">"Telemóvel</span><span style="color: silver;"> </span><span style="color: green;">(resumo)"</span><span style="color: black;">,</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">file_date</span><span style="color: silver;"> </span><span style="color: black;">+</span><span style="color: silver;"> </span><span style="color: green;">"_tlm.csv"</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: navy;">3</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">cv_tr</span><span style="color: black;">};</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;"></span> </pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">auto</span><span style="color: silver;"> </span><span style="color: black;">cv_r</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: black;">[]</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: purple;">SplitContainer</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">&</span><span style="color: silver;"> </span>c<span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span><span style="color: olive;">return</span><span style="color: silver;"> </span>stod<span style="color: black;">(</span>replace_first_copy<span style="color: black;">(</span>c<span style="color: black;">[</span><span style="color: navy;">13</span><span style="color: black;">],</span><span style="color: silver;"> </span><span style="color: green;">","</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: green;">"."</span><span style="color: black;">));};</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">TrafficFile</span><span style="color: black;"><</span><span style="color: olive;">decltype</span><span style="color: black;">(</span><span style="color: black;">cv_r</span><span style="color: black;">)></span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">resumo</span><span style="color: black;">{</span><span style="color: green;">"Resumo"</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">file_date</span><span style="color: silver;"> </span><span style="color: black;">+</span><span style="color: silver;"> </span><span style="color: green;">"_rsm.csv"</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: navy;">8</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">cv_r</span><span style="color: black;">};</span></pre>
<div style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
<span style="color: black;"></span> </div>
<div style="text-align: justify;">
</div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>Compare<span style="color: black;">(</span><span style="color: black;">tel_resumo</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">resumo</span><span style="color: black;">);</span></pre>
<div style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
<span style="color: black;"></span> </div>
<div style="text-align: justify;">
</div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">auto</span><span style="color: silver;"> </span><span style="color: black;">cv_d</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: black;">[]</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: purple;">SplitContainer</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">&</span><span style="color: silver;"> </span>c<span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span><span style="color: olive;">return</span><span style="color: silver;"> </span>stod<span style="color: black;">(</span>replace_first_copy<span style="color: black;">(</span>c<span style="color: black;">[</span><span style="color: navy;">22</span><span style="color: black;">],</span><span style="color: silver;"> </span><span style="color: green;">","</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: green;">"."</span><span style="color: black;">));};</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">TrafficFile</span><span style="color: black;"><</span><span style="color: olive;">decltype</span><span style="color: black;">(</span><span style="color: black;">cv_d</span><span style="color: black;">)></span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">detalhe</span><span style="color: black;">{</span><span style="color: green;">"Detalhe"</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">file_date</span><span style="color: silver;"> </span><span style="color: black;">+</span><span style="color: silver;"> </span><span style="color: green;">"_det.csv"</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: navy;">4</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">cv_d</span><span style="color: black;">};</span></pre>
<div style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
<span style="color: black;"></span> </div>
<div style="text-align: justify;">
</div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">auto</span><span style="color: silver;"> </span><span style="color: black;">cv_td</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: black;">[]</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: purple;">SplitContainer</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">&</span><span style="color: silver;"> </span>c<span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span><span style="color: olive;">return</span><span style="color: silver;"> </span>stod<span style="color: black;">(</span>replace_first_copy<span style="color: black;">(</span>c<span style="color: black;">[</span><span style="color: navy;">4</span><span style="color: black;">],</span><span style="color: silver;"> </span><span style="color: green;">","</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: green;">"."</span><span style="color: black;">))</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">+</span><span style="color: silver;"> </span>stod<span style="color: black;">(</span>replace_first_copy<span style="color: black;">(</span>c<span style="color: black;">[</span><span style="color: navy;">8</span><span style="color: black;">],</span><span style="color: silver;"> </span><span style="color: green;">","</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: green;">"."</span><span style="color: black;">))</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">+</span><span style="color: silver;"> </span>stod<span style="color: black;">(</span>replace_first_copy<span style="color: black;">(</span>c<span style="color: black;">[</span><span style="color: navy;">31</span><span style="color: black;">],</span><span style="color: silver;"> </span><span style="color: green;">","</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: green;">"."</span><span style="color: black;">));};</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">TrafficFile</span><span style="color: black;"><</span><span style="color: olive;">decltype</span><span style="color: black;">(</span><span style="color: black;">cv_td</span><span style="color: black;">)></span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">tel_detalhe</span><span style="color: black;">{</span><span style="color: green;">"Telemóvel</span><span style="color: silver;"> </span><span style="color: green;">(detalhe)"</span><span style="color: black;">,</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">file_date</span><span style="color: silver;"> </span><span style="color: black;">+</span><span style="color: silver;"> </span><span style="color: green;">"_tlm.csv"</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: navy;">3</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">cv_td</span><span style="color: black;">};</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;"></span> </pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>Compare<span style="color: black;">(</span><span style="color: black;">detalhe</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">tel_detalhe</span><span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">}</span></pre>
<div style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
<span style="color: black;"></span> </div>
<h4 style="text-align: justify;">
Validate</h4>
<div style="text-align: justify;">
The validation is performed by comparing files in sets of two. For each file, we load the pair <em>(key, total)</em> into a container, and then we compare the totals for each key. Since there is no guarantee that every key is present on both files, when we find a key that exists on both containers, we remove that key from both containers.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
This is the function that performs that comparison. We output every key that has different totals in both files.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
In Ruby.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">def compare(first, second)<br /> first_data = </span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> get_unified_totals(first.filename, first.key_position, </span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> first.value_position, &first.calc_value)<br /> second_data = </span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> get_unified_totals(second.filename, second.key_position, </span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> second.value_position, &second.calc_value)</span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> <br /> first_data.each() do |key, value|<br /> if second_data.has_key?(key)<br /> if (value - second_data[key]).abs() > 0.0009<br /> puts("ERRO! #{key} tem valores incoerentes: #{value}" +</span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> " e #{second_data[key]}")<br /> end</span></div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"><br /> first_data.delete(key)<br /> second_data.delete(key)<br /> end<br /> end</span></div>
<div style="text-align: left;">
<span style="font-family: Courier New; font-size: x-small;"></span> </div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> check_remaining(first_data)<br /> check_remaining(second_data)<br />end</span></div>
<div style="text-align: left;">
<br />In C++. </div>
<div style="text-align: left;">
</div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">template</span><span style="color: silver;"> </span><span style="color: black;"><</span><span style="color: olive;">typename</span><span style="color: silver;"> </span><span style="color: purple;">T1</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: olive;">typename</span><span style="color: silver;"> </span><span style="color: purple;">T2</span><span style="color: black;">></span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">void</span><span style="color: silver;"> </span><span style="color: black;">Compare</span><span style="color: black;">(</span><span style="color: purple;">T1</span><span style="color: silver;"> </span><span style="color: black;">first</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: purple;">T2</span><span style="color: silver;"> </span><span style="color: black;">second</span><span style="color: black;">)</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">{</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">CardEntries</span><span style="color: silver;"> </span><span style="color: black;">first_data</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>GetUnifiedTotals<span style="color: black;">(</span><span style="color: black;">first</span><span style="color: black;">.</span>filename<span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">first</span><span style="color: black;">.</span>key_position<span style="color: black;">,</span><span style="color: silver;"> </span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">first</span><span style="color: black;">.</span>calc_value<span style="color: black;">);</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">CardEntries</span><span style="color: silver;"> </span><span style="color: black;">second_data</span><span style="color: silver;"> </span><span style="color: black;">=</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>GetUnifiedTotals<span style="color: black;">(</span><span style="color: black;">second</span><span style="color: black;">.</span>filename<span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">second</span><span style="color: black;">.</span>key_position<span style="color: black;">,</span><span style="color: silver;"> </span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">second</span><span style="color: black;">.</span>calc_value<span style="color: black;">);</span></pre>
<div style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
<span style="color: black;"></span> </div>
<div style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
<span style="color: black;"></span>
</div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">for</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: olive;">auto</span><span style="color: silver;"> </span><span style="color: black;">it</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: black;">first_data</span><span style="color: black;">.</span>cbegin<span style="color: black;">();</span><span style="color: silver;"> </span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">it</span><span style="color: silver;"> </span><span style="color: black;">!=</span><span style="color: silver;"> </span><span style="color: black;">first_data</span><span style="color: black;">.</span>cend<span style="color: black;">();</span><span style="color: silver;"> </span><span style="color: navy;">NOOP</span><span style="color: silver;"> </span><span style="color: black;">)</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">auto</span><span style="color: silver;"> </span><span style="color: black;">f</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: black;">second_data</span><span style="color: black;">.</span>find<span style="color: black;">(</span><span style="color: black;">it</span><span style="color: black;">-></span>first<span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;"></span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">if</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: black;">f</span><span style="color: silver;"> </span><span style="color: black;">!=</span><span style="color: silver;"> </span><span style="color: black;">second_data</span><span style="color: black;">.</span>end<span style="color: black;">())</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">if</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: black;">fabs</span><span style="color: black;">(</span><span style="color: black;">it</span><span style="color: black;">-></span>second<span style="color: silver;"> </span><span style="color: black;">-</span><span style="color: silver;"> </span><span style="color: black;">f</span><span style="color: black;">-></span>second<span style="color: black;">)</span><span style="color: silver;"> </span><span style="color: black;">></span><span style="color: silver;"> </span>VALUE_DIFF<span style="color: black;">)</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>cout<span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">"ERRO!</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">it</span><span style="color: black;">-></span>first<span style="color: silver;"> </span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><span style="color: green;">tem</span><span style="color: silver;"> </span><span style="color: green;">valores</span><span style="color: silver;"> </span><span style="color: green;">incoerentes:</span><span style="color: silver;"> </span><span style="color: green;">"</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">it</span><span style="color: black;">-></span>second<span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><span style="color: green;">e</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">f</span><span style="color: black;">-></span>second<span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><span style="color: green;">("</span><span style="color: silver;"> </span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">fabs</span><span style="color: black;">(</span><span style="color: black;">it</span><span style="color: black;">-></span>second<span style="color: silver;"> </span><span style="color: black;">-</span><span style="color: silver;"> </span><span style="color: black;">f</span><span style="color: black;">-></span>second<span style="color: black;">)</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">")"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span>endl<span style="color: black;">;</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<div style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
<span style="color: black;"></span> </div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">first_data</span><span style="color: black;">.</span>erase<span style="color: black;">(</span><span style="color: black;">it</span><span style="color: black;">++);</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">second_data</span><span style="color: black;">.</span>erase<span style="color: black;">(</span><span style="color: black;">f</span><span style="color: black;">);</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">else</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">++</span><span style="color: black;">it</span><span style="color: black;">;</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<div style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
<span style="color: black;"></span> </div>
<div style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
<span style="color: black;"></span>
</div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>CheckRemaining<span style="color: black;">(</span><span style="color: black;">first_data</span><span style="color: black;">);</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>CheckRemaining<span style="color: black;">(</span><span style="color: black;">second_data</span><span style="color: black;">);</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">}</span> </pre>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Since we remove all keys that exist on both containers, in the end, each container will have only the keys that didn't exist on the other container. We then use another function to validate these keys, which should all have a 0 total.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Here's Ruby.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: left;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">def check_remaining(data_set)<br /> data_set.each() do |key, value|<br /> if (value - 0).abs() > 0.0001<br /> puts("AVISO! #{key} tem valor: #{value}")<br /> end<br /> end<br />end</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Here's C++. Once again, note the code similarity, how the C++ code isn't any more complex than the Ruby code.</div>
<div style="text-align: justify;">
</div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">void</span><span style="color: silver;"> </span><span style="color: black;">CheckRemaining</span><span style="color: black;">(</span><span style="color: purple;">CardEntries</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">data_set</span><span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">for</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: olive;">auto</span><span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">item</span><span style="color: silver;"> </span><span style="color: black;">:</span><span style="color: silver;"> </span><span style="color: black;">data_set</span><span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">if</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: black;">fabs</span><span style="color: black;">(</span><span style="color: black;">item</span><span style="color: black;">.</span>second<span style="color: silver;"> </span><span style="color: black;">-</span><span style="color: silver;"> </span><span style="color: navy;">0</span><span style="color: black;">)</span><span style="color: silver;"> </span><span style="color: black;">></span><span style="color: silver;"> </span>ZERO_DIFF<span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>cout<span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">"AVISO!</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">item</span><span style="color: black;">.</span>first<span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><span style="color: green;">tem</span><span style="color: silver;"> </span><span style="color: green;">valor:</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">item</span><span style="color: black;">.</span>second<span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span>endl<span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;"></span> </pre>
<h4 style="text-align: justify;">
Adding up</h4>
<div style="text-align: justify;">
This is the function that reads a file and creates a container with the key and its total, which is the sum of all the values for all the occurrences of the key. The file is a CSV, but since I'm on Ruby 1.8.7, I preferred not to use Ruby's CSV lib(s); after all, I just needed to split the line on a "<em>;</em>", so I did it "manually".</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">def get_unified_totals(filename, key_position, value_position = 0)<br /> totals = Hash.new(0)<br /> <br /> File.open(filename) do |file|<br /> # skip header<br /> file.gets()<br /> <br /> while line = file.gets()<br /> a = line.split(';')<br /> if block_given?()<br /> totals[a[key_position]] += yield(a)<br /> else<br /> totals[a[key_position]] += </span></div>
<div style="text-align: justify;">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> a[value_position].gsub(',', '.').to_f()<br /> end<br /> end<br /> end<br /> <br /> return totals<br />end</span></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The C++ version is a bit simpler, because we always pass a lambda.</div>
<div style="text-align: justify;">
</div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">template</span><span style="color: silver;"> </span><span style="color: black;"><</span><span style="color: olive;">typename</span><span style="color: silver;"> </span><span style="color: purple;">T</span><span style="color: black;">></span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: purple;">CardEntries</span><span style="color: silver;"> </span><span style="color: black;">GetUnifiedTotals</span><span style="color: black;">(</span><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: black;">filename</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: olive;">short</span><span style="color: silver;"> </span><span style="color: black;">key_position</span><span style="color: black;">,</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">T</span><span style="color: silver;"> </span><span style="color: black;">calc_value</span><span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>ifstream<span style="color: silver;"> </span><span style="color: black;">inFile</span><span style="color: black;">{</span><span style="color: black;">filename</span><span style="color: black;">};</span></pre>
<div style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
<span style="color: black;"></span> </div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: black;">line</span><span style="color: black;">;</span>
</pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>getline<span style="color: black;">(</span><span style="color: black;">inFile</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">line</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">inFile</span><span style="color: black;">.</span>widen<span style="color: black;">(</span><span style="color: green;">'\n'</span><span style="color: black;">)); <span style="color: green;">//</span><span style="color: silver;"> </span><span style="color: green;">Skip</span><span style="color: silver;"> </span><span style="color: green;">header</span></span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">CardEntries</span><span style="color: silver;"> </span><span style="color: black;">totals</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">SplitContainer</span><span style="color: silver;"> </span><span style="color: black;">c</span><span style="color: black;">;</span></pre>
<div style="text-align: justify;">
</div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">while</span><span style="color: black;">(</span>getline<span style="color: black;">(</span><span style="color: black;">inFile</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">line</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">inFile</span><span style="color: black;">.</span>widen<span style="color: black;">(</span><span style="color: green;">'\n'</span><span style="color: black;">)))</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span>split<span style="color: black;">(</span><span style="color: black;">c</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">line</span><span style="color: black;">,</span><span style="color: silver;"> </span>is_any_of<span style="color: black;">(</span><span style="color: green;">";"</span><span style="color: black;">));</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">totals</span><span style="color: black;">[</span>stoi<span style="color: black;">(</span><span style="color: black;">c</span><span style="color: black;">[</span><span style="color: black;">key_position</span><span style="color: black;">])]</span><span style="color: silver;"> </span><span style="color: black;">+=</span><span style="color: silver;"> </span><span style="color: black;">calc_value</span><span style="color: black;">(</span><span style="color: black;">c</span><span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<div style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
<span style="color: black;"></span> </div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span><span style="color: black;">totals</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">}</span> </pre>
<div style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
</div>
<h4 style="text-align: justify;">
TL;DR</h4>
<div style="text-align: justify;">
When you have a task to do, just pick the language you're most familiar/comfortable with, unless you have a very good reason not to. The much-famed "productivity gap" may not be as large as is usually advertised.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
One thing I read often is that a good programmer is productive/competent/idiomatic with any language. I don't doubt it, although I do struggle a bit to accept some quirks (e.g., Ruby's "no return" policy).</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
However, I believe we all have a natural affinity towards some language(s)/style(s); that's our comfort zone, and that's where we'll have a tendency to be most productive. I'll write a bit more about this on my next post.</div>
<div style="text-align: justify;">
<br /> </div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-14966388181469783662014-06-10T20:32:00.000+01:002014-06-10T20:32:43.031+01:00Processing command line options in Ruby<h4 abp="394">
The story so far</h4>
<div abp="395" style="text-align: justify;">
<div abp="1658">
I've been setting up a scripting environment at work, as I've <a abp="396" href="http://cidebycide.blogspot.pt/2014/05/its-been-long-time.html" target="_blank">mentioned previously</a>. After considering Perl, Python, and Ruby, we chose the latter.</div>
</div>
<div abp="397" style="text-align: justify;">
<div abp="1661">
</div>
</div>
<div abp="398" style="text-align: justify;">
<div abp="1663">
Ruby itself was installed from RPMs by the sysadmins. Then, I've installed Ruby Gems locally, and all the gems are also locally installed. This minimizes our dependency on the sysadmins, i.e., we don't have to open a request every time we need a new gem installed. The server has no internet connection, so we download the gems and run a local install, which means sorting out dependencies manually. So far, it has been going smoothly, and I'm quite impressed by the way gem management is handled.</div>
</div>
<div abp="399" style="text-align: justify;">
<div abp="1665">
</div>
</div>
<div abp="400" style="text-align: justify;">
<div abp="1667">
One of our top goals is working with Informix DBs, and I'm happy to report that the Ruby Informix gem installed without a single hiccup (did I already mention I'm impressed?), and worked right out of the box (because I'd like to leave that quite clear - I'm impressed).</div>
</div>
<div abp="401" style="text-align: justify;">
<div abp="1669">
</div>
</div>
<div abp="402" style="text-align: justify;">
<div abp="1671">
This move to Ruby was caused, in part, by a server migration, where we decided to take the opportunity to simplify our batch environment. We currently have a mix of Java and shell scripts, with a liberal sprinkling of awk and some Perl. We'll keep the Java processes as-is, but we're planning on moving the scripts to Ruby.</div>
</div>
<div abp="403" style="text-align: justify;">
<div abp="1673">
</div>
</div>
<div abp="404" style="text-align: justify;">
<div abp="1675">
The first goal is migrating everything to the new servers, making only the necessary changes in order to keep things working with a new set of system requirements (e.g., replacing FTP with SFTP). With time, we'll be converting all the scripting logic to Ruby.</div>
</div>
<div abp="405" style="text-align: justify;">
<div abp="1677">
</div>
</div>
<div abp="406" style="text-align: justify;">
<div abp="1679">
So, I've been diving into Ruby, in a mix of planning and prototyping, trying to get a grasp of the language's basics, and creating some building blocks for future scripts.<br />
</div>
</div>
<h4 abp="407" style="text-align: justify;">
Ruby & Command line options - GetoptLong</h4>
<div abp="409" style="text-align: justify;">
<div abp="1682">
I'm currently working on a component to process command line arguments, similar (in goal, if not in design) to what I've done <a abp="411" href="https://github.com/PauloCaetano/bluesy/blob/master/src/app_config/prog_options.h" target="_blank">here</a>.</div>
</div>
<div abp="413" style="text-align: justify;">
<div abp="1685">
</div>
</div>
<div abp="414" style="text-align: justify;">
<div abp="1687">
As I looked at how this is done in Ruby, the first option I found was <em abp="475">GetoptLong</em>. I set up the options and began writing the code to do something with it. And I immediately thought "I need something else". Why?</div>
</div>
<div abp="414" style="text-align: justify;">
<div abp="1690">
</div>
</div>
<div abp="415" style="text-align: justify;">
<div abp="1692">
Well, when you have a <a abp="477" href="http://www.ruby-doc.org/stdlib-2.1.2/libdoc/getoptlong/rdoc/GetoptLong.html" target="_blank">class</a> that lacks a method to get an option by name, forcing you to loop through all the options with a switch/case that says "If the current option is this, then do that", I have to wonder - does anyone actually think this is elegant?</div>
</div>
<div abp="415" style="text-align: justify;">
<div abp="1695">
</div>
</div>
<div abp="417" style="text-align: justify;">
<div abp="1697">
Yes, I know. I could build such a method myself. After all, Ruby allows me to add methods to existing classes, so I could add a getter that took a name as argument, and returned the value of the option with that name or <em abp="532">nil</em>/exception if it didn't exist. But I couldn't believe there was no alternative. I couldn't be the only one thinking "This is sub-par design", there had to be a better way.<br />
</div>
</div>
<h4 abp="417" style="text-align: justify;">
Ruby & Command line options - OptionParser</h4>
<div abp="419" style="text-align: justify;">
<div abp="1701">
There is. It's called <a abp="535" href="http://www.ruby-doc.org/stdlib-2.1.2/libdoc/optparse/rdoc/OptionParser.html" target="_blank">OptionParser</a>. It's definitely better, and it seems quite powerful and complete. However, I've yet to find an example/tutorial that shows me how to do a couple of things that are dead simple in, e.g., <em abp="1703">Boost.Program_options</em>:</div>
<div abp="1704">
</div>
</div>
<div abp="420" style="text-align: justify;">
<div abp="1706">
The first is setting up a required option, making the option processing throw an exception if it's not present. Notice how easy it is with Boost:</div>
</div>
<div abp="420" style="text-align: justify;">
<div abp="1708">
</div>
</div>
<div abp="1709">
<div abp="1710">
<span abp="1711" style="font-family: "Courier New", Courier, monospace; font-size: x-small;">("fich,f", po::value<string>(&fileName)-><strong abp="1712"><em abp="1713"><span abp="1714" style="background-color: yellow;">required()</span></em></strong>,</span><span abp="1717" style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> "Ficheiro a processar")</span></div>
</div>
<div abp="1718">
<div abp="1719">
</div>
</div>
<div abp="421" style="text-align: justify;">
<div abp="1721">
<em abp="1722">OptionParser</em> has a concept called "mandatory", but it means "If you include this option in the command line, you must specify its value". However, if you don't include it, no exception is thrown.</div>
</div>
<div abp="421" style="text-align: justify;">
<div abp="1724">
</div>
</div>
<div abp="421" style="text-align: justify;">
<div abp="1726">
The second is setting up a default value directly in the options definition, instead of having to do it in some other code, even if it's local to the options definition. Once again, courtesy of Boost:</div>
</div>
<div abp="421" style="text-align: justify;">
<div abp="1728">
</div>
</div>
<div abp="421" style="text-align: justify;">
<div abp="1730">
<span abp="1731" style="font-family: "Courier New", Courier, monospace; font-size: x-small;">("validnc,c", po::bool_switch(&validateFieldNr)-><strong abp="1732"><em abp="1733"><span abp="1734" style="background-color: yellow;">default_value(false)</span></em></strong>,</span><br />
<div abp="1735">
<span abp="1736" style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> "Valida nr. de campos por linha e termina")</span></div>
</div>
</div>
<div abp="421" style="text-align: justify;">
<div abp="1738">
<br />
And I already have a pet peeve with <em abp="1739">OptionParser</em>. Suppose you have this:</div>
</div>
<div abp="421" style="text-align: justify;">
<div abp="1741">
<br /></div>
<div abp="1742">
<span abp="1743" style="font-family: "Courier New", Courier, monospace; font-size: x-small;">options[:delimiter] = ';'</span><br />
<div abp="1744">
<span abp="1745" style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> opts.on('-d', '--delimiter', </span><span abp="1748" style="font-family: "Courier New", Courier, monospace; font-size: x-small;">'Delimitador utilizado no ficheiro de dados') </span><span abp="1751" style="font-family: "Courier New", Courier, monospace; font-size: x-small;">do |delim|</span></div>
</div>
</div>
<div abp="421" style="text-align: justify;">
<div abp="1750">
<div abp="1752">
<span abp="1753" style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> options[:delimiter] = delim</span></div>
<div abp="1754">
<span abp="1755" style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> end</span></div>
</div>
</div>
<div abp="421" style="text-align: justify;">
<div abp="1757">
<br /></div>
<div abp="1758">
Looking at this, you'd think "I have a default delimiter, ';', and I have an option to specify a different delimiter on the command line". Seems logical, right? Well, not quite. If you specify this option on the command line, <code abp="1759" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">options[:delimiter]</code> will be set to <code abp="1760" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">true</code>, and your delimiter will be left in <code abp="1761" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">ARGV</code>, i.e., it won't be consumed by <em abp="1762">OptionParser</em>.</div>
</div>
<div abp="421" style="text-align: justify;">
<div abp="1764">
</div>
</div>
<div abp="421" style="text-align: justify;">
<div abp="1766">
Here's what you need, instead:</div>
</div>
<div abp="421" style="text-align: justify;">
</div>
<div abp="421" style="text-align: justify;">
<span abp="1769" style="font-family: "Courier New", Courier, monospace; font-size: x-small;">options[:delimiter] = ';'</span><br />
<div abp="1770">
<span abp="1771" style="font-family: "Courier New", Courier, monospace; font-size: x-small;">opts.on('-d', '--delimiter <strong abp="1772"><em abp="1773"><span abp="1774" style="background-color: yellow;">delim</span></em></strong>', </span><span abp="1776" style="font-family: "Courier New", Courier, monospace; font-size: x-small;">'Delimitador utilizado no ficheiro de dados') d</span><span abp="1778" style="font-family: "Courier New", Courier, monospace; font-size: x-small;">o |delim|</span></div>
<div abp="421" style="text-align: justify;">
<div abp="1779">
<span abp="1780" style="font-family: "Courier New", Courier, monospace; font-size: x-small;"> options[:delimiter] = delim</span></div>
<div abp="1781">
<span abp="1782" style="font-family: "Courier New", Courier, monospace; font-size: x-small;">end</span></div>
<div abp="1783">
</div>
<div abp="421" style="text-align: justify;">
By the way, you don't need to use "delim" in '--delimiter delim', you can use anything, as long as it's there. Fortunately, I wasn't the first one to get bitten by this little detail, and I quickly found <a abp="1785" href="https://www.ruby-forum.com/topic/4417263" target="_blank">someone else wondering why were all his values true or false</a>.<br />
<div abp="1786">
</div>
<div abp="421" style="text-align: justify;">
While I can't help but wonder at the reasoning that led to "This looks like a good idea", my ignorance on the language/class means I'll just live with it, since I don't feel competent to do better.<br />
<div abp="1788">
</div>
<h4 abp="421" style="text-align: justify;">
Pet Peeve - Documentation</h4>
<div abp="421" style="text-align: justify;">
Yes, this is my pet peeve. Docs. <em abp="1791">OptionsParser</em>'s <a abp="1792" href="http://www.ruby-doc.org/stdlib-2.1.2/libdoc/optparse/rdoc/OptionParser.html#class-OptionParser-label-Minimal+example" target="_blank">minimal example</a> is too minimal to be useful, and the <a abp="1793" href="http://www.ruby-doc.org/stdlib-2.1.2/libdoc/optparse/rdoc/OptionParser.html#class-OptionParser-label-Complete+example" target="_blank">complete example</a> is so crowded, that details like this get lost in the noise; not that there's anything wrong with that, that's what a complete example is for, it's the minimal example that shouldn't be quite so minimal.</div>
<div abp="421" style="text-align: justify;">
</div>
<div abp="421" style="text-align: justify;">
I believe a rule like "If you want your options to have a value, you have to put something - anything - following it on the long form string" should be made more visible in the documentation. Actually, most of the Ruby documentation I've found so far is quite minimalistic/optimistic. Tutorials like Boost's (yes, I'm using Boost as an example of good documentation; no, I never thought that day would come), or troubleshooting sections are absent from most of the docs I've found.</div>
<div abp="421" style="text-align: justify;">
</div>
<div abp="421" style="text-align: justify;">
E.g., take a look at <a abp="1798" href="http://www.ruby-doc.org/stdlib-2.1.2/libdoc/optparse/rdoc/OptionParser.html#method-i-make_switch" target="_blank">make_switch</a> and see what you can make of it. Then, see the <a abp="1799" href="http://www.ruby-doc.org/stdlib-2.1.2/libdoc/optparse/rdoc/OptionParser.html#class-OptionParser-label-Complete+example" target="_blank">complete example</a>. Finally, <a abp="1800" href="http://ruby.about.com/od/advancedruby/a/optionparser2.htm" target="_blank">look at this tutorial</a>. It's only after I read this tutorial that I understood the semantics of "mandatory" and "optional" in this context, and gained a better understanding of how <em abp="1801">OptionParser</em> works.<br />
<div abp="1802">
</div>
<div abp="421" style="text-align: justify;">
And going back to the "optimistic" bit I mentioned above, here's what I mean - sentences like these (which are from the tutorial) should be in the class's docs:<br />
<ul abp="1804">
<li abp="1805">Switches that take a parameter only need to state the parameter name in the long form of the switch.</li>
<li abp="1806">While your option string can define the parameter to be called "a,b,c", OptionParser will blindly allow any number of elements in the list. So, if you need a specific number of elements, be sure to check the array length yourself.</li>
</ul>
<div abp="1807">
<br />
Another example - if you go to <a abp="1808" href="https://rubygems.org/">rubygems.org</a>, you have the <a abp="1809" href="https://rubygems.org/pages/download">installation instructions</a>, which end with this:</div>
<div abp="421">
<div abp="1812">
<blockquote abp="1813" class="tr_bq">
For more details and other options, see: </blockquote>
<blockquote abp="1814" class="tr_bq">
ruby setup.rb --help</blockquote>
And, after a few hours of dealing with issues on Ruby Gems setup, I had to ask - why doesn't it end with this:<br />
<div abp="1815">
<blockquote abp="1816" class="tr_bq">
For more details and other options, see <<em abp="1817">this link for online docs, where we explain said details and options with more depth than we ever will in a help message</em>></blockquote>
<div abp="1818">
<br /></div>
<div abp="1819" style="text-align: justify;">
Then, we have the <a abp="1821" href="http://guides.rubygems.org/">guides</a>. Filled with useful info, no denying that. However, when I needed to learn about things like <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">GEM_HOME</code> and <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">RUBYLIB</code>, I had to go elsewhere. While we could argue the latter is not actually Gem specific, I still believe it should be there, close to the sections regarding Ruby Gems installation and setup. Not all of us can just go <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">gem update</code> or <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">ruby setup.rb</code> with "<em>you may need admin/root</em>". Some of us don't even have an internet connection to begin with.</div>
<div abp="1824">
</div>
<h4 abp="1824">
TL;DR</h4>
<div abp="1824">
As I dive into Ruby, I like most of what I see, especially after having learnt to appreciate duck typing, available with C++ templates, and the total decoupling it provides.</div>
<div abp="1824">
</div>
<div abp="1824">
So far, I've met a few design choices that baffle me, and the docs are definitely a weak point. Fortunately, there's this internet thingie where people are more than willing to share their knowledge.</div>
<div abp="1824">
</div>
<div abp="1824">
As for processing command line arguments, I've settled for this "pattern":</div>
<div abp="1824">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">options = {}</span></div>
<div abp="1824">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"></span> </div>
<div abp="1824">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">options[:delimiter] = ';'<br />opts.on('-d', '--delimiter delim', </span><span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">'Delimitador utilizado no ficheiro de dados') </span><span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">do |delim|<br /> options[:delimiter] = delim<br />end</span></div>
<div abp="1824">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"></span> </div>
<div abp="1824">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">options[:title] = false<br />opts.on('-t', '--title', </span><span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">'Indica se o ficheiro de dados tem header de título') </span><span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">do<br /> options[:title] = true<br />end</span></div>
<div abp="1824">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;"></span> </div>
<div abp="1824">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">options[:settings] = nil<br />opts.on('-s', '--settings sf', 'Ficheiro de configurações') do |sf|<br /> options[:settings] = sf<br />end</span></div>
<div abp="1824">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">...</span></div>
<div abp="1824">
<span style="font-family: "Courier New", Courier, monospace; font-size: x-small;">if options[:settings] == nil<br /> puts('Tem que indicar o ficheiro a processar')<br /> usage()<br /> exit<br />end</span></div>
<div abp="1824">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com2tag:blogger.com,1999:blog-1647814752446097280.post-66013516746937204802014-05-29T08:47:00.002+01:002014-05-29T08:55:54.316+01:00What is performance?<div style="text-align: justify;">
I've restarted watching Alex Stepanov's A9 Lectures, "Efficient Programming with Components", and if there's one thing I find essential in what he says is that, despite all the "programming recipes" we find and use, it's important that we think. I've recently been reminded of this need to think, concerning optimization.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
We all have our recipes. As far as optimization is concerned, my recipe is:</div>
<div style="text-align: justify;">
<ul>
<li><div style="text-align: justify;">
Go for readability first. Optimize as needed.</div>
</li>
<li><div style="text-align: justify;">
"<em>Using C++ == you should extract every single ounce of performance available, because otherwise you'd be more productive in any other programming language</em>" is not a dogma. And, as far as productivity goes, it's not even necessarily true.</div>
</li>
</ul>
</div>
<div style="text-align: justify;">
<br />
<h4>
A simple scenario</h4>
<div style="text-align: justify;">
Suppose we have a list of <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">char[]</code> and we want to find duplicates on said list. In its simplest form, testing two arrays for equality means traversing both, comparing each element until we reach the end of either array, or find a difference.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
We can consider several additions to this algorithm, in order to optimise it.<br />
</div>
<h4>
Test for self</h4>
<div style="text-align: justify;">
We could start by testing for self-comparison. Stepanov has a point when he says this is not an optimization, because most of the time we will not be comparing an element (in our case, a <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">char[]</code>) to itself. This brings us to one of those cases where we need to think. Maybe not on equality, since that is trivial; but let's consider assignment.</div>
<br />
<div style="text-align: justify;">
When defining assignment, should we test for self-assignment? All over the web, the recipes sound a very loud "YES". And yet, most of the time, that test will evaluate to false. The question we should ask ourselves is - if I perform self-assignment, what will happen?</div>
<br />
<div style="text-align: justify;">
Will I release/duplicate resources? Will I invalidate a class's invariants? Then, self-assignment must be prevented, and the test is required. Not because of optimization, but because a particular class requires it. If not, will it be terribly expensive? In this case, it may actually be an optimization. Will we be self-assigning some floats? How expensive is that? OTOH, how expensive is the test? Is it even worth thinking about, or should we just follow the recipe and put it in there by default?</div>
<br />
<div style="text-align: justify;">
As with everything concerning optimization, there's no clear-cut answer. Even though I'm inclined to agree with Stepanov on this, I'd probably include the test for self-assignment by default, and consider removing it if, after profiling my code, I could make the case that removing it would benefit performance.<br />
</div>
<h4>
Test for size</h4>
<div style="text-align: justify;">
Back to our quest for duplicates on a list, we could test for different sizes. Suppose we store each of our elements in a simple structure like this:</div>
<div style="text-align: justify;">
</div>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">struct</span><span style="color: silver;"> </span><span style="color: purple;">SimpleArray</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">size_t</span><span style="color: silver;"> </span><span style="color: maroon;">size</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: black;">*</span><span style="color: silver;"> </span><span style="color: maroon;">arr</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">};</span></pre>
<br />
<div style="text-align: justify;">
Testing for size means not having to traverse the array, so that's a good thing. Not for the traversing itself, that would be trivial, unless our arrays were longer than the processor's cache lines, but because we'd avoid going to memory again to read <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">*arr</code> (<code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">arr</code> itself should be on the processor's cache). That is a good thing.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Except when it isn't.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
What if you know your data set is composed of arrays that have fixed length? Again, you may measure and conclude the impact of this test is negligible. Or it may mean the difference between respecting a performance requirement or not. In this particular case, if I had to optimise, I'd skip the structure and work directly on the array, because the size would be irrelevant.</div>
<div style="text-align: justify;">
</div>
<h4 style="text-align: justify;">
A simple scenario - what we don't know...</h4>
<div style="text-align: justify;">
We need to think, in order to make decisions. And for that, we need data.</div>
<ul>
<li><div style="text-align: justify;">
What is our process doing? If we're invoking services across a network, I doubt either a test for self-comparison or a size test on fixed size arrays will have much of an impact.</div>
</li>
<li><div style="text-align: justify;">
What is the actual weight of these trivial operations? Under our expected workload? Under our worst-case scenario? Under 4x our worst-case scenario? When another process on our machine suddenly goes haywire and gobbles up resources like crazy?</div>
</li>
<li><div style="text-align: justify;">
Is our process critical? Does it have strict performance requirements, with associated penalties?</div>
</li>
</ul>
<div style="text-align: justify;">
</div>
<h4>
The big picture</h4>
<div style="text-align: justify;">
We sometimes have to deal with performance issues, where all the data we have to perform an analysis is "This damn thing is too slow". Based on this treasure trove of data, we have to consider: Our application; the application servers; the web servers; the database servers; the middleware servers; the servers hosting the services we consume (usually, via the middleware servers); and all the myriad of network equipment allowing all these nodes to communicate.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
And I don't need more than two hands to count the cases where performance-related issues were caused by application code. And, most of those cases were caused by poor design, rather than by poor implementation - such as an app we received where an operation that failed was placed back into the queue for retrying; but <em>a)</em> instead of applying a delay before retrying, it was placed in the queue for immediate reprocessing; and <em>b)</em> it was placed back into the queue even if the error was not recoverable (e.g., a telephone number with 5 digits). As you might imagine, much fun (and quasi-DOS attacks) ensued.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
So, let's get back to our title...</div>
<div style="text-align: justify;">
</div>
<h4 style="text-align: justify;">
What is performance?</h4>
<div style="text-align: justify;">
When we think of performance, we envision CPU cycles and cache hits/misses; or that we're processing X lines per second from this file, and we need to process 4X; or sending data via the network, and can we really afford to use SOAP, or should we choose a light-weight protocol (or even roll our own).</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Suppose we have <em>Platform A</em>, which invokes a service on <em>Platform B</em>, via a <em>Middleware Server</em>. The service on <em>PlatB</em> sends back <em><u>something</u></em> which we then use to call another service on <em>PlatB</em>, which gives us the actual result.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The straightforward implementation looks like this:</div>
<div style="text-align: justify;">
</div>
<div style="text-align: left;">
PlatA (invoke) -> MWare (invoke) -> PlatB -> (return) -> MWare (return) -> Plat A<br />
PlatA (invoke) -> MWare (invoke) -> PlatB -> (return) -> MWare (return) -> Plat A</div>
<div style="text-align: left;">
<br />
On invocation #1, <em>PlatA</em> gets the <em><u>something</u></em> required to get the result, and on invocation #2 gets the actual result.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Now, looking at this, we have the obvious optimization:</div>
<div style="text-align: justify;">
</div>
<div style="text-align: left;">
PlatA (invoke) -> MWare (invoke) -> PlatB -> (return) -> MWare<br />
MWare (invoke) -> PlatB -> (return) -> MWare (return) -> Plat A</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
In fact, not only have we just saved a few seconds from the whole process, but we also abstracted <em>PlatA</em> from <em>PlatB's</em> two-call design. Brilliant, right?</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Well...</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Let's suppose we're responsible for <em>PlatA</em> and we receive a complaint from a costumer, saying his data is all wrong and he won't pay his invoice until we sort it out. Our analysis concludes we're getting wrong data from <em>PlatB</em>. We contact their support team, but in order to perform their analysis they require the <em><u>something</u></em> they sent us for that particular invocation. So, now we have to contact the <em>MWare</em> support team, ask for that piece of data, and then send it to <em>PlatB</em>'s team. And, during all this time, the costumer's waiting; and our invoice is not getting paid.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
"<em>Hold on!</em>" you say "<em>That's not related to process performance, that's an operational problem</em>". Yes, it is. And that's irrelevant, unless you're developing in some sort of hermit's vacuum with no contact with the organization for which you develop. Is that the case? I didn't think so.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Yes, the fact that we may have to wait 1-2 hours before we even begin to actually analyse the cause of the costumer's complaint is an operational problem. But that doesn't make it - and its consequences - any less real. And the potential of this operational problem has been fulfilled by our optimization.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Let's look at the gains and losses of this optimization:</div>
<ul>
<li><div style="text-align: justify;">
We've cut a few seconds off each invocation. Let's be optimistic and assume few == 10.</div>
</li>
<li>We've added 1-2 hours to the response time, in case of costumer's complaints.</li>
</ul>
<div style="text-align: justify;">
If we look at the "recipe" that says "don't optimize for the uncommon case", everything looks fine. However, different cases have different weights, and if there's one particular case where you want to be as fast as you can is when you've got an unsatisfied customer waiting for an answer (and saying he won't pay you until he gets one).</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
So much for recipes...</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
So, all things considered, what is performance? I don't have a clear-cut answer to this question, but I believe it goes beyond "how many requests per second can we handle".<br />
</div>
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-37051260255868786042014-05-22T22:44:00.000+01:002014-05-22T22:44:39.106+01:00Logger Abstraction (PoC)<div abp="200" style="text-align: justify;">
<div abp="424">
<div abp="831">
I've finally uploaded my logging macros to <a abp="833" href="https://github.com/PauloCaetano/SimpleSampleTuts/tree/master/MacroLogger" target="_blank">github</a>, along with a sample program (you must have either Boost Log or Poco installed to run it). In this post, I'll detail its design.</div>
</div>
</div>
<div abp="201" style="text-align: justify;">
<div abp="426">
<div abp="837">
</div>
</div>
</div>
<div abp="202" style="text-align: justify;">
<div abp="428">
<div abp="840">
My original requirements were prompted by a particular "use-case" - adding reusable classes to an application and allowing those classes to use the application's logging implementation, instead of whatever implementation was originally used. So, in this scenario, my requirements translate to: <strong>1)</strong> The reusable classes must be used with no changes; and <strong>2)</strong> The application developer should only need to create a header file with a list of well-defined macros that will invoke the app's logging implementation, thus causing the reusable classes to invoke that same implementation.</div>
</div>
</div>
<div abp="203" style="text-align: justify;">
<div abp="430">
<div abp="843">
</div>
</div>
</div>
<div abp="204" style="text-align: justify;">
<div abp="432">
<div abp="846">
I've divided this into several header files, keeping in mind requirement #2. Let's take a look at these header files, then. </div>
<div abp="846">
</div>
</div>
</div>
<h4 abp="205">
Macro Overloading - macro_overload_base.h</h4>
<div abp="206" style="text-align: justify;">
<div abp="435">
<div abp="850">
This is the foundation of it all. It's a group of macros that allow overloading based on the number of arguments, up to a limit of 16.</div>
</div>
</div>
<div abp="207" style="text-align: justify;">
<div abp="437">
<div abp="853">
</div>
</div>
</div>
<div abp="208" style="text-align: justify;">
<div abp="439">
<div abp="856">
My first design required the distinction between zero arguments, one argument, and more than one argument. However, the complexity of correctly detecting zero arguments was more than I was willing to accept, so I've worked around that requirement. Detecting invocations with one argument proved to be good enough, and the resulting macros, although still ugly, are a lot simpler.</div>
</div>
</div>
<div abp="209" style="text-align: justify;">
<div abp="441">
<div abp="859">
</div>
</div>
</div>
<div abp="210" style="text-align: justify;">
<div abp="443">
<div abp="862">
I've been all over the web while searching for this, and I've been a bit beyond my knowledge quite some times (which was one of the reasons why I decided to work around the zero arguments requirement); These were <a abp="212" href="http://efesx.com/2010/07/17/variadic-macro-to-count-number-of-arguments/" target="_blank">my</a> <a abp="315" href="http://stackoverflow.com/questions/1872220/is-it-possible-to-iterate-over-arguments-in-variadic-macros" target="_blank">starting</a> <a abp="446" href="http://stackoverflow.com/questions/11761703/overloading-macro-on-number-of-arguments" target="_blank">points</a>, in case you're interested.</div>
</div>
</div>
<div abp="210" style="text-align: justify;">
<div abp="448">
<div abp="868">
</div>
</div>
</div>
<div abp="217" style="text-align: justify;">
<div abp="450">
<div abp="871">
Detecting the number of arguments is up to the <code abp="451" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">PCBASE__MOVERLOAD_SELECT_VALUE</code> macro. In order to make it work, you must call it with the correct list of values. <code abp="452" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">PCBASE__MOVERLOAD_ONE_ARG_OR_MORE</code> calls it like this</div>
</div>
</div>
<div abp="218">
<div abp="454">
<div abp="876">
<br /></div>
</div>
<pre abp="455" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="456" style="color: navy;">#define</span><span abp="457" style="color: silver;"> </span><span abp="458" style="color: navy;">PCBASE__MOVERLOAD_ONE_ARG_OR_MORE</span><span abp="459" style="color: black;">(...)</span><span abp="460" style="color: silver;"> </span><span abp="461" style="color: silver;">\</span></pre>
<pre abp="462" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="463" style="color: silver;"> </span><span abp="464" style="color: navy;">PCBASE__MOVERLOAD_SELECT_VALUE</span><span abp="465" style="color: black;">(</span>__VA_ARGS__<span abp="466" style="color: black;">,</span><span abp="467" style="color: silver;">\</span></pre>
<pre abp="468" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="469" style="color: silver;"> </span><span abp="470" style="color: navy;">2</span><span abp="471" style="color: black;">,</span><span abp="472" style="color: navy;">2</span><span abp="473" style="color: black;">,</span><span abp="474" style="color: navy;">2</span><span abp="475" style="color: black;">,</span><span abp="476" style="color: navy;">2</span><span abp="477" style="color: black;">,</span><span abp="478" style="color: navy;">2</span><span abp="479" style="color: black;">,</span><span abp="480" style="color: navy;">2</span><span abp="481" style="color: black;">,</span><span abp="482" style="color: navy;">2</span><span abp="483" style="color: black;">,</span><span abp="484" style="color: navy;">2</span><span abp="485" style="color: black;">,</span><span abp="486" style="color: navy;">2</span><span abp="487" style="color: black;">,</span><span abp="488" style="color: navy;">2</span><span abp="489" style="color: black;">,</span><span abp="490" style="color: navy;">2</span><span abp="491" style="color: black;">,</span><span abp="492" style="color: navy;">2</span><span abp="493" style="color: black;">,</span><span abp="494" style="color: navy;">2</span><span abp="495" style="color: black;">,</span><span abp="496" style="color: navy;">2</span><span abp="497" style="color: black;">,</span><span abp="498" style="color: navy;">2</span><span abp="499" style="color: black;">,</span><span abp="500" style="color: navy;">1</span><span abp="501" style="color: black;">)</span></pre>
</div>
<div abp="219">
<div abp="503">
<div abp="926">
</div>
</div>
</div>
<div abp="219" style="text-align: justify;">
<div abp="505">
<div abp="929">
because we just want to know if we have one argument or more than one argument.</div>
</div>
</div>
<div abp="219" style="text-align: justify;">
<div abp="507">
<div abp="932">
<br /></div>
</div>
</div>
<div abp="219" style="text-align: justify;">
<div abp="509">
<div abp="935">
OTOH, <code abp="510" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">PCBASE__MOVERLOAD_VA_NUM_ARGS</code> calls it like this</div>
</div>
</div>
<div abp="219">
<div abp="512">
<div abp="939">
</div>
</div>
</div>
<div abp="219">
<pre abp="514" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="515" style="color: navy;">#define</span><span abp="516" style="color: silver;"> </span><span abp="517" style="color: navy;">PCBASE__MOVERLOAD_VA_NUM_ARGS</span><span abp="518" style="color: black;">(...)</span><span abp="519" style="color: silver;"> </span><span abp="520" style="color: silver;">\</span></pre>
</div>
<div abp="219">
<pre abp="522" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="523" style="color: silver;"> </span><span abp="524" style="color: navy;">PCBASE__MOVERLOAD_SELECT_VALUE</span><span abp="525" style="color: black;">(</span>__VA_ARGS__<span abp="526" style="color: black;">,</span><span abp="527" style="color: silver;"> \</span></pre>
</div>
<div abp="219">
<pre abp="529" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="530" style="color: silver;"> </span><span abp="531" style="color: navy;">16</span><span abp="532" style="color: black;">,</span><span abp="533" style="color: navy;">15</span><span abp="534" style="color: black;">,</span><span abp="535" style="color: navy;">14</span><span abp="536" style="color: black;">,</span><span abp="537" style="color: navy;">13</span><span abp="538" style="color: black;">,</span><span abp="539" style="color: navy;">12</span><span abp="540" style="color: black;">,</span><span abp="541" style="color: navy;">11</span><span abp="542" style="color: black;">,</span><span abp="543" style="color: navy;">9</span><span abp="544" style="color: black;">,</span><span abp="545" style="color: navy;">8</span><span abp="546" style="color: black;">,</span><span abp="547" style="color: navy;">7</span><span abp="548" style="color: black;">,</span><span abp="549" style="color: navy;">6</span><span abp="550" style="color: black;">,</span><span abp="551" style="color: navy;">5</span><span abp="552" style="color: black;">,</span><span abp="553" style="color: navy;">4</span><span abp="554" style="color: black;">,</span><span abp="555" style="color: navy;">3</span><span abp="556" style="color: black;">,</span><span abp="557" style="color: navy;">2</span><span abp="558" style="color: black;">,</span><span abp="559" style="color: navy;">1</span><span abp="560" style="color: black;">)</span></pre>
</div>
<div abp="219">
<div abp="989">
<br /></div>
</div>
<div abp="219" style="text-align: justify;">
<div abp="991">
because we need to know the exact number of arguments. <code abp="563" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">PCBASE__MOVERLOAD_FOR_EACH</code> does something similar, but passes as arguments the names of the macros that will allow to apply an action to each argument. E.g.,</div>
</div>
<div abp="219">
<div abp="994">
<span abp="565" style="color: silver;"> </span></div>
</div>
<div abp="219">
<pre abp="567" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="568" style="color: navy;">PCBASE__MOVERLOAD_FOR_EACH</span><span abp="569" style="color: black;">(<<,</span><span abp="570" style="color: silver;"> </span><span abp="571" style="color: green;">"["</span><span abp="572" style="color: black;">,</span><span abp="573" style="color: silver;"> </span>__FILE__<span abp="574" style="color: black;">,</span><span abp="575" style="color: silver;"> </span><span abp="576" style="color: green;">":"</span><span abp="577" style="color: black;">,</span><span abp="578" style="color: silver;"> </span>__LINE__<span abp="579" style="color: black;">,</span><span abp="580" style="color: silver;"> </span><span abp="581" style="color: green;">"]</span><span abp="582" style="color: silver;"> </span><span abp="583" style="color: green;">"</span><span abp="584" style="color: black;">,</span><span abp="585" style="color: silver;"> </span></pre>
</div>
<div abp="219">
<pre abp="587" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="588" style="color: silver;"> </span><span abp="589" style="color: green;">"Blimey!</span><span abp="590" style="color: silver;"> </span><span abp="591" style="color: green;">I</span><span abp="592" style="color: silver;"> </span><span abp="593" style="color: green;">didn't</span><span abp="594" style="color: silver;"> </span><span abp="595" style="color: green;">expect</span><span abp="596" style="color: silver;"> </span><span abp="597" style="color: green;">the</span><span abp="598" style="color: silver;"> </span><span abp="599" style="color: green;">Spanish</span><span abp="600" style="color: silver;"> </span><span abp="601" style="color: green;">Inquisition!"</span><span abp="602" style="color: black;">,</span><span abp="603" style="color: silver;"> </span></pre>
</div>
<div abp="219">
<pre abp="605" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="606" style="color: silver;"> </span><span abp="607" style="color: black;">chiefWeapons</span><span abp="608" style="color: black;">,</span><span abp="609" style="color: silver;"> </span><span abp="610" style="color: black;">mill</span><span abp="611" style="color: black;">.</span><span abp="612" style="color: black;">Trouble</span><span abp="613" style="color: black;">(),</span><span abp="614" style="color: silver;"> </span><span abp="615" style="color: navy;">42</span><span abp="616" style="color: black;">);</span></pre>
</div>
<div abp="219">
</div>
<div abp="219">
<div abp="1049">
</div>
<div abp="1049">
becomes</div>
</div>
<div abp="219">
<div abp="1051">
<span abp="620" style="color: silver;"> </span></div>
</div>
<div abp="219">
<pre abp="622" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="623" style="color: black;"><<</span><span abp="624" style="color: silver;"> </span><span abp="625" style="color: green;">"["</span><span abp="626" style="color: silver;"> </span><span abp="627" style="color: black;"><<</span><span abp="628" style="color: silver;"> </span>__FILE__<span abp="629" style="color: silver;"> </span><span abp="630" style="color: black;"><<</span><span abp="631" style="color: silver;"> </span><span abp="632" style="color: green;">":"</span><span abp="633" style="color: silver;"> </span><span abp="634" style="color: black;"><<</span><span abp="635" style="color: silver;"> </span>__LINE__<span abp="636" style="color: silver;"> </span><span abp="637" style="color: black;"><<</span><span abp="638" style="color: silver;"> </span><span abp="639" style="color: green;">"]</span><span abp="640" style="color: silver;"> </span><span abp="641" style="color: green;">"</span><span abp="642" style="color: silver;"> </span></pre>
</div>
<div abp="219">
<pre abp="644" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="645" style="color: silver;"> </span><span abp="646" style="color: black;"><<</span><span abp="647" style="color: silver;"> </span><span abp="648" style="color: green;">"Blimey!</span><span abp="649" style="color: silver;"> </span><span abp="650" style="color: green;">I</span><span abp="651" style="color: silver;"> </span><span abp="652" style="color: green;">didn't</span><span abp="653" style="color: silver;"> </span><span abp="654" style="color: green;">expect</span><span abp="655" style="color: silver;"> </span><span abp="656" style="color: green;">the</span><span abp="657" style="color: silver;"> </span><span abp="658" style="color: green;">Spanish</span><span abp="659" style="color: silver;"> </span><span abp="660" style="color: green;">Inquisition!"</span><span abp="661" style="color: silver;"> </span></pre>
</div>
<div abp="219">
<pre abp="663" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="664" style="color: silver;"> </span><span abp="665" style="color: black;"><<</span><span abp="666" style="color: silver;"> </span><span abp="667" style="color: black;">chiefWeapons</span><span abp="668" style="color: silver;"> </span><span abp="669" style="color: black;"><<</span><span abp="670" style="color: silver;"> </span><span abp="671" style="color: black;">mill</span><span abp="672" style="color: black;">.</span><span abp="673" style="color: black;">Trouble</span><span abp="674" style="color: black;">()</span><span abp="675" style="color: silver;"> </span><span abp="676" style="color: black;"><<</span><span abp="677" style="color: silver;"> </span><span abp="678" style="color: navy;">42</span></pre>
</div>
<div abp="219">
</div>
<div abp="219" style="text-align: justify;">
<div abp="1113">
</div>
<div abp="1113">
You may have noticed the macro names look quite ugly. Since there's no namespace partitioning with macros, I've decided to make these names as ugly as I possibly can, to minimize name clashing.</div>
</div>
<div abp="219" style="text-align: justify;">
<div abp="1115">
</div>
</div>
<div abp="219" style="text-align: justify;">
<div abp="1117">
Now, Let's move up one layer.</div>
<div abp="1117">
</div>
</div>
<h4 abp="219" style="text-align: justify;">
Logging Interface Type Abstraction - li_concat.h / li_outop.h</h4>
<div abp="219" style="text-align: justify;">
<div abp="1120">
Here, we build on <em abp="685">macro_overload_base.h</em> to create the macros that will receive the logging arguments and call the user-supplied macros (USMs), which will, in turn, call the logging implementation.</div>
</div>
<div abp="219" style="text-align: justify;">
<div abp="1123">
</div>
</div>
<div abp="219" style="text-align: justify;">
<div abp="1125">
<strong abp="688">There is an abstraction leak at this point.</strong> At some point in this "macro chain", we have to invoke the USMs. This means we have a contact point, similar to this:<span abp="689" style="color: silver;"> </span></div>
</div>
<div abp="219" style="text-align: justify;">
<div abp="1129">
<span abp="691" style="color: silver;"></span> </div>
</div>
<pre abp="693" style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-indent: 0px;"><span abp="694" style="color: navy;">#define</span><span abp="695" style="color: silver;"> </span>PCBASE__LAMOVERLOAD_LOG_IMPL_1<span abp="696" style="color: black;">(</span>level<span abp="697" style="color: black;">,</span><span abp="698" style="color: silver;"> </span><span abp="699" style="color: black;">...)</span><span abp="700" style="color: silver;"> </span><span abp="701" style="color: silver;">\</span></pre>
<pre abp="693" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"> PCBLUESY__<span abp="704" style="color: black;">##</span>level<span abp="705" style="color: black;">(</span>__VA_ARGS__<span abp="706" style="color: black;">)</span></pre>
<pre abp="707" style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-indent: 0px;"><span abp="708" style="color: navy;">#define</span><span abp="709" style="color: silver;"> </span>PCBASE__LAMOVERLOAD_LOG_IMPL_2<span abp="710" style="color: black;">(</span>level<span abp="711" style="color: black;">,</span><span abp="712" style="color: silver;"> </span>x<span abp="713" style="color: black;">,</span><span abp="714" style="color: silver;"> </span><span abp="715" style="color: black;">...)</span><span abp="716" style="color: silver;"> </span><span abp="717" style="color: silver;">\</span></pre>
<pre abp="718" style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-indent: 0px;"> PCBLUESY__<span abp="720" style="color: black;">##</span>level<span abp="721" style="color: black;">((</span>x<span abp="722" style="color: black;">)</span><span abp="723" style="color: silver;"> </span>PCBASE__MOVERLOAD_FOR_EACH<span abp="724" style="color: black;">(+,</span><span abp="725" style="color: silver;"> </span>__VA_ARGS__<span abp="726" style="color: black;">))</span></pre>
<div abp="219" style="text-align: justify;">
<div abp="1167">
</div>
</div>
<div abp="219" style="text-align: justify;">
<div abp="1169">
On the left-hand side we have the names from the logging abstraction macros, on the right-hand side we have the USMs.</div>
</div>
<div abp="219" style="text-align: justify;">
<div abp="1171">
</div>
</div>
<div abp="219" style="text-align: justify;">
<div abp="1173">
I considered three locations for this contact point:</div>
<ol abp="731">
<li abp="732"><div abp="733" style="text-align: justify;">
<div abp="1177">
Place it in the logging abstraction headers, i.e., in <em abp="734">li_concat.h</em> and <em abp="735">li_outop.h</em>. I rejected this idea because it would require the user to edit an extra header file, thus going against requirement #2.</div>
</div>
</li>
<li abp="736"><div abp="737" style="text-align: justify;">
<div abp="1182">
Place it in the user-supplied header.</div>
</div>
</li>
<li abp="738"><div abp="739" style="text-align: justify;">
<div abp="1185">
Create a separate header just for these macros.</div>
</div>
</li>
</ol>
<div abp="740" style="text-align: justify;">
<div abp="1187">
While I don't like the fact the we'll have references to "abstraction names" in the user-supplied header, it seemed the best alternative, so I went for alternative #2.</div>
</div>
<div abp="741">
<div abp="1189">
<em abp="742"></em> </div>
</div>
<div abp="743" style="text-align: justify;">
<div abp="1192">
<em abp="744">li_output.h</em> is quite simple - for each argument, prepend a "<<" to it. <em abp="745">li_concat.h</em> is more complex, because we can't add a "+" to a single argument.</div>
</div>
<div abp="746">
<div abp="1196">
</div>
</div>
<div abp="747" style="text-align: justify;">
<div abp="1198">
In fact, <em abp="748">li_output.h</em> is so simple it could almost be dispensed with; however I couldn't come up with a design clean enough without it. Besides, keeping it maintains the parallelism between the design for these two interfaces, concatenation and stream.</div>
</div>
<div abp="749">
<div abp="1201">
</div>
</div>
<div abp="750" style="text-align: justify;">
<div abp="1203">
<strong abp="751">NOTE:</strong> Concatenation is working, but it doesn't actually respect requirement #1 (read why <a abp="753" href="http://cidebycide.blogspot.pt/2014/05/logging-argument-for-stream-interface.html" target="_blank">here</a>), because it's not automatically converting its arguments to string.</div>
<div abp="1203">
</div>
</div>
<h4 abp="750" style="text-align: justify;">
Logging Interface Type Selection - log_interface_type.h</h4>
<div abp="750" style="text-align: justify;">
<div abp="1208">
This is where we define the interface type, which can be one of:</div>
<ul abp="1209">
<li abp="1210"><strong abp="1211">Comma.</strong> Function call interface with several arguments, such as we would have in a <code abp="1212" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">printf()</code>-like output function. I have not implemented this.</li>
<li abp="1213"><strong abp="1214">Stream output operator</strong> (<code abp="1215" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">operator<<</code>).</li>
<li abp="1216"><strong abp="1217">Concatenation</strong> (using <code abp="1218" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">+</code>). Function call interface with only one argument, created from the concatenation of several arguments. Since it's a binary operator, it requires a more complex implementation, because it needs to distinguish between two different cases: one argument, which must not involve any concatenation (<code abp="1219" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">"a" +</code> is not a valid expression); and more than one argument, which must be concatenated.</li>
</ul>
<div abp="750" style="text-align: justify;">
<div abp="1221">
This header file will also <em abp="1222">#include</em> the correct header file for the interface type chosen. For now, it's a choice of either <em abp="1223">li_concat.h</em> or <em abp="1224">li_outop.h</em>. Both are described above.</div>
<div abp="1225">
</div>
</div>
<div abp="750" style="text-align: justify;">
<div abp="1227">
We use this it by adding a <em abp="1228">#define</em> to the project file/makefile, defining which interface type we want. E.g., on Qt Creator, to use the stream output operator, we'd do something like this on the .pro file:</div>
<div abp="1229">
<br /></div>
<pre abp="1230" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="1231" style="color: purple;">DEFINES</span><span abp="1232" style="color: silver;"> </span>+=<span abp="1233" style="color: silver;"> </span>"PCBLUESY__LOGINTERFACETYPE=3"</pre>
<div abp="1234">
<br /></div>
<div abp="1235">
The default type (if we haven't <em abp="1236">#defined</em> <code abp="1237" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">PCBLUESY__LOGINTERFACETYPE</code> anywhere) is the stream output operator.</div>
<div abp="1238">
<br /></div>
<div abp="1239">
For now, I'll leave this header specific to the application, i.e., I'll have to create a new header for each application. I suspect this is not the best design, but I'll wait until I've used it a few times to see how it turns out.</div>
<div abp="1239">
</div>
<h4 abp="1240">
Logging implementation - e.g., poco_log.h or boost_log.h</h4>
<div abp="1241">
This is where we define the macros that will directly invoke the required functionality in the logging implementation (e.g., Poco or Boost).</div>
<div abp="1242">
<br /></div>
<div abp="1243">
The way I've set it up, we have a macro to get the logger (e.g., for Boost Log):</div>
<div abp="1244">
<br /></div>
<pre abp="1245" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="1246" style="color: navy;">#define</span><span abp="1247" style="color: silver;"> </span><span abp="1248" style="color: navy;">PCBLUESY__GETLOGGER</span><span abp="1249" style="color: black;">(</span>PCBLUESY_LOG_NAME<span abp="1250" style="color: black;">)</span><span abp="1251" style="color: silver;"> </span><span abp="1252" style="color: silver;">\</span></pre>
<pre abp="1253" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="1254" style="color: silver;"> </span>src<span abp="1255" style="color: black;">::</span>severity_logger<span abp="1256" style="color: black;"><</span>boost<span abp="1257" style="color: black;">::</span>log<span abp="1258" style="color: black;">::</span>trivial<span abp="1259" style="color: black;">::</span>severity_level<span abp="1260" style="color: black;">></span><span abp="1261" style="color: silver;"> \</span></pre>
<pre abp="1262" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="1263" style="color: silver;"> </span>PCBLUESY__BOOSTLOG</pre>
<div abp="1264">
<br /></div>
<div abp="1265">
Then, we have the top level logging macro, i.e., the macro that will get used in all the logging statements in the code:</div>
<div abp="1266">
<br /></div>
<pre abp="1267" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="1268" style="color: navy;">#define</span><span abp="1269" style="color: silver;"> </span><span abp="1270" style="color: navy;">PCBLUESY__LOG</span><span abp="1271" style="color: black;">(</span>level<span abp="1272" style="color: black;">,</span><span abp="1273" style="color: silver;"> </span><span abp="1274" style="color: black;">...)</span><span abp="1275" style="color: silver;"> \</span></pre>
<pre abp="1276" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="1277" style="color: silver;"> </span>PCBASE__LOG_ABSTRACTION<span abp="1278" style="color: black;">(</span>level<span abp="1279" style="color: black;">,</span><span abp="1280" style="color: silver;"> </span>__VA_ARGS__<span abp="1281" style="color: black;">)</span></pre>
<div abp="1282">
<br /></div>
<div abp="1283">
These are the only two macros used in the application code. We then have the actual logging macros, i.e., the macros that call the logging implementation. Again, example for Boost Log:</div>
<div abp="1284">
<br /></div>
<pre abp="1285" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="1286" style="color: navy;">#define</span><span abp="1287" style="color: silver;"> </span><span abp="1288" style="color: navy;">PCBLUESY__PCBLUESY__TRACE</span><span abp="1289" style="color: black;">(...)</span><span abp="1290" style="color: silver;"> </span><span abp="1291" style="color: silver;">\</span></pre>
<pre abp="1292" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="1293" style="color: silver;"> </span><span abp="1294" style="color: navy;">BOOST_LOG_SEV</span><span abp="1295" style="color: black;">(</span>PCBLUESY__BOOSTLOG<span abp="1296" style="color: black;">,</span><span abp="1297" style="color: silver;"> \</span></pre>
<pre abp="1298" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="1299" style="color: silver;"> </span>boost<span abp="1300" style="color: black;">::</span>log<span abp="1301" style="color: black;">::</span>trivial<span abp="1302" style="color: black;">::</span>severity_level<span abp="1303" style="color: black;">::</span>trace<span abp="1304" style="color: black;">)</span><span abp="1305" style="color: silver;"> </span>__VA_ARGS__</pre>
<div abp="1306">
<br /></div>
<div abp="1307">
Why the <code abp="1308" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">PCBLUESY__</code> repetition? This is the way the macro is used in the code:</div>
<div abp="1309">
<span abp="1310" style="color: silver;"> </span></div>
<pre abp="1311" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="1312" style="color: navy;">PCBLUESY__LOG</span><span abp="1313" style="color: black;">(</span>PCBLUESY__ERROR<span abp="1314" style="color: black;">,</span><span abp="1315" style="color: silver;"> \</span></pre>
<pre abp="1316" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="1317" style="color: silver;"></span><span abp="1318" style="color: green;"> "Blimey!</span><span abp="1319" style="color: silver;"> </span><span abp="1320" style="color: green;">I</span><span abp="1321" style="color: silver;"> </span><span abp="1322" style="color: green;">didn't</span><span abp="1323" style="color: silver;"> </span><span abp="1324" style="color: green;">expect</span><span abp="1325" style="color: silver;"> </span><span abp="1326" style="color: green;">the</span><span abp="1327" style="color: silver;"> </span><span abp="1328" style="color: green;">Spanish</span><span abp="1329" style="color: silver;"> </span><span abp="1330" style="color: green;">Inquisition</span><span abp="1331" style="color: silver;"> </span><span abp="1332" style="color: green;">ERROR!"</span><span abp="1333" style="color: black;">, \</span></pre>
<pre abp="1334" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="1335" style="color: silver;"> </span><span abp="1336" style="color: black;">chiefWeapons</span><span abp="1337" style="color: black;">,</span><span abp="1338" style="color: silver;"> </span><span abp="1339" style="color: black;">mill</span><span abp="1340" style="color: black;">.</span><span abp="1341" style="color: black;">Trouble</span><span abp="1342" style="color: black;">(),</span><span abp="1343" style="color: silver;"> </span><span abp="1344" style="color: black;">42</span><span abp="1345" style="color: black;">);</span></pre>
<div abp="1346">
</div>
<div abp="1347">
I'm using <code abp="1348" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">PCBLUESY__ERROR</code> as logging level in order to distinguish it from any other <code abp="1349" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">*ERROR*</code> defined "out there". Since these names are defined in this header and won't be used anywhere else, I figured a little uglyness would be harmless, and could actually be useful.</div>
<div abp="1350">
</div>
<div abp="1351">
Finally...</div>
<div abp="1352">
</div>
<div abp="1353">
How do we use this? I've set up an example on my <a abp="1413" href="https://github.com/PauloCaetano/SimpleSampleTuts/tree/master/MacroLogger" target="_blank">"SimpleSampleTuts" github</a>. You'll need Boost Log and/or Poco C++ to see it in action. And if you use any other logging lib, provided it has an interface compatible with the ones discussed here, you should be able to create a header like <em abp="1354">poco_log.h</em>/<em abp="1355">boost_log.h</em> and start using it.</div>
<div abp="1356">
</div>
<div abp="1357">
One final detail - initializing the logger. If you use a different implementation, you'll have to add that code, too. </div>
</div>
</div>
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-26924772622324311242014-05-12T13:27:00.000+01:002014-05-12T13:27:30.155+01:00Logging - The argument for the stream interface<div abp="166" style="text-align: justify;">
<div abp="284">
Of all the things mentioned in my <a abp="170" href="http://cidebycide.blogspot.pt/2014/05/its-been-long-time.html" target="_blank">"resurface" post</a>, I've been dedicating attention to my "logging macro front-end". To recap, the goal is to abstract the user code from the logging implementation used, thus allowing to substitute for another logging implementation with no changes to the code.</div>
</div>
<div abp="168" style="text-align: justify;">
<div abp="291">
</div>
</div>
<div abp="172" style="text-align: justify;">
<div abp="293">
I want something like this:</div>
<div abp="294">
</div>
</div>
<pre abp="295" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="296" style="color: navy;">LOG_FUNCTION_MACRO</span><span abp="297" style="color: black;">(</span><span abp="298" style="color: navy;">ERROR_DEFINE_MACRO</span><span abp="299" style="color: black;">,</span><span abp="300" style="color: silver;"> </span></pre>
<pre abp="301" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="302" style="color: silver;"> </span><span abp="303" style="color: green;">"Blimey!</span><span abp="304" style="color: silver;"> </span><span abp="305" style="color: green;">I</span><span abp="306" style="color: silver;"> </span><span abp="307" style="color: green;">didn't</span><span abp="308" style="color: silver;"> </span><span abp="309" style="color: green;">expect</span><span abp="310" style="color: silver;"> </span><span abp="311" style="color: green;">the</span><span abp="312" style="color: silver;"> </span><span abp="313" style="color: green;">Spanish</span><span abp="314" style="color: silver;"> </span><span abp="315" style="color: green;">Inquisition!"</span><span abp="316" style="color: black;">,</span><span abp="317" style="color: silver;"> </span></pre>
<pre abp="318" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="319" style="color: silver;"> </span>chiefWeapons<span abp="320" style="color: black;">,</span><span abp="321" style="color: silver;"> </span>mill<span abp="322" style="color: black;">.</span>Trouble<span abp="323" style="color: black;">(),</span><span abp="324" style="color: silver;"> </span><span abp="325" style="color: navy;">42</span><span abp="326" style="color: black;">);</span></pre>
<div abp="172" style="text-align: justify;">
<div abp="328">
<br /></div>
</div>
<div abp="172" style="text-align: justify;">
<div abp="330">
This is then "translated" into whatever interface the logging implementation provides for logging. So, with Boost Log, this could become something like this:</div>
<div abp="331">
</div>
</div>
<pre abp="332" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="333" style="color: navy;">BOOST_LOG_SEV</span><span abp="334" style="color: black;">(</span>someLog<span abp="335" style="color: black;">,</span><span abp="336" style="color: silver;"> </span><span abp="337" style="color: purple;">boost</span><span abp="338" style="color: black;">::</span><span abp="339" style="color: purple;">log</span><span abp="340" style="color: black;">::</span><span abp="341" style="color: purple;">trivial</span><span abp="342" style="color: black;">::</span>severity_level<span abp="343" style="color: black;">::</span>error<span abp="344" style="color: black;">)</span><span abp="345" style="color: silver;"> </span></pre>
<pre abp="346" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="347" style="color: silver;"> </span><span abp="348" style="color: black;"><<</span><span abp="349" style="color: silver;"> </span>__FILE__<span abp="350" style="color: silver;"> </span><span abp="351" style="color: black;"><<</span><span abp="352" style="color: silver;"> </span>__LINE__<span abp="353" style="color: silver;"> </span></pre>
<pre abp="354" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="355" style="color: silver;"> </span><span abp="356" style="color: black;"><<</span><span abp="357" style="color: silver;"> </span><span abp="358" style="color: green;">"Blimey!</span><span abp="359" style="color: silver;"> </span><span abp="360" style="color: green;">I</span><span abp="361" style="color: silver;"> </span><span abp="362" style="color: green;">didn't</span><span abp="363" style="color: silver;"> </span><span abp="364" style="color: green;">expect</span><span abp="365" style="color: silver;"> </span><span abp="366" style="color: green;">the</span><span abp="367" style="color: silver;"> </span><span abp="368" style="color: green;">Spanish</span><span abp="369" style="color: silver;"> </span><span abp="370" style="color: green;">Inquisition!"</span><span abp="371" style="color: silver;"> </span></pre>
<pre abp="372" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="373" style="color: silver;"> </span><span abp="374" style="color: black;"><<</span><span abp="375" style="color: silver;"> </span>chiefWeapons<span abp="376" style="color: silver;"> </span><span abp="377" style="color: black;"><<</span><span abp="378" style="color: silver;"> </span>mill<span abp="379" style="color: black;">.</span>Trouble<span abp="380" style="color: black;">()</span><span abp="381" style="color: silver;"> </span><span abp="382" style="color: black;"><<</span><span abp="383" style="color: silver;"> </span><span abp="384" style="color: navy;">42</span><span abp="385" style="color: black;">;</span></pre>
<div abp="372" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">
</div>
<div abp="387" style="text-align: justify;">
<div abp="454">
Or, using Poco Logger's stream interface:<br />
</div>
</div>
<pre abp="390" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="391" style="color: olive;">if</span><span abp="392" style="color: silver;"> </span><span abp="393" style="color: black;">(</span>someLogRef<span abp="394" style="color: black;">.</span>rdbuf<span abp="395" style="color: black;">()-></span>logger<span abp="396" style="color: black;">().</span>error<span abp="397" style="color: black;">())</span></pre>
<pre abp="398" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="399" style="color: silver;"> </span>someLogRef<span abp="400" style="color: black;">.</span>error<span abp="401" style="color: black;">()</span><span abp="402" style="color: silver;"> </span><span abp="403" style="color: black;"><<</span><span abp="404" style="color: silver;"> </span>__FILE__<span abp="405" style="color: silver;"> </span><span abp="406" style="color: black;"><<</span><span abp="407" style="color: silver;"> </span>__LINE__</pre>
<pre abp="408" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="409" style="color: silver;"> </span><span abp="410" style="color: black;"><<</span><span abp="411" style="color: silver;"> </span><span abp="412" style="color: green;">"Blimey!</span><span abp="413" style="color: silver;"> </span><span abp="414" style="color: green;">I</span><span abp="415" style="color: silver;"> </span><span abp="416" style="color: green;">didn't</span><span abp="417" style="color: silver;"> </span><span abp="418" style="color: green;">expect</span><span abp="419" style="color: silver;"> </span><span abp="420" style="color: green;">the</span><span abp="421" style="color: silver;"> </span><span abp="422" style="color: green;">Spanish</span><span abp="423" style="color: silver;"> </span><span abp="424" style="color: green;">Inquisition!"</span><span abp="425" style="color: silver;"> </span></pre>
<pre abp="426" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="427" style="color: silver;"> </span><span abp="428" style="color: black;"><<</span><span abp="429" style="color: silver;"> </span>chiefWeapons<span abp="430" style="color: silver;"> </span><span abp="431" style="color: black;"><<</span><span abp="432" style="color: silver;"> </span>mill<span abp="433" style="color: black;">.</span>Trouble<span abp="434" style="color: black;">()</span><span abp="435" style="color: silver;"> </span><span abp="436" style="color: black;"><<</span><span abp="437" style="color: silver;"> </span><span abp="438" style="color: navy;">42</span><span abp="439" style="color: silver;"> </span><span abp="440" style="color: black;"><<</span><span abp="441" style="color: silver;"> </span>endl<span abp="442" style="color: black;">;</span></pre>
<pre abp="443" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="444" style="color: olive;">else</span><span abp="445" style="color: silver;"> </span><span abp="446" style="color: black;">(</span><span abp="447" style="color: olive;">void</span><span abp="448" style="color: black;">)</span><span abp="449" style="color: silver;"> </span><span abp="450" style="color: navy;">0;</span></pre>
<div abp="451" style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-indent: 0px;">
<div abp="452">
</div>
</div>
<div abp="453" style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
<div abp="454">
Since I prefer a stream interface, that's where I began my work. Then, I moved on to what I call the "concatenation interface", where everything is concatenated into a single string. This was my first attempt, a few months ago, when I was using Poco Logger, but wasn't aware of Poco LogStream. The reason I settled on this was because I'm not a fan of the "format string" interface (i.e., <em abp="455">printf()</em>-like).</div>
</div>
<div abp="456" style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
<div abp="457">
</div>
</div>
<div abp="458" style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
<div abp="459">
So, starting from our logging macro:</div>
<div abp="460">
</div>
</div>
<pre abp="461" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="462" style="color: navy;">LOG_FUNCTION_MACRO</span><span abp="463" style="color: black;">(</span><span abp="464" style="color: navy;">ERROR_DEFINE_MACRO</span><span abp="465" style="color: black;">,</span><span abp="466" style="color: silver;"> </span></pre>
<pre abp="467" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="468" style="color: silver;"> </span><span abp="469" style="color: green;">"Blimey!</span><span abp="470" style="color: silver;"> </span><span abp="471" style="color: green;">I</span><span abp="472" style="color: silver;"> </span><span abp="473" style="color: green;">didn't</span><span abp="474" style="color: silver;"> </span><span abp="475" style="color: green;">expect</span><span abp="476" style="color: silver;"> </span><span abp="477" style="color: green;">the</span><span abp="478" style="color: silver;"> </span><span abp="479" style="color: green;">Spanish</span><span abp="480" style="color: silver;"> </span><span abp="481" style="color: green;">Inquisition!"</span><span abp="482" style="color: black;">,</span><span abp="483" style="color: silver;"> </span></pre>
<pre abp="484" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="485" style="color: silver;"> </span>chiefWeapons<span abp="486" style="color: black;">,</span><span abp="487" style="color: silver;"> </span>mill<span abp="488" style="color: black;">.</span>Trouble<span abp="489" style="color: black;">(),</span><span abp="490" style="color: silver;"> </span><span abp="491" style="color: navy;">42</span><span abp="492" style="color: black;">);</span></pre>
<div abp="172" style="text-align: justify;">
<div abp="494">
<br /></div>
</div>
<div abp="495" style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
<div abp="496">
we'd have something similar to this:</div>
<div abp="497">
</div>
</div>
<pre abp="498" style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-indent: 0px;"><span abp="499" style="color: navy;">poco_error</span><span abp="500" style="color: black;">(</span>someLogRef<span abp="501" style="color: black;">,</span><span abp="502" style="color: silver;"> </span>__FILE__<span abp="503" style="color: silver;"> </span><span abp="504" style="color: black;">+</span><span abp="505" style="color: silver;"> </span>__LINE__<span abp="506" style="color: silver;"> </span></pre>
<pre abp="507" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="508" style="color: silver;"> </span><span abp="509" style="color: black;">+</span><span abp="510" style="color: silver;"> </span><span abp="511" style="color: green;">"Blimey!</span><span abp="512" style="color: silver;"> </span><span abp="513" style="color: green;">I</span><span abp="514" style="color: silver;"> </span><span abp="515" style="color: green;">didn't</span><span abp="516" style="color: silver;"> </span><span abp="517" style="color: green;">expect</span><span abp="518" style="color: silver;"> </span><span abp="519" style="color: green;">the</span><span abp="520" style="color: silver;"> </span><span abp="521" style="color: green;">Spanish</span><span abp="522" style="color: silver;"> </span><span abp="523" style="color: green;">Inquisition!"</span><span abp="524" style="color: silver;"> </span></pre>
<pre abp="525" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="526" style="color: silver;"> </span><span abp="527" style="color: black;">+</span><span abp="528" style="color: silver;"> </span>chiefWeapons<span abp="529" style="color: silver;"> </span><span abp="530" style="color: black;">+</span><span abp="531" style="color: silver;"> </span>mill<span abp="532" style="color: black;">.</span>Trouble<span abp="533" style="color: black;">()</span><span abp="534" style="color: silver;"> </span><span abp="535" style="color: black;">+</span><span abp="536" style="color: silver;"> </span><span abp="537" style="color: navy;">42</span><span abp="538" style="color: black;">);</span></pre>
<div abp="539" style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
<div abp="540">
<br /></div>
<div abp="541">
And while I always preferred the stream interface, as I worked more on concatenation, I became aware it was not just a matter of preference; the stream interface is vastly superior. What do I mean by "superior"?</div>
</div>
<div abp="542" style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
<div abp="543">
</div>
</div>
<div abp="544" style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin: 0px; text-align: justify; text-indent: 0px;">
<div abp="545">
Let's look at this:</div>
<div abp="546">
</div>
</div>
<pre abp="547" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">someStream<span abp="548" style="color: silver;"> </span><span abp="549" style="color: black;"><<</span><span abp="550" style="color: silver;"> </span>__FILE__<span abp="551" style="color: silver;"> </span><span abp="552" style="color: black;"><<</span><span abp="553" style="color: silver;"> </span>__LINE__</pre>
<pre abp="554" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="555" style="color: silver;"> </span><span abp="556" style="color: black;"><<</span><span abp="557" style="color: silver;"> </span><span abp="558" style="color: green;">"Blimey!</span><span abp="559" style="color: silver;"> </span><span abp="560" style="color: green;">I</span><span abp="561" style="color: silver;"> </span><span abp="562" style="color: green;">didn't</span><span abp="563" style="color: silver;"> </span><span abp="564" style="color: green;">expect</span><span abp="565" style="color: silver;"> </span><span abp="566" style="color: green;">the</span><span abp="567" style="color: silver;"> </span><span abp="568" style="color: green;">Spanish</span><span abp="569" style="color: silver;"> </span><span abp="570" style="color: green;">Inquisition!"</span><span abp="571" style="color: silver;"> </span></pre>
<pre abp="572" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="573" style="color: silver;"> </span><span abp="574" style="color: black;"><<</span><span abp="575" style="color: silver;"> </span>chiefWeapons<span abp="576" style="color: silver;"> </span><span abp="577" style="color: black;"><<</span><span abp="578" style="color: silver;"> </span>mill<span abp="579" style="color: black;">.</span>Trouble<span abp="580" style="color: black;">()</span><span abp="581" style="color: silver;"> </span><span abp="582" style="color: black;"><<</span><span abp="583" style="color: silver;"> </span><span abp="584" style="color: navy;">42</span></pre>
<div abp="172" style="text-align: justify;">
<div abp="586">
</div>
</div>
<div abp="172" style="text-align: justify;">
<div abp="588">
<code abp="589" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">__FILE__</code> and "Blimey! etc..." are <code abp="590" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">char*</code> (I'll ignore constness here), and work right out of the box. Ditto for <code abp="591" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">__LINE__</code> and 42. So, our wildcards here are <code abp="592" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">mill.Trouble()</code> and <code abp="593" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">chiefWeapons</code>; for the sake of argument, let's assume <code abp="594" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">mill.Trouble()</code> returns a float and <code abp="595" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">chiefWeapons</code> is a container that defines its own <code abp="596" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">operator<<()</code>. This means close to 84% of our logging line works with no work required on our part. Our only additional work is defining <code abp="597" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">operator<<()</code> for whatever type <code abp="598" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">chiefWeapons</code> happens to be. And we probably would define it anyway, since output to a stream is always a handy feature, IMHO.</div>
<div abp="599">
</div>
</div>
<div abp="172" style="text-align: justify;">
<div abp="601">
Now, let's look at this:</div>
</div>
<div abp="172" style="text-align: justify;">
<div abp="603">
<br /></div>
<pre abp="604" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">__FILE__<span abp="605" style="color: silver;"> </span><span abp="606" style="color: black;">+</span><span abp="607" style="color: silver;"> </span>__LINE__</pre>
<pre abp="608" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="609" style="color: silver;"> </span><span abp="610" style="color: black;">+</span><span abp="611" style="color: silver;"> </span><span abp="612" style="color: green;">"Blimey!</span><span abp="613" style="color: silver;"> </span><span abp="614" style="color: green;">I</span><span abp="615" style="color: silver;"> </span><span abp="616" style="color: green;">didn't</span><span abp="617" style="color: silver;"> </span><span abp="618" style="color: green;">expect</span><span abp="619" style="color: silver;"> </span><span abp="620" style="color: green;">the</span><span abp="621" style="color: silver;"> </span><span abp="622" style="color: green;">Spanish</span><span abp="623" style="color: silver;"> </span><span abp="624" style="color: green;">Inquisition!"</span><span abp="625" style="color: silver;"> </span></pre>
<pre abp="626" style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span abp="627" style="color: silver;"> </span><span abp="628" style="color: black;">+</span><span abp="629" style="color: silver;"> </span>chiefWeapons<span abp="630" style="color: silver;"> </span><span abp="631" style="color: black;">+</span><span abp="632" style="color: silver;"> </span>mill<span abp="633" style="color: black;">.</span>Trouble<span abp="634" style="color: black;">()</span><span abp="635" style="color: silver;"> </span><span abp="636" style="color: black;">+</span><span abp="637" style="color: silver;"> </span><span abp="638" style="color: navy;">42</span></pre>
<div abp="639">
</div>
</div>
<div abp="641" style="text-align: justify;">
<div abp="642">
This is supposed to be concatenation; concatenation assumes some string type. Since none of these arguments is a string type, we'd need to convert them. That's not difficult, but the question is - where would the conversion occur?</div>
</div>
<div abp="643">
<br /></div>
<div abp="644" style="text-align: justify;">
<div abp="645">
We don't want to place it in the original logging line, because we want it to be interface-agnostic. However, that's the only place where we know the type of each argument; we certainly couldn't place it in our macro mechanism, because macro parameters have no type.</div>
</div>
<div abp="646">
<br /></div>
<div abp="647" style="text-align: justify;">
<div abp="648">
We could create a family of template functions for this, and solve our problem through specialization - if we pass a string type, just return the string itself (yes, I'm ignoring the several string types in C++ libs and the necessity to copy those into a single type); if we pass a <code abp="649" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">char*</code>, build a string with it; if we pass an <code abp="650" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">int</code>, call <code abp="651" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">to_string()</code> (or similar); etc, meaning, every type we use would need a way to convert to string. And, while we might not require a template specialization for each type (e.g., we could use <code abp="652" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">to_string()</code> for <code abp="653" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">int</code>, <code abp="654" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">long</code>, or <code abp="655" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">float</code>), we'd be pretty close to that mark.</div>
</div>
<div abp="656">
<br /></div>
<div abp="657" style="text-align: justify;">
So, assuming this could be pulled off, with a proper design, it's still more work than taking advantage of a group of core types that have an already-functioning <code abp="658" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">operator<<()</code>, and only adding this to other types that require it.</div>
<div abp="659">
<br /></div>
<div abp="660" style="text-align: justify;">
Then, there is the question of performance - unless we use some mechanism like <a abp="662" href="http://qt-project.org/doc/qt-5/qstring.html#more-efficient-string-construction" target="_blank">QstringBuilder</a>, concatenation will be much more expensive than streaming output.</div>
<div abp="660">
</div>
<div abp="664" style="text-align: justify;">
Finally, there is one last point that makes me prefer the stream interface, one that I've come upon as my logging usage became more "complex" - no conversions necessary. Conversions are one of the sources of problems in C/C++, and while we can mark them as <em>explicit</em>, I prefer sticking to a simple rule of defining no unnecessary conversions. If I only need a conversion to string when I'm outputting to log, then it is an unnecessary conversion.</div>
<div abp="664">
</div>
<div abp="665" style="text-align: justify;">
So, where does this leaves my "logging macro front-end"? I'm going to finish my work and publish it with only the stream interface functional. The concatenation interface will be semi-functional, meaning no provision for conversion to string. I realize this is mostly self-defeating, since this means I probably won't use it. But I have two good options with <code style="background: rgb(255, 255, 255); color: black; font-size: 14px;">operator<<()</code> at the moment, so I'll stick to it, for the time being.</div>
<div abp="667">
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-88310990181968963182014-05-04T00:29:00.000+01:002014-05-04T12:49:44.404+01:00Single-line comments that want to be multi-line<div style="text-align: justify;">
<strong>Update:</strong> While working on this code today, I had some "mystical" results, and ran a rebuild instead of the usual build. Et voilà, gcc presented me with this: "warning: multi-line comment [-Wcomment]". So, in all fairness, this issue isn't as much of an issue as it appeared at first.<br />
<br />
So, we have our good-ole multi-line comment, aka, C comment:</div>
<br />
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: green;">/*</span><span style="color: silver;"> </span><span style="color: green;">I</span><span style="color: silver;"> </span><span style="color: green;">am</span><span style="color: silver;"> </span><span style="color: green;">a</span><span style="color: silver;"> </span><span style="color: green;">long</span><span style="color: silver;"> </span><span style="color: green;">comment,</span><span style="color: silver;"> </span><span style="color: green;">spanning</span><span style="color: silver;"> </span><span style="color: green;">a</span><span style="color: silver;"> </span><span style="color: green;">lot</span><span style="color: silver;"> </span><span style="color: green;">of</span><span style="color: silver;"> </span><span style="color: green;">lines,</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: green;">I</span><span style="color: silver;"> </span><span style="color: green;">just</span><span style="color: silver;"> </span><span style="color: green;">go</span><span style="color: silver;"> </span><span style="color: green;">on</span><span style="color: silver;"> </span><span style="color: green;">and</span><span style="color: silver;"> </span><span style="color: green;">on</span><span style="color: silver;"> </span><span style="color: green;">until</span><span style="color: silver;"> </span><span style="color: green;">I</span><span style="color: silver;"> </span><span style="color: green;">start</span><span style="color: silver;"> </span><span style="color: green;">foaming</span><span style="color: silver;"> </span><span style="color: green;">at</span><span style="color: silver;"> </span><span style="color: green;">the</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: green;">mouth</span><span style="color: silver;"> </span><span style="color: green;">and</span><span style="color: silver;"> </span><span style="color: green;">falling</span><span style="color: silver;"> </span><span style="color: green;">over</span><span style="color: silver;"> </span><span style="color: green;">backwards,</span><span style="color: silver;"> </span><span style="color: green;">and...</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: green;">I</span><span style="color: silver;"> </span><span style="color: green;">say,</span><span style="color: silver;"> </span><span style="color: green;">I</span><span style="color: silver;"> </span><span style="color: green;">seem</span><span style="color: silver;"> </span><span style="color: green;">to</span><span style="color: silver;"> </span><span style="color: green;">have</span><span style="color: silver;"> </span><span style="color: green;">drifted</span><span style="color: silver;"> </span><span style="color: green;">a</span><span style="color: silver;"> </span><span style="color: green;">bit,</span><span style="color: silver;"> </span><span style="color: green;">haven't</span><span style="color: silver;"> </span><span style="color: green;">I...?</span><span style="color: silver;"> </span><span style="color: green;">*/</span></pre>
<div style="text-align: justify;">
<br />
Then, we have our heavy-duty single-line comment, aka, C++ comment (actually, since C99, this has been a bit of a misnomer): </div>
<br />
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: green;">//</span><span style="color: silver;"> </span><span style="color: green;">What</span><span style="color: silver;"> </span><span style="color: green;">do</span><span style="color: silver;"> </span><span style="color: green;">we</span><span style="color: silver;"> </span><span style="color: green;">mean</span><span style="color: silver;"> </span><span style="color: green;">by</span><span style="color: silver;"> </span><span style="color: green;">no?</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: green;">//</span><span style="color: silver;"> </span><span style="color: green;">What</span><span style="color: silver;"> </span><span style="color: green;">do</span><span style="color: silver;"> </span><span style="color: green;">we</span><span style="color: silver;"> </span><span style="color: green;">mean</span><span style="color: silver;"> </span><span style="color: green;">by</span><span style="color: silver;"> </span><span style="color: green;">yes?</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: green;">//</span><span style="color: silver;"> </span><span style="color: green;">What</span><span style="color: silver;"> </span><span style="color: green;">do</span><span style="color: silver;"> </span><span style="color: green;">we</span><span style="color: silver;"> </span><span style="color: green;">mean,</span><span style="color: silver;"> </span><span style="color: green;">allowing backslash</span><span style="color: silver;"> </span><span style="color: green;">\</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">line<span style="color: silver;"> </span>continuation<span style="color: silver;"> </span>to<span style="color: silver;"> </span>work<span style="color: silver;"> </span>on<span style="color: silver;"> </span>single<span style="color: black;">-</span>line<span style="color: silver;"> </span>comments<span style="color: black;">?</span><span style="color: silver;"> </span><span style="color: silver;">\</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;">Why<span style="color: black;">?</span></pre>
<br />
<div style="text-align: justify;">
Oh, yes, this will happily compile. Let's see it in action, in a terribly contrived example:</div>
<br />
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: olive;">int</span><span style="color: silver;"> </span><span style="color: black;">main</span><span style="color: black;">()</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: green;">//</span><span style="color: silver;"> </span><span style="color: green;">We</span><span style="color: silver;"> </span><span style="color: green;">don't</span><span style="color: silver;"> </span><span style="color: green;">pass</span><span style="color: silver;"> </span><span style="color: green;">any</span><span style="color: silver;"> </span><span style="color: green;">argument</span><span style="color: silver;"> </span><span style="color: green;">to</span><span style="color: silver;"> </span><span style="color: green;">CountFiles()</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: green;">//</span><span style="color: silver;"> </span><span style="color: green;">because</span><span style="color: silver;"> </span><span style="color: green;">we</span><span style="color: silver;"> </span><span style="color: green;">always</span><span style="color: silver;"> </span><span style="color: green;">start</span><span style="color: silver;"> </span><span style="color: green;">at</span><span style="color: silver;"> </span><span style="color: green;">\</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">int</span><span style="color: silver;"> </span><span style="color: black;">tot_files</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: navy;">0</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">tot_files</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: black;">CountFiles</span><span style="color: black;">();</span></pre>
<br />
<div style="text-align: justify;">
So, our intrepid - and rather <em>uncognizant</em> - developer documents the design decision to always start counting files at the current drive's root. Developing on the Windows side of C++, and being eco-minded, he decides to save 3 characters by replacing "root" with "\".</div>
<br />
<div style="text-align: justify;">
The compiler (in this case, gcc) rewards him with this beautiful message: "error: 'tot_files' was not declared in this scope".</div>
<br />
<div style="text-align: justify;">
In all fairness, VC++ correctly flags the continuation lines as comments, the "syntax artists" responsible for painting our IDEs in all those lovely colours correctly paint those lines as comments. Qt Creator? Not so much, as you can readily see from the code snippet above. Not that I blame them, really; I imagine they have more important things to do.</div>
<br />
<div style="text-align: justify;">
Reading about it, I learned this behaviour occurs because continuation lines are eliminated (i.e., the backslash and the newline are removed, thus joining the lines together) before comments are removed.</div>
<br />
<div style="text-align: justify;">
I find this a bit strange. It would be more sensible for the first step to be comment removal. Which would have the beneficial side-effect of getting rid of this brilliant rule (in the "brilliant bean" sense, I mean) .</div>
<br />
<div style="text-align: justify;">
Yes, I know, there are more important things to do.<br />
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-25202696166058998362014-05-01T12:34:00.001+01:002014-05-01T12:34:25.713+01:00It's Been A Long Time<div abp="295" style="text-align: justify;">
<div abp="375">
Actually, the song is called "<a abp="296" href="http://www.youtube.com/watch?v=0WzG64syKHA" target="_blank">Rock and Roll</a>", but it <em abp="297">has</em> been a long time.</div>
</div>
<div abp="298" style="text-align: justify;">
<div abp="379">
</div>
</div>
<div abp="299" style="text-align: justify;">
<div abp="381">
It all started in late September, as I've mentioned in a previous post. We rolled out a massive project, and spent quite some time picking up the pieces. Shortly thereafter, I was involved in a new massive project, and it kept me busier than usual until late January. During this time, I had little energy left to pursue my personal projects. On the other hand, I did pick up the guitar again, which I hadn't done in months. And, while there haven't been any more massive projects since that time, there has been enough research to keep this busy schedule.</div>
</div>
<div abp="300" style="text-align: justify;">
<div abp="383">
</div>
</div>
<div abp="301" style="text-align: justify;">
<div abp="385">
Still, I haven't been idle on the personal project front. And, in some cases, there has been some overlap - lessons learned on the personal front that carry over the professional, and vice-versa. So, what has happened during this long time? Actually, it's still happening, it's a Work in Progress.</div>
<div abp="385">
</div>
</div>
<h4 abp="303">
Math</h4>
<div abp="304" style="text-align: justify;">
<div abp="388">
I've started working on programming puzzles, and I quickly became aware that my math knowledge is lacking, since the vast majority of such puzzles is math-based. I began working on this, but I have a very long road ahead. It's been progressing slowly. </div>
<div abp="388">
</div>
</div>
<h4 abp="305">
C</h4>
<div abp="306" style="text-align: justify;">
<div abp="391">
I've also realized my knowledge of C, and how it interacts with C++, is also lacking. So, I'm - slowly - starting to learn some of C's particularities. It's making me realize, among other things, how much I really like C++.</div>
<div abp="391">
</div>
</div>
<h4 abp="307">
Systems knowledge</h4>
<div abp="308" style="text-align: justify;">
<div abp="394">
I've been extending my systems knowledge. This is the area where most of the above-mentioned overlap happens. Due to requirements on one of the projects (mentioned above), I began with the working of certificates, DNS, and http requests. During the project, it was all very task-oriented, i.e., getting the knowledge necessary to perform specific tasks. Now, I'm going for a more systematic approach.</div>
<div abp="394">
</div>
</div>
<h4 abp="309">
Build gcc</h4>
<div abp="310" style="text-align: justify;">
<div abp="397">
I've set up a VM with CentOS and built a local gcc installation from scratch (which is actually something a friend had suggested to me a long time ago). I've set up an environment similar to what I have on Windows, with Qt Creator and gcc 4.8, and I've built ICU and Boost. Then, I've decided to take a step back because the method I used to build gcc was quite time-consuming and involved, and I'm now investigating if there's an easier/faster way to do it. Also, from what I can see <a abp="312" href="http://gcc.gnu.org/install/prerequisites.html" target="_blank">here</a>, building CLoog together with gcc is now supported (I didn't see this a few months ago, when I built gcc), so I'll definitely give it a try.</div>
<div abp="397">
</div>
</div>
<h4 abp="314">
Linking</h4>
<div abp="314" style="text-align: justify;">
<div abp="401">
I've also started learning more about linking, both static and dynamic, after being bitten by an unexpected versioning issue. As I've said above, I've built ICU and Boost, and used the latest versions available at the time. However, the version of ICU I've built was 52.x, and the version included with Qt was 51.x. I didn't think much of it, trusting I could use symlinks to the same version for both Boost and Qt. No such luck. When I tried using ICU 52.x for both, I got an error from QtCore about an undefined symbol: <code abp="402" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">u_strToLower_51</code>. Puzzled by the version numbering on function names, I searched online and learned that DLL/SO symbol resolution works differently on Unix/Linux and Windows. This means I'll have to plan my building process more carefully. I don't want to carry different versions of the same libs around (especially ICU, which is huge). Since I get Qt pre-built, that will mean using the ICU version that comes with Qt, instead of building my own.</div>
<div abp="401">
</div>
</div>
<h4 abp="314">
Logging </h4>
<div abp="314" style="text-align: justify;">
<div abp="405">
I've been taking on logging again. Not only taking a better look at Boost Log, but also at Poco Logger. I've already seen something I've missed the first time around - Poco Logger has a stream interface; however, I found no way to set the value of <code abp="406" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">__FILE__</code> and <code abp="407" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">__LINE__</code> on the format string. So, I've decided to move forward by writing those values out with the message. On Boost Log, there is a way to do it, using custom formatters, but I've decided to use the same "solution" I've used for Poco Logger, i.e., write <code abp="408" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">__FILE__</code> and <code abp="409" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">__LINE__</code> in a sort of faux-format before the message. I'll probably implement a proper solution later on; I have an idea of how it may be done on Boost, but not yet on Poco.</div>
</div>
<div abp="314">
<div abp="411">
</div>
</div>
<div abp="314" style="text-align: justify;">
And I've decided to get rid of my logging bridge class template and stick with macros. Yes, evil, probably. But... I've been saying from the start I won't get rid of macros because I want <code abp="413" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">__FILE__</code> and <code abp="414" style="background: rgb(255, 255, 255); color: black; font-size: 14px;">__LINE__</code>, and I want to write it only once, on the macro definition. And my goal of being able to swap logging implementations can be achieved solely with macros. Also, by using variadic macros, I can deal with the case where different implementations have a different number of arguments, which was the reason for using the class template and SFINAE in the first place.</div>
<div abp="314" style="text-align: justify;">
</div>
<h4 abp="314">
Local scripting environment</h4>
<div abp="314" style="text-align: justify;">
Due to work requirements, I've been setting up a scripting environment for a local user, on a Red Hat server. Among other things, I wanted to avoid building from source. And, as an added bonus, the machine has no internet connectivity. At first, I decided to user Perl. And, after much gnashing of teeth (and of many other body parts, some of which I had no idea were capable of gnashing), I gave up. Why? Too many hurdles, and the realization that the only viable alternative would be building from source. So, I turned to Ruby. So far, it's going much better, and I see two main reasons for this:</div>
<div abp="314">
<ol abp="418">
<li abp="419"><div abp="420" style="text-align: justify;">
Ruby, unlike Perl, has not become a "system component". This means we can ask the sysadmins to install it from the RPM repo without fear of breaking anything (e.g., system scripts).</div>
</li>
<li abp="421"><div abp="422" style="text-align: justify;">
I found the module (<em abp="423">gem</em>, in Ruby parlance) management simpler. Installing Ruby Gem locally with no internet connection was simple, and so was installing gems. I still have to deal with dependencies manually, but even that has been simpler. And there is a possibility that the gem for connecting to Informix DBs may not require native building, which was not the case in Perl.</div>
</li>
</ol>
</div>
<div abp="422" style="text-align: justify;">
</div>
<h4 abp="315">
github</h4>
<div abp="315" style="text-align: justify;">
I've added some of the simple code I've done recently to github, <a abp="427" href="https://github.com/PauloCaetano/bluesy" target="_blank">here</a>, including an evolution of the <a abp="497" href="http://cidebycide.blogspot.pt/2013/12/boost-program-options.html" target="_blank">AppOptions class template</a>. The design remains mostly the same (some minor interface changes), and even the implementation changes are minor.</div>
<div abp="316">
</div>
<div abp="317" style="text-align: justify;">
Well, that's it. I'll try to return to a more regular posting schedule.</div>
<div abp="318">
</div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-86637525676971678742013-12-05T08:18:00.001+00:002013-12-05T08:18:58.368+00:00Boost program options<div style="text-align: justify;">
I've been using boost program_options, and I've grown to like it. However, after setting up the options for a few programs, I felt the need to minimize the code repetition involved.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
My first idea was to put the options in a configuration file and read it at start-up. But I found the <code style="background: #ffffff; color: black; font-size: 14px;">add_options()</code> syntax ill-suited for this, and it would require a great deal of work to get all the possible combinations working (required options, default values, etc), even assuming I'd limit all options to <code style="background: #ffffff; color: black; font-size: 14px;">value<string></code>; and that's without going into multivalue options (e.g., <code style="background: #ffffff; color: black; font-size: 14px;">value<vector<string>></code>). So, I've decided to settle for good enough - I've divided the work required to configure the options in two classes.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The first class is a class template, AppOptions, and it takes care of the generic stuff, i.e., that which remains unchanged in every app.</div>
<br />
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">template</span><span style="color: silver;"> </span><span style="color: black;"><</span><span style="color: olive;">typename</span><span style="color: silver;"> </span><span style="color: purple;">SpecificOptions</span><span style="color: black;">></span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">class</span><span style="color: silver;"> </span><span style="color: purple;">AppOptions</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">public</span><span style="color: black;">:</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">AppOptions</span><span style="color: black;">(</span><span style="color: olive;">int</span><span style="color: silver;"> </span>argc<span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: black;">*</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: silver;"> </span>argv<span style="color: black;">[],</span><span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">*</span><span style="color: silver;"> </span>opTitle<span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">void</span><span style="color: silver;"> </span><span style="color: black;">PrintHelp</span><span style="color: black;">()</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: silver;"> </span><span style="color: black;">{</span><span style="color: silver;"> </span><span style="color: purple;">std</span><span style="color: black;">::</span>cout<span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: maroon;">desc</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: purple;">std</span><span style="color: black;">::</span>endl<span style="color: black;">;</span><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: silver;"> </span><span style="color: purple;">SpecificOptions</span><span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">GetOptions</span><span style="color: black;">()</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: silver;"> </span><span style="color: black;">{</span><span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span><span style="color: maroon;">so</span><span style="color: black;">;</span><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">bool</span><span style="color: silver;"> </span><span style="color: black;">HasShownHelp</span><span style="color: black;">()</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: silver;"> </span><span style="color: black;">{</span><span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span><span style="color: maroon;">shownHelp</span><span style="color: black;">;</span><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">private</span><span style="color: black;">:</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">template</span><span style="color: silver;"> </span><span style="color: black;"><</span><span style="color: olive;">typename</span><span style="color: silver;"> </span><span style="color: purple;">SpecOpt</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: olive;">typename</span><span style="color: silver;"> </span><span style="color: purple;">CharT</span><span style="color: black;">></span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;"> friend</span><span style="color: silver;"> </span><span style="color: purple;">std</span><span style="color: black;">::</span><span style="color: purple;">basic_ostream</span><span style="color: black;"><</span>CharT<span style="color: black;">>&</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">operator</span><span style="color: black;"><<(</span><span style="color: purple;">std</span><span style="color: black;">::</span><span style="color: purple;">basic_ostream</span><span style="color: black;"><</span>CharT<span style="color: black;">>&</span><span style="color: silver;"> </span>os<span style="color: black;">,</span><span style="color: purple;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: purple;"> AppOptions</span><span style="color: black;"><</span>SpecOpt<span style="color: black;">></span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">&</span><span style="color: silver;"> </span>obj<span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">bool</span><span style="color: silver;"> </span><span style="color: black;">GotRequestForHelp</span><span style="color: black;">(</span>po<span style="color: black;">::</span>variables_map<span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">vm</span><span style="color: black;">,</span><span style="color: purple;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: purple;"> SpecificOptions</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">so</span><span style="color: black;">)</span><span style="color: silver;"> </span><span style="color: olive;">const</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span><span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span><span style="color: black;">vm</span><span style="color: black;">.</span>count<span style="color: black;">(</span><span style="color: black;">so</span><span style="color: black;">.</span>GetHelpOption<span style="color: black;">());</span><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">bool</span><span style="color: silver;"> </span><span style="color: maroon;">shownHelp</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>po<span style="color: black;">::</span>options_description<span style="color: silver;"> </span><span style="color: maroon;">desc</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>po<span style="color: black;">::</span>variables_map<span style="color: silver;"> </span><span style="color: maroon;">vm</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">SpecificOptions</span><span style="color: silver;"> </span><span style="color: maroon;">so</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">};</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<br />
<div style="text-align: justify;">
The SpecificOptions template parameter will contain all the different options/logic for each application. We expose it through <code style="background: #ffffff; color: black; font-size: 14px;">GetOptions()</code>, because the app will need it to access the actual option values.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<code style="background: #ffffff; color: black; font-size: 14px;">opTitle</code> is the caption shown on the help message's first line. <code style="background: #ffffff; color: black; font-size: 14px;">shownHelp</code> is set to true when the user requests the "help message", i.e., a list of the app's options.</div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<br /></div>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">template</span><span style="color: silver;"> </span><span style="color: black;"><</span><span style="color: olive;">typename</span><span style="color: silver;"> </span><span style="color: purple;">SpecOpt</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: olive;">typename</span><span style="color: silver;"> </span><span style="color: purple;">CharT</span><span style="color: black;">></span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">friend</span><span style="color: silver;"> </span><span style="color: purple;">std</span><span style="color: black;">::</span><span style="color: purple;">basic_ostream</span><span style="color: black;"><</span><span style="color: purple;">CharT</span><span style="color: black;">>&</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">operator</span><span style="color: black;"><<(</span><span style="color: purple;">std</span><span style="color: black;">::</span><span style="color: purple;">basic_ostream</span><span style="color: black;"><</span><span style="color: purple;">CharT</span><span style="color: black;">>&</span><span style="color: silver;"> </span><span style="color: black;">os</span><span style="color: black;">,</span><span style="color: purple;"> AppOptions</span><span style="color: black;"><</span><span style="color: purple;">SpecOpt</span><span style="color: black;">></span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">obj</span><span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">os</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">obj</span><span style="color: black;">.</span><span style="color: maroon;">so</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span><span style="color: black;">os</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<br />
<div style="text-align: justify;">
<code style="background: #ffffff; color: black; font-size: 14px;">operator<<()</code> is rather basic, not much to see here, except to note that this requires that SpecificOptions also overloads <code style="background: #ffffff; color: black; font-size: 14px;">operator<<()</code>.</div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<br /></div>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">template</span><span style="color: silver;"> </span><span style="color: black;"><</span><span style="color: olive;">typename</span><span style="color: silver;"> </span><span style="color: purple;">SpecificOptions</span><span style="color: black;">></span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: purple;">AppOptions</span><span style="color: black;"><</span><span style="color: purple;">SpecificOptions</span><span style="color: black;">>::</span><span style="color: purple;">AppOptions</span><span style="color: black;">(</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;"> </span><span style="color: olive;">int</span><span style="color: silver;"> </span><span style="color: black;">argc</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: black;">*</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: silver;"> </span><span style="color: black;">argv</span><span style="color: black;">[], </span><span style="color: silver;"></span><span style="color: olive;">char</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">*</span><span style="color: silver;"> </span><span style="color: black;">optTitle</span><span style="color: black;">)</span><span style="color: silver;"> </span><span style="color: black;">:</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;"> </span><span style="color: maroon;">shownHelp</span><span style="color: black;">{</span><span style="color: olive;">false</span><span style="color: black;">},</span><span style="color: silver;"> </span><span style="color: maroon;">desc</span><span style="color: black;">{</span><span style="color: black;">optTitle</span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: maroon;">so</span><span style="color: black;">.</span>DefineOptions<span style="color: black;">(</span><span style="color: maroon;">desc</span><span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>po<span style="color: black;">::</span>store<span style="color: black;">(</span>po<span style="color: black;">::</span>parse_command_line<span style="color: black;">(</span><span style="color: black;">argc</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">argv</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: maroon;">desc</span><span style="color: black;">),</span><span style="color: silver;"> </span><span style="color: maroon;">vm</span><span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">if</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: black;">GotRequestForHelp</span><span style="color: black;">(</span><span style="color: maroon;">vm</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: maroon;">so</span><span style="color: black;">))</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: maroon;">shownHelp</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: olive;">true</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">PrintHelp</span><span style="color: black;">();</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">else</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">try</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>po<span style="color: black;">::</span>notify<span style="color: black;">(</span><span style="color: maroon;">vm</span><span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: maroon;">so</span><span style="color: black;">.</span>Validate<span style="color: black;">();</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">catch</span><span style="color: silver;"> </span><span style="color: black;">(</span>po<span style="color: black;">::</span>required_option<span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">ro</span><span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: navy;">BOOST_THROW_EXCEPTION</span><span style="color: black;">(</span>ConfigRequiredOptionMissing<span style="color: black;">()</span><span style="color: silver;"> </span><span style="color: black;"><<</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>config_error_string<span style="color: black;">(</span><span style="color: green;">"Required</span><span style="color: silver;"> </span><span style="color: green;">option</span><span style="color: silver;"> </span><span style="color: green;">missing:</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><span style="color: black;">+</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">ro</span><span style="color: black;">.</span>get_option_name<span style="color: black;">()));</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<br />
<div style="text-align: justify;">
The ctor is where everything is set up. After calling <code style="background: #ffffff; color: black; font-size: 14px;">SpecificOptions::DefineOptions()</code> we get the atual command line arguments passed to our app. I borrowed an idea from a <a href="http://stackoverflow.com/questions/5395503/required-and-optional-arguments-using-boost-library-program-options" target="_blank">Stack Overflow article</a>, to check for the help option before calling <code style="background: #ffffff; color: black; font-size: 14px;">program_options::notify()</code>; this call performs validations (e.g., required options), and it makes no sense to perform those validations if the user just wants to see our help message and option list (there's no reason why I couldn't make <code style="background: #ffffff; color: black; font-size: 14px;">GotRequestForHelp()</code> a free function, but I'll leave it as a member, for now).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Also, if that's all the user wants to see, it makes no sense to continue processing and we have to let the app know that. At first, I thought about throwing an exception from the ctor. In the end, I settled for setting a flag and allowing the app to check it.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You'll note the <code style="background: #ffffff; color: black; font-size: 14px;">so.Validate()</code> call. I first considered <a href="http://www.boost.org/doc/html/program_options/howto.html#idp163429032" target="_blank">custom validators</a>, thinking it could make for a neater design. However, the docs mention these as a way of customizing parsing/conversion, not actually performing validation, and I didn't like the design I found in the examples that used them (with regards to validation requirements). Also, I figured such a design would make it more difficult to validate sets of related options. And then I noticed the example that performs validations of related options (<i>$BOOST_DIR</i>/libs/program_options/example/real.cpp) also uses auxiliary functions to perform such validation, so that settled it.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The exception thrown is defined in its own header, which contains other exceptions, and it's a simple boost exception.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So much for the generic part. What about the specific?</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let's use an example from one of my apps (renamed, to protect critical trade secrets):</div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<br /></div>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">class</span><span style="color: silver;"> </span><span style="color: purple;">ExampleOptions</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">public</span><span style="color: black;">:</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">void</span><span style="color: silver;"> </span><span style="color: black;">DefineOptions</span><span style="color: black;">(</span>po<span style="color: black;">::</span>options_description<span style="color: black;">&</span><span style="color: silver;"> </span>desc<span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"><span style="color: silver;"> </span><span style="color: olive;">void</span><span style="color: silver;"> </span><span style="color: black;">Validate</span><span style="color: black;">();</span></span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">std</span><span style="color: black;">::</span><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: black;">GetHelpOption</span><span style="color: black;">()</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: silver;"> </span><span style="color: black;">{</span><span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span><span style="color: green;">"help"</span><span style="color: black;">;</span><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">std</span><span style="color: black;">::</span><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: black;">GetOperation</span><span style="color: black;">()</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: silver;"> </span><span style="color: black;">{</span><span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span><span style="color: maroon;">operation</span><span style="color: black;">;</span><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">private</span><span style="color: black;">:</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">friend</span><span style="color: silver;"> </span><span style="color: purple;">std</span><span style="color: black;">::</span><span style="color: purple;">ostream</span><span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">operator</span><span style="color: black;"><<(</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;"> </span><span style="color: purple;">std</span><span style="color: black;">::</span><span style="color: purple;">ostream</span><span style="color: black;">&</span><span style="color: silver;"> </span>os<span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: purple;">ExampleOptions</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">&</span><span style="color: silver;"> </span>obj<span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">std</span><span style="color: black;">::</span><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: maroon;">operation</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">};</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">ostream<span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">operator</span><span style="color: black;"><<(</span>ostream<span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">os</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: purple;">ExampleOptions</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">obj</span><span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">os</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">"Operação:</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">obj</span><span style="color: black;">.</span><span style="color: maroon;">operation</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span><span style="color: black;">os</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">void</span><span style="color: silver;"> </span><span style="color: purple;">ExampleOptions</span><span style="color: black;">::</span><span style="color: black;">DefineOptions</span><span style="color: black;">(</span><span style="color: purple;">options_description</span><span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">desc</span><span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">desc</span><span style="color: black;">.</span><span style="color: black;">add_options</span><span style="color: black;">()</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: green;">"help,h"</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: green;">"Mensagem</span><span style="color: silver;"> </span><span style="color: green;">de</span><span style="color: silver;"> </span><span style="color: green;">ajuda"</span><span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: green;">"oper,o"</span><span style="color: black;">,</span><span style="color: silver;"> </span>value<span style="color: black;"><</span><span style="color: purple;">string</span><span style="color: black;">>(&</span><span style="color: maroon;">operation</span><span style="color: black;">)-></span>required<span style="color: black;">(),</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;"> </span><span style="color: silver;"></span><span style="color: green;">"Operação</span><span style="color: silver;"> </span><span style="color: green;">a</span><span style="color: silver;"> </span><span style="color: green;">efectuar.</span><span style="color: silver;"> </span><span style="color: green;">C</span><span style="color: silver;"> </span><span style="color: green;">-</span><span style="color: silver;"> </span><span style="color: green;">Operação</span><span style="color: silver;"> </span><span style="color: green;">de</span><span style="color: silver;"> </span><span style="color: green;">crédito;\n"</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: green;">"P</span><span style="color: silver;"> </span><span style="color: green;">-</span><span style="color: silver;"> </span><span style="color: green;">Operação</span><span style="color: silver;"> </span><span style="color: green;">de</span><span style="color: silver;"> </span><span style="color: green;">parametrização"</span><span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">void</span><span style="color: silver;"> </span><span style="color: purple;">ExampleOptions</span><span style="color: black;">::</span><span style="color: black;">Validate</span><span style="color: black;">()</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">if</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: maroon;">operation</span><span style="color: silver;"> </span><span style="color: black;">==</span><span style="color: silver;"> </span><span style="color: green;">"P"</span><span style="color: silver;"> </span><span style="color: black;">||</span><span style="color: silver;"> </span><span style="color: maroon;">operation</span><span style="color: silver;"> </span><span style="color: black;">==</span><span style="color: silver;"> </span><span style="color: green;">"p"</span><span style="color: silver;"> </span><span style="color: black;">||</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: maroon;">operation</span><span style="color: silver;"> </span><span style="color: black;">==</span><span style="color: silver;"> </span><span style="color: green;">"C"</span><span style="color: silver;"> </span><span style="color: black;">||</span><span style="color: silver;"> </span><span style="color: maroon;">operation</span><span style="color: silver;"> </span><span style="color: black;">==</span><span style="color: silver;"> </span><span style="color: green;">"c"</span><span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: navy;">BOOST_THROW_EXCEPTION</span><span style="color: black;">(</span>ConfigInvalidOption<span style="color: black;">()</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>config_error_string<span style="color: black;">(</span><span style="color: green;">"Operação</span><span style="color: silver;"> </span><span style="color: green;">desconhecida:</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><span style="color: black;">+</span><span style="color: silver;"> </span><span style="color: maroon;">operation</span><span style="color: black;">));</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">}</span></pre>
<br />
<div style="text-align: justify;">
Nothing tricky here, just a couple of notes.</div>
<ol style="text-align: justify;">
<li>We only defined <code style="background: #ffffff; color: black; font-size: 14px;">operator<<()</code> for ostream, not for wostream, even though the <code style="background: #ffffff; color: black; font-size: 14px;">operator<<()</code> we defined for AppOptions is prepared for both.</li>
<li>We're outputting plenty of non-ANSI characters with little concern for locale issues. Obviously, this causes problems, particularly on a Windows console. On my next post I'll show the solution I came up with to deal with this.</li>
</ol>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
And how do we use it?</div>
<div style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">
<br /></div>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">int</span><span style="color: silver;"> </span><span style="color: black;">main</span><span style="color: black;">(</span><span style="color: olive;">int</span><span style="color: silver;"> </span><span style="color: black;">argc</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: silver;"> </span><span style="color: black;">*</span><span style="color: black;">argv</span><span style="color: black;">[])</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">AppOptions</span><span style="color: black;"><</span><span style="color: purple;">ExampleOptions</span><span style="color: black;">></span><span style="color: silver;"> </span><span style="color: black;">appOpt</span><span style="color: black;">{</span><span style="color: black;">argc</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: black;">argv</span><span style="color: black;">,</span><span style="color: silver;"> </span><span style="color: green;">"Opções</span><span style="color: silver;"> </span><span style="color: green;">de</span><span style="color: silver;"> </span><span style="color: green;">Exemplo"</span><span style="color: black;">};</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">if</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: black;">appOpt</span><span style="color: black;">.</span><span style="color: black;">HasShownHelp</span><span style="color: black;">())</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span><span style="color: navy;">0</span><span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>cout<span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">appOpt</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span>endl<span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"></span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: purple;">string</span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: silver;"> </span><span style="color: black;">op</span><span style="color: silver;"> </span><span style="color: black;">=</span><span style="color: silver;"> </span><span style="color: black;">appOpt</span><span style="color: black;">.</span><span style="color: black;">GetOptions</span><span style="color: black;">().</span><span style="color: black;">GetOperation</span><span style="color: black;">();</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: olive;">if</span><span style="color: silver;"> </span><span style="color: black;">((</span><span style="color: black;">op</span><span style="color: silver;"> </span><span style="color: black;">==</span><span style="color: silver;"> </span><span style="color: green;">"P"</span><span style="color: black;">)</span><span style="color: silver;"> </span><span style="color: black;">||</span><span style="color: silver;"> </span><span style="color: black;">(</span><span style="color: black;">op</span><span style="color: silver;"> </span><span style="color: black;">==</span><span style="color: silver;"> </span><span style="color: green;">"p"</span><span style="color: black;">))</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">...</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<div style="text-align: justify;">
<br />
Pretty simple, and all we have to repeat for each app is the code that is actually different. I still itch to tackle that "options in a config file" design, but I'll leave that to another day.</div>
<br />Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-19176875937185167502013-11-28T23:43:00.000+00:002013-11-28T23:43:23.893+00:00Every now and then one must emerge to let the world know one's alive<div style="text-align: justify;">
So...<br /><br />1. The puzzle mentioned in my previous post is solved. I've increased the +/- 4M lines to 16M, and the difference from pass-by-value to pass-by-reference increased to a little over 1 min. So, there's a difference, but it's irrelevant. This was also a good example of something I've read before, that the compiler takes certain liberties when optimizing classes it knows - such as making calls directly to the implementation of standard containers, instead of using the usual interface. In this case, instead of using std map's copy ctor, it directly invoked the underlying red-black tree copy implementation.<br /><br />So, the song remains the same - measure first, and optimize only what's required.<br /><br />2. I've upgraded to Qt Creator 2.8.1/Qt 5.1.1, and I've rebuilt all the libs to work with mingw's gcc 4.8. I've also created scripts to automate building boost and ICU. While developing the boost script (in perl), I've come across a peculiar problem, but this time I've decided to work around it (half the work is in perl, the other half in a DOS batch script), instead of trying to figure out the cause. Life's too short, and all that jazz...<br /><br />3. Watching Alex Stepanov's A9 lectures made me realize I was familiar only with C++'s OO paradigm, and that I had to diversify. So, I've began approaching my designs in a different fashion, applying generic programming whenever possible and resisting the urge to turn almost everything into an object. I'll address this in future posts, hopefully.<br /><br />4. My libssh2 + boost asio work has been deployed. Not in the grandiose manner I envisioned, filled with pools of ssh connections and a multitude of threads, but in a more modest setting - a command line utility that reads a few files and runs a list of commands on a remote server. It's indeed a humble beginning, but it has already proved its success, and it will allow me another shot at something that got me stuck - how to apply logging to it (actually, for this utility, I <i>#define</i>d out all logging, because I wasn't happy with it).<br /><br />I believe I got stuck because I tried to solve the problem of applying logging to reusable code, which is more complex than the problem I'll address now - how to apply logging from the point of view of an app (i.e., the code the uses the reusable code). I hope this different - and simpler - point of view will prove more productive.<br /></div>
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0tag:blogger.com,1999:blog-1647814752446097280.post-72227480127980538192013-10-06T22:40:00.000+01:002013-10-06T22:40:20.146+01:00g++ optimization mysteries<div style="text-align: justify;">
It's been a long time. Work has gone into overdrive, courtesy of a huge scope project. And not only has my spare time taken a hit, but, more importantly, there have been too many days when I get home and all I can do is pick up a book, or pick up my guitar, or watch a nice TV show with my wife (we're quite partial to Jamie Oliver shows on 24 Kitchen).<br />
<br />
Still, I haven't abandoned C++, quite the opposite. I've been working on a few utilities to process files, and I've been experimenting with different options, and measuring each option's performance.<br />
<br />
The last one I've tried left me with an interesting - and, so far, unsolved - puzzle.<br />
<br />
We have a file where each line contains a field in a form; a whole form can be eight or nine lines (depending on whether all the form fields were filled). I've created a program that reads this file and outputs each form's fields on one line; something like this:</div>
<br />
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">while</span><span style="color: silver;"> </span><span style="color: black;">(</span>getline<span style="color: black;">(...))</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: green;">// TOKENIZE THE LINE</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: green;">// GET THE FIELD'S DESCRIPTION AND VALUE</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: green;">// USE THE FIELD'S DESCRIPTION AS A MAP INDEX AND </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: green;"> // STORE THE VALUE IN THE MAP</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: green;">// IF WE'VE READ ALL THE FIELDS, PRINT THE FORM</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<div style="text-align: justify;">
<br />
"<i>Printing the form</i>" means outputting the map to <code style="background: #ffffff; color: black; font-size: 14px;">cout</code>, which I did like this on my first version:<br />
<br /></div>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">void</span><span style="color: silver;"> </span><span style="color: black;">OutputForm</span><span style="color: black;">(</span><span style="color: purple;">CobForm</span><span style="color: black;">&</span><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>cout<span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"dist"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"conc"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"tlm"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"freg"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"status"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"ID"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><< </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"dt"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"result"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"tipo"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span>endl<span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">}</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<br />
<div style="text-align: justify;">
Actually, my first version had a <code style="background: #ffffff; color: black; font-size: 14px;">CobForm const&</code>, which the compiler prompty rejected, reminding me - probably in a slightly amused tone - that map's <code style="background: #ffffff; color: black; font-size: 14px;">operator[]</code> isn't <code style="background: #ffffff; color: black; font-size: 14px;">const</code>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So, I ran this against the 3.8M lines input file, and it took +/- 1:32 on my PC; I ran it 10 times, and the variation was minimal, less than 1 second.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Then, I've decided to change it to pass-by-value:</div>
<br />
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: olive;">void</span><span style="color: silver;"> </span><span style="color: black;">OutputForm</span><span style="color: black;">(</span><span style="color: purple;">CobForm</span><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">{</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>cout<span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"dist"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"conc"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"tlm"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"freg"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"status"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"ID"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><< </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"dt"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"result"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span><span style="color: green;">";"</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span><span style="color: black;">form</span><span style="color: black;">[</span><span style="color: green;">"tipo"</span><span style="color: black;">]</span><span style="color: silver;"> </span><span style="color: black;"><<</span><span style="color: silver;"> </span>endl<span style="color: black;">;</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;">}</span></pre>
<br />
<div style="text-align: justify;">
Another 10 runs, and no noticeable difference, +/- 1:33, again with variation below 1 second between runs.</div>
<div style="text-align: justify;">
<br /></div>
At first, I thought maybe this function was inlined. However, <i>nm </i>disagreed:<br />
<span style="color: black;"></span> <br />
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: navy;">00401b70</span><span style="color: silver;"> </span>T<span style="color: silver;"> </span>OutputForm<span style="color: black;">(</span>std<span style="color: black;">::</span>map<span style="color: black;"><</span>std<span style="color: black;">::</span>string<span style="color: black;">,</span><span style="color: silver;"> </span>std<span style="color: black;">::</span>string<span style="color: black;">,</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>std<span style="color: black;">::</span>less<span style="color: black;"><</span>std<span style="color: black;">::</span>string<span style="color: black;">>,</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;"> </span><span style="color: silver;"></span>std<span style="color: black;">::</span>allocator<span style="color: black;"><</span>std<span style="color: black;">::</span>pair<span style="color: black;"><</span>std<span style="color: black;">::</span>string<span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">,</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>std<span style="color: black;">::</span>string<span style="color: black;">></span><span style="color: silver;"> </span><span style="color: black;">></span><span style="color: silver;"> </span><span style="color: black;">>)</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Yes, I was building in release mode. I added this to my Qt Creator project file, to keep the linker from removing the symbols:</div>
<div style="text-align: justify;">
<br /></div>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: purple;">QMAKE_LFLAGS_RELEASE</span><span style="color: silver;"> </span>-=<span style="color: silver;"> </span>-Wl,-s</pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> </pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<div style="text-align: justify;">
Next, I've decided to look at the generated assembly. I'm far from an expert, but I thought "No harm in taking a look, right?"</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First, pass by reference. This is what the compiler generated:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="color: black;"></span> </div>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: navy;">119</span><span style="color: silver;"> </span>OutputForm<span style="color: black;">(</span>form<span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: navy;">0x40588e</span><span style="color: silver;"> </span><span style="color: black;"><+</span><span style="color: navy;">0x19cd</span><span style="color: black;">></span><span style="color: silver;"> </span>movl<span style="color: silver;"> </span>$0x8<span style="color: black;">,-</span><span style="color: navy;">0x1e8</span><span style="color: black;">(%</span>ebp<span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: navy;">0x405898</span><span style="color: silver;"> </span><span style="color: black;"><+</span><span style="color: navy;">0x19d7</span><span style="color: black;">></span><span style="color: silver;"> </span>lea<span style="color: silver;"> </span><span style="color: black;">-</span><span style="color: navy;">0x150</span><span style="color: black;">(%</span>ebp<span style="color: black;">),%</span>ecx</pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: navy;">0x40589e</span><span style="color: silver;"> </span><span style="color: black;"><+</span><span style="color: navy;">0x19dd</span><span style="color: black;">></span><span style="color: silver;"> </span>mov<span style="color: silver;"> </span><span style="color: black;">%</span>ecx<span style="color: black;">,(%</span>esp<span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: navy;">0x4058a1</span><span style="color: silver;"> </span><span style="color: black;"><+</span><span style="color: navy;">0x19e0</span><span style="color: black;">></span><span style="color: silver;"> </span>call<span style="color: silver;"> </span><span style="color: navy;">0x401b70</span><span style="color: silver;"> </span><span style="color: black;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;"> <</span>OutputForm<span style="color: black;">(</span>std<span style="color: black;">::</span>map<span style="color: black;"><</span>std<span style="color: black;">::</span>string<span style="color: black;">,</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>std<span style="color: black;">::</span>string<span style="color: black;">,</span><span style="color: silver;"> </span>std<span style="color: black;">::</span>less<span style="color: black;"><</span>std<span style="color: black;">::</span>string<span style="color: black;">>,</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>std<span style="color: black;">::</span>allocator<span style="color: black;"><</span>std<span style="color: black;">::</span>pair<span style="color: black;"><</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;"> </span>std<span style="color: black;">::</span>string<span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">,</span><span style="color: silver;"> </span>std<span style="color: black;">::</span>string<span style="color: black;">></span><span style="color: silver;"> </span><span style="color: black;">></span><span style="color: silver;"> </span><span style="color: black;">>&)></span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<br />
<div style="text-align: justify;">
With the following addresses: </div>
<br />
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: maroon;">form</span><span style="color: black;">:</span><span style="color: silver;"> </span><span style="color: navy;">0x28fcf8</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: maroon;">ebp</span><span style="color: black;">:</span><span style="color: silver;"> </span><span style="color: navy;">0x28fe48</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: maroon;">esp</span><span style="color: black;">:</span><span style="color: silver;"> </span><span style="color: navy;">0x28fc10</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<br />
<div style="text-align: justify;">
So, we start by moving 8 into <code style="background: #ffffff; color: black; font-size: 14px;">0x28fc60</code> (<code style="background: #ffffff; color: black; font-size: 14px;">-0x1e8(%ebp)</code>), although I couldn't figure out why. Then, we move <code style="background: #ffffff; color: black; font-size: 14px;">form</code>'s address into <code style="background: #ffffff; color: black; font-size: 14px;">ecx</code>, move that into the address pointed by <code style="background: #ffffff; color: black; font-size: 14px;">esp</code> (setting up the call argument), and we call <code style="background: #ffffff; color: black; font-size: 14px;">OutputForm()</code>. In <code style="background: #ffffff; color: black; font-size: 14px;">OutputForm()</code>, I was able to verify that <code style="background: #ffffff; color: black; font-size: 14px;">form</code>'s address was <code style="background: #ffffff; color: black; font-size: 14px;">0x28fcf8</code>.</div>
<br />
<div style="text-align: justify;">
Next, I did the same thing for the pass by value version. Which got me this: </div>
<br />
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: navy;">119</span><span style="color: silver;"> </span>OutputForm<span style="color: black;">(</span>form<span style="color: black;">);</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: navy;">0x40593d</span><span style="color: silver;"> </span><span style="color: black;"><+</span><span style="color: navy;">0x1a5c</span><span style="color: black;">></span><span style="color: silver;"> </span>movl<span style="color: silver;"> </span>$0x9<span style="color: black;">,-</span><span style="color: navy;">0x218</span><span style="color: black;">(%</span>ebp<span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: navy;">0x405947</span><span style="color: silver;"> </span><span style="color: black;"><+</span><span style="color: navy;">0x1a66</span><span style="color: black;">></span><span style="color: silver;"> </span>lea<span style="color: silver;"> </span><span style="color: black;">-</span><span style="color: navy;">0x150</span><span style="color: black;">(%</span>ebp<span style="color: black;">),%</span>ecx</pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: navy;">0x40594d</span><span style="color: silver;"> </span><span style="color: black;"><+</span><span style="color: navy;">0x1a6c</span><span style="color: black;">></span><span style="color: silver;"> </span>mov<span style="color: silver;"> </span><span style="color: black;">%</span>ecx<span style="color: black;">,(%</span>esp<span style="color: black;">)</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: navy;">0x405950</span><span style="color: silver;"> </span><span style="color: black;"><+</span><span style="color: navy;">0x1a6f</span><span style="color: black;">></span><span style="color: silver;"> </span>call<span style="color: silver;"> </span><span style="color: navy;">0x401b70</span><span style="color: black;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;"> <</span>OutputForm<span style="color: black;">(</span>std<span style="color: black;">::</span>map<span style="color: black;"><</span>std<span style="color: black;">::</span>string<span style="color: black;">,</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>std<span style="color: black;">::</span>string<span style="color: black;">,</span><span style="color: silver;"> </span>std<span style="color: black;">::</span>less<span style="color: black;"><</span>std<span style="color: black;">::</span>string<span style="color: black;">>,</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;"> </span><span style="color: silver;"></span>std<span style="color: black;">::</span>allocator<span style="color: black;"><</span>std<span style="color: black;">::</span>pair<span style="color: black;"><</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;"> </span>std<span style="color: black;">::</span>string<span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">,</span><span style="color: silver;"> </span>std<span style="color: black;">::</span>string<span style="color: black;">></span><span style="color: silver;"> </span><span style="color: black;">></span><span style="color: silver;"> </span><span style="color: black;">>)></span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: maroon;">form</span><span style="color: black;">:</span><span style="color: silver;"> </span><span style="color: navy;">0x28fcc8</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: maroon;">ebp</span><span style="color: black;">:</span><span style="color: silver;"> </span><span style="color: navy;">0x28fe48</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: maroon;">esp</span><span style="color: black;">:</span><span style="color: silver;"> </span><span style="color: navy;">0x28fbe0</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now, first thing I noticed is - no copy ctor. We're passing by value, but there's no copy ctor. Just to make sure, I made a debug build, and there it was, in all its splendor:</div>
<br />
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: navy;">0x402262</span><span style="color: silver;"> </span><span style="color: black;"><+</span><span style="color: navy;">0x00f6</span><span style="color: black;">></span><span style="color: silver;"> </span>call<span style="color: silver;"> </span><span style="color: navy;">0x40a3e8</span><span style="color: silver;"> </span><span style="color: black;"><</span>std<span style="color: black;">::</span>map<span style="color: black;"><</span>std<span style="color: black;">::</span>string<span style="color: black;">,</span><span style="color: silver;"> </span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> std<span style="color: black;">::</span>string<span style="color: black;">,</span><span style="color: silver;"> </span>std<span style="color: black;">::</span>less<span style="color: black;"><</span>std<span style="color: black;">::</span>string<span style="color: black;">>,</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;"> </span><span style="color: silver;"></span>std<span style="color: black;">::</span>allocator<span style="color: black;"><</span>std<span style="color: black;">::</span>pair<span style="color: black;"><</span> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> std<span style="color: black;">::</span>string<span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">,</span><span style="color: silver;"> </span>std<span style="color: black;">::</span>string<span style="color: black;">></span><span style="color: silver;"> </span><span style="color: black;">></span><span style="color: silver;"> </span><span style="color: black;">>::</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: black;"> </span>map<span style="color: black;">(</span>std<span style="color: black;">::</span>map<span style="color: black;"><</span>std<span style="color: black;">::</span>string<span style="color: black;">,</span><span style="color: silver;"> </span>std<span style="color: black;">::</span>string<span style="color: black;">,</span> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> std<span style="color: black;">::</span>less<span style="color: black;"><</span>std<span style="color: black;">::</span>string<span style="color: black;">>,</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"><span style="color: silver;"> </span>std<span style="color: black;">::</span>allocator<span style="color: black;"><</span>std<span style="color: black;">::</span>pair<span style="color: black;"><</span> </pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"> std<span style="color: black;">::</span>string<span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">,</span><span style="color: silver;"> </span>std<span style="color: black;">::</span>string<span style="color: black;">></span><span style="color: silver;"> </span><span style="color: black;">></span><span style="color: silver;"> </span><span style="color: black;">></span><span style="color: silver;"> </span><span style="color: olive;">const</span><span style="color: black;">&)></span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<br />
<div style="text-align: justify;">
Then, I thought - maybe the compiler's decided it can perform a "sort-of-pass-by-ref" optimization. However, <code style="background: #ffffff; color: black; font-size: 14px;">form</code>'s address was <code style="background: #ffffff; color: black; font-size: 14px;">0x28fcc8</code>, and the address set up as an argument was <code style="background: #ffffff; color: black; font-size: 14px;">-0x150(%ebp)</code>, i.e., <code style="background: #ffffff; color: black; font-size: 14px;">0x28fcf8</code>. And, as soon as I stepped into <code style="background: #ffffff; color: black; font-size: 14px;">OutputForm()</code>, I was able to confirm that <code style="background: #ffffff; color: black; font-size: 14px;">form</code>'s address in its scope was, indeed, <code style="background: #ffffff; color: black; font-size: 14px;">0x28fcf8</code>.</div>
<br />
<div style="text-align: justify;">
Another thought occured me - perhaps it's some sort of alias. Maybe there's been no string allocation at all. So, I went back to the previous scope, and checked the addresses of <code style="background: #ffffff; color: black; font-size: 14px;">form[0]</code>:</div>
<br />
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">form<span style="color: black;">[</span><span style="color: navy;">0</span><span style="color: black;">].</span>first<span style="color: black;">:</span><span style="color: silver;"> </span><span style="color: navy;">0x783618</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">form<span style="color: black;">[</span><span style="color: navy;">0</span><span style="color: black;">].</span>second<span style="color: black;">:</span><span style="color: silver;"> </span><span style="color: navy;">0x78361c</span></pre>
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<br />
<div style="text-align: justify;">
Then, I went into <code style="background: #ffffff; color: black; font-size: 14px;">OutputForm()</code> again, and the addresses were different:</div>
<br />
<pre style="-qt-block-indent: 0; -qt-paragraph-type: empty; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;"></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">form<span style="color: black;">[</span><span style="color: navy;">0</span><span style="color: black;">].</span>first<span style="color: black;">:</span><span style="color: silver;"> </span><span style="color: navy;">0x783c18</span></pre>
<pre style="-qt-block-indent: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-indent: 0px;">form<span style="color: black;">[</span><span style="color: navy;">0</span><span style="color: black;">].</span>second<span style="color: black;">:</span><span style="color: silver;"> </span><span style="color: navy;">0x783c1c</span></pre>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So, even though I can find no trace of a copy ctor, the fact is the addresses are different at each scope. And, for now, I have no idea what exactly is going on here.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
However, this just shows, once again, the importance of measuring before "optimizing".</div>
<br />
<br />
Paulo Caetanohttp://www.blogger.com/profile/03574085197537324973noreply@blogger.com0