tag:blogger.com,1999:blog-26343534763774993082024-03-14T07:49:43.404-06:00The Code SpeaksCode snippets, magic scripts and design ideas (Blog is dead)Unknownnoreply@blogger.comBlogger12125tag:blogger.com,1999:blog-2634353476377499308.post-80231377735508941822008-02-15T15:49:00.008-07:002008-02-15T16:37:18.134-07:00Open source is good for your health<h2>Linux helps to code for Windows too</h2><p>What exactly <code class="inline">Variant.<a href="http://msdn2.microsoft.com/en-us/library/2kc812h8(VS.80).aspx">ChangeType</a>( VT_NULL )</code> does? Will it free any memory owned by variant?</p><p>Common sense suggests "yes", but looking at all these low level struct-union-macros games I cannot avoid being paranoid sometimes. Unfortunately, MSDN help does not have such level of details and does not have any notions specifically about <code class="inline">VT_NULL</code> usage here.</p><p>I am glad I've found <a href="http://www.winehq.org/">Wine</a> sources and could check their logic. Assuming their <code class="inline"><a href="http://source.winehq.org/source/dlls/oleaut32/variant.c#L81">VARIANT_Coerce</a></code> mimics Windows API logic I can be sure now that memory is freed. Hooray! I do not have to debug <code class="inline">_variant_t</code>!</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2634353476377499308.post-56939157045205175332007-09-28T07:09:00.000-06:002007-09-28T07:19:26.555-06:00Idea: background building of Visual Studio C++ projects<p>Sometimes I come up with crazy ideas about programs or scripts that could do magic.</p>
<p>Since I don't have time or knowledge to implement them all, I decided at least describe them here. Hopefully somebody else finds them useful and decides to make them a reality. In this case, I will be the first to help. When you think of something long enough, it gets more and more details, single blog post cannot describe them all but just some key points only.</p>
<h2>CPP background compiler</h2>
<p>Ok, today's idea is about compiling source files. I often wish that Visual Studio compiled projects on a background, while you editing them. Of course, the changed files would need to be recompiled. Updating headers would require many cpp files to be recompiled... So what? Those files will take their time anyway, when you press "Build". But if you have most of the files compiled on a background, building the project from IDE would be much faster, since only the recently changed files would need to be compiled and only linkage would left.</p>
<h3>Simple and stupid approach: build it all</h3>
<p>Just pick up the solution or project and run a batch file which would constantly call devenv with /build switch to attempt to build the project. Make that process idle priority, so it would not affect other programs much.</p>
<p>Visual Studio doesn't like much if you're saving source files during compilation. If that is a cpp file which was saved, then during next build request, it should figure out that obj file has creation time less than cpp and recompile it. Not a big deal, but this shall work only if my following assumptions are true:
<ol class="abclist"><li>Compiler loads entire cpp file into memory before compiling it (including preprocessing)</li>
<li>Obj file creation time equals to the time when file was started to be written on disk, not when it was closed</li>
<li>The time between cpp was loaded into compiler's memory and the time obj file was opened on disk is negligibly small (or even better — obj file is opened before cpp file was read from the disk.</li></ol></p>
<p>Of course, modifying header may cause more recompilations, since Visual Studio must figure out what cpp files depend on it and recompile them. I don't see much problems, as soon as the assumptions above are ok.</p>
<p>Well, almost no problems. If you update stdafx.h this means you should recompile stdafx.cpp. And if you're recompiling stdafx.cpp this means you should recompile all cpps in the project. I am not sure Visual Studio /build is smart enough to figure that out, so this is better to be tested.</p>
<p>One small thing:</p>
<h3>Synchronization with Visual Studio IDE</h3>
<p>Having another instance of compiler writing some obj file will prevent Visual Studio to compile that file from IDE. This means we should synchronize IDE with our background script. Practically this means we should stop or kill that background IDE before building project from IDE.</p>
<p>I see this could be done by creating a macro, which would call <a href="http://www.microsoft.com/technet/sysinternals/utilities/pskill.mspx">pskill.exe</a> (written by Mark Russinovich from <a href="http://www.microsoft.com/technet/sysinternals/default.mspx">Sysinternals</a>) before actually starting a build from IDE. To avoid running background compilation script manually after IDE build finishes, we could run it from project post-build event. However this will only work if IDE compilation was successful. Otherwise — alas, I don't see how to call a macro after build finishes with error. Maybe creating IDE add-on would help?</p>
<p>Ok, that seems not too efficient to build an entire project on background, since it will do scanning all of the project files and sometimes that can be a lot. The synchronization problems with IDE make it worse too.</p>
<h3>How about we compile only cpps?</h3>
<p>We could run compiler itself (cl.exe) on all cpp files of the project, just like IDE does. It would require to pick up project options from vcproj file, also we would need to clean the objs after compiler options were updated in vcproj (and don't forget about IDE environment variables). That seems like more difficult to do, but still nothing too special.</p>
<p>This way IDE would do the linkage and all post-build stuff and our background script would only compile the cpps as they get updated.</p>
<p>Synchronization would be less required, since the background script would do nothing after all cpps are compiled. So every time you start the build, it could just wait until the background script finishes compiling all the recently updated cpps and then start IDE build (presumably only linkage would left at this point). As a signal that he is done, the background script could create an empty file with predefined name in project directory, which could be easily checked by macro for existence. Also, this macro would need to call "SaveAllFiles" manually so background script would not wake up after IDE saves the modified source files before starting a build.</p>
<p>The only thing which makes complicates this approach more is that background script should watch header files too and recompile all affected cpps (having stdafx in mind too), i.e. reproduce more of the IDE logic. Having many nested include files makes this task not so trivial. However still doable.</p>
<h3>Sounds familiar?</h3>
<p>If we can do pretty much what IDE does with the builds, maybe we could leave it only editing of files and projects and avoid synchronization problems just by relying on background compilation scripts?</p>
<p>We could remap standard shortcuts so they pass commands to our "engine" and even redirect it's output to IDE build windows probably. If that cannot be done with macros, maybe add-on could work instead.</p>
<p>Another thing I often desperately need in Visual Studio is queueing the projects compilation. Usually this is required when you have big solution and few projects you want to be built. You start "Build this project only" on one project and then wait patiently until it finishes, then you run nother project the same way... Of course you can create build configuration and group such projects there. But sometimes it is just "this and that" and not worth creating a configuration for a single case.</p>
<p>So, at this point having a command "add to the building queue" would be perfect, but there is no such thing in IDE (at least in Visual Studio 7.1 aka 2003). But if we had a script-engine capable of building projects, adding some queueing to it would be pretty simple and convenient.</p>
<p>This is pretty close actually to having own IDE for C++ projects, but that is another big idea. =)</p>
<p>Let me know if you implement some of these approaches. Of course, if I ever do this, I will write about it here. Maybe having a plan and design in form of a blog post will make this come true sooner — we'll see…</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2634353476377499308.post-92181015892161913412007-07-27T15:01:00.000-06:002007-07-27T15:41:02.788-06:00Requirements for TPPThis is the first part of requirements for the perfect project. It turns out they are "level 0", i.e. the most essential ones. More requirements shall be published later and specify user-generated content features, internationalization and maybe some insights about further functions evolution.
<h1>Glossary</h1>
<p><b>TPP, the perfect project</b> = code name for this program I want to develop. Later this can be changed by other name.</p>
<p><b>Program, Software</b> = in most cases any 3<sup>rd</sup> party software which shall be shipped and managed with the help of TPP. This doesn't include any system libraries, video codecs or anything like that. Note: This may include some scripts which actually only configure existing software, update some settings or change behavior of the programs already installed. Note: The program means separate functionality unit which can be independently installed or uninstalled. This shall not be a module extending the functionality of the existing program, because it will introduce dependencies between modules if main program is being uninstalled and dependant module wasn't. User shall not know or decide about these dependencies during install or uninstall (however she can select packages of software to install as single program using TPP). Alternatively, for some add-ons, we could have them installable to "main" host program, but still consider uninstall as atomic operation for host program with all its add-ons altogether. <span style="background: yellow none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">More examples are needed to think this all through.</span></p>
<p><b>Installation, Program installation</b> = Installation and configuration any program, the process which includes downloading and copying all necessary program files, registering the software within operating system and existing software environment and configuring all program settings which are required for user to work with the
program.</p>
<p><b>Rebooting, operation system rebooting</b> = The actions which are needed to be performed during program installation which assume giving all control from TPP back to operating system. Usually this means shutting down the operating system and starting it again automatically and TPP taking control again after some moment. During rebooting, the user may be asked to log in to operating system before TPP activates. User can also postpone the installation for any time simply by shutting down the computer during rebooting, or by logging in the operating system using account other than he used to work with TPP.</p>
<p><b>Safe rebooting, rebooting safely</b> = <span style="background: yellow none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">shall be defined later</span> and depend whether the user have opened programs which cannot close automatically without losing the user data.</p>
<h1>TPP Requirements (F = functional, NF = non-functional)</h1>
<h2>Browsing programs</h2>
<ol class="law">
<li>(F) TPP shall allow the user to browse available programs.
<ol class="law">
<li>(NF) User shall be required to have an internet connection to browse and install programs with help of TPP.</li>
<li>(F) TPP shall allow the user to select and clarify his selection of category of the program he is looking for from the pre-defined catalog.</li>
<li>(F) The catalog of programs should allow the user to find the program:
<ol class="law">
<li>(F) Using keywords describing desired functionality. For example: graphics editor, photo editor, antivirus software etc.</li>
<li>(F) Using keywords describing the program's description or name as provided by author.</li>
<li>(F) Using keywords describing the program as given by other users.</li>
<li>(F) Using keywords describing desired task that should be accomplished with the help of the program. For example: write CD, copy DVD, print book, draw picture, record movie, copy movie, protect from viruses etc.</li>
</ol></li>
</ol></li>
</ol>
<h2>Installing programs</h2>
<ol class="law" style="counter-reset: item 1;">
<li>(F) TPP shall allow the user to install the selected program automatically.
<ol class="law">
<li>(F) User shall not be asked for any parameters during program installation.
<ol class="law">
<li>(F) User shall not be asked for the permission to download the program from internet or any other resource.</li>
<li>(F) User shall not be asked the path where to install the program.</li>
<li>(F) User shall not be asked to remove older version of the software being installed.</li>
<li>(F) User shall not be asked to install other prerequisite libraries or programs required by software being installed.</li>
<li>(F) User shall not be asked to accept any license agreements.</li>
<li>(F) User shall not be asked to customize functionality package for the software being installed.</li>
<li>(F) User shall not be asked the language of the program interface.</li>
<li>(F) If the program user selected to install already installed, the program shall be re-installed as it was a newer version of the software, without any confirmations (see req. 2.1.2).</li>
</ol></li>
<li>(F) If the program installation required rebooting the computer, the user shall be notified about that before installation starts.
<ol class="law">
<li>(F) If rebooting can be done safely, the user shall not be asked for any permission to do it.</li>
<li>(F) If rebooting cannot be done safely, the user shall be asked the permission for it before installation starts.</li>
</ol></li>
<li>(F) At any point during installation except the time when operating system is being rebooted, the user shall be able to cancel the installation.
<ol class="law">
<li>(F) When installation is cancelled, all the changes made during the installation shall be rolled back to the state as they were before installation started.
<ol class="law">
<li>(F) User shall not be asked to confirm the rollback.</li>
<li>(F) If rollback requires rebooting again and it can be done safely, it should be done without asking the user for permission. Otherwise the user shall be asked for the permission to reboot.</li>
</ol></li>
</ol></li>
</ol></li>
</ol>
<h2>Browsing installed programs</h2>
<ol class="law" style="counter-reset: item 2;">
<li>(F) TPP shall allow the user to browse installed programs on his computer using the same functionality as described in requirements 1.
<ol class="law">
<li>(NF) User shall not be required to have internet connection to browse and view existing installed software.</li>
</ol></li>
</ol>
<h2>Uninstalling programs</h2>
<ol class="law" style="counter-reset: item 3;">
<li>(F) TPP shall allow the user to uninstall any program installed using TPP automatically.
<ol class="law">
<li>(F) Uninstalling the program shall not leave any files or folders created as the part of its work unless those files are documents created by user and manually saved by him at location where the program was installed. For example: program uninstall shall not leave custom setting files, shared libraries, shared plug-ins, game save files etc.</li>
<li>(F) User shall not be asked for any parameters during program uninstall.
<ol class="law">
<li>(F) User shall not be asked for confirmation to uninstall the program.</li>
<li>(F) User shall not be asked for confirmation to remove some files or libraries, shared or not shared by other applications.</li>
<li>(F) User shall not be asked to rollback to older version of the software after uninstalling the selected one, if the selected one was installed over older version.</li>
<li>(F) User shall not be asked for any feedbacks to the creators of the program or anybody else.</li>
<li>(F) User shall not be asked to remove only some components of software instead of uninstall.</li>
</ol></li>
<li>(F) If program uninstall requires rebooting the computer, the user shall be notified about that before uninstall starts.
<ol class="law">
<li>(F) If rebooting can be done safely, the user shall not be asked for any permission to do it.</li>
<li>(F) If rebooting cannot be done safely, the user shall be asked the permission for it before uninstall starts.</li>
</ol></li>
<li>(F) At any point during uninstall except the time when operating system is being rebooted, the user shall be able to cancel uninstall.
<ol class="law">
<li>(F) When uninstall is cancelled, all the changes made during uninstall shall be rolled back to the state as they were before uninstall started.
<ol class="law">
<li>(F) User shall not be asked to confirm the rollback.</li>
<li>(F) If rollback requires rebooting again and it can be done safely, it should be done without asking the user for permission. Otherwise the user shall be asked for the permission to reboot.</li>
</ol></li>
</ol></li>
</ol></li>
</ol>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2634353476377499308.post-34091284214737363802007-04-15T22:40:00.000-06:002007-04-16T00:05:42.095-06:00The perfect project: Problem formulationOk, we are gonna do some software project and do it as best as we can (Let's use "we", cause I don't like using "I" all the times. Anyway if you are reading, then you are participating already). Best practices, processes, technologies — all of that is welcomed until it is useful. And perfect. =)
So, what are we gonna do? Let it be something simple enough to not stuck in technical details, but complex enough to have value and serve as a playground for demonstrating the processes and stuff.
Let it be... Fibonacci numbers calculator. No, even better — factorial number calculator! Or, maybe a converter of temperature between Celcius and Fahrenheit?
This is the first stop. That is the problem of 99% of the books about programming we have. People read them to learn programming, to learn how to create things. And they start with the wrong examples.
<blockquote><p><a href="http://technologyreview.com/Infotech/17831/">Technology Review: Why is most software so bad?</a></p><p>[…]
</p><p>Technology Review: How can we fix the mess we are in?</p><p>Bjarne Stroustrup: In theory, the answer is simple: educate our software developers better, use more-appropriate design methods, and design for flexibility and for the long haul. Reward correct, solid, and safe systems. Punish sloppiness.</p></blockquote>
When a student starts to learn programming, what book it is pointed first? Yes, a programming language book. Like <a href="http://www.amazon.com/C++-Programming-Language-Special-3rd/dp/0201700735">C++ Programming Language</a>. And what happens after that? On conferences like <a href="http://www.sdexpo.com/%22">SD West 2007</a>, Bjarne Stroustrup and Herb Sutter — the gurus, the leaders of software development world — spend hours explaining software developers (adults now) the things they do wrong. Like why they should avoid using C-arrays and favor std::vector. That's ridiculous! And just in the middle of that (around $175 per hour BTW), each of them uses fopen/fclose on their slides to demonstrate the value and proper usage of constructors/destructors and smart pointers:
Bjarne:<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh21aXqzBsvFHdngAbxVoZrywRyRLiXVwUghUl8c6YP2HLwFbf_sTmq6hTk1BMwnZ_t2XC4rZW3Xcfh04zGBnRhnFfx8YPuIKh_oHgrB_AJzY2O7n-DFWLYouDJxHKPfnj4i5i145u0VZ0/s1600-h/GoodInterfaces.GIF"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh21aXqzBsvFHdngAbxVoZrywRyRLiXVwUghUl8c6YP2HLwFbf_sTmq6hTk1BMwnZ_t2XC4rZW3Xcfh04zGBnRhnFfx8YPuIKh_oHgrB_AJzY2O7n-DFWLYouDJxHKPfnj4i5i145u0VZ0/s400/GoodInterfaces.GIF" alt="" id="BLOGGER_PHOTO_ID_5053894466390867106" border="0" /></a>
And Herb:<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ_jD_AZmyF4KTjRUpckAumeYfaGlblhsNLiBQVZctLECvzrNsADGIzjyGUN-1Bo5Ai3qiXKadGxlGzp41LZSmNPe__uPxH6bWP_Sy5cOvjL3reN2SHHCxXJyLKKrq1hoxrVFfZIe7kBI/s1600-h/ModernCppLibraries.GIF"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ_jD_AZmyF4KTjRUpckAumeYfaGlblhsNLiBQVZctLECvzrNsADGIzjyGUN-1Bo5Ai3qiXKadGxlGzp41LZSmNPe__uPxH6bWP_Sy5cOvjL3reN2SHHCxXJyLKKrq1hoxrVFfZIe7kBI/s400/ModernCppLibraries.GIF" alt="" id="BLOGGER_PHOTO_ID_5053894573765049522" border="0" /></a>
While we have such stupid (std::ifstream hopefully will be revealed on SD West 2008) examples, we are gonna have developers (students yesterday) using these examples in real world projects. Because examples are supposed to be followed and are followed, no matter how "sloppy" they are.
<h3 class='post-title'>The perfect project: so what are we gonna do?</h3><em>WHO CARES</em> about calculating the Fibonacci numbers? Who needs those silly, artificial and useless examples? If you ever need those, go and find them. Google them, lookup in Wikipedia or whatever. But real programs should be useful and provide <em>value for people</em>.
To make our project perfect, we are gonna find something useful and not done yet. Something you cannot <a href="http://www-inst.eecs.berkeley.edu/~maratb/readings/NoSilverBullet.html">just buy instead of constructing</a> — thanks to <a href="http://www.cs.unc.edu/~brooks/">Frederick Brooks</a> for the idea!
Let's spend some time thinking about what that could be.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2634353476377499308.post-4200343925859298442007-04-15T22:09:00.000-06:002007-04-15T22:39:04.631-06:00The perfect project: StartEvery software project is a part of developers' lives. We are spending our time through the usual processes from task formulation, project inception, requirements, design and coding to the testing and ongoing development of a new baby of ours. It can be a whole new module of the system, or just a modification of it, but it goes all the same.
That's our lives. That's our legacy. Should we care about how it goes?
Sometimes I feel desperate because I think I am doing something useless, or with low value, or ineffectively. Sometimes almost everything around seems so imperfect and clumsy that I wonder how we come up with this ugly world of computers, programs and designs.
There's always options. Either waste this hour, and that hour for this stupid task, or do something with it — rethink, automate or (even better) eliminate at all.
I believe there should be a way to improve the world of software development and the world as the whole. There's should be a way to provide identification and accumulation of human experience and avoiding same errors repeating again.
I'm gonna try to form and store my thoughts here. Haven't come up with the better title of it as "The perfect project". That's right, no capital letters, let's start with the small ones.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2634353476377499308.post-28896190076456568982007-04-09T23:17:00.000-06:002007-04-09T23:20:12.711-06:00Any bool operators? (real example)<code class=cpp><span class=cppkw>if</span> ( !spResults.empty() && !spResults->empty() )...</code>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2634353476377499308.post-60388839587850519232007-04-09T23:13:00.000-06:002007-07-27T15:31:50.095-06:00Readable exceptions fun<code class=cpp><span class=cppmacro>#include</span> <span class=cppstring><stdexcept></span><br>
<span class=cppmacro>#include</span> <span class=cppstring><iostream></span><br>
<br>
<span class=cppkw>class</span> Class<br>
{<br>
<span class=cppkw>public</span>:<br>
<span class=cppkw>struct</span> Exception<br>
{<br>
<span class=cppkw>struct</span> Any : <span class=cppkw>public</span> std::exception {};<br>
<span class=cppkw>struct</span> CannotConstruct : <span class=cppkw>public</span> Any {};<br>
};<br>
<br>
Class() { <span class=cppkw>throw</span> Exception::CannotConstruct(); }<br>
};<br>
<br>
<span class=cppkw>void</span> iKnowAboutClassAndItsConstruction (<span class=cppkw>void</span>)<br>
{<br>
<span class=cppkw>try</span><br>
{<br>
Class();<br>
}<br>
<span class=cppkw>catch</span> (Class::Exception::CannotConstruct&)<br>
{<br>
std::cout << <span class=cppstring>"got Class::Exception::CannotConstruct.\n"</span>;<br>
<span class=cppcomment>// Do something... or:</span><br>
<span class=cppkw>throw</span>;<br>
}<br>
}<br>
<br>
<span class=cppkw>void</span> iKnowAboutClasses (<span class=cppkw>void</span>)<br>
{<br>
<span class=cppkw>try</span><br>
{<br>
<span class=cppcomment>// do something useful and specific with Class(es):</span><br>
iKnowAboutClassAndItsConstruction(<wbr />);<br>
<span class=cppcomment>// ...</span><br>
<span class=cppcomment>// ...</span><br>
}<br>
<span class=cppkw>catch</span> (Class::Exception::Any&)<br>
{<br>
std::cout << <span class=cppstring>"got some Class::Exception.\n"</span>; <br>
<span class=cppcomment>// Do something... or:</span><br>
<span class=cppkw>throw</span>;<br>
}<br>
}<br>
<br>
<span class=cppkw>void</span> main (<span class=cppkw>void</span>)<br>
{<br>
<span class=cppkw>try</span><br>
{<br>
<span class=cppcomment>// let's do something with Class(es):</span><br>
iKnowAboutClasses();<br>
}<br>
<span class=cppcomment>// main -- don't care about any specific exceptions but standard:</span><br>
<span class=cppkw>catch</span> (std::exception&) { std::cout << <span class=cppstring>"got std::exception.\n"</span>; }<br>
<span class=cppkw>catch</span> (...) { std::cout << <span class=cppstring>"got unknown exception.\n"</span>; }<br>
}</code><br>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2634353476377499308.post-25117878736296418422007-02-10T20:46:00.000-07:002007-04-21T11:16:17.224-06:00My Firefox extensionsI decided to put my list of Firefox extensions here. First, so I can always pick them up and quickly install on a new machine and don't forget anything. Second, probably you find some of them useful for you too! =)
Used frequently:
<ul><li><a href="http://del.icio.us/help/firefox/extension">Del.icio.us</a>: this one is for bookmarks. I keep most of <a href="http://del.icio.us/alexandroid/">my bookmarks on del.icio.us</a> now. However sometimes I feel like it's working slower and slower, so I may switch to something else soon, like Google bookmarks. I am sure that if Google ever get del.icio.us instead of Yahoo, the servuce would be much faster and interesting than it is now… Also since del.icio.us bookmarks are public, I am using browser bookmarks for intranet sites at work.</li>
<li><a href="https://addons.mozilla.org/firefox/1122/">Tab Mix Plus</a>: tabs support became standard feature of Firefox 2.0, however I kept using this extension, cause I suspect it provides way more ways for customizing the tabs interface and behavior.</li>
<li><a href="https://addons.mozilla.org/firefox/1865/">Adblock Plus</a>: you set it and forget it, but it saves you from tons of banners over the web. And it disables flash banners too.</li>
<li><a href="http://roachfiend.com/archives/2005/02/07/bugmenot/">BugMeNot</a>: just added this one, so can't tell much. It goes to <a href="http://www.bugmenot.com/">Bugmenot.com</a> and picks up a password for the site which demands free registration. So you don't need to do that manually.</li>
<li><a href="https://addons.mozilla.org/firefox/3199/">Link Alert</a>: displays small icon near the cursor when you place it over the link. The icon gives a hint what the link is pointing to: new window, word or excel document, java script or something else. Sometimes that turns out to be handy.</li>
<li><a href="https://addons.mozilla.org/firefox/3479/">Winestripe</a>: this is not an addon but Firefox 2.0 theme which makes buttons to appear similar to Firefox 1.5. I didn't like those new shadows and glares, so this theme is a must for me. =)</li>
<li><a href="https://addons.mozilla.org/firefox/1419/">IE Tab</a>: let you open some sites in a tab which displayed using IE engine. Useful for ugly sites which are IE-compatible only. Normally I avoid such sites, but sometimes I can't (company intranet again) and this addon strikes.</li></ul>
Used occasionally:
<ul><li><a href="https://addons.mozilla.org/firefox/748/">Greasemonkey</a>: this one is a hit. It maintains collection of scripts which can tweak any page you are viewing, for example, remove something, add new links or change site layout. There's <a href="http://userscripts.org/">online library of such scripts</a> too. So far I installed:<ul><li><a href="http://userscripts.org/scripts/show/6155">Craigslist image preview </a>: displays images for the posts which have them, pretty useful!</li><li><a href="http://userscripts.org/scripts/show/3784">Google link preview</a>: allows to preview the page from search results in a small frame and don't open the site in a new tab.</li><li><a href="http://blog.persistent.info/2006/05/smart-google-reader-subscribe-button.html">Smart Google Reader Subscribe Button</a>: allows quickly subscribe to RSS feed, avoiding the confirmation page FireFox does by default. Also it displays a tick mark if subscription already exists. This is actually the modified version of <a href="http://userscripts.org/scripts/show/2571">Jasper's Google Reader subscribe</a> (without tick marks).</li></ul></li>
<li><a href="https://addons.mozilla.org/en-US/firefox/addon/918">gTranslate</a>: web translator which uses <a href="http://www.google.com/translate_t">Google translation service</a> to translate either a highlighted word (no extra pages are opened!) or an entire website. Comes very useful when I suddenly surf to germal or french blog to find answers for my questions...</li>
<li><a href="https://addons.mozilla.org/en-US/firefox/addon/3361">translator</a>: similar to the previous one. Actually I am not sure which one of them I am using when... This addon puts an icon in the status bar so one can select manually languages to translate from and into. Also uses Google.</li>
<li><a href="https://addons.mozilla.org/firefox/134/">Copy Plain Text</a>: removes formatting when you copy-paste text from web page to some editor, so you won't get crazy fonts, styles or headers pasted in your document.</li>
<li><a href="https://addons.mozilla.org/firefox/2390/">Video Downloader</a>: this one seems to be very popular, but I used it maybe once or twice. The fact is that normally I don't need to download videos from <a href="http://youtube.com">Youtube</a> or whatsoever, I just bookmark them. Only when I need to watch a long video offline I use this addon.</li>
<li><a href="http://mozilla.dorando.at/readme.html">keyconfig</a>: I use this one only once and only for single thing — make Ctrl+N open new tab instead of opening new window. I don't want to get used to Ctrl+T, because its more difficult to press =) and because IE uses Ctrl+N.</li>
<li><a href="https://addons.mozilla.org/firefox/636/">PDF Download</a>: let you decide whether you want to open clicked PDF document in the browser tab or using Acrobat Reader, or just download it. Pretty handy.</li>
<li><a href="https://addons.mozilla.org/firefox/77/">Sage</a>: RSS reader, pretty simple, fast and snappy. I read all my blogs in <a href="http://www.google.com/reader/">Google Reader</a>, because I want to access them from anywhere and this addon stores them locally. However its still handy for intranet blogs (yes, we have them, can you imagine that?), which I don't want to store in Google Reader.</li></ul>
Just in case:
<ul><li><a href="https://addons.mozilla.org/firefox/3408/">Save As Image</a>: Saves entire web page as an image, including scrollable part. Should be very useful for web reviews or web designers. I didn't used it so far, however I just like the idea to have this ability handy.</li>
<li><a href="https://addons.mozilla.org/firefox/1806/">DOM Inspector</a>: another web developer's tool which let you explore the page content and design. Probably it comes in standard Firefox package, I'm not sure.</li></ul>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2634353476377499308.post-63377581851172972632007-02-04T13:55:00.000-07:002007-07-27T15:33:25.962-06:00Printing map keysNote <code class=inline>select1st</code> is not a part of Standard C++ Library but STL. Particularly it's supported by STLPort.
<code class=cpp><span class=cppkw>typedef</span> std::map< std::string, std::string > Parameters;<br>
Parameters parameters;<br>
...<br>
std::ostringstream os;<br>
os << <span class=cppstring>"Wrong parameters: "</span>;<br>
std::transform( parameters.begin(), parameters.end(),<br>
std::ostream_iterator<std::string>( os, <span class=cppstring>" "</span> ),<br>
std::select1st< Parameters::value_type >() );<br>
<span class=cppkw>throw</span> Exception( os.str() );</code>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2634353476377499308.post-15359254483479115712007-02-04T13:34:00.000-07:002007-02-04T14:01:35.289-07:00Prepare sources in HTML fileThis is a quick way to gather all your .h and .cpp files in one HTML file and print them out.
<code class=cpp>dir /o-n /b *.hpp *.h *.cpp | perl -e "print '<html><body><pre>';while(<>){local $/;print'<h1>';print;print'</h1>';open IN, $_;my $t=<IN>;$t =~ s/</&lt;/gs;print $t;}" >src.htm</code>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2634353476377499308.post-59371979080863316462007-02-03T23:30:00.000-07:002007-07-27T15:37:05.036-06:00File reading contestSample output:
<code class=cpp> >streamReadingContest_StlPort.exe 50mb<br>
reading 50mb...<br>
reserveDistanceCopyStreamItersViaInserter 0.4<br>
seekAndLoadArray 0.75<br>
seekAndLoadVector 0.8<br>
seekAndLoadVectorReserve 0.8<br>
putInStringStream 3.8<br>
assignToStreamItersInterval 0.8<br>
reserveAssignToStreamItersInterval 0.3<br>
copyStreamItersViaInserter 0.75<br>
<br>
>streamReadingContest_home.exe 50mb<br>
reading 50mb...<br>
reserveDistanceCopyStreamItersViaInserter 0.5<br>
seekAndLoadArray 2.95<br>
seekAndLoadVector 2.95<br>
seekAndLoadVectorReserve 3<br>
putInStringStream 4.45<br>
assignToStreamItersInterval 3.65<br>
reserveAssignToStreamItersInterval 0.45<br>
copyStreamItersViaInserter 3.25</code>
Looks like the winner is <code class=inline><span class=em>reserveAssignToStreamItersInterval</span></code>. =)<br>
<code class=cpp><span class=cppmacro>#include</span> <span class=cppstring><fstream></span><br>
<span class=cppmacro>#include</span> <span class=cppstring><sstream></span><br>
<span class=cppmacro>#include</span> <span class=cppstring><iostream></span><br>
<span class=cppmacro>#include</span> <span class=cppstring><string></span><br>
<span class=cppmacro>#include</span> <span class=cppstring><vector></span><br>
<span class=cppmacro>#include</span> <span class=cppstring><ctime></span><br>
<br>
<span class=cppkw>typedef</span> std::string FileName;<br>
<br>
<span class=cppkw>typedef</span> <span class=cppkw>void</span> (LoadFunc) (<span class=cppkw>const</span> FileName& fileName, std::string& result);<br>
<br>
<span class=cppkw>void</span> seekAndLoadArray (<span class=cppkw>const</span> FileName& fileName, std::string& result)<br>
{<br>
std::ifstream inFile( fileName.c_str(), std::ios::binary );<br>
<br>
inFile.seekg( <span class=cppnumber>0</span>, std::ios_base::end );<br>
<span class=cppkw>unsigned</span> <span class=cppkw>long</span> fileSize = inFile.tellg();<br>
inFile.seekg( <span class=cppnumber>0</span>, std::ios_base::beg );<br>
<br>
<span class=cppkw>char</span>* buf = <span class=cppkw>new</span> <span class=cppkw>char</span>[ fileSize ];<br>
inFile.read( buf, fileSize );<br>
result.assign( buf, buf + fileSize );<br>
<span class=cppkw>delete</span>[] buf;<br>
}<br>
<br>
<span class=cppkw>void</span> seekAndLoadVector (<span class=cppkw>const</span> FileName& fileName, std::string& result)<br>
{<br>
std::ifstream inFile( fileName.c_str(), std::ios::binary );<br>
<br>
inFile.seekg( <span class=cppnumber>0</span>, std::ios_base::end );<br>
<span class=cppkw>unsigned</span> <span class=cppkw>long</span> fileSize = inFile.tellg();<br>
inFile.seekg( <span class=cppnumber>0</span>, std::ios_base::beg );<br>
<br>
std::vector<<span class=cppkw>char</span>> buf( fileSize );<br>
buf.resize( fileSize );<br>
<br>
inFile.read( &buf[<span class=cppnumber>0</span>], fileSize );<br>
result.assign( buf.begin(), buf.end() );<br>
}<br>
<br>
<span class=cppkw>void</span> seekAndLoadVectorReserve (<span class=cppkw>const</span> FileName& fileName, std::string& result)<br>
{<br>
std::ifstream inFile( fileName.c_str(), std::ios::binary );<br>
<br>
inFile.seekg( <span class=cppnumber>0</span>, std::ios_base::end );<br>
<span class=cppkw>unsigned</span> <span class=cppkw>long</span> fileSize = inFile.tellg();<br>
inFile.seekg( <span class=cppnumber>0</span>, std::ios_base::beg );<br>
<br>
std::vector<<span class=cppkw>char</span>> buf( fileSize );<br>
buf.resize( fileSize );<br>
<br>
inFile.read( &buf[<span class=cppnumber>0</span>], fileSize );<br>
result.reserve( fileSize );<br>
result.assign( buf.begin(), buf.end() );<br>
}<br>
<br>
<span class=cppkw>void</span> putInStringStream (<span class=cppkw>const</span> FileName& fileName, std::string& result)<br>
{<br>
std::ifstream inFile( fileName.c_str(), std::ios::binary );<br>
std::ostringstream resultStringStream;<br>
<br>
<span class=cppkw>char</span> ch;<br>
<span class=cppkw>while</span> (inFile.get( ch ))<br>
{<br>
resultStringStream.put( ch );<br>
}<br>
<br>
result = resultStringStream.str();<br>
}<br>
<br>
<span class=cppkw>void</span> assignToStreamItersInterval (<span class=cppkw>const</span> FileName& fileName, std::string& result)<br>
{<br>
std::ifstream inFile (fileName.c_str(), std::ios::binary);<br>
std::istreambuf_iterator<<span class=cppkw>char</span>> b( inFile ), e;<br>
result.assign( b, e );<br>
}<br>
<br>
<span class=cppkw>void</span> reserveAssignToStreamItersInterval (<span class=cppkw>const</span> FileName& fileName, std::string& result)<br>
{<br>
std::ifstream inFile (fileName.c_str(), std::ios::binary);<br>
std::istreambuf_iterator<<span class=cppkw>char</span>> b( inFile ), e;<br>
result.reserve( std::distance( b, e ) );<br>
result.assign( b, e );<br>
}<br>
<br>
<span class=cppkw>void</span> copyStreamItersViaInserter (<span class=cppkw>const</span> FileName& fileName, std::string& result)<br>
{<br>
std::ifstream inFile (fileName.c_str(), std::ios::binary);<br>
std::istreambuf_iterator<<span class=cppkw>char</span>> b( inFile ), e;<br>
result.clear();<br>
std::copy( b, e, std::back_inserter( result ) );<br>
}<br>
<br>
<span class=cppkw>void</span> reserveDistanceCopyStreamItersViaInserter (<span class=cppkw>const</span> FileName& fileName, std::string& result)<br>
{<br>
std::ifstream inFile (fileName.c_str(), std::ios::binary);<br>
std::istreambuf_iterator<<span class=cppkw>char</span>> b( inFile ), e;<br>
result.resize( std::distance( b, e ) );<br>
std::copy( b, e, result.begin() );<br>
}<br>
<br>
FileName fileName;<br>
<br>
<span class=cppkw>void</span> testLoad (LoadFunc loader, <span class=cppkw>const</span> std::string& loaderName)<br>
{<br>
<span class=cppkw>const</span> <span class=cppkw>int</span> NumTests = <span class=cppnumber>20</span>;<br>
<span class=cppkw>double</span> acc = <span class=cppnumber>0.0</span>;<br>
std::cout << loaderName << <span class=cppstring>" "</span>;<br>
<br>
<span class=cppkw>for</span> (<span class=cppkw>int</span> i = <span class=cppnumber>0</span>; i < NumTests; ++i)<br>
{<br>
std::string result;<br>
<br>
time_t start = std::time( <span class=cppnumber>0</span> );<br>
loader( fileName, result );<br>
time_t end = std::time( <span class=cppnumber>0</span> );<br>
<br>
acc += end - start;<br>
}<br>
std::cout << acc / NumTests << <span class=cppstring>"\n"</span>;<br>
}<br>
<br>
<span class=cppkw>void</span> main (<span class=cppkw>int</span> argc, <span class=cppkw>char</span> **argv)<br>
{<br>
<span class=cppkw>if</span> (argc > <span class=cppnumber>1</span>)<br>
{<br>
fileName = argv[<span class=cppnumber>1</span>];<br>
<br>
std::cout << <span class=cppstring>"reading "</span> << fileName << <span class=cppstring>"...\n"</span>;<br>
<br>
testLoad( reserveDistanceCopyStreamItersViaInserter, <span class=cppstring>"reserveDistanceCopyStreamItersViaInserter"</span> );<br>
testLoad( seekAndLoadArray, <span class=cppstring>"seekAndLoadArray"</span> );<br>
testLoad( seekAndLoadVector, <span class=cppstring>"seekAndLoadVector"</span> );<br>
testLoad( seekAndLoadVectorReserve, <span class=cppstring>"seekAndLoadVectorReserve"</span> );<br>
testLoad( putInStringStream, <span class=cppstring>"putInStringStream"</span> );<br>
testLoad( assignToStreamItersInterval, <span class=cppstring>"assignToStreamItersInterval"</span> );<br>
testLoad( reserveAssignToStreamItersInterval, <span class=cppstring>"reserveAssignToStreamItersInterval"</span> );<br>
testLoad( copyStreamItersViaInserter, <span class=cppstring>"copyStreamItersViaInserter"</span> );<br>
}<br>
<span class=cppkw>else</span><br>
{<br>
std::cout << <span class=cppstring>"Expected filename as a parameter!"</span>;<br>
}<br>
}</code>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2634353476377499308.post-19495950195986450992007-02-03T22:15:00.000-07:002007-07-27T15:39:08.865-06:00Touch for C++ h and cpp filesThis is the batch file Touch.bat which I use for creating new files. When you create C++ source file it fills it with custom headers and includes. Pretty handy for adding new source files to Visual Studio projects. =)<br>
<code class=bat>@echo off<br>
if exist <span class=batarg>%1</span> goto <span class=batlabel>alreadyexist</span><br>
goto <span class=batlabel>nop</span> ><span class=batarg>%1</span><br>
<span class=batlabel>:nop</span><br>
if <span class=batstring>"%~x1"</span>==<span class=batstring>".h"</span> goto <span class=batlabel>horcpp</span><br>
if <span class=batstring>"%~x1"</span>==<span class=batstring>".cpp"</span> goto <span class=batlabel>horcpp</span><br>
goto <span class=batlabel>:EOF</span><br>
<br>
<span class=batlabel>:horcpp</span><br>
echo <span class=batstring>/** >>%1</span><br>
echo <span class=batstring>* @file %1 >>%1</span><br>
echo <span class=batstring>* >>%1</span><br>
echo <span class=batstring>* @version \$Id: Exp $ >>%1</span></span><br>
echo <span class=batstring>*/ >>%1</span><br>
if <span class=batstring>"%~x1"</span>==<span class=batstring>".h"</span> goto <span class=batlabel>h</span><br>
if <span class=batstring>"%~x1"</span>==<span class=batstring>".cpp"</span> goto <span class=batlabel>cpp</span><br>
echo <span class=batstring>Error, file is expected to be .h or .cpp on this point.</span><br>
goto <span class=batlabel>:EOF</span><br>
<br>
<span class=batlabel>:h</span><br>
echo <span class=batstring>#pragma once >>%1</span><br>
goto <span class=batlabel>:EOF</span><br>
<br>
<span class=batlabel>:cpp</span><br>
rem <span class=batcomment>use ^> ^< to escape.</span><br>
echo <span class=batstring>#include "StdAfx.h" >>%1</span><br>
echo <span class=batstring>#include "%~n1.h" >>%1</span><br>
goto <span class=batlabel>:EOF</span><br>
<br>
<span class=batlabel>:alreadyexist</span><br>
echo <span class=batstring>File %1 already exists, please delete it manually.</span><br>
goto <span class=batlabel>:EOF</span></code>Unknownnoreply@blogger.com0