After long time using auto-complete and semantic Ididn't like how this combination was working, so I search in the web for a better solution and I found auto-complete-clang. Clang is a LLVM driver for C/C++ language, and can be used for IDE task, like auto completing. Brian Jiang took company code for clang and released a clang source for auto-complete(Brian Jiang repository in github). This version worked very well, and used yasnippet in order to indicate parameters of the functions, but had a big problem: it needed emacs saves buffer before calling clang.
I have done some modifications for solving this problem and I have merged my changes with similar changes from Damien R repository in github. You can download the final version in my own repository.
From 1999 to 2005 I did an unfinished game called Shike (name of this web come from this game). It was a pity that I couldn't finish it because it was looking a really good game, but I failed in two important things:
Premature optimizations.
Complex algorithms.
I can say that thanks to this project I learned in a practical way the goodness of the old UNIX rule: the KISS principle, Keep It Simple Stupid. If you can't do a good smooth scroll because your hardware isn't enough power, then design your game in other way and avoid it, because if you begin to implement complex algorithms it is sure you will get problems in other place of your code (this is special true in an assembler code, where do it small modifications means change a lot of code). IF SOMETHING BECOME VERY COMPLEX TRY OTHER WAY.
You can see a small demo in youtube: Shike in YouTube, and if you want take a look of the assembler code you can visit Shike sources.
The game was a RPG in which you handle 3 character at same time. You can select items for each character and other typical actions of this kind of games.
It was a pity, but thanks to the errors of this failed project I learned a lot of things, things that you have to do and things you don't have to do.
CEDET (Collection
of Emacs Development Environment Tools) it is a power module written for emacs which adds semantic features to this editor. It is used for example by ECB (Emacs Code Browser) in order to show methods or functions of the buffer.
The
major problem of CEDET it is based in the complex configuration that it
requires. There is good articles about this issue in the net (for
example A Gentle introduction to CEDET)
which solved me a lot of problems. I am going to do a brief description of my
configuration and I hope this can help to others in this task. You can
take a look to my emacs configuration in my git repository.
semantic-load: Initialize semantics for all supported modes.
semanticdb-system: Contains defuns for system databases
semantic-gcc: Contains defuns for auto configure in base to gcc.
semantic-ia: Contains defuns needed for completions, locations or documentation.
ede: Project management. It is needed in order to help semantic parser.
ede-locate: Part of ede which locates files of a project.
semantic-gcc-setup: Execute gcc, analyze output and set variables with correct values based in the compiler.
semantic-load-turn-everething-on: Enable all semantic features (we will disable undesired features later).
semantic-load-enable-excessive-code-helpers: Enable some helpers that are disabled by default.
semanticdb-load-system-caches: Load system caches generated with semantic-create-system-database.
global-ede-mode: Enable ede for all supported modes.
global-semantic-idle-completions-mode: Disable idle auto completions because it conflicts with the modules auto-complete which I use for this.
After this first initialization I have to added some customized defuns. Actual version of CEDET uses a ring buffer for jump locations, but I prefer a stack instead. So I need use two defuns taken from CEDET mailing list:
(defvar semantic-tags-location-ring (make-ring 20))
(defun semantic-goto-definition (point)
"Goto definition using semantic-ia-fast-jump
save the pointer marker if tag is found"
(interactive "d")
(condition-case err
(progn
(ring-insert semantic-tags-location-ring (point-marker))
(semantic-ia-fast-jump point))
(error
;;if not found remove the tag saved in the ring
(set-marker (ring-remove semantic-tags-location-ring 0) nil nil)
(signal (car err) (cdr err)))))
(defun semantic-pop-tag-mark ()
"popup the tag save by semantic-goto-definition"
(interactive)
(if (ring-empty-p semantic-tags-location-ring)
(message "%s" "No more tags available")
(let* ((marker (ring-remove semantic-tags-location-ring 0))
(buff (marker-buffer marker))
(pos (marker-position marker)))
(if (not buff)
(message "Buffer has been deleted")
(switch-to-buffer buff)
(goto-char pos)))))
CEDET uses some external tools for some task, so it is needed configure it if you want take data from them. But in other hand I want use my configuration in some places where these tools are not present. So my code have to test if these tools are installed.
Global: CEDET uses GNU Global in order to help semantic in symref locations and tags definitions, and to ede in project files locations (and it is used by auto-complete to). CEDET doesn't handle the Global database, so we have to create and update it periodically with the command gtags.
CScope: CEDET uses CScope in order to help semantic in symref locations and tags definitions, and to ede in project files locations. CEDET handle automatically CScope databases, so you don't need special commands for it.
In my home computer I have installed all these tools and I let to CEDET decides which tool is better in each case (sometimes it gets information of various tools at same time), and a small cron script helps me to maintain my Globals and IDutils databases updated each day.
I have finished the colletcion that will be sold in next BCN RU. This time the company selected is Zigurat, and the games in the pack are:
Afteroids
Nuclear Bowls
Sir Fred
Sito Pons
Arkos 1
Arkos 2
Arkos 3
Carlos Sainz
Curro Jimenez
Paris Dakar
Emilio Sanchez Vicario
El Poder Oscuro
Commando Quatro
El misterio del Nilo
You can browse the code of this collection in zigurat collection repository. Remember this collection means a lot of work fixing the original games (I have to disassemble them because I haven't original source), and thanks to this you will run them in all MSX without portability problems. So if you like them, buy it in next meeting! [AAMSX page](http://www.aamsx.com/eng/default.html)
One of the biggest problem of the memory use when you are in a resources limited target is the high cost of dynamic memory functions malloc and free. Dynamic memory is usually implement as a single or double linked list (double linked is faster but increment minimun size of allocated memory), and malloc runs over this list searching for a block with enough size for the request memory, and free inserts the block which contains the memory into the list (and joins to next or previous block if they are contiguous). These operations are very slow.
Other solution is using alloca function, which returns a pointer to allocated memory into the stack, that can be implemented with only a pair of instruction and has the advantage that memory is freeded automatically when function returns. But alloca has problems too:
Doesn't check for memory bounds.
Due to the use of stack is very dangerous uses it as parameter of a function
It is compiler and machine depend and it is not part of ANSI C or C99.
I think problem 1 is not important because there isn't way of checking correctness of a stacked array too. For example:
char vector[30];
is equivalent to
char * vector = alloca(30);
And there isn't way of checking stack overflow in recursive functions (at least in a portable way of course). And even in C99 exists dynamic arrays:
So although alloca can be dangerous due to it doesn't test limit, it is safe when we can assume small sizes. Typical use is getting a path name.
In the other hand although isn't standard it is supplied by almost compilers and there is a portable implementation (but less efficient because it uses heap memory).
So alloca is a desirable function for a limited resource environment as Z80. After looking for it in documentation of my compiler (Hitech C) I saw that it didn't have it, so I had to implement it. The first problem that I had to solve was I needed an inline implementation, but I didn't have the sources of the compiler. Some time ago I did a small perl script which did some peephole optimizations to the assembler code generated with the option -S, and I saw that solution could come thanks to this optimizer. A inline substitution wasn't different of a peephole optimization.
In first step I wrote alloca.h header:
#ifndef __ALLOCA_H__
#define __ALLOCA_H__
#ifndef _STDDEF
typedef unsigned size_t;
#endif
/*
Be aware of using push/pop and alloca in the same function
due to this can cause a stack corruption.
*/
void * alloca(size_t size);
unsigned push(unsigned val);
unsigned pop(void);
#ifndef _DEBUG_ALLOCA
#define push(val) _builtin_push(val)
#define pop _builtin_pop
#define alloca(val) _builtin_alloca(val)
void * _builtin_alloca(size_t size);
unsigned _builtin_push(unsigned val);
unsigned _builtin_pop(void);
#endif /* debug */
#endif /* __ALLOCA_H__ */
I inserted two inlined functions more (push and pop that I will explain them later). So with this macro substitution I added a new peephole optimization in my perl script:
With these perl regular expressions we already have done it. For each inlined function we need delete global and signal declarations because in other case the assembler will fail. Due to the compiler thinks he is calling to a real function it stores first parameter in de register (binary protocol used by this compiler) and allows modify all register except iy, so in alloca case we only need decrement stack pointer.
The other 2 functions, push and pop, are used to implement a very, very optimized stack in the z80 stack, for example for a search algorithm.
In emacs 24 branch there is a new hook called gdb-stopped-hook which is called each time that gdb stop after executing some command. This hook can be very useful for implementing a Eclipse feature that is missed in emacs, highlight the current line. Emacs paints a small icon in the fringe in order to indicate the line, but this is not enough for me. I use the package highline.el that contains the functions highline-highlight-current-line and highline-unhighlight-current-line, allowing light or unlight the current line in a easy way:
This function open file file into gdb-source-window (window where gud show the current line) move to line line and light or unlight the line based in light. So I only need put my code into the hook calling this function:
This hook is called with a parsed MI response, where we can get the actual file and line using bindat-get-field. After this we only need unlight the line when gud is stopped:
I have put public my emacs configuration repository, where you can find a lot of good snippets (my .init.el is about 1000 lines of code). You can browse it in my emacs repository. I will comment some of the best snippets in next entries.
One of the most important parts of software develop is the tests of the code. If you don't have a good set of unit test and regression test then you can insert important bugs in your code in maintain phase. There are important frameworks for unit tests using java (JUnits), c++ (CppUnits) and even in SmallTalk (SUnit). Searching in the web I found some frameworks for C (Check, GNU Autounit or CUnit), but this frameworks are very complex so I don't like them. Part of the Unix philosophy is the KISS principle ( Keep It Simple Stupid), so I prefer a simple solution that I could use in a limited platform as MSX is (remember only 64K RAM addressable). In the other side I found MinUnit, a minimal framework (It is only 4 code lines!!!!), and I thought it can be a good beginning point for my own framework.
All test are based in assertions that must be true, so this idea can be easy chained to the secure programming based in assert macro. ANSI C assert macro tests the expression passed as parameter and if it is evaluated to false, an error message is printed in stderr and abort is called. Almost people think that after this your program will finish, but this is not true, due to when abort is called, a SIGABRT is raised, and you can set your own signal handler for it. So we have to capture this signal and jump to a known point after an assert is false. It's easy understand we need setjmp and longjmp functions.
The setjmp and longjmp functions are commonly said that are not a good programming style because cause spaghetii code (for example in longjmp linux man page it is said), but people often forget that they are used a lot in moderm Object Oriented programs, but they call them exceptions. An exception is only an stacked longjmp solution, so there is a place for them in good code ;).
setjmp sets a point which can be restored using longjmp, but it does something else, returns a value. This value will be 0 when the function is called due to the usual way of the program, but if the program calls longjmp, setjmp returns other value, so you can used this like test result.
So you only have to include this file in the site where you want to execute your test (see that sigabrt is defined as static, so it is a local function and you can define it in each file without problem of duplicate names).
Now we only have to design our test. For example:
#include "utest.h"
int sum(int i, int j)
{
assert(i != j);
return i + j + 3;
}
int main(void)
{
run_test("Sum of possitive numbers:", assert(sum(2, 1) > 0));
run_test("Sum of negative numbers:", assert(sum(-1, -2) < 0));
run_test("Sum of zero values:", assert(sum(0, 0) < 0));
run_end();
return 0;
}
If we execute this code we will get the next output:
Test 0 Sum of possitive numbers: ... OK test: main.c:17: main: Assertion `sum(-1, -2) < 0' failed. Test 1 Sum of negative numbers: ... FAILED test: main.c:7: sum: Assertion `i != j' failed. Test 2 Sum of zero values: ... FAILED FAILED 2 TESTS
You can see that tests 0 and 2 failed and you can the assertion failed. With this macros we have a good unit test framework that we can use without be worried about memory consuptiom.
This is the first input of this blog, where I will post technical issues about some of my computer hobbies: MSX, Linux and programming (and of course the best editor of the world, Emacs). I hope you will enjoy with this blog and see you here soon.