Code Style Guide
This is a draft of the official OpenWrt Code Style Guide: conventions to follow when writing code for OpenWrt. It is not yet approved or agreed upon, and is subject to change based on discussion and consensus but is drafted here based on common trends observed in the codebase.
General
Applies to all source code files.
- Code can be indented using either tabs or spaces, as long as it is consistent within the source code file
- Avoid trailing spaces at the end of lines
- Files should be terminated with a new line
Scripts
The main shell used in OpenWrt is the Almquist Shell, ash/sh (#!/bin/sh). Code should conform to the POSIX specification. Tools such as shellcheck can be used to ensure code conforms to the POSIX specification. Some important examples include: variable quoting and the expression of logical statements.
Init Scripts
Scripts that launch programs or services are typically stored in the /etc/init.d/
directory. These scripts are written for either procd or the deprecated ucitrack.
- An opening curly brace goes on the same line as the function declaration, e.g.:
my_function() {
Config Files
Files to store configuration have their own formatting, see this link for details: uci
Makefiles
Makefiles have their own special mix of syntax that must be observed.
- Use tabs instead of spaces for all sections except for the Package/description section
For the Package/description section, indent with two spaces:
define Package/example SECTION:=utils CATEGORY:=Utilities TITLE:=Example DEPENDS:=+example-dependency endef
Other functions should be indented with a full tab:
define Package/example/install $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/example.init $(1)/etc/init.d/example $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) ./files/example $(1)/usr/bin/example $(INSTALL_DIR) $(1)/etc/config $(INSTALL_DATA) ./files/example.config $(1)/etc/config/example endef
LuCI
Javascript
Options
Option signatures should be put onto a new line after the option name, and subsequent parameters in the signature started on their own line. Line breaks should be tabbed in to be flush with the line above.
o = s.taboption('general', widgets.NetworkSelect, 'mmifacename', _('Name of ModemManager Interface'), _("Applies to Ping Reboot and Restart Interface modes</i> <br> If using ModemManager, \ you can have Watchcat restart your ModemManger interface by specifying its name.")); o.depends({ mode: 'restart_iface' }); o.optional = true;