CharSyam
Tag | Location | Media | Guestbook | Admin

'프로그래밍/게으른 개발자를 위한 팁'에 해당하는 글(6)
2009/11/30   Makefile Sample
2009/11/21   재미나고 유용한 VC 옵션 한가지
2009/11/07   급히 수정해야 하는 버그는 또 다른 버그를 만든다.
2009/11/02   바람풍과 바담뿡
2009/05/11   Continuous Integration
2009/04/21   SVN의 External 기능


2010/04/14 03:20 2010/04/14 03:20
코드 스니핏 - urlencode, urldecode 샘플

갑자기 필요해졌는데 –_-, 괜찮은 소스코드가 없었다.

그렇다고 내가 만든건 아니고 qDecoder 에서 decode 부분을 –_-( qDecoder에서는 한글이 인코딩이 안되네) 또 어디에서(어디더라, ) encode 부분을 가져와서 간단하게 인터페이스만 살짝 바꾼 버전이다.

고로 –_- 아무것도 내가 한건 없다라고 보면 될듯

MAC에서는 NSString 이 기본적으로 해주는데, c 쪽은 다 직접 해줘야 한다라는 –_-

#include <stdio.h>
#include <string.h>
#include <memory.h>
static const unsigned char hexchars[] = "0123456789ABCDEF";

char *url_encode(char const *s, int len, int *new_length)
{
    register unsigned char c;
    unsigned char *to, *start;
    unsigned char const *from, *end;

    from = s;
    end = s + len;
    start = to = (unsigned char *) malloc(3 * len + 1);

    while (from < end) {
        c = *from++;
        if (c == ' ') {
            *to++ = '+';
#ifndef CHARSET_EBCDIC
        } else if ((c < '0' && c != '-' && c != '.') ||
            (c < 'A' && c > '9') ||
            (c > 'Z' && c < 'a' && c != '_') ||
            (c > 'z')) {
                to[0] = '%';
                to[1] = hexchars[c >> 4];
                to[2] = hexchars[c & 15];
                to += 3;
#else /*CHARSET_EBCDIC*/
        } else if (!isalnum(c) && strchr("_-.", c) == NULL) {
            /* Allow only alphanumeric chars and '_', '-', '.'; escape the rest */
            to[0] = '%';
            to[1] = hexchars[os_toascii[c] >> 4];
            to[2] = hexchars[os_toascii[c] & 15];
            to += 3;

#endif /*CHARSET_EBCDIC*/
        } else {
            *to++ = c;
        }
    }

    *to = 0;
    if (new_length) {
        *new_length = to - start;
    }

    return (char *) start;
}

/**
* Decode URL encoded string.
*
* @param str    a pointer of URL encoded string.
*
* @return    the length of bytes stored in str in case of successful, otherwise returns NULL
*
* @note
* This modify str directly. And the 'str' is always terminated by NULL character.
*/
static char _x2c(char hex_up, char hex_low)
{
    char digit;

    digit = 16 * (hex_up >= 'A'
        ? ((hex_up & 0xdf) - 'A') + 10 : (hex_up - '0'));
    digit += (hex_low >= 'A'
        ? ((hex_low & 0xdf) - 'A') + 10 : (hex_low - '0'));
    return (digit);
}

int url_decode(char *str, char *target, int size) {
    char *pEncPt, *pBinPt, *pTarPt;

    if (str == NULL || target == NULL || size == 0 ) {
        return 0;
    }

    pBinPt = str;
    pTarPt = target;

    for(pEncPt = str; *pEncPt != '\0'; pEncPt++) {
        if( (pTarPt - target) >= size )
        {
            pTarPt--;
            break;
        }

        switch (*pEncPt) {
            case '+': {
                *pTarPt++ = ' ';
                break;
            }
            case '%': {
                *pTarPt++ = _x2c(*(pEncPt + 1), *(pEncPt + 2));
                pEncPt += 2;
                break;
            }
            default: {
                *pTarPt++ = *pEncPt;
                break;
            }
        }
    }
    *pTarPt = '\0';

    return (pTarPt - target);
}

int main()
{
    int i, n;
    unsigned char dest[256] = {0x00,};
    unsigned char test[256] = {0x00,};
    char *pTarget;
    unsigned char *str[] = {
        "안녕하세요",
        "hello world 안녕하세요\n",
         "hello\%20world\%20\%be\%c8",
        "A B C D E F G",
        NULL
    };

    int count = 0;
    char *pDest = str[count];
    while( NULL != pDest){
        printf("Original : %d %s\r\n", strlen(pDest), pDest);
        pTarget = url_encode(pDest, strlen(pDest), NULL);
        printf("encode   : %d %s\n", strlen(pTarget), pTarget);

        n = url_decode(pTarget, test, 256);
        test[n] = 0;
        printf("decode   : %d %s\n", n, test);

        free(pTarget);
        count++;
        pDest = str[count];
    }

    return 0;
}



2009/11/30 00:18 2009/11/30 00:18
Makefile Sample

그냥 내가 보통 사용하는 Makefile Sample

sample 을 잘 보면 몇 가지 안 쓰는 부분들이 있지만, Makefile 의 문법을 알기 위해서 나중에 쓸 수 있는

부분들이라서 같이 올린다.

.SUFFIXES   =   .cpp .o
AR          =   ar
CC          =   g++
CFLAGS      =
LIBS        =
INCS        =
OBJS        =   cs_socket_addr.o \
                cs_socket.o \
                cs_netutil.o \
                cs_acceptor_socket.o \
                cs_connector_socket.o
SRCS        =   $(OBJS: .o=.cpp)

TARGET      =   netlib.a
TEST1       =   client_test
TEST2       =   server_test

all     :       $(TARGET) $(TEST1) $(TEST2)

$(TARGET) :     $(OBJS)
                $(AR) rcv $(TARGET) $(OBJS)

$(TEST1)    :   $(TARGET) $(TEST1).o
                $(CC) -o $(TEST1) $(TEST1).o $(TARGET)

$(TEST2)    :   $(TARGET) $(TEST2).o
                $(CC) -o $(TEST2) $(TEST2).o $(TARGET)
.cpp.o      :
                $(CC) -c $(CFLAGS) $*.cpp

dep         :
                    gccmakedepend $(SRCS)
clean       :
                    rm -rf $(OBJS) $(TARGET) $(TEST1) $(TEST2) core



2009/11/21 11:54 2009/11/21 11:54
재미나고 유용한 VC 옵션 한가지

한방빌드를 만들어서 쓰다보면, 다음과 같은 경우가 생깁니다.

1. 소스 트리는 하나로 유지하고 싶다.

2. 나가는 대상에 따라서 서로 다른 기능이 동작해야 한다.(바이너리에서 완전히 빠져있게)

사실 결론은 하나입니다. #ifdef 등으로 기능이 다르게 동작하게 하는 것.

그럼 여기에 적용할 수 있는 간단한 방법은 다음과 같습니다.

1. 소스 트리를 따로 유지한다. –> 1번에 위배되고, 유지보수에 손이 많이 갑니다.

2. 프로젝트 속성을 여러개 만들어서, 사용한다. 하지만, 이것도, 한 솔루션에 프로젝트가 여러 개 있다면, 굉장히 번거로운 작업이 생깁니다.

3. 하나의 프로젝트 속성을 쓰데, 매번, 빌드 할 때, #define 속성을 변경해준다.

4. 빌드 시, 자동으로 소스 코드에 설정에 맞는 #define 이 들어가도록 빌드 스크립트를 작성한다.

위에 것들을 보면 4번이 그래도 가장 나아보입니다. 그리고, 설정 작업이 복잡해 진다면, 4번 형태로 가는게 좋을듯 합니다.

그런데, 지금부터 알려드릴(이미 공개된 ㅋㅋ) 옵션을 사용하게 되면, 한방에 처리가 됩니다.

뭐냐 하면,  CL 이라는 환경 변수입니다.

먼저 자세한 건 다음 사이트에서 알 수 있습니다.

http://msdn.microsoft.com/en-us/library/kezkeayy.aspx

간단하게 설명하자면 set CL=-D_TEST_A_

이런식으로 지정하면 빌드시에 자동으로 _TEST_A_ 옵션이 적용됩니다. –D 뿐만 아니라 다른 것들도 쉽게 바뀌게 됩니다. 즉, 같은 빌드 프로세스를 타면서 앞쪽에 CL옵션을 설정해서 #define 한것과 같은 효과를 낼 수 있습니다.

간단한 빌드 프로세스에서는 위의 4번과 같은 방법을 쓰지 않고도 효과적으로 사용할 수 있습니다.



2009/11/07 02:24 2009/11/07 02:24
급히 수정해야 하는 버그는 또 다른 버그를 만든다.

크, 역시 급히 수정해야 하는 버그는 새로운 버그군을 만들어 낸다.

오늘 급히 수정해야 할 버그를 고치기 위해서, 코드에 변경을 했다.

그 다음부터 –_-, 동작이 하나씩 안되기 시작하더니, 급기야 –_-, 주요 기능이 동작하지 않게 되었다.

물론, 원인을 하나하나 분석하기 시작해서 이전 코드의 동작이 제대로 되도록 수정을 하기는 했지만 –_-

흑흑흑…

급한 마음으로 코드를 짜면, 역시 버그가 나올 수 밖에 없다.

좋은 테스트 코드가 있다면 좋겠지만, 아직 그러기에는 힘든 T.T



2009/11/02 01:50 2009/11/02 01:50
바람풍과 바담뿡

혹시 예전에 이런 얘기를 들어본 적이 있는가?

어미 게가 아기 게는 바르게 걷기를 바래서, 아기 게의 걸음을 보정해 주려고 노력하는 이야기…

이 이야기의 요점은… 어미 게의 감동적인 자식 교육이 아니라, 잘못된 교육이라는 것이다.

이걸 아주 강하게 느끼는 것이, 현재의 나다 T.T

내 코드는 좀 더럽다 –_-, 아주 깔끔하게 짜는 것도 아니고, 시간이 없을 때에는 더더욱, 더러운 코드를 생산한다. 스멜이 강하게 나는!!!

그런데, 이번에 프로젝트를 진행하면서, 나와 신입 프로그래머 한명이 담당하게 되었다.

그런데, 코드 리뷰를 해주고, 해당 코드를 수정할 일이 있어서, 코드를 보는데, 우어어어어, 알아보는 데 시간이 걸렸다. 그런데 재미있는 것은, 이 친구가 작성한 다른 코드를 보면, 아주 깜끔한 코드 부터, 아주 더러운 코드까지 각양각생이었다.

그 이유가 무엇일까?

원인은 바로 기존 코드의 참고이다. 즉, 참고한 코드가 깔끔한 코드이면, 신입이 작성한 코드도 깔끔한 코드가 되고, 참고한 코드가 더러운 코드가 되면, 신입이 작성한 코드도 매우 더러운 코드가 되어버리는 것이다.

그리고 가슴아프게도, 더러운 코드 부분은 나의 더러운 코드를 보고 흉내를 낸것이었다.

그걸 보니, 코드를 깔끔하게 짜야겠다라는 생각이 부쩍든다. 왜냐하면, 참고할 코드를 작성하는 선배가

바담뿡 하고 있는데, 그걸 보고 배우는 신입사원이 바람풍 할리는 없기 때문이다.

결국, 누구의 잘못이 아니라, 나의 잘못이다. 더더욱 깔끔한 코드를 생성하려고 노력해야겠다.



2009/05/11 23:42 2009/05/11 23:42
Continuous Integration

Continuous Integration(이하 CI) – 지속적인 통합이라는 의미다.

요새 꽤나 “이슈” 가 많이 되고 있는(사실은 좀 이전에~~~) 주제이기도 하다.

 

보통 CI 라고 하면, CI 툴을 사용해서 설치하면 되지 않는가 라고 생각하기 쉽다.

사실 이 말도 맞다. 하지만, 모든 것이 그렇듯이 CI의 핵심은 “사람” 이고 “팀원” 이다.

 

먼저 CI의 구성 요소를 살펴보자.

1. 소스 형상 관리 시스템( SVN, CVS, VSS 등등 뭐든지 좋다. )

- 소스 형상 관리 시스템이 없다면,  솔직히 CI가 구성되지 않는다. 상상해보자.

특정 시간마다, 수많은 사람들이 USB나, 이메일 등 을 통해서 서로 다른 소스를 던져준다면?

수많은 버그와 함께, 코드 되돌리기 신공이 난무하게 될 것이다.  SVN을 쓰더라도 머지가 힘들 수도

있지만 (사실 SVN 등을 쓸 때, 머지의 책임은 뒤에 커밋하는 사람이 지는 것이다. ) 과연 어느 것이

쉬울지는 잠시만 적응해 보면 안다.

 

2. 빌드 머신 과 한방 빌드

보통 빌드라는 건, 개발자가 자신의 로컬 머신에서 VS등에서 F7 등을 눌리면 되는 것으로 생각하기 쉽다. 그러나, 빌드라는 것도, 공식 빌드, QA 빌드, 개발자 테스트 빌드, 개발도중의 빌드 등으로 나눌 수 있다. 여기서 개발 도중에 개발자가 하는 빌드를 빼고는 개발자 테스트 빌드 조차도 한방 빌드라는 공식화된 빌드 루틴을 타야 한다.

한방 빌드라는 것은, 그냥 배치 스크립트 등을 딱 한번 누르면, 깨끗한 머신에서 알아서 소스코드를 가져오고, 필요한 라이브러리를 링크해서 빌드 결과를 알려줄 수 있는 시스템이다. 그 안에는 사람의 손이 추가로 가서는 안 된다.

일일 빌드라는 유명한 것도, 이 한방 빌드로 만들어져야 한다.

3. CI 툴

사실 CI 툴은 편의를 도와주는 것이지만 사용하기 힘들다면 꼭 안써도 된다. 그냥 2의 한방 빌드를 예약 작업으로 걸어놓고, 10분이나, 1시간 단위로 돌려서 결과를 확인해도 된다. 하지만, 편의를 도와준다는 것은 생산성을 향상시켜준다는 것을 알아야 한다.

4. 사람(별표 백만개)

위의 시스템이 잘 갖춰져 있어도, 쓰는 사람들에 따라서 천지 차이다. –_-

SVN이 있더라도 하루에 한번 체크인을 한다든지, 3개월에 한번 한다든지 한다면, 별 의미가 없다.

같은 한방 빌드라도, 필요한 부분을 빨리 체크해서 결과를 알려주는 것과, 모두 끝난뒤에야 결과를 알려주는 등의 것도 어떻게 구성하는지에 따라서 매우 결과가 달라진다.

CI툴의 리포트도 사람이 신경쓰지 않으면 전혀 의미가 없다.

그래서 결국 사람이 가장 중요하다.

위에 것들이 관심이 있다면, 최소 1,2번 까지라도 설정해 보길 바란다.

CI 툴중에 소스코드를 커밋한걸 감지하고 있다가 소스코드가 커밋될 때마다 빌드해서 알려주는

기능도 있으니, 누군가 커밋을 빼 먹어 생기는 문제가 많다면, 이런 기능을 이용해 보는것도 어떨까?



2009/04/21 00:02 2009/04/21 00:02
SVN의 External 기능

최근에 발견한(검색한) 기능 중에서 SVN에 External 이라는 기능이 있다는 것을 알게 됬다.

그런데 바로 이 기능이 대박이다.

프로젝트를 진행하다 보면 다음과 같은 구성이 될 때가 있다.

A,B,C 라는 프로젝트가 있고, 공통 Component D 가 있다.

image

그럼 SVN 의 구조는 위와 같은 형태가 된다. 이러면 소스 트리에 공통 Component를 같이 넣어두던지

매번 따로 소스코드를 CheckOut 받아줘야 한다. 이러면 문제가, 최상위에서 Update 를 받아도 해당

공통 Component 는 따로 Update를 받아야 한다.

 

이것을 해결해 주는 것이 바로 External 키워드이다. 타 SVN Repogitory 를 자신의 하위 디렉토리처럼

인식시켜서, 한방에 다운로드를 받을 수 있게 한다. 이것을 설정하는 방법은 간단하다. SVN에서는 커맨드

를 이용해서 주면 되고, TortoiseSVN에서는 TortoiseSVN->Properties 를 선택한 다음

Property Name 으로 svn:externals 라고 설정하고, Value 로 다운로드 받을 디렉토리 경로명으로

지정하면 된다.

 

value : component http://sample.svn.com/sampleproject/sample_component

위와 같이 지정해주면 끝!!!

Technorati 태그:


BLOG main image
CharSyam
 Notice
 Category
전체 (90)
(19)
(3)
프로그래밍 (61)
게임 (1)
Server Setting (5)
대학원 (1)
 TAGS
구글테스트 qsort 일자리 창출 소프트웨어 아키텍처 문서화 모듈 분할 뷰 전문가 미디어법 WindowsMobile 도전 임베디드 OS 만들기 CAB 촘스키 Abstract Factory google test 삽질운하 DTM_SETIMAGE TearUp 이미지로드 주식 뷰패킷 모듈 사용 뷰 한글바로가기 RAPI 여론 조작 googletest 일일빌드 Window Mobile 6 일일 빌드 SetUp WindowMobile 다국어바로가기
 Calendar
«   2010/07   »
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
 Recent Entries
YES24 총알 배송 광고
CMake &ndash; CMakeLis...
Autotools 관련 좋은 링...
고수와 전문가의 차이
Zookeeper 설치 방법
 Recent Comments
오~ 이 책도 땡기는군요...
ohyecloudy - 05/25
항상 정리해야 되는데,...
CharSyam - 05/13
잘 정리하셨네요. ^^
고감자 - 05/12
네, 저도 동감합니다....
CharSyam - 2009
http://www.thisisgame....
ParkPD - 2009
 Recent Trackbacks
Discount patio furniture.
Discount furniture.
Furniture competition.
Furniture design compe...
Acomplia ribona.
Acomplia.
Premarin.
Premarin vaginal cream.
스크럼과 XP
The note of Legendre
 Archive
2010/07
2010/06
2010/05
2010/04
2010/03
 Link Site
 Visitor Statistics
Total : 38341
Today : 43
Yesterday : 73
rss
Powered by Tistory & Designed by webnoon.net