I understand that one of the main vim's main goals are portability and customisation. Abundance of comments in the manual about things working differently on various problems does not surprise me. However, I don't understand why almost every feature can be disabled with a compile flag, what purpose does it serve? Wouldn't it be easier to be able to disable features in runtime, with some kind of configuration?
As far as I understand (I tried diving into vim code, but didn't write any patches), it makes the code base much more complicated, and that's exactly what Neovim developers are trying to remove. Why did vim developers follow this approach?
There are several forces for having many flags (some of which have already been mentioned in the comments):
portability: with quite different (and exotic, like DOS and Amiga) operating systems to support, different (GUI) libraries must be included, so there's a definite need for conditional compilation via #ifdef
on many Linux distributions, a tiny build of Vim serves as the default implementation for vi; that one should not have any of the extended features
it allows for utter flexibility: developers / packagers can mix and match freely (though I guess most will stick to the default tiny / big / huge feature bundles)
So, my (unofficial) guess is that a useful and necessary (see above) feature was increasingly used for more and more features as Vim grew and matured. Initially, this is good (consistency, a single mechanism to configure). When problems started to appear, it was too late to retroactively switch to a (better?) approach (like runtime configuration); the (development and testing) effort would now be prohibitive.
Related
I am getting interested in the Oberon language and I would like to know: is the language actually used by common programmers or is it still only used by researchers? Is it production-ready? What I have in mind are non-scientific applications requiring GUI support and possibly Internet connectivity (at least client-side POP3 and SMTP functionality).
Also, which of the Oberon flavors would you recommend for my needs (Oberon2, Active Oberon, etc)? The simpler, the better, as long as it is well maintained and has some community.
If possible, I would like to run my applications in a conventional host environment (Windows or Linux), without the need for a special runtime environment or a special operating system.
Thanks
BlackBox has some of what you want, runs on flavors of Windows.
There are also some environments that compile to Java bytecode and target the JVM.
Look at POW, and Gardens Point Component Pascal.
I happen to be using some command-line only tools that are Oberon Compilers.
OO2C is an Oberon to C compiler (but the output is not for human consumption).
Ofront is an Oberon to Human-Readable C, but I haven't yet set up a linux box to run it on. (otherwise, it is supposed to run inside of BlackBox on Windows).
There is also Oxford Oberon Compiler by Professor Spivey. A VERY enjoyable Compiler that compiles to a Virtual Machine, but the whole object code is a self-contained application (albeit command -line).
It is a VERY small download, meant for an educational environment, keeps everything CLEAN, and works well for prototyping some of the grunt work or procedures/modules of your code. It also is supposed to allow bitmap drawing in XWindows in Black and White only, probably for drawing graphs, etc, but I have not had an opportunity to use that feature yet.
It has a GUI-based debugger, profiling, and some other interesting tools, and still is very small by comparison to most modern compilers like gcc. It is also totally stand alone.
Works on Mac, Win, Linux, and has source.
By comparison, OO2C took me about a day of futzing and compiling to get it going (but it is working).
I don't have a Windows box right now, so I can't run my copy of BlackBox, but it had a full GUI, and lots of Source code available at the Component Pascal Collection website.
http://www.zinnamturm.eu/index.htm
If you are looking for source code you should also check out that site in hopes you don't have to reinvent the wheel.
Really a joy to step into Oberon after having to fight C/C++ all day long to get simple stuff done.
OBNC is a new compiler for the latest version (2016) of the original Oberon language by Niklaus Wirth. It compiles via C and makes it easy to interface to existing C libraries.
https://miasap.se/obnc/
Given that Oberon [language] was developed as a complete [operating-]system, and that ETH's CS department ran ALL its computers (even the secretary's) on it I should think it is application-ready. This according to the following PDF:
http://www.ics.uci.edu/~franz/Site/pubs-pdf/BC03.pdf
is the language actually used by common programmers or is it still only used by researchers?
There was/is little use of the original Oberon language outside academia; there was some industrial adaptation of Oberon dialects like e.g. Component Pascal.
Is it production-ready?
Depends on your requirements. Given todays expectations of software developers the (original) language and available toolchains seem very minimalistic.
non-scientific applications requiring GUI support and possibly Internet connectivity ... in a conventional host environment... which of the Oberon flavors would you recommend for my needs?
GUI support and network programming in a conventional host environment is e.g. supported by https://blackboxframework.org as already mentioned, which uses a language related to Oberon.
You could also have a look at https://github.com/rochus-keller/Oberon which includes a platform independend IDE with semantic navigation and a source-level debugger, plus a platform independent foreign function interface as a language extension which allows you to directly use any C shared library, and thus reuse the plethora of existing proven GUI or network libraries out there without having to program in C. It also offers a modern, lean syntax variant without all the semicolons and capitalized keywords, which should appeal especially to younger developers; but of course also the traditional syntax is supported, even mixed modern/traditional syntax projects.
Variations of this question have been asked, but not specific to GNU/Linux and C. I use Komodo Edit as my usual Editor, but I'd actually prefer something that can be used from CLI.
I don't need C++ support; it's fine if the tool can only handle plain C.
I really appreciate any direction, as I was unable to find anything.
I hope I'm not forced to 'roll' something myself.
NOTE: Please refrain from mention vim; I know it exists and what its capabilities are. I purposefully choose to avoid vim, which is why I use Komodo (or nano on the servers).
I don't think that a pure console refactoring tool would be nice to use.
I use Eclipse CDT on linux to write and refactor C-Code.
There exists also Xrefactory for Emacs http://www.xref.sk/xrefactory/main.html
if a non console refactoring tool is o.k for you as well.
C-xrefactory was an open source version of xrefactory, covering C and Java, made available on SourceForge by Marián Vittek under GPLv2.
For those interested, there's an actively maintained c-xrefactory fork on GitHub:
https://github.com/thoni56/c-xrefactory
The goal of the GitHub fork is to refactor c-xrefactory itself, add a test suite, and try to document the original source code (which is rather obscure). Maybe, in the future, also convert it into an LSP C language server and refactoring tool.
C-xrefactory works on Emacs; setup scripts and instructions can be found at the repository. Windows users can run it via WSL/WSL2.
You could consider coding a GCC plugin or a MELT extension (MELT is a domain specific language to extend GCC) for your needs.
However, such approach would take you some time, because you'll need to understand some of GCC internals.
For Windows only, and not FOSS but you said "any direction..."
Our DMS Software Reengineering Toolkit" with its C Front End can apply transformations to C source code. DMS can be configured to carry out custom, complex reliable transformations, although the configuration isn't as easy as typing just a command like "refactor frazzle by doobaz".
One of the principal stumbling blocks is still the preprocessor. DMS can transform code that has preprocessor directives in typical places (around statements, expressions, if/for/while loop heads, declarations, etc.) but other "unstructured conditionals" give it trouble. You can run DMS by expanding the preprocessor directives out of existence, or more imporantly, expanding out the ones that give it trouble, but mostly people don't like this because they prefer to keep thier preprocessor directives. So it isn't perfect.
[Another answer suggested Concinelle, which looks pretty good from my point of view. As far as I know, it doesn't handle preprocessor directives at all; I could be wrong and it might handle some cases as DMS does, but I'm sure it can't handle all the cases].
You don't want to consider rolling your own. Building a transformation/refactoring tool is much harder than you might guess having never tried it. You need full, accurate parsers for the (C) dialect of interest and just that is pretty hard to get right. You need a preprocessor, symbol tables, flow analysis, transformation, code regeneration machinery, ... this stuff takes years of effort to build and get right. Trust me, been there, done that.
I'm finding myself doing more C/C++ code against Win32 lately, and coming from a C# background I've developed an obsession with "clean code" that is completely consistent, so moving away from the beautiful System.* namespace back to the mishmash of #defines that make up the Win32 API header files is a bit of a culture shock.
After reading through MSDN's alphabetical list of core Win32 functions I realised how simple Win32's API design actually is, and it's unfortunate that it's shrouded with all the cruft from the past 25 years, including many references to 16-bit programming that are completely irrelevant in today's 64-bit world.
I'm due to start a new C/C++ project soon, and I was thinking about how I could recreate Win32's headers on an as-needed basis. I could design it to be beautiful, and yet it would maintain 100% binary (and source) compatibility with existing programs (because the #defines ultimately resolve the same thing).
I was wondering if anyone had attempted this in the past (Google turned up nothing), or if anyone wanted to dissuade me from it.
Another thing I thought of, was how with a cleaner C Win32 API, it becomes possible to design a cleaner and easier to use C++ Win32 API wrapper on top, as there wouldn't be any namespace pollution from the old C Win32 items.
EDIT:
Just to clarify, I'm not doing this to improve compilation performance or for any kind of optimisation, I'm fully aware the compiler does away with everything that isn't used. My quest here is to have a Win32 header library that's a pleasure to work with (because I won't need to depress Caps-lock every time I use a function).
Don't do this.
It may be possible, but it will take a long time and will probably lead to subtle bugs.
However, and more importantly, it will make your program utterly impossible for anyone other than you to maintain.
There's no point in doing this. Just because there's additional cruft doesn't mean it's compiled into the binary (anything unused will be optimized out). Furthermore, on the EXTREME off-chance that anything DOES change (I dunno, maybe WM_INPUT's number changes) it's just a lot easier to use the system headers. Furthermore, what's more intuitive? I think #include <windows.h> is a lot easier to understand than #include "a-windows-of-my-own.h".
Also, honestly you never should need to even look at the contents of windows.h. Yeah I've read it, yeah it's ugly as sin, but it does what I need it to and I don't need to maintain it.
Probably the ONLY downside of using the real windows.h is that it MAY slow down compilation by a few milliseconds.
No. What's the point? Just include <windows.h>, and define a few macros like WIN32_LEAN_AND_MEAN, VC_EXTRALEAN, NOGDI, NOMINMAX, etc. to prune out the things you don't want/need to speed up your compile times.
Although the Win32 headers might be considered "messy", you pretty much never have to (or want to) look inside them. All you need to know is documented in the Win32 SDK. The exact contents of the header files are an implementation detail.
There is a ton of stuff in there that would be time-consuming and unnecessarily finicky to replicate, particularly relating to different versions of the Win32 SDK.
I recommend:
#include <windows.h>
In my opinion, this is bad practice. Tidiness and brevity is achieved by keeping to the standard practice as much as possible, and leveraging as much as possible from the platform. You need to assume Microsoft to have the ultimate expertise in their own platform, with some aspects going beyond what you know right now. In simple words, it's their product and they know best.
By rolling your own:
... you branch off from Microsoft's API, so Microsoft could no longer deliver updates to you through their standard channels
... you may introduce bugs due to your own hubris, feeling you've figured something out while you haven't
... you'd be wasting a lot of time for no tangible benefit (as the C headers don't carry any overhead into the compiled binary)
... you'd eventually create a project that's less elegant
The most elegant code is one that carries more LOC of actual program logic and as little as possible LOC for "housekeeping" (i.e. code not directly related to the task at hand). Don't fail to leverage the Platform SDK headers to make your project more elegant.
This has been attempted in the past.
In its include directory, MinGW contains its own version of windows.h. Presumably this exists to make the headers work with gcc. I don't know if it will work with a Microsoft compiler.
a previous relevant question from me is here Reverse Engineering old paint programs
I have set up my base of operations here: http://animatorpro.org
wiki coming soon.
Okay, so now I have a 300,000 line legacy MSDOS codebase. It's sort of a "be careful what you wish for" situation. I am not an experienced C programmer. I'm not entirely inexperienced either, but for all intents and purposes I'm a noob to the language and in particular the intricacies of its libraries. I am especially ignorant of the vagaries of the differences between C programs written specifically for MSDOS and programs that are cross platform. However I have been studying this code base for over a year now, and this is what I know about Animator Pro:
Compilers and tools used:
Watcom C compiler
tcmake (make program from Turbo C)
386asm, a specialised assembler for the Phar Lap dos extender
and of course, the Phar Lap dos extender itself.
a selection of obscure dos utilities
Much of the compilation seems to be driven by batch files. Though I have obtained copies of all these tools, I have not yet succeeded at compiling it. (though I have compiled its older brother, autodesk animator original.
It's got a plugin system that replicates DLL before DLL's were available, based on REX. The plugin system handles:
Video Drivers (with a plethora of included VESA drivers)
Input drivers (including wacom tablets, and keyboards)
Drawing Tools
Inks (Like photoshop's filters, or blending modes)
Scripting Addons (essentially compiled scripts)
File formats
It's got its own script interpreter named POCO, based on the C language- The scripting language has enough power to do virtually all the things the plugin system can do- Just slower.
Given this information, this is my development plan. Please criticise this. The source code is available in the link above, so you can easily, if you are so inclined, assess the situation yourself.
Compile with its original tools.
Switch to using DJGPP, and make the necessary changes to get it to compile with that, plus the original assembler.
Include the Allegro.cc "Game" library, and switch over as much functionality to that library as possible- Perhaps by simply writing new video and input drivers that use the Allegro API. I'm thinking allegro rather than SDL because: there is a DOS version of Allegro, and fascinatingly, one of its core functions is the ability to play Animator Pro's native format FLIC.
Hopefully after 3, I will have eliminated most or all of the Assembler in the project. I say hopefully, because it's in an obscure dialect that doesn't assemble in any modern free assembler without significant modification. I have tried them all. Whatever is left gets converted to assemble in NASM, or to C code if I can define the assembler's actual function.
Switch the dos extender from Phar Lap to HX Dos http://www.japheth.de/HX.html, Which promises to replicate as much of the WIN32 api as possible. Then make all the necessary code changes for that to work.
Switch to the win32 version of Allegro.cc, assuming that the win32 version can run on top of HXDos. Make any further necessary changes
Modify the plugin system to use some kind of standard cross platform plugin library. What this would be, I have no idea. Maybe you can offer some suggestions? I talked to the developer who originally wrote the plugin system, and he said some of the things it does aren't possible on modern OS's because of segmentation restrictions. I'm not sure what this means, but I'm guessing it means all the plugins will need to be rewritten almost from scratch.
Magically, I got all the above done, and we can try and make it run in windows, osx, and linux, whilst dealing with other cross platform niggles like long file names, and things I haven't thought of.
Anyone got a problem with any of this? Is allegro a good choice? if not, why? what would you do about this plugin system? What would you do different? Is this whole thing foolish, and should I just rewrite it from scratch, using the original as inpiration? (it would apparently take the original developer "About a month" to do that)
One thing I haven't covered above is the text/font system. Not sure what to do about that, but Animator Pro has its own custom font format, but also is able to use Postscript Type 1 fonts, and some other formats.
My biggest concern with your plan, in a nutshell: Your approach seems to be to attempt to keep the whole enormous thing working at all times, tweaking the environment ever-further away from DOS. During each tweak to the environment, that means you will have approximately a billion subtle assumptions that might have broken at once, none of which you necessarily understand yet. Untangling them all at once will be incredibly painful.
If I were doing the port, my approach would be to disable as much code as possible to get SOMETHING running in a modern environment, and bring the parts back online, one piece at a time. Write a simple test harness program that loads a display driver and draws some stuff, and compile it for DOS to make sure you understand the interface. Then write some C code that implements the same interface, but with Allegro (or SDL or SFML), and make that program work under Windows or Linux. When the output differs, you have a simple test case to work from.
Your entire job on this port is swapping out implementations of various interfaces and functions with completely new ones. This is a job that unit testing excels at. Don't write any new code without a test of some kind that runs on the old code under DOS! Make your potential problems as small and simple as you possibly can. Port assembly code instead of rewriting it only if you're reasonably confident that it will actually make your job easier (ie, algorithmic stuff that compiles fine with few tweaks under NASM). Don't bite off a bigger piece than you can comfortably fit in your brain at once.
I, for one, look forward to seeing your progress! I think what you're attempting to do is great. Thanks for doing it.
Hmmm - I might approach it by writing an OpenGL video "driver" for it. and todays machines are fast enough with tons of ram that you could do all the pixel specific algorithms on main CPU into a back buffer and it would work. As the "generic" VGA driver just mapped the video buffer to a pointer this would be a place to start. There was a zoom mode in the UI so you can look at the pixels on a high res display.
It is often very difficult to take an existing non-trivial code base that wasn't written with portability in mind - you mention a few - and then try to make it portable. There will be a lot of problems on the way. It is probably a better idea to start from scratch and rewrite the code using the existing code as reference only. If you start from scratch you can leverage existing portable UI solution in your new project like Qt.
Are there any plugins or built-in methods in Vim for performing refactoring on C or C++ code, something like the refactoring tools in Eclipse?
I'm especially keen on the extract method refactoring tool from Eclipse that will determine parameters from new methods and typically also guess a variable to use as the return value.
No, although Vim is a good environment for editing, and can be customised in a lot of ways (code folding, syntax colouring, macro expansion etc.) most of these are done on the syntax level, rather than the semantic level. Even the code folding just matches up opposing braces.
To do a proper refactoring, you have to have a lot of semantic knowledge about the AST, what variables are declared in which scope, and so on. IDEs like Eclipse build up a cache of the variables defined in each lexical scope, so that they can quickly refer back to where they are used in terms of determining what to rename and where.
That's not to say that you can't do some things syntactically; after all, one can just take out a block of code and put it into a separate function easily enough. You might even be able to guess at some parameters (e.g. find a list of the variables, find out which ones have local declarations, remove them and what's left are your parameters. But Eclipse also does other things—like figuring out whether any variables are modified in the function, and ensuring they're passed back by the return value. It also checks for any thrown exceptions, and add them to the list.
The net effect is that whilst you may be able to approximate some of these in Vim, you really aren't going to be able to get this working in a Vim-only enviornment. You could either use a Vim-like keybinding in Eclipse proper, or look at eclim. From the home page:
The primary goal of eclim is to bring
Eclipse functionality to the Vim
editor. The initial goal was to
provide Eclipse’s java functionality
in vim, but support for various other
languages (c/c++, php, python, ruby,
css, html, xml, etc.) have been added
and several more are planned.
Eclim is less of an application and
more of an integration of two great
projects. The first, Vim, is arguably
one of the best text editors in
existence. The second, Eclipse,
provides many great tools for
development in various languages. Each
provides many features that can
increase developer productivity, but
both still leave something to be
desired. Vim lacks native Java support
and many of the advanced features
available in Eclipse. Eclipse, on the
other hand, still requires the use of
the mouse for many things, and when
compared to Vim, provides a less than
ideal interface for editing text.
That is where eclim comes into play.
Instead of trying to write an IDE in
Vim or a Vim editor in Eclipse, eclim
provides an Eclipse plug-in that
exposes Eclipse features through a
server interface, and a set of Vim
plug-ins that communicate with Eclipse
over that interface.
This not only gives an Eclipse-like environment, it is Eclipse. But you still get the navigation and text editing features of vim. It sounds like this might suit your needs, although the documentation on refactoring support doesn't indicate that it provides an extract method functionality.
I've written a generic refactoring plugin. C++ is one of the primary languages handled (as it's my primary language at work). Method extraction is supported.
For C++, the plugin is able (thanks to ctags) to deduce most (but unfortunately not always all -- thanks to ctags...) of the variables coming in and out of the extracted function.
I still have to write a little dialog box to select how the in/out variables shall be exchanged (const ref, rvalue ref, copy, pointer, tuples, struct, and so on) (BTW, help is welcome as GUIs are not my thing ^^').
After searching high and low for vim with refactoring for C++, this is the best solution I have come up with.
Visual Studio 2013 and higher - Great IDE for C++ development and debugging, but does not have sufficient refactoring or vim
Install the vsvim plugin - Now, you have all the vim navigation, searching, string replacement, etc. (Some advanced features are not supported)
Install Resharp C++ - Great for refactoring at the cost of speed. It makes it a bit clunky, but if you want to infer auto generate methods/variables, rename local/global/method variables or functions, Search for usages in the solution, and more features, makes it extremely worth it.
This is the best combination I found for C++ development, debugging and refactoring. Makes me at least 3x - 5x faster. Hope it helps you as well.