Scintilla and SciTE |
Scintilla와 SciTE의 소스 코드는 본인의 취향을 따른다. 본인 마음대로 결정한 것도 있고 본인의 미적 감각에 기반한 것도 있다. 그러나 누구나 다 정확하게 좋아하지는 않을지라도 모든 코드가 똑같이 보이게 만드는 것이 좋다.
이런 관례를 따르지 않는 코드도 허용은 되지만, 시간이 지나면서 서서히 관례에 맞게 된다. 신틸라 코드는 SciTE보다 더 엄격하게 관례를 따른다. 단 상대적으로 독립적인 모듈인 어휘분석기들은 예외이다. 다른 이들이 관리하는 어휘분석기는 제출된 그대로 둔다. 단 경고는 수정해서 전체 프로젝트가 깨끗하게 컴파일되도록 한다.
비록 버그가 좀 있지만 AStyle 포맷팅 프로그램은 다음을 인자로 주면 코드를 올바르게 포맷한다: '--style=attach --indent=force-tab=8 --keep-one-line-blocks pad-header --unpad-paren --pad-comma --indent-cases --align-pointer=name --pad-method-prefix pad-return-type --pad-param-type --align-method-colon --pad-method-colon=after'
Scintilla와 SciTE의 디자인 목표는 현재 나와있는 컴파일러들이 다양한 플랫폼에서 높은 수행성능과 자원을 적게 사용하도록 하는 이식성을 목표로 한다. 신틸라는 SciTE보다 더 엄격하게 이식성이 요구된다. 왜냐하면 낮은 성능의 플랫폼에도 이식될 가능성이 있기 때문이다. Scintilla 코드는 "g++ --std=c++17" 옵션을 가지고 C++17로 빌드해야 한다. SciTE는 g++ 7.1과 MSVC 2017.6 그리고 Clang 5.0 컴파일러에서 널리 지원하는 C++17 특징을 사용할 수 있다.
이식성을 확보하기 위하여, C++ 특징의 하위 집합만 사용된다. 예외와 템블릿을 사용할 수도 있지만, 신틸라는 C는 물론 C++에서도 사용되기 때문에, 예외는 Scintilla 밖으로 던져지지 않으며 모든 예외는 신틸라에서 돌려주기 전에 반드시 잡아야 한다. 실행-시간 유형은 정보가 메모리 사용에 추가되기 때문에 꺼진 상태로 둔다. 'Scintilla' 이름 공간은 SCI_NAMESPACE 정의에 기반하여 선택적으로 사용된다. 이 덕분에 macOS에서 이름 충돌 해결에 도움이 된다.
ILexer와 같이 SCI_METHOD가 들어 있는 인터페이스를 구현할 때 SCI_METHOD 전처리기 정의를 사용해야 하며 그 방법밖에 없다.
헤더는 언제나 scripts/HeaderOrder.txt 파일에 주어진 순서대로 포함시켜야 한다.
goto 서술문은 사용되지 않는다. 처음 FORTRAN 프로그램을 유지 관리하던 때의 나쁜 기억 때문이다. union 특징은 안전하지-않은-유형의 값에 접근할 가능성이 있기 때문에 사용되지 않는다.
(char *)s 같은 구형 C 스타일의 형변환을 사용하지 말자. 대신에 가능하면 const_cast<char *>(s)와 같이 아주 엄격한 형태의 C++ 형변환을 사용하자. 가능하면 reinterpret_cast보다 static_cast와 const_cast를 사용하자. 코드는 실행-사간 유형의 정보와 함께 컴파일되므로, dynamic_cast는 작동하지 않는다.
새 스타일의 형변환을 사용하면 장점은 어떤 문제가 진행중인지 명시적으로 상세하게 기술한다는 것이다. 그리고 뭔가 잠재적으로 안전하지 못한 것이 처리되고 있다는 신호로 작동한다.
상수(const)를 많이 다룬 코드일 수록 사람이든 컴파일러든 훨씬 더 쉽게 이해할 수 있다. 그래서 const 매개변수를 사용하고 const_cast를 피하자.
코드가 잘 작성되고 이식성이 있기 위하여, 거의 모든 경고가 켜진 상태로 컴파일된다. 이 때문에 가끔 완전히 올바른 거짓 가정(false positives)에 경고가 일어나기도 한다. 하지만 해당 코드를 바꿔서 경고를 피하면 일반적으로 빠르고 가독성에도 충격이 별로 없다.
모든 변수를 초기화하고 변수의 영역을 최소화하자. 사용하기 바로 전에 변수가 정의되어 있으면 그 지점 전까지는 코드가 잘못 사용될 수 없다. C++ 표준 라이브러리와 현재 사용하는 컴파일러에 호환성이 있는 회돌이 선언을 사용하자.
신틸라에 메쏘드가 많으면 메모리가 고갈될 수 있다. 메모리 고갈을 점검하고 처리해야 한다. 그러나 일단 메모리 고갈이 일어나면, 처리하기 매우 어렵다. 신틸라의 데이터 구조의 상태가 불안할 수 있기 때문이다. 그래서 고정 길이 버퍼가 종종 사용된다. 간단하고 메모리 고갈을 걱정할 필요가 없기 때문이다. 그러나 버퍼 길이에 신경써야 한다.
C++의 new 그리고 delete 연산자들은 C의 malloc와 free 보다 더 좋다. new와 delete는 유형에 안전하기 때문이다.
여는 괄호, '{'는 제어 구조가 시작하는 처음에 두어야 한다. 그리고 닫는 괄호, '}'는 줄에서 들여쓴 부분에 있어야 한다. else 절이 있으면, '}'와 같은 절에 둔다. 이 형태는 줄을 덜 사용한다. 따라서 더 많은 코드를 화면에 보여줄 수 있다. 완전하게 괄호를 지은 제어 구조가 더 좋다. 왜냐하면 이렇게 해야 수정이 올바르게 될 것이고 신틸라의 접기기능이 작동할 가능성이 더 높기 때문이다. 표현식에 괄호가 없이 반환하면 그 표현식은 함수 호출이 아니라 키워드이다.
bool fn(int a) {'='와 비교 연산사 사이 양쪽의 공간은 두지 않고 '='를 일렬로 정렬하려고 시도하지 않는다. '(' 앞뒤의 공간은 함수 호출에서는 사용되지 않지만, ',' 뒤에는 공간 하나를 둔다. 짧은 표현식에 있는 토큰 사이에 공간이 없지만 긴 표현식에는 있을 수 있다. '{'에 공간을 둔다. ';' 앞에는 공간이 없다. 포인터를 뜻하는데 사용되는 '*' 뒤에는 공간이 없다. '['나 ']' 뒤에는 공간을 두지 않는다. 키워드와 '(' 사이에 공간 하나를 둔다.
void StoreConditionally(int c, const char *s) {식별자는 대소문자를 혼용하고 밑줄문자는 사용하지 않는다. 클래스와 함수 그리고 메쏘드 이름은 대문자로 시작하고 대문자를 더 사용해 단어를 구별한다. 변수는 소문자로 시작하고 대문자를 사용해 단어를 구분한다. 회돌이 계수와 유사 변수들은 단순하게 그냥 'i'와 같이 이름짓는다. 함수 호출은 앞에 전역 영역 수식자인 '::' 를 두어서 메쏘드 호출과 차별화된다.
class StorageZone {렉서는 별도의 Lexilla 프로젝트로 이동했다. 프로젝트는 GitHub에 있고 여기에서 갱신된다.
문제점이나 요청은 렉실라 프로젝트 페이지에 보내자.
모든 어휘 상태는 수정된 LexicalStyles.iface에 정의하자.
사용하는 컴파일러에 경고가 없어야 한다. 기타 컴파일러의 경고는 특징 요청 게시판에 고지된다.
sc.ch는 int 유형이다: 이것을 문자로 해서 건네지 말자.