달력

4

« 2024/4 »

  • 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
2013. 1. 21. 11:06

SVN(Subversion) 명령어 사용 방법 Enjoy/etc2013. 1. 21. 11:06

출처 : http://blog.naver.com/sjh77ch/62179981



SVN(Subversion)은 형상관리를 위한 도구이다. 다시 말하면 소프트웨어 개발의 버전 관리 시스템이다.

 

SVN에서 많이 사용되는 명령어는 다음과 같다.

 

checkout 또는 co - 저장소(repository)에서 로컬 작업공간으로 소스를 받아오는 것.

$ svn checkout 저장소URL [PATH...]

: 지정된 로컬경로에 저장소의 소스가 복사된다. 경로가 지정안되면 저장소URL의 맨마지막 디렉토리명이 저장될 디렉토리로 사용되어진다. -r 옵션으로 리비전을 지정한 경우엔 해당 리비전의 소스를 가져온다.

예제) svn checkout -r 99 http://repository/src src

설명) 저장소에서 리비전 번호 99의 src경로내의 소스를 가져온다.

 

update 또는 up - 저장소(repository)의 최신 내용으로 로컬 소스를 갱신 한다.

$ svn update [PATH...]

: 기본적으로 최신 리비전을 반영한다. 그러나 -r 옵션으로 리비전을 지정한 경우엔 그 리비전으로 맞춘다.

 

commit 또는 ci - 로컬에서 수정된 내용을 저장소에 적용시킨다.

$ svn commit [PATH...]

: 기본적으로 이 명령을 내리면 수정 사항을 코멘트할 수 있게 로그 편집기가 실행된다. lock된 파일이나 디렉토리는 commit성공후 자동적으로 unlock된다.

 

lock - 저장소의 파일이나 디렉토리를 잠근다.

$ svn lock TARGET

: lock이 걸린 파일이나 디렉토리는 다른 사용자가 변경하여 commit할 수 없다. 해당 경로의 작업이 너무 방대하여 그 동안 다른 사용자가 수정하지 못하도록 할때 유용.

 

unlock - 저장소의 잠근 파일이나 디렉토리를 풀어준다.

$ svn unlock TARGET

: lock의 반대. 기본적으로 lock을 건 사용자가 풀어줘야 한다.

 

add - 새 파일이나 디렉토리를 추가한다.

$ svn add PATH...

: add 명령은 지정된 PATH의 새로운 파일이나 디렉토리를 버전관리 대상에 등록할 뿐이므로, add후 commit 명령을 수행해야만 실제로 저장소에 해당 파일이 추가된다.

 

delete 또는 del, remove, rm - 파일이나 디렉토리를 제거한다.

$ svn delete PATH...(URL)

: delete 명령은 add와 반대로 해당 PATH의 파일이나 디렉토리을 버전관리 대상에서 삭제한다. 역시 commit 명령을 수행해야만 실제로 저장소에서 해당 목록이 제거된다. URL로 지정했을 경우 해당 목록은 즉시 저장소에서 제거된다.

 

 

copy 또는 cp - 로컬 사본이나 저장소 내용을 복사한다. 브랜치(branch)를 만들기 위해 사용.

$ svn copy SRC  DST

: SRC가 로컬경로이고 DST도 로컬경로일 경우, 로컬복사되고 commit시 저장소에 복사 목록이 추가 저장된다. SRC가 로컬경로이고 DST가 저장소URL일 경우, URL에 복사되고 즉시 commit됨. SRC가 저장소URL이고 DST가 로컬경로일 경우, 로컬로 checkout하고 commit시 저장소에 해당 사본이 추가.

SRC가 저장소URL이고 DST도 저장소URL일 경우, 저장소 내에 브랜치(branch)를 만듬.

 

move 또는 mv, rename, ren - 파일이나 디렉토리의 이름을 바꾸거나 이동시킨다. 이 명령은 copy후 delete와 같다.

$ svn move SRC  DST

: SRC가 로컬경로이고 DST도 로컬경로일 경우, 로컬로 rename 또는 move되고 commit시 저장소에 반영된다. SRC가 저장소URL이고 DST도 저장소URL일 경우, 저장소에서 rename,move가 바로 commit됨.

 

info - 해당 파일에 대한 정보를 출력한다.

$ svn info TARGET

: TARGET의 저장소 URL경로나 마지막 수정 일자등에 대한 정보를 보여준다.

 

log - 해당 경로나 파일의 로그( 리비전에 따라 변경된 내역)를 볼수 있다.

$ svn log [PATH]

: 지정된 로컬 PATH에 대한 로그를 출력한다. -r 옵션을 지정하면 출력할 리비젼 범위등을 정할 수 있다.

예제) svn log -r 30:100 test.c

설명) 리비전 번호 30~100 내에서 test.c에 대한 로그를 출력한다.

 

status 또는 stat, st - 로컬 경로의 파일이나 디렉토리의 상태를 보여준다.

$ svn status [PATH]

: 해당 파일이 수정, 추가되었는지 등의 정보를 보여준다. -u 옵션을 주면 저장소의 최신 리비젼이 얼마인지 알려준다.

 

diff 또는 di - 서로 다른 리비젼 간에 차이점을 출력해준다.

$ svn diff [-r N:MTARGET

: 지정된 파일이나 경로에 대해 이전 리비젼하고 차이점을 보여준다. -r 을 지정하면 리비젼 N과 M사이의 차이점을 출력해준다.

예제) svn -r 30:45 test

설명) test 경로내에서 리비젼 번호 30과 45의 차이점을 출력해준다.

 

merge - 두 source 사이에 변경 내용을 작업 경로에 적용해준다.

1. $ svn merge URL1[@NURL2[@M] [PATH]

2. $ svn merge [-r N:MSOURCE [PATH]

: 1. URL1[리비젼 N]과 URL2[리비젼 M]을 비교하여, 변경 내용을 작업경로에 적용한다.

  2. SOURCE의 리비젼 N과 M을 비교하여, 해당 작업경로에 적용한다.

merge는 branch로 분리된 source에 대해 각각의 변경 내용을 현재의 작업에 병합하고자 할때 유용하다.

 

blame 또는 praise, annotate, ann - 지정한 파일이나 URL의 내용 수정내역을 각 라인별로 보여준다.

$ svn blame TARGET

: 해당 파일의 각 라인에 대해 리비젼과 작성자를 나타내 준다. 누가 언제 어떤행을 수정했는지 알수 있음.

 

import - 파일과 디렉토리를 저장소에 추가한다.

$ svn import [PATHURL

 

: URL에 지정된 PATH의 하위 디렉토리는 재귀적으로 추가되며, 필요시 상위 디렉토리가 자동으로 생성된다.

 

export - 저장소에서 순수하게 프로그램 소스만 가져온다.

$ svn export URL [PATH]

: export는 버전관리를 위한 부속 파일들은 제외하고 순수한 소스만 받아오기 때문에, 주로 source release 용도로 사용되게된다. -r 옵션을 지정해서 해당 리비젼의 소스를 받아올 수 있다.

:
Posted by 라면스프
2013. 1. 14. 16:44

[C] HTTP POST로 파일 업로드하는 코드 Enjoy/etc2013. 1. 14. 16:44

출처 : http://visu4l.tistory.com/396



[C] HTTP POST로 파일 업로드하는 코드


Java나 C++ objective-c는 http 용 기본 라이브러리가 있어서 편하지만


C용은 직접 만들어 써야한다. 이미 제작해서 라이브러리는 배포하는곳도 있지만 간단한 파일을 보내는데


어마어마한 라이브러리는 포함시킬필요는 없다.


그래서 C 언어로 간한히 POST 업로드하는 코드를 만들어 놨다.


body를 만드는 부분이 중요하다. 그렇기 때문에 상세히 분석후 수정하여 사용하자.



예문

:
Posted by 라면스프
2013. 1. 10. 10:10

Flex DataGrid ItemRenderer #3 Enjoy/FLEX2013. 1. 10. 10:10

출처 : http://igna84.blogspot.kr/2010/03/flex-datagrid-itemrenderer-3-%EB%98%90%EB%8B%A4%EB%A5%B8-%EC%A0%84%EC%9F%81%EC%9D%98-%EC%84%9C%EB%A7%89.html



Flex DataGrid ItemRenderer #3- 또다른 전쟁의 서막

지난 시간 제기한 문제점은 아래와 같았습니다.

 

1. "Y", "N" 값으로만 작동하게 되어있다.

2. CheckBox를 클릭하면 뭔가 다른 행동을 하고 싶을땐 어떻게 하나.

 

외부에서 들어오는 데이터가 "0"이나 "1"이면 어떻한다?(혹은 true 나 false일지도..)

CheckBox를 클릭하면 Alert 창이 떠야한다면?

 

이럴때마다 ItemRenderer를 열어서 수정해야한다면 말이 안되겠지요.

일단 2번 같은 경우는 제가 알기로는 두가지 방법이 있습니다만 그중 하나는 Bubbles라는 이벤트 속성을 이용하는 방법입니다만 ItemRenderer에서 이벤트를 발생시키면서 bubbles 속성을 true로 지정해주면 DataGrid 밖에서 이벤트를 받아올 수 있지요.

다만.. bubbles라는 녀석의 특성상 데이터가 많이 꼬일 염려가 있다는게 문제입니다.

(꼬인다는건 "디버깅"이 어려워질 수 있다는 말을 쉽게 풀어 쓴 말입니다.)

 

그래서 저는 가장 확실한 방법으로 CallBack 함수를 지정해 놓는 방법을 선택했습니다.

아래의 코드를 봐주세요.

 

Main.mxml
[code xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:renderers="classes.controls.renderers.*">
<mx:Script>
    <![CDATA[
    import mx.collections.ArrayCollection;
    import mx.controls.Alert;

    [Bindable]
    private var ac:ArrayCollection = new ArrayCollection([
                                        {index:1, description:"test1", toggle:"Y"},
                                        {index:2, description:"test2", toggle:"N"},
                                        {index:3, description:"test3", toggle:"N"},
                                        {index:4, description:"test4", toggle:"Y"},
                                        {index:5, description:"test5", toggle:"N"},
                                        {index:6, description:"test6", toggle:"N"},
                                        {index:7, description:"test7", toggle:"Y"},
                                        {index:8, description:"test8", toggle:"N"},
                                        {index:9, description:"test9", toggle:"N"},
                                        {index:10, description:"test10", toggle:"N"},
                                        {index:11, description:"test11", toggle:"N"},
                                        {index:12, description:"test12", toggle:"N"}
                                        ]);

    public function checkBoxRendererClickHandler(data:Object):void
    {
        Alert.show("click by " + data.description);
    }
    ]]>
</mx:Script>
<mx:DataGrid dataProvider="{ac}">
    <mx:columns>
        <mx:DataGridColumn headerText="index" dataField="index" />
        <mx:DataGridColumn headerText="description" dataField="description" />
        <mx:DataGridColumn headerText="radio" dataField="toggle">
            <mx:itemRenderer>
                <mx:Component>
                    <renderers:CheckBoxRenderer onClickFunction="{outerDocument.checkBoxRendererClickHandler}" />
                </mx:Component>
            </mx:itemRenderer>
        </mx:DataGridColumn>
    </mx:columns>
</mx:DataGrid>
</mx:Application>
[/code]

CheckBoxRenderer.as
[code as3]
package classes.controls.renderers
{
//-----------------------------------------------------------------------------
//
//  Import
//
//-----------------------------------------------------------------------------
import flash.events.MouseEvent;

import mx.core.IDataRenderer;
import mx.controls.CheckBox;
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.mx_internal;
import mx.events.FlexEvent;

use namespace mx_internal;

public class CheckBoxRenderer extends CheckBox
{
    //-----------------------------------------------------------------------------
    //
    //  Constructor
    //
    //-----------------------------------------------------------------------------
    /**
     *  Constructor.
     */
    public function CheckBoxRenderer()
    {
        super();
    }

    //-----------------------------------------------------------------------------
    //
    //  Variables
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     *  데이터 변경 확인 플래그
     */
    private var dataChanged:Boolean = false;

    //-----------------------------------------------------------------------------
    //
    //  Properties
    //
    //-----------------------------------------------------------------------------
    //-------------------------------------
    //  onClickFunction
    //-------------------------------------
    /**
     *  @private
     */    
    private var _onClickFunction:Function;
    /**
     *  클릭시 실행할 콜백함수 속성
     */
    public function set onClickFunction(value:Function):void
    {
        _onClickFunction = value;
    }
    /**
     *  @private
     */    
    public function get onClickFunction():Function
    {
        return onClickFunction;
    }
    //-----------------------------------------------------------------------------
    //
    //  Override Properties
    //
    //-----------------------------------------------------------------------------
    override public function set data(value:Object):void
    {
        super.data = value;

        dataChanged = true;
        invalidateProperties();
    }

    //-----------------------------------------------------------------------------
    //
    //  Override Methods
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     */
    override protected function createChildren():void
    {
        super.createChildren();
    }

    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();

        if(dataChanged)
        {
            dataChanged = false;
            updateProperties();
        }
    }

    /**
     *  @private
     */
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        currentIcon.x = (unscaledWidth - currentIcon.width) / 2;
    }

    //-----------------------------------------------------------------------------
    //
    //  Methods
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     *  CheckBox의 속성을 변경
     */
    private function updateProperties():void
    {
        if(listData.label == "Y")
        {
            selected = true;
        }
        else
        {
            selected = false;
        }

        invalidateDisplayList();
    }

    //-----------------------------------------------------------------------------
    //
    //  Override EventHandler
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     */
    override protected function clickHandler(event:MouseEvent):void
    {
        super.clickHandler(event);

        //data[DataGridListData(listData).dataField] = selected ? "Y" : "N";

        if(selected)
        {
            data[DataGridListData(listData).dataField] = "Y";
        }
        else
        {
            data[DataGridListData(listData).dataField] = "N";
        }

        if(_onClickFunction != null)
        {
            _onClickFunction(data);
        }
    }
}
}
[/code]

 

위와같이 코딩하게 되면 아래와 같은 산출물이 나오게 됩니다.

 

 

CheckBoxRenderer를 클릭해보세요. Alert창이 뜨는걸 볼 수 있지요.

그럼 2번 문제는 해결된것 같습니다. 그럼 1번 문제인 "Y", "N" 이외의 다른 문자열이 들어올땐 어떻게 할까요? 라는 문제는 방금 2번 문제를 해결한것과 같이 해결하면 될것 같습니다.

아래 처럼요.

 

[code as3]
package classes.controls.renderers
{
//-----------------------------------------------------------------------------
//
//  Import
//
//-----------------------------------------------------------------------------
import flash.events.MouseEvent;

import mx.core.IDataRenderer;
import mx.controls.CheckBox;
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.mx_internal;
import mx.events.FlexEvent;

use namespace mx_internal;

public class CheckBoxRenderer extends CheckBox
{
    //-----------------------------------------------------------------------------
    //
    //  Constructor
    //
    //-----------------------------------------------------------------------------
    /**
     *  Constructor.
     */
    public function CheckBoxRenderer()
    {
        super();
    }

    //-----------------------------------------------------------------------------
    //
    //  Variables
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     *  데이터 변경 확인 플래그
     */
    private var dataChanged:Boolean = false;
    //-----------------------------------------------------------------------------
    //
    //  Properties
    //
    //-----------------------------------------------------------------------------
    //-------------------------------------
    //  onClickFunction
    //-------------------------------------
    /**
     *  @private
     */    
    private var _onClickFunction:Function;

    /**
     *  클릭시 실행할 콜백함수 속성
     */
    public function set onClickFunction(value:Function):void
    {
        _onClickFunction = value;
    }

    /**
     *  @private
     */    
    public function get onClickFunction():Function
    {
        return onClickFunction;
    }

    //-------------------------------------
    //  selectedFlag
    //-------------------------------------
    /**
     *  @private
     */    
    private var _selectedFlag:Array = ["Y", "N"];

    /**
     *  <p>true, false를 처리할 flag를 Array형태로 받아 처리.</p>
     *  <p>이때 selectedFlag의 length는 2를 초과할 수 없음.</p>
     *  @default    ["Y", "N"]
     */    
    public function set selectedFlag(value:Array):void
    {
        if(value.length > 2)
        {
            throw(new Error("selectedFlag:Array의 값은 두개를 초과할 수 없습니다."));
        }
        _selectedFlag = value;
    }

    /**
     *  @private
     */    
    public function get selectedFlag():Array
    {
        return _selectedFlag;
    }
    //-----------------------------------------------------------------------------
    //
    //  Override Properties
    //
    //-----------------------------------------------------------------------------
    override public function set data(value:Object):void
    {
        super.data = value;
        dataChanged = true;
        invalidateProperties();
    }
    //-----------------------------------------------------------------------------
    //
    //  Override Methods
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     */
    override protected function createChildren():void
    {
        super.createChildren();
    }

    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();

        if(dataChanged)
        {
            dataChanged = false;

            updateProperties();
        }
    }

    /**
     *  @private
     */
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        currentIcon.x = (unscaledWidth - currentIcon.width) / 2;
    }

    //-----------------------------------------------------------------------------
    //
    //  Methods
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     *  CheckBox의 속성을 변경
     */
    private function updateProperties():void
    {
        if(data[DataGridListData(listData).dataField] == _selectedFlag[0])
        {
            selected = true;
        }
        else
        {
            selected = false;
        }

        invalidateDisplayList();
    }

    //-----------------------------------------------------------------------------
    //
    //  Override EventHandler
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     */
    override protected function clickHandler(event:MouseEvent):void
    {
        super.clickHandler(event);

        //data[DataGridListData(listData).dataField] = selected ? _selectedFlag[0] : _selectedFlag[1];

        if(selected)
        {
            data[DataGridListData(listData).dataField] = _selectedFlag[0];
        }
        else
        {
            data[DataGridListData(listData).dataField] = _selectedFlag[1];
        }

        if(_onClickFunction != null)
        {
            _onClickFunction(data);
        }
    }
}
}
[/code]

이렇게 수정하고 나면 눈으로 보기엔 아무 바뀐게 없어 보일지 모르겠지만 데이터가 "Y", "N"이 아니라 true나 false로 들어온다 하더라도 selectedFlag를 변경해주면 바로 적용할 수 있게 된다.

(163번째 줄 확인 꼭 하셔야합니다. label로 되어있던걸 data에서 바로 값을 뽑아서 비교하게끔 했어요. 이유는 true나 false같은 경우는 String이 아니기때문에 비교식 성립이 안되거든요.)

 

아래와 같이 Main.mxml 파일을 수정해보면 알 수 있다.

[code xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:renderers="classes.controls.renderers.*">
<mx:Script>
    <![CDATA[
    import mx.collections.ArrayCollection;
    import mx.controls.Alert;

    [Bindable]
    private var ac:ArrayCollection = new ArrayCollection([
                               {index:1, description:"test1", toggle:true},
                               {index:2, description:"test2", toggle:false},
                               {index:3, description:"test3", toggle:false},
                               {index:4, description:"test4", toggle:true},
                               {index:5, description:"test5", toggle:false},
                               {index:6, description:"test6", toggle:false},
                               {index:7, description:"test7", toggle:true},
                               {index:8, description:"test8", toggle:false},
                               {index:9, description:"test9", toggle:false},
                               {index:10, description:"test10", toggle:false},
                               {index:11, description:"test11", toggle:false},
                               {index:12, description:"test12", toggle:false}
                               ]);

    public function checkBoxRendererClickHandler(data:Object):void
    {
        Alert.show("click by " + data.description);
    }
    ]]>
</mx:Script>
<mx:DataGrid dataProvider="{ac}">
    <mx:columns>
        <mx:DataGridColumn headerText="index" dataField="index" />
        <mx:DataGridColumn headerText="description" dataField="description" />
        <mx:DataGridColumn headerText="radio" dataField="toggle">
            <mx:itemRenderer>
                <mx:Component>
                    <renderers:CheckBoxRenderer
                        selectedFlag="{[true, false]}"
                        onClickFunction="{outerDocument.checkBoxRendererClickHandler}" />
                </mx:Component>
            </mx:itemRenderer>
        </mx:DataGridColumn>
    </mx:columns>
</mx:DataGrid>

</mx:Application>
[/code]

이제 대충 감이 오시나요?

Renderer에 대해서 감이 오셨다면 다행입니다.

하지만 "CheckBox"는 대충 알겠는데 "ComboBox"는? "ComboBoxRenderer"는 어떻게 만드나요? 라고 하신다면 1, 2, 3회에 걸쳐 Renderer에 대해 설명한 이유가 없어요. 다시 한번 훑어보시고 연구하시면 될거 같아요.

답은 스스로 만들어가는 것.

 

다음 시간엔... HeaderRenderer를 해볼까 하다가 좀 다른게 만져보고 싶어져서.. 기대하세요.

:
Posted by 라면스프