1. member function overloading with const & non-const
2. How about const parameter?
ex1. void fun(const int var);
void fun(int var);
The var is passed by value, thus, whether it's const or not won't make difference for its caller. This will lead to compilation error.
ex2. void fun(const char* pVar);
void fun(char* pVar);
The pVar can change var in its caller, thus it makes sense. Same reason for reference. And it will have no compilation error.
From
http://www.geeksforgeeks.org/archives/24724?utm_source=feedburner&utm_medium=email&utm_campaign=Feed%3A+Geeksforgeeks+%28GeeksforGeeks%29
C++ allows functions to be overloaded on the basis of const-ness of parameters only if the const parameter is a reference or a pointer. That is why the program 1 failed in compilation, but the program 2 worked fine. This rule actually makes sense. In program 1, the parameter ‘i’ is passed by value, so ‘i’ in fun() is a copy of ‘i’ in main(). Hence fun() cannot modify ‘i’ of main(). Therefore, it doesn’t matter whether ‘i’ is received as a const parameter or normal parameter. When we pass by reference or pointer, we can modify the value referred or pointed, so we can have two versions of a function, one which can modify the referred or pointed value, other which can not.
Friday, October 12, 2012
Sunday, September 2, 2012
design pattern
State machine:
Run <-> Stand
driver.m_state->run()
class State
{
void run();
void stand();
};
class Driver
{
private:
State* m_state;
public:
Driver(State *pState) : m_state(pState) {};
~Driver() { };
void Run() { return m_state->run(); };
void Stand() { return m_state->stand(); };
};
class RunState : public State
{
public:
void stand() { };
};
class StandState : public State
{
public:
void run() { };
};
int main()
{
Driver sb(new StandState());
sb.Run(); // invoke the StandState::run();
return 0;
}
Program on interface
Run <-> Stand
driver.m_state->run()
class State
{
void run();
void stand();
};
class Driver
{
private:
State* m_state;
public:
Driver(State *pState) : m_state(pState) {};
~Driver() { };
void Run() { return m_state->run(); };
void Stand() { return m_state->stand(); };
};
class RunState : public State
{
public:
void stand() { };
};
class StandState : public State
{
public:
void run() { };
};
int main()
{
Driver sb(new StandState());
sb.Run(); // invoke the StandState::run();
return 0;
}
Program on interface
Wednesday, August 29, 2012
new int VS new int()
引用自C++ Primer, 4th, 第5.11节 new和delete表达式
如果不提供显式初始化,动态创建的对象与在函数内定义的变量初始化方式相同(第 2
.3.4 节)。对于类类型的对象,用该类的默认构造函数初始化;而内置类型的对象则无
初始化。
string *ps = new string; // initialized to empty string
int *pi = new int; // pi points to an uninitialized int
同样也可对动态创建的对象做值初始化(value-initialize)(第 3.3.1 节):
string *ps = new string(); // initialized to empty string
int *pi = new int(); // pi points to an int value-initialized to 0
cls *pc = new cls(); // pc points to a value-initialized object of typ
e cls
以上表明程序员想通过在类型名后面使用一对内容为空的圆括号对动态创建的对象做值
初始化。内容为空的圆括号表示虽然要做初始化,但实际上并未提供特定的初值。对于
提供了默认构造函数的类类型(例如 string),没有必要对其对象进行值初始化:无论
程序是明确地不初始化还是要求进行值初始化,都会自动调用其默认构造函数初始化该
对象。而对于内置类型或没有定义默认构造函数的类型,采用不同初始化方式则有显著
的差别:
int *pi = new int; // pi points to an uninitialized int
int *pi = new int(); // pi points to an int value-initialized to
0
第一个语句的 int 型变量没有初始化,而第二个语句的 int 型变量则被初始化为0。
如果不提供显式初始化,动态创建的对象与在函数内定义的变量初始化方式相同(第 2
.3.4 节)。对于类类型的对象,用该类的默认构造函数初始化;而内置类型的对象则无
初始化。
string *ps = new string; // initialized to empty string
int *pi = new int; // pi points to an uninitialized int
同样也可对动态创建的对象做值初始化(value-initialize)(第 3.3.1 节):
string *ps = new string(); // initialized to empty string
int *pi = new int(); // pi points to an int value-initialized to 0
cls *pc = new cls(); // pc points to a value-initialized object of typ
e cls
以上表明程序员想通过在类型名后面使用一对内容为空的圆括号对动态创建的对象做值
初始化。内容为空的圆括号表示虽然要做初始化,但实际上并未提供特定的初值。对于
提供了默认构造函数的类类型(例如 string),没有必要对其对象进行值初始化:无论
程序是明确地不初始化还是要求进行值初始化,都会自动调用其默认构造函数初始化该
对象。而对于内置类型或没有定义默认构造函数的类型,采用不同初始化方式则有显著
的差别:
int *pi = new int; // pi points to an uninitialized int
int *pi = new int(); // pi points to an int value-initialized to
0
第一个语句的 int 型变量没有初始化,而第二个语句的 int 型变量则被初始化为0。
Tuesday, July 31, 2012
different xml parser: expat VS libxml2
Refer to
http://stackoverflow.com/questions/399704/xml-parser-for-c
Due to a thread in expat, expat has a little higher benchmark than libxml2. But just a little.
Also another xml parser writer in C++ is mentioned - http://xerces.apache.org/xerces-c/
The xml parser won't be a key factor for our project.
Currently, expat is adopted in aoo/symphony. It's based on stream.
http://baike.baidu.com/view/4997565.htm
http://stackoverflow.com/questions/399704/xml-parser-for-c
Due to a thread in expat, expat has a little higher benchmark than libxml2. But just a little.
Also another xml parser writer in C++ is mentioned - http://xerces.apache.org/xerces-c/
The xml parser won't be a key factor for our project.
Currently, expat is adopted in aoo/symphony. It's based on stream.
http://baike.baidu.com/view/4997565.htm
Friday, July 27, 2012
STL VS StdLib
Look around stack overflow and get some knowledge on STL and StdLib.
Quote from below link:
http://stackoverflow.com/questions/5205491/whats-this-stl-vs-c-standard-library-fight-all-about/5205571#5205571
The "STL"(C++ Standard Template Library) was written by Alexander Stepanov in the days long before C++ was standardized. It's used as library of C++.
The original STL is now often called "an implementation of the C++ Standard Template Library" (rather backwards to actual history!), in the same way that your Microsoft Visual Studio or GCC ships an implementation of the C++ Standard Library. But the "Standard Template Library" and the "Standard Library" are not the same thing.
Don't refer to the C++ Standard Library as "STL". Maybe try stdlib.
Some additional info:
In addition, there are some STL-like libraries that are in fact implementations of the original STL, not the C++ Standard Library. Until recently, STLPort was one of them (and even there, the confusion abounds!).
My comments: see what's from STLPort site:
STLport is a multiplatform C++ Standard Lib implementation.(Still stdlib? Maybe check the confusion later.)
STL has hash_map while C++ Standard Lib doesn't.
STL has no std namespace (IIRC) while C++ Standard Lib does.
Quote from below link:
http://stackoverflow.com/questions/5205491/whats-this-stl-vs-c-standard-library-fight-all-about/5205571#5205571
The "STL"(C++ Standard Template Library) was written by Alexander Stepanov in the days long before C++ was standardized. It's used as library of C++.
The original STL is now often called "an implementation of the C++ Standard Template Library" (rather backwards to actual history!), in the same way that your Microsoft Visual Studio or GCC ships an implementation of the C++ Standard Library. But the "Standard Template Library" and the "Standard Library" are not the same thing.
Don't refer to the C++ Standard Library as "STL". Maybe try stdlib.
C++ standard includes much more things outside the STL, so the term "C++ standard library" is more correct (and is what's actually used by the standards documents).
Some additional info:
In addition, there are some STL-like libraries that are in fact implementations of the original STL, not the C++ Standard Library. Until recently, STLPort was one of them (and even there, the confusion abounds!).
My comments: see what's from STLPort site:
STLport is a multiplatform C++ Standard Lib implementation.(Still stdlib? Maybe check the confusion later.)
STL has hash_map while C++ Standard Lib doesn't.
STL has no std namespace (IIRC) while C++ Standard Lib does.
Some components of the C++ standard library include STL components like vector, list and algorithms like copy and swap.
My comments: It seems that std::string isn't included in STL? Just see the "std::" before string.
My comments: It seems that std::string isn't included in STL? Just see the "std::" before string.
Thursday, July 12, 2012
Stl containers
1. Map's insert
Because map containers do not allow for duplicate key values, the insertion operation checks for each element inserted whether another element exists already in the container with the same key value, if so, the element is not inserted and its mapped value is not changed in any way.
Thus, below code's output will be 2 instead of 3.
map<int, int> iMap;
iMap.insert(map<int, int>::value_type(1, 2));
map<int, int>::iterator it = iMap.find(1);
if (it != iMap.end())
{
iMap.insert(map<int, int>::value_type(1, 3));
it = iMap.find(1);
if (it != iMap.end())
{
cout << it->second << endl;
}
}
Something additional is its return value:
returns a pair, with its member pair::first set to an iterator pointing to either the newly inserted element or to the element that already had its same key in the map. The pair::second element in the pair is set totrue if a new element was inserted or false if an element with the same key existed.
It means you can use its return value's second to check if this insertion is a success or not.
Because map containers do not allow for duplicate key values, the insertion operation checks for each element inserted whether another element exists already in the container with the same key value, if so, the element is not inserted and its mapped value is not changed in any way.
Thus, below code's output will be 2 instead of 3.
map<int, int> iMap;
iMap.insert(map<int, int>::value_type(1, 2));
map<int, int>::iterator it = iMap.find(1);
if (it != iMap.end())
{
iMap.insert(map<int, int>::value_type(1, 3));
it = iMap.find(1);
if (it != iMap.end())
{
cout << it->second << endl;
}
}
Something additional is its return value:
returns a pair, with its member pair::first set to an iterator pointing to either the newly inserted element or to the element that already had its same key in the map. The pair::second element in the pair is set totrue if a new element was inserted or false if an element with the same key existed.
It means you can use its return value's second to check if this insertion is a success or not.
What do "(void) var;" and "(void) 0;" mean?
1. (void)var
It is seen often in AOO. What does it mean?
Maybe to avoid a compilation warning because "var" isn't used?
From:http://stackoverflow.com/questions/6145548/what-is-the-purpose-of-the-statement-voidc
2. (void) 0
From: http://stackoverflow.com/questions/2198950/why-is-void-0-a-no-operation-in-c-and-c
For __noop in MS, see below quotation from MSDN
http://msdn.microsoft.com/en-us/library/s6btaxcs%28VS.80%29.aspx
// compiler_intrinsics__noop.cpp
// compile with or without /DDEBUG
#include <stdio.h>
#if DEBUG
#define PRINT printf_s
#else
#define PRINT __noop
#endif
int main() {
PRINT("\nhello\n");
}
3. (void) func()
Consider the following code snippet:
int func(void);
...
(void) func();
Here I'm casting the return value of the function to void. That certainly makes it look like there's a data type called void. In reality, this sort of cast is a special case; it tells the compiler that you want to throw away the return value of the function. The compiler would do that anyway if you hadn't included the cast to void, so cast to void is unnecessary. Some people use it as idiom to tell lint, the compiler, and [most importantly] the maintenance programmers that they knew the function returns a value but deliberately decided to ignore it.
It is seen often in AOO. What does it mean?
Maybe to avoid a compilation warning because "var" isn't used?
From:http://stackoverflow.com/questions/6145548/what-is-the-purpose-of-the-statement-voidc
2. (void) 0
Q: I have seen debug printfs in glibc which internally is defined as
(void) 0, if NDEBUG is defined. Likewise the __noop for Visual C++ compiler is there too. The former works on both GCC and VC++ compilers, while the latter only on VC++. Now we all know that both the above statements will be treated as no operation and no respective code will be generated; but here's where I've a doubt.
In case of
__noop, MSDN says that it's a intrinsic function provided by the compiler. Coming to (void) 0 ~ Why is it interpreted by the compilers as no op? Is it a tricky usage of the C language or does the standard say something about it explicity? Or even that is something to do with the compiler implementation?
A:
(void)0 (+;) is a valid, but 'does-nothing' C++ expression, that's everything. It doesn't translate to the no-op instruction of the target architecture, it's just an empty statement as placeholder whenever the language expects a complete statement (for example as target for a jump label, or in the body of anif clause).For __noop in MS, see below quotation from MSDN
http://msdn.microsoft.com/en-us/library/s6btaxcs%28VS.80%29.aspx
The __noop intrinsic specifies that a function should be ignored and the argument list be parsed but no code be generated for the arguments. It is intended for use in global debug functions that take a variable number of arguments.
// compile with or without /DDEBUG
#include <stdio.h>
#if DEBUG
#define PRINT printf_s
#else
#define PRINT __noop
#endif
int main() {
PRINT("\nhello\n");
}
3. (void) func()
Consider the following code snippet:
int func(void);
...
(void) func();
Here I'm casting the return value of the function to void. That certainly makes it look like there's a data type called void. In reality, this sort of cast is a special case; it tells the compiler that you want to throw away the return value of the function. The compiler would do that anyway if you hadn't included the cast to void, so cast to void is unnecessary. Some people use it as idiom to tell lint, the compiler, and [most importantly] the maintenance programmers that they knew the function returns a value but deliberately decided to ignore it.
Wednesday, July 11, 2012
something about compiler and linker
Q: -DDEBUG
A: in code, you can use below code special for debug version
#ifdef DEBUG
// do sth for debug
#else
// do sth for release
#endif
Q: -DSTLPORT_VERSION=400
A: define STLPORT_VERSION=400
A: in code, you can use below code special for debug version
#ifdef DEBUG
// do sth for debug
#else
// do sth for release
#endif
Q: -DSTLPORT_VERSION=400
A: define STLPORT_VERSION=400
Tuesday, July 10, 2012
Monday, July 9, 2012
Tips on emacs
M-x find-name-dired RET
Press "t" to select all files found
Press "Q" (shift Q) to start the search/replace
Press "t" to select all files found
Press "Q" (shift Q) to start the search/replace
Wednesday, July 4, 2012
makefile
Some tips on debug makefile
1. make -p|tee make.out
-p, --print-data-base Print make's internal database.
2. make -n
-d Print lots of debugging information.
--debug[=FLAGS] Print various types of debugging information.
1. make -p|tee make.out
-p, --print-data-base Print make's internal database.
2. make -n
-n, --just-print, --dry-run, --recon
Don't actually run any commands; just print them.
3. make -d
-d Print lots of debugging information.
--debug[=FLAGS] Print various types of debugging information.
Tuesday, July 3, 2012
ZZ ranlib
linux下编译静态库的时候,ar不带任何选项打包成.a文件后,对其进行ranlib操作有什么用,如果不进行ranlib操作会有什么后果,我编译的时候没用这步操作也能正常运行,请达人给讲解一下。谢谢。
http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/make-11.html
更新静态库的符号索引表
本小节的内容相对简单。前边提到过,静态库文件需要使用“ar”来创建和维护。当给静态库增建一个成员时(加入一个.o文件到静态库中),“ar”可直接将需要增加的.o文件简单的追加到静态库的末尾。之后当我们使用这个库进行连接生成可执行文件时,链接程序“ld”却提示错误,这可能是:主程序使用了之前加入到库中的.o文件中定义的一个函数或者全局变量,但连接程序无法找到这个函数或者变量。
这个问题的原因是:之前我们将编译完成的.o文件直接加入到了库的末尾,却并没有更新库的有效符号表。连接程序进行连接时,在静态库的符号索引表中无法定位刚才加入的.o文件中定义的函数或者变量。这就需要在完成库成员追加以后让加入的所有.o文件中定义的函数(变量)有效,完成这个工作需要使用另外一个工具“ranlib”来对静态库的符号索引表进行更新。
我们所使用到的静态库(文档文件)中,存在这样一个特殊的成员,它的名字是“__.SYMDEF”。它包含了静态库中所有成员所定义的有效符号(函数名、变量名)。因此,当为库增加了一个成员时,相应的就需要更新成员“__.SYMDEF”,否则所增加的成员中定义的所有的符号将无法被连接程序定位。完成更新的命令是:
ranlib ARCHIVEFILE
通常在Makefile中我们可以这样来实现:
libfoo.a: libfoo.a(x.o) libfoo.a(y.o) ...
ranlib libfoo.a
它所实现的是在更新静态库成员“x.o”和“y.o”之后,对静态库的成员“__.SYMDEF”进行更新(更新库的符号索引表)。
如果我们使用GNU ar工具来维护、管理静态库,我们就不需要考虑这一步。GNU ar本身已经提供了在更新库的同时更新符号索引表的功能(这是默认行为,也可以通过命令行选项控制ar的具体行为。可参考 GNU ar工具的man手册)。
Thursday, June 28, 2012
Openssl's weak key generation
OpenSSL prior to 1.0.0 may use its own function for random number generating and it's vulnerable.
After 1.0.0, it may use OS's if available, and if not available, it still use its own.
What keys are used for:
http://www.openssl.org/docs/HOWTO/keys.txt
Vulnerabilities:
http://www.openssl.org/news/vulnerabilities.html
This topic seems to start from Debian platform. And this posts method to test on your platform, Debian based or not. Don't work on cygwin, however.
http://www.debianadmin.com/fix-for-weak-opensslopenssh-keys-in-debian.html
Quote some here:
Some more links:
http://www.debian.org/security/2008/dsa-1571
http://www.us-cert.gov/cas/techalerts/TA08-137A.html
After 1.0.0, it may use OS's if available, and if not available, it still use its own.
What keys are used for:
http://www.openssl.org/docs/HOWTO/keys.txt
Vulnerabilities:
http://www.openssl.org/news/vulnerabilities.html
This topic seems to start from Debian platform. And this posts method to test on your platform, Debian based or not. Don't work on cygwin, however.
http://www.debianadmin.com/fix-for-weak-opensslopenssh-keys-in-debian.html
Quote some here:
The Debian team has provided a tool that can be used to determine if any such weak keys exist on the system, and it can be run by anyone, regardless of whether they use Debian or not. To begin, download the dowkd.pl perl script and use it to test SSH keys of the host system:
$ cd ~/tmp
$ wget http://security.debian.org/project/extra/dowkd/dowkd.pl.gz
$ wget http://security.debian.org/project/extra/dowkd/dowkd.pl.gz.asc
$ gpg
--keyserver subkeys.pgp.net --recv-keys 02D524BE
$ gpg
--verify dowkd.pl.gz.asc
$ gunzip dowkd.pl.gz
$ perl dowkd.pl host localhost
This will download the dowkd.pl perl script and also import a Debian security team member’s key from subkeys.pgp.net. If the archive verifies okay with gpg, unarchive it, and then run the script in host-checking mode against the localhost.
If the script detects that the host key is weak, it will indicate such. Next, run the script against user keys on the system:
# perl dowkd.pl user
This check should be run as root in order to obtain access to every user’s keys. The script will check the keys and also the authorized_keys file and will alert you if the fingerprint to a remote host indicates a vulnerable key as well. If you wish to check a specific user, append the user name to the command:
# perl dowkd.pl user ruchi
If the script indicates that any keys are weak, they should be removed and regenerated immediately.
Some more links:
http://www.debian.org/security/2008/dsa-1571
http://www.us-cert.gov/cas/techalerts/TA08-137A.html
Monday, June 25, 2012
Some comments on choices=headaches from More Joel on Software
The example doesn't make too much sense to me until I see:
Each additional choice makes complete sense until you find yourself explaining to your uncle that he has to choose between fifteen different ways to turn off a laptop.
It really hurts my ball when I tried to explain something similar to my father...
Days ago, I need to design a config file per request, and my original opinion is "KISS". To re-use existing config file(a stupid txt) may seem too naive, stupid and not popular at all. However, I did prefer to a little bit better choice-ini file a lot to popular "xml" type. It's only simple request internally, thus, less choices/less effort makes sense to me.
Each additional choice makes complete sense until you find yourself explaining to your uncle that he has to choose between fifteen different ways to turn off a laptop.
It really hurts my ball when I tried to explain something similar to my father...
Days ago, I need to design a config file per request, and my original opinion is "KISS". To re-use existing config file(a stupid txt) may seem too naive, stupid and not popular at all. However, I did prefer to a little bit better choice-ini file a lot to popular "xml" type. It's only simple request internally, thus, less choices/less effort makes sense to me.
Interesting article on memory leak
From codeproject, I may try it some day since I was stuck with howto find out memory leak in Openoffice.However, the issue in OO mainly comes from share_pointer, much harder to detect.
http://www.codeproject.com/Articles/393957/Cplusplus-Memory-Leak-Finder
http://www.codeproject.com/Articles/393957/Cplusplus-Memory-Leak-Finder
Saturday, June 23, 2012
Why not stl?
There has been such opinion for a while. However, it's not the time I should know why not stl now, maybe. Put a discussion thread from stackoverflow here for reference.
I hate template, since it makes debug process much more complex. Sometimes, it does help save a lot of coding, to admit it or not .
http://stackoverflow.com/questions/266523/drawbacks-to-templates-and-the-stl-in-c
I hate template, since it makes debug process much more complex. Sometimes, it does help save a lot of coding, to admit it or not .
http://stackoverflow.com/questions/266523/drawbacks-to-templates-and-the-stl-in-c
Friday, June 22, 2012
FAQ
FAQ
Q: cifs_mount failed w return code 22 on Ubuntu 11
A: apt-get install smbfs
Q: mount command on Mac
A: sudo mount_smbfs "//bjcheny:zhao&123@bjcheny-work/301" /Volumes/ # for Mac
Q: gdb on Mac
A: different from what's on linux
http://developer.apple.com/library/mac/#technotes/tn2124/_index.html
Q: if [ -s /etc/redhat-release ]
A: size is no zero
http://tldp.org/LDP/abs/html/fto.html
Q: list all users on Linux
A: cat /etc/passwd | cut -d":" -f1
Also, to find out the total number of accounts, enter:
http://linux.die.net/man/8/useradd
http://linux.die.net/man/8/userdel
[root@www ~]# cat /etc/redhat-release
http://stackoverflow.com/questions/810839/throwing-exceptions-from-constructors
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.8
Q: switch tabs in terminal on Mac
A: cmd + {
Q: cifs_mount failed w return code 22 on Ubuntu 11
A: apt-get install smbfs
Q: mount command on Mac
A: sudo mount_smbfs "//bjcheny:zhao&123@bjcheny-work/301" /Volumes/ # for Mac
Q: gdb on Mac
A: different from what's on linux
- gdb -arch i386 301/IBM\ Lotus\ Symphony.app/
- b IniParser::IniParser
- r
- (opt) kill # and then build and replace dylib
- (opt) r # gdb will re-read dylib
cat /etc/passwd | wc -l- useradd -d [home directory]
- userdel -r
http://developer.apple.com/library/mac/#technotes/tn2124/_index.html
Q: if [ -s /etc/redhat-release ]
A: size is no zero
http://tldp.org/LDP/abs/html/fto.html
Q: list all users on Linux
A: cat /etc/passwd | cut -d":" -f1
Also, to find out the total number of accounts, enter:
Q: useradd & userdelA: http://linux.die.net/man/8/useradd
http://linux.die.net/man/8/userdel
Q: Is /etc/redhat-release existing on CentOSA: Yes, as below:[root@www ~]# cat /etc/redhat-release
Q: can I throw an exception in constructor?A: yes, throwing an exception from the failed constructor is the standard way of doing this. See below:http://stackoverflow.com/questions/810839/throwing-exceptions-from-constructors
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.8
Q: switch tabs in terminal on Mac
A: cmd + {
Q: class A {operator int(){}};A: class obj; obj.operator int(); int n = obj;
Q: Howto man c lib functions on ubuntu?
A: apt-get install manpages-dev
man 3 <function>
eg: man 3 printf
man -k <keyword> - list related function
eg: man -k printf
eg: man 3 printf
man -k <keyword> - list related function
eg: man -k printf
Q: config blinking cursor on ubuntuA: alt-f2; gconf-editor; desktop-gnome-interface-cursor_blink
Q: IB Vs UB A: IB: Implementation-defined behaviour. The standard leaves it up to the particular compiler/platform to define the precise behaviour, but requires that it be defined.Using implementation-defined behaviour can be useful, but makes your code less portable.UB: Undefined behaviour. The standard does not specify how a program invoking undefined behaviour should behave. Also known as "nasal demons" because theoretically it could make demons fly out of your nose.Using undefined behaviour is nearly always a bad idea. Even if it seems to work sometimes, any change to environment, compiler or platform can randomly break your code.Q: Some unexpected commentsA: We should know that in C++ source code, if compiled with GCC, "<:" means "[", ":>" means "]", "<%" means "{", "%>" means "}", "%:" means "#", "%:" means "##". If compiled with MSVC, "??=","??/","??'" means "#", "\", "^".
Please pay attention that if you write: int a = 1; // some comments ??/ a++; printf("%d", a );
Compiled with MSVC you'll get print result is "1" but not "2" as you expected. This is because the "??/" is replaced as "\", which means the comments will extend to the next line, the same as: int a = 1; // some comments \ a++; printf("%d", a );
Wednesday, June 20, 2012
Avoid re-inventing wheels when parsing config file
Using boost instead of inventing your own wheels. It depends a new object brought in boost 1.42.0, Property Tree.
You can use it to parse below types of config files: Xml/Json/Ini/Info. Refer to below link:
http://www.boost.org/doc/libs/1_42_0/doc/html/boost_propertytree/parsers.html
http://stackoverflow.com/questions/4703134/is-there-a-way-to-print-config-file-for-boost-program-options
Assume the ini config file looks like:
Then,
http://stackoverflow.com/questions/6175502/how-to-parse-ini-file-with-boost
However, it's necessary to keep in mind on how to write your own iniparser.
Data structure in HXX file:
struct ini_NameValue
{
string sName;
string sValue;
inline ini_NameValue() SAL_THROW( () ) {}
inline ini_NameValue(string const & name, string const & value )
: sName( name ),
sValue( value )
{}
};
typedef std::list<ini_NameValue> NameValueList;
struct ini_Section
{
string sName;
NameValueList lList;
};
typedef std::map<string,ini_Section>IniSectionMap;
class IniParser
{
IniSectionMap mAllSection;
public:
IniSectionMap * getAllSection(){return &mAllSection;};
ini_Section * getSection(string const & secName);
IniParser(string const & rIniName)
throw(IOException );
#if DEBUG_LEVEL > 0
void Dump();
#endif
};
Implementation in CXX file.
IniParser::IniParser(string const & rIniName)
{
oslFileHandle handle=NULL;
if (!iniUrl.empty())
fileError = osl_openFile(iniUrl, &handle, osl_File_OpenFlag_Read);
while (getLine(handle, line))
{
// TODO: skip some comments line that starts with "/*" or "#" or "//"
sal_Int32 nIndex = line.indexOf('=');
if (nIndex >= 1)
{
ini_Section *aSection = &mAllSection[sectionName];
struct ini_NameValue nameValue;
nameValue.sName = line.copy(0,nIndex).trim();
nameValue.sValue = line.copy(nIndex+1).trim();
aSection->lList.push_back(nameValue);
}
else
{
sal_Int32 nIndexStart = line.indexOf('[');
sal_Int32 nIndexEnd = line.indexOf(']');
if ( nIndexEnd > nIndexStart && nIndexStart >=0)
{
sectionName = (line.copy(nIndexStart + 1,nIndexEnd - nIndexStart -1).trim();
if (sectionName.empty())
sectionName = string("no name section");
ini_Section *aSection = &mAllSection[sectionName];
aSection->sName = sectionName;
}
}
}
osl_closeFile(handle);
}
ini_Section * IniParser::getSection(OUString const & secName)
{
if (mAllSection.find(secName) != mAllSection.end())
return &mAllSection[secName];
return NULL;
}
Above code only gives a basic model on iniparser.
You can use it to parse below types of config files: Xml/Json/Ini/Info. Refer to below link:
http://www.boost.org/doc/libs/1_42_0/doc/html/boost_propertytree/parsers.html
http://stackoverflow.com/questions/4703134/is-there-a-way-to-print-config-file-for-boost-program-options
Assume the ini config file looks like:
[Section1]
Value1 = 10
Value2 = a_text_string
Then,
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
...
boost::property_tree::ptree pt;
boost::property_tree::ini_parser::read_ini("config.ini", pt);
std::cout << pt.get<std::string>("Section1.Value1") << std::endl;
std::cout << pt.get<std::string>("Section1.Value2") << std::endl;
http://stackoverflow.com/questions/6175502/how-to-parse-ini-file-with-boost
However, it's necessary to keep in mind on how to write your own iniparser.
Data structure in HXX file:
struct ini_NameValue
{
string sName;
string sValue;
inline ini_NameValue() SAL_THROW( () ) {}
inline ini_NameValue(string const & name, string const & value )
: sName( name ),
sValue( value )
{}
};
typedef std::list<ini_NameValue> NameValueList;
struct ini_Section
{
string sName;
NameValueList lList;
};
typedef std::map<string,ini_Section>IniSectionMap;
class IniParser
{
IniSectionMap mAllSection;
public:
IniSectionMap * getAllSection(){return &mAllSection;};
ini_Section * getSection(string const & secName);
IniParser(string const & rIniName)
throw(IOException );
#if DEBUG_LEVEL > 0
void Dump();
#endif
};
Implementation in CXX file.
IniParser::IniParser(string const & rIniName)
{
oslFileHandle handle=NULL;
if (!iniUrl.empty())
fileError = osl_openFile(iniUrl, &handle, osl_File_OpenFlag_Read);
while (getLine(handle, line))
{
// TODO: skip some comments line that starts with "/*" or "#" or "//"
sal_Int32 nIndex = line.indexOf('=');
if (nIndex >= 1)
{
ini_Section *aSection = &mAllSection[sectionName];
struct ini_NameValue nameValue;
nameValue.sName = line.copy(0,nIndex).trim();
nameValue.sValue = line.copy(nIndex+1).trim();
aSection->lList.push_back(nameValue);
}
else
{
sal_Int32 nIndexStart = line.indexOf('[');
sal_Int32 nIndexEnd = line.indexOf(']');
if ( nIndexEnd > nIndexStart && nIndexStart >=0)
{
sectionName = (line.copy(nIndexStart + 1,nIndexEnd - nIndexStart -1).trim();
if (sectionName.empty())
sectionName = string("no name section");
ini_Section *aSection = &mAllSection[sectionName];
aSection->sName = sectionName;
}
}
}
osl_closeFile(handle);
}
ini_Section * IniParser::getSection(OUString const & secName)
{
if (mAllSection.find(secName) != mAllSection.end())
return &mAllSection[secName];
return NULL;
}
Above code only gives a basic model on iniparser.
Sunday, June 17, 2012
Make own hello's rpm
It sucks when I tried to post my first tech notes on hi.baidu.com. It's lost by no reason.
Thus, I may need to recall my issues and solutions, and re-post it here.
Follow below's url to make hello's rpm.
http://fedoraproject.org/wiki/How_to_create_a_GNU_Hello_RPM_package
http://fedoraproject.org/wiki/How_to_create_an_RPM_package
https://fedoraproject.org/wiki/Common_Rpmlint_issues
Don't copy all the spec from above url, edit the local generated spec instead.
However, there are several issues during this process and all are resolved
1. installed but unpackaged files found: /usr/local/info/dir
Append "rm -f %{buildroot}/%{_datadir}/info/dir" in %install section.
Some more macro for directories fyi:
/usr/bin/xxx => %{_bindir}/xxx
/usr/lib/xxx => %{_libdir}/xxx
/usr/include/xxx => %{_includedir}/xxx
/usr/share/xxx => %{_datadir}/xxx
/usr/man/xxx => %{_mandir}/xxx
For more, refer below:
http://fedoraproject.org/wiki/Packaging/RPMMacros
2. rpmlint hello.spec ../SRPMS/hello* ../RPMS/*/hello* |tee rpmlint.log
1)files-attr-not-set
Add "%defattr(-,root,root,-)" in %files section, and then get:
%files -f %{name}.lang
%defattr(-,root,root,-)
%doc AUTHORS ChangeLog COPYING NEWS README THANKS TODO
2)file-not-utf8
Indicates that the text encoding of the specified file, usually a documentation file, is not in UTF8.
iconv -f iso8859-1 -t utf-8 ChangeLog > ChangeLog.conv && mv -f ChangeLog.conv ChangeLog
Some basic commands for tar used:
ls -l hello/ChangeLog
1. tar -tvf hello-2.8.tar|grep ChangeLog
2. tar -f hello-2.8.tar --delete hello/ChangeLog
3. tar -uvf hello.tar hello/ChangeLog
Done:
[bjcheny@bjcheny-rh6 SPECS]$ rpmlint hello.spec ../SRPMS/hello* ../RPMS/*/hello* |tee rpmlint.log
3 packages and 1 specfiles checked; 0 errors, 0 warnings.
3. useful macros to make platform specific code
%if (0%{?fedora} >= 9|| 0%{?rhel} > 5)
#do stuff%endif
%if 0%{rhel_version}%{centos_version} == 0
# do stuff
%endif
http://www.rpm.org/max-rpm/s1-rpm-multi-platform-dependent-conditional.html
http://www.linux-archive.org/rpm-package-manager/70241-canonical-way-detect-platform-distribution.html
4. packaging python
http://en.opensuse.org/openSUSE:Packaging_Python
Subscribe to:
Posts (Atom)