이럴 때 필요하다.

디렉토리 A에 top.sh, a.sh, b.sh 등이 있고 top.sh에서 a.sh, b.sh 등을 상대경로를 이용해서 실행한다고 하자. 디렉토리 B에서 ../../path-to-A/top.sh를 하면 경로가 꼬여서 a.sh, b.sh를 제대로 못 찾게 된다. 그렇게 때문에 top.sh 내부에서 caller의 위치와 무관하게 top.sh가 속한 디렉토리 경로를 구해야할 필요가 생긴다.


http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in


DIR="$( unset CDPATH && cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"


* $0를 사용하면 bash script에서 source 명령어로 다른 bash script를 가져올 때 원래의 bash script 경로를 얻게된다. 그래서 ${BASH_SOURCE[0]}를 사용하는 것이 좋다.

* dirname을 이용하여 basename을 제외한 경로를 얻는다.

* cd한 후 pwd를 해서 절대 경로를 얻는다.


bash script 자체가 link로 연결되어 있고, 진짜 원본의 디렉토리를 알고 싶은 경우 링크된 stackoverflow 사이트에 직접가서 코드를 읽어보자.


그리고 bash script 내에서 cd 등을 사용한 경우 원하는 대로 동작하지 않는다. 그러나 bash script의 가장 앞에 이 코드를 두면 간단하게 해결되는 문제이다.


CDPATH 관련 문제도 있다고 한다. CDPATH는 cd 명령을 사용할 때 사용하는 PATH이다. Subshell을 띄우고 unset CDPATH를 하면 된다. (위 코드에서 $(와 ) 사이에서 unset한 것은 밖에 영향을 안 준다.)

그런데 다음과 같이 cd 경로를 명시적으로 적어주는 방법이 더 간단한 것 같다.

cd ./"$( dirname "${BASH_SOURCE[0]}" # THIS IS WRONG WAY

이렇게 하면 안 된다는 것을 발견했다. 그냥 unset CDPATH를 하는 것이 정확한 방법이다.

Posted by asdfzxcv
프로그래밍/C/C++2013. 5. 9. 11:40
Posted by asdfzxcv
프로그래밍/C/C++2011. 6. 21. 18:50
#include <stdio.h>
int main()
{
        printf("%u\n", (-320) % 20u);            // 16
        printf("%u\n", ((unsigned) -320) % 20u); // 16
        printf("%u\n", (-320) / 20u);            // 214748348
        printf("%u\n", ((unsigned) -320) / 20u); // 214748348
        return 0;
}
Posted by asdfzxcv
프로그래밍/C/C++2011. 4. 14. 23:38
가장 쉬워보이는 방법인
A ## __LINE__
은 (적어도 gcc를 포함한) 여러 컴파일러에서 원하는 대로 작동하지 않는다. 그럼 어떻게 해야 하느냐? 구글링을 해봤다.

http://stackoverflow.com/questions/3580533/c-preprocessor-magic

아직 이렇게 되는 원리를 이해할 수 없다. 아무튼 저걸 성공한 저 분에게 경의를 표한다.
(http://stackoverflow.com/users/15168/jonathan-leffler)
설명을 적어준 분에게도.
(http://stackoverflow.com/users/187690/andreyt)
#define DECLARE(x) _DECLARED_VARIABLE_ ## x ## _LINE_ ## __LINE__

#define DECLARE11(x, line) _DECLARED_VARIABLE_ ## x ## _LINE_ ## line
#define DECLARE10(x) DECLARE11(x, __LINE__)

#define DECLARE23(line) _LINE_ ## line
#define DECLARE22(x) _DECLARED_VARIABLE_ ## x
#define DECLARE21(x, line) DECLARE22(x) ## DECLARE23(line)
#define DECLARE20(x) DECLARE21(x, __LINE__)

#define DECLARE32(line) _LINE_ ## line
#define DECLARE31(x, line) _DECLARED_VARIABLE_ ## x ## DECLARE32(line)
#define DECLARE30(x) DECLARE31(x, __LINE__)

#define DECLARE42(x, line) _DECLARED_VARIABLE_ ## x ## _LINE_ ## line
#define DECLARE41(x, line) DECLARE42(x, line)
#define DECLARE40(x) DECLARE41(x, __LINE__)

int DECLARE(y);
int DECLARE10(z) = 12;
int DECLARE20(a) = 37;
int DECLARE30(b) = 91;
int DECLARE40(c) = 129;
이 많은 코드 중 (아마도) DECLARE40만 원하는 대로 동작할 것이다. (컴파일러에 따라 다를 수도 있다.) 컴파일이 안 되는 DECLARE20과 DECLARE30을 제외하고 나머지의 결과는 다음과 같다.
int _DECLARED_VARIABLE_y_LINE___LINE__;
int _DECLARED_VARIABLE_z_LINE___LINE__ = 12;
int _DECLARED_VARIABLE_c_LINE_23 = 129;
결론적으로 다음과 같이 사용하면 된다. Static assert의 경우 크기가 음수인 배열을 typedef로 선언하면서 컴파일 에러를 발생시키는 방식이다. 이건 (http://stackoverflow.com/questions/1597704/verifying-that-c-c-signed-right-shift-is-arithmetic-for-a-particular-compiler)에서 본 것.
#define LINE2(x, line) x ## line
#define LINE1(x, line) LINE2(x, line)
#define LINE(x) LINE1(x, __LINE__)
#define MY_STATIC_ASSERT2(x, line) \
        typedef int MyStaticAssert_line_ ## line[(x) ? 1 : -1]
#define MY_STATIC_ASSERT1(x, line) MY_STATIC_ASSERT2(x, line)
#define MY_STATIC_ASSERT(x) MY_STATIC_ASSERT1(x, __LINE__)
그 외에 참고할 만한 곳
http://en.wikibooks.org/wiki/C_Programming/Preprocessor
Posted by asdfzxcv
프로그래밍2011. 4. 14. 20:13
프로그래밍 언어에서 나머지 연산을 할 때 결과가 세 종류 이상 있다.
편의상 p = q * n + r의 표기를 따르자. p가 피제수, n이 제수, q가 몫, r이 나머지.

http://en.wikipedia.org/wiki/Modulo_operation
위키에는 truncated division, floored division, Euclidean definition 방식을 설명하고 있다. 이것이 일반적으로 사용되는 용어인지는 불확실하다. 아무튼 간략하게 요약하면,
방식 q sgn(r)
Truncated round toward zero sgn(p)
Floored round toward negative infinity sgn(n)
Euclidean \(\mathop{\mathrm{sgn}}\nolimits(n) \left\lfloor \frac{p}{\left|n\right|} \right\rfloor\) \( \geq 0 \)
 
그리고 toward positive infinity는 쓰는 경우가 있는지 모르겠다.

개인적으로는 floored division 또는 Euclidean definition 방식이 수학적으로 아름답다고 느끼지만 --- 사실 다른 사람도 그렇게 주장한다. --- 프로그래밍 언어에서는 그냥 truncated division 방식을 쓰는 경우가 많다. 자세한 것은 위키를 읽어보자.

C 언어에서 2로 나누는 것을 floored division으로 하고 싶으면, arithmetic shift를 써야 하는데, 문제는 C 언어에서 음수에 대한 >>가 implementation defined이다. 그래서 컴파일러가 >>를 어떻게 처리하는지 알아야 하는 경우가 있다.
http://stackoverflow.com/questions/1597704/verifying-that-c-c-signed-right-shift-is-arithmetic-for-a-particular-compiler
헐, 크기가 음수인 array를 만들어서 컴파일 에러를 발생시키다니 천재적인 방법인 듯. 이런 식으로도 compiler time assert가 가능하구나. 하지만 문제가 하나 있는데, __LINE__이 치환되지 않고 그냥 __LINE__으로 들어간다는 것이다. 이 문제는 글을 새로 작성했다. (http://noexists.tistory.com/183)
#define RIGHT_SHIFT_IS_ARITHMETIC \
    ( (((signed int)-1)>>1) == ((signed int)-1) )
MY_STATIC_ASSERT(RIGHT_SHIFT_IS_ARITHMETIC);
Posted by asdfzxcv
프로그래밍/C/C++2010. 11. 22. 19:33
Posted by asdfzxcv
프로그래밍/C/C++2010. 3. 20. 11:50
http://www.gnu.org/s/libc/manual/html_node/Parsing-Program-Arguments.html

프로그램에서 argument 처리하는데 쓰는 라이브러리
getopt, argp, suboptions
Posted by asdfzxcv
프로그래밍/C/C++2009. 1. 19. 12:49
Qt library를 윈도우에서 컴파일하기

메뉴얼만 보고 따라하면 잘 안 된다.
sspi.h의 문제는 다음글을 참고하여 고치자.
http://clifford.soup.io/post/10396099/Bugfix-Building-Qt-4-4-3-on
그래도 컴파일이 안 되면 다음글을 참고하여 고치자.
http://niftools.sourceforge.net/forum/viewtopic.php?f=4&p=15485

디버그 메시지를 볼 수 없다. qDebug(), printf 등의 함수를 사용하고 싶다.
.pro파일에 "CONFIG += console"을 적어준다.
이런 문제는 QMake Manual을 찾는게 좋다.

#include <QSqlDatabase>등을 추가해도 컴파일이 안 된다.
.pro파일에 "QT += sql"을 적어준다.
http://doc.trolltech.com/4.0/qtsql.html

SQLite를 쓰려고 했는데 한글 정렬이 안 된다.
한참을 구글링해도 답이 안 나오다가 겨우 해결했다.
이것은 사실 Qt 문제가 아니라 SQLite 문제이지만 따로 글쓰기 귀찮아서 여기에 적는다.
query.exec("PRAGMA encoding = \"UTF-8\"");
이 명령은 테이블이 하나도 없을 때만 가능하다.
http://www.sqlite.org/pragma.html
Posted by asdfzxcv