PageSourceSearch

https://chronolog.dev/docs/assets/js/929e5942.dddd9149.js

js chronolog.dev collected 2026-10-04 18:03:10 UTC 13,552 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkdocs=globalThis.webpackChunkdocs||[]).push([[2804],{27362(e,n,i){i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>a,frontMatter:()=>d,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"contributing/guidelines/code-style","title":"Code Style","description":"ChronoLog is a C++17 project. All formatting is enforced by clang-format-18 in CI \u2014 pull requests that don\'t pass the format check cannot be merged.","source":"@site/versioned_docs/version-2.8.0/contributing/guidelines/code-style.md","sourceDirName":"contributing/guidelines","slug":"/contributing/guidelines/code-style","permalink":"/docs/2.8.0/contributing/guidelines/code-style","draft":false,"unlisted":false,"editUrl":"https://github.com/grc-iit/ChronoLog/tree/main/docs/versioned_docs/version-2.8.0/contributing/guidelines/code-style.md","tags":[],"version":"2.8.0","sidebarPosition":2,"frontMatter":{"sidebar_position":2,"title":"Code Style"},"sidebar":"contributingSidebar","previous":{"title":"Git Workflow","permalink":"/docs/2.8.0/contributing/guidelines/git-workflow"},"next":{"title":"CI/CD","permalink":"/docs/2.8.0/contributing/guidelines/ci-cd"}}');var s=i(74848),t=i(28453);const d={sidebar_position:2,title:"Code Style"},l="Code Style",o={},c=[{value:"Formatting Tool",id:"formatting-tool",level:2},{value:"Running Locally",id:"running-locally",level:2},{value:"Pre-commit Hook",id:"pre-commit-hook",level:3},{value:"IDE Integration",id:"ide-integration",level:2},{value:"CLion",id:"clion",level:3},{value:"VS Code",id:"vs-code",level:3},{value:"Other Editors",id:"other-editors",level:3},{value:"CI Enforcement",id:"ci-enforcement",level:2},{value:"Naming Conventions",id:"naming-conventions",level:2},{value:"Error Handling and Logging",id:"error-handling-and-logging",level:2},{value:"Error Codes",id:"error-codes",level:3},{value:"Logging",id:"logging",level:3},{value:"Additional Static Analysis",id:"additional-static-analysis",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"code-style",children:"Code Style"})}),"\n",(0,s.jsxs)(n.p,{children:["ChronoLog is a C++17 project. All formatting is enforced by ",(0,s.jsx)(n.strong,{children:"clang-format-18"})," in CI \u2014 pull requests that don't pass the format check cannot be merged."]}),"\n",(0,s.jsx)(n.h2,{id:"formatting-tool",children:"Formatting Tool"}),"\n",(0,s.jsx)(n.p,{children:"Install clang-format-18 from the default Ubuntu 24.04 repositories:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo apt-get update && sudo apt-get install -y clang-format-18\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The project configuration lives at ",(0,s.jsx)(n.a,{href:"https://github.com/grc-iit/ChronoLog/tree/develop/.github/code-style/ChronoLog.clang-format",children:(0,s.jsx)(n.code,{children:".github/code-style/ChronoLog.clang-format"})}),". Key settings:"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Setting"}),(0,s.jsx)(n.th,{children:"Value"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Column limit"}),(0,s.jsx)(n.td,{children:"120 characters"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Indent width"}),(0,s.jsx)(n.td,{children:"4 spaces"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Tabs"}),(0,s.jsx)(n.td,{children:"Never"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Pointer alignment"}),(0,s.jsxs)(n.td,{children:["Left (",(0,s.jsx)(n.code,{children:"int* p"}),")"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Brace wrapping"}),(0,s.jsx)(n.td,{children:"Allman style (braces on their own line)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Sort includes"}),(0,s.jsx)(n.td,{children:"Never (preserves intentional ordering)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Bin-pack arguments/parameters"}),(0,s.jsx)(n.td,{children:"No (one per line when wrapped)"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"running-locally",children:"Running Locally"}),"\n",(0,s.jsx)(n.p,{children:"Format a single file:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"clang-format-18 -i -style=file:.github/code-style/ChronoLog.clang-format path/to/file.cpp\n"})}),"\n",(0,s.jsx)(n.h3,{id:"pre-commit-hook",children:"Pre-commit Hook"}),"\n",(0,s.jsxs)(n.p,{children:["The repository includes a ready-made hook at ",(0,s.jsx)(n.code,{children:".github/code-style/pre-commit"})," that automatically formats staged C/C++ files before each commit. Install it by copying it into your local hooks directory:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cp .github/code-style/pre-commit .git/hooks/pre-commit\nchmod +x .git/hooks/pre-commit\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The hook searches for ",(0,s.jsx)(n.code,{children:"clang-format-18"})," in ",(0,s.jsx)(n.code,{children:"~/.local/bin"}
1),", ",(0,s.jsx)(n.code,{children:"/usr/local/bin"}),", ",(0,s.jsx)(n.code,{children:"/usr/bin"}),", and ",(0,s.jsx)(n.code,{children:"$PATH"}),". You can override the binary by setting the ",(0,s.jsx)(n.code,{children:"CLANG_FORMAT"})," environment variable."]}),"\n",(0,s.jsx)(n.h2,{id:"ide-integration",children:"IDE Integration"}),"\n",(0,s.jsx)(n.h3,{id:"clion",children:"CLion"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Go to ",(0,s.jsx)(n.strong,{children:"File > Settings > Editor > Code Style > C/C++"})]}),"\n",(0,s.jsxs)(n.li,{children:["Click the gear icon and choose ",(0,s.jsx)(n.strong,{children:"Import Scheme"})]}),"\n",(0,s.jsxs)(n.li,{children:["Import ",(0,s.jsx)(n.code,{children:".github/code-style/ChronoLog.xml"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"vs-code",children:"VS Code"}),"\n",(0,s.jsxs)(n.p,{children:["Install the ",(0,s.jsx)(n.strong,{children:"Clang-Format"})," extension (or use clangd), then add to your workspace settings:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n  "C_Cpp.clang_format_path": "/usr/bin/clang-format-18",\n  "C_Cpp.clang_format_style": "file:${workspaceFolder}/.github/code-style/ChronoLog.clang-format",\n  "editor.formatOnSave": true\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"other-editors",children:"Other Editors"}),"\n",(0,s.jsxs)(n.p,{children:["Point your editor's clang-format integration at the ",(0,s.jsx)(n.code,{children:".github/code-style/ChronoLog.clang-format"})," file and ensure it uses version 18. Different versions may produce different output."]}),"\n",(0,s.jsx)(n.h2,{id:"ci-enforcement",children:"CI Enforcement"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"Clang Format Check"})," workflow runs on every pull request that touches C/C++ files (",(0,s.jsx)(n.code,{children:".cpp"}),", ",(0,s.jsx)(n.code,{children:".h"}),", ",(0,s.jsx)(n.code,{children:".hpp"}),", ",(0,s.jsx)(n.code,{children:".cc"}),", ",(0,s.jsx)(n.code,{children:".cxx"}),", ",(0,s.jsx)(n.code,{children:".c"}),"). When formatting issues are found:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"The workflow posts a comment on your PR listing the affected files"}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.code,{children:"clang-format-patches"})," artifact is uploaded with patch files"]}),"\n",(0,s.jsx)(n.li,{children:"The check fails, blocking the PR"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"To fix a failed check:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'# Option A: download and apply the patch artifact\ngh run download <run-id> -n clang-format-patches\ngit apply format_fixes.patch\n\n# Option B: format the files manually\nclang-format-18 -i -style=file:.github/code-style/ChronoLog.clang-format <file>\n\n# Then commit and push\ngit add -u && git commit -m "style: fix formatting"\ngit push\n'})}),"\n",(0,s.jsx)(n.h2,{id:"naming-conventions",children:"Naming Conventions"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Element"}),(0,s.jsx)(n.th,{children:"Convention"}),(0,s.jsx)(n.th,{children:"Example"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Classes / Structs"}),(0,s.jsx)(n.td,{children:"PascalCase"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"StoryChunk"}),", ",(0,s.jsx)(n.code,{children:"ChronoKeeperClient"})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Methods / Functions"}),(0,s.jsx)(n.td,{children:"camelCase"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"acquireStory()"}),", ",(0,s.jsx)(n.code,{children:"processEvent()"})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Member variables"}),(0,s.jsxs)(n.td,{children:["camelCase, private members prefixed with ",(0,s.jsx)(n.code,{children:"the"})]}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"theStoryId"}),", ",(0,s.jsx)(n.code,{children:"theEventQueue"})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Local variables"}
1),(0,s.jsx)(n.td,{children:"camelCase"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"storyName"}),", ",(0,s.jsx)(n.code,{children:"eventCount"})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Enums"}),(0,s.jsx)(n.td,{children:"PascalCase name, UPPER_CASE values"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"enum class CLogStoryAcquisitionResult { CL_SUCCESS, CL_ERR_UNKNOWN }"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Typedefs / Aliases"}),(0,s.jsx)(n.td,{children:"PascalCase"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"StoryId"}),", ",(0,s.jsx)(n.code,{children:"ChunkMap"})]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Namespaces"}),(0,s.jsx)(n.td,{children:"lowercase"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"chronolog"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Header guards"}),(0,s.jsxs)(n.td,{children:[(0,s.jsx)(n.code,{children:"#ifndef"})," with full path"]}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"#ifndef CHRONO_COMMON_CHRONOLOG_ERRCODE_H"})})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Constants / Macros"}),(0,s.jsx)(n.td,{children:"UPPER_CASE"}),(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"MAX_STORY_CHUNK_SIZE"})})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"error-handling-and-logging",children:"Error Handling and Logging"}),"\n",(0,s.jsx)(n.h3,{id:"error-codes",children:"Error Codes"}),"\n",(0,s.jsxs)(n.p,{children:["ChronoLog uses integer error codes defined in ",(0,s.jsx)(n.code,{children:"src/chrono-common/include/chronolog_errcode.h"}),". Return ",(0,s.jsx)(n.code,{children:"CL_SUCCESS"})," (0) on success and negative values on failure. The file provides ",(0,s.jsx)(n.code,{children:"to_string()"})," conversion functions for human-readable log output."]}),"\n",(0,s.jsx)(n.h3,{id:"logging",children:"Logging"}),"\n",(0,s.jsxs)(n.p,{children:["ChronoLog uses ",(0,s.jsx)(n.a,{href:"https://github.com/gabime/spdlog",children:"spdlog"})," through wrapper macros:"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Macro"}),(0,s.jsx)(n.th,{children:"Use"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"LOG_TRACE(...)"})}),(0,s.jsx)(n.td,{children:"Verbose debugging (off in release)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"LOG_DEBUG(...)"})}),(0,s.jsx)(n.td,{children:"Developer-facing diagnostics"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"LOG_INFO(...)"})}),(0,s.jsx)(n.td,{children:"Normal operational messages"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"LOG_WARNING(...)"})}),(0,s.jsx)(n.td,{children:"Unexpected but recoverable situations"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"LOG_ERROR(...)"})}),(0,s.jsx)(n.td,{children:"Failures that affect a single operation"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"LOG_CRITICAL(...)"})}),(0,s.jsx)(n.td,{children:"Unrecoverable errors"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"additional-static-analysis",children:"Additional Static Analysis"}),"\n",(0,s.jsxs)(n.p,{children:["The CMake build includes a ",(0,s.jsx)(n.strong,{children:"cpplint"})," target for additional style checking. This is not enforced in CI but can be useful during development:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cmake --build build --target cpplint\n"})})]})}function a(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453(e,n,i){i.d(n,{R:()=>d,x:()=>l});var r=i(96540);const s={},t=r.createContext(s);function d(e){const n=r.useContext(t);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.